unflatten : add an escape character (#70474)

This commit is contained in:
Emmanuel Cazenave 2022-10-19 13:17:43 +02:00
parent 3f571b6587
commit 9d01872495
2 changed files with 36 additions and 3 deletions

View File

@ -29,6 +29,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import re
from passerelle.utils.validation import is_number
@ -49,10 +50,22 @@ def unflatten(d, separator=FLATTEN_SEPARATOR):
# ok d is a dict
def map_digits(l):
return [int(x) if is_number(x) else x for x in l]
def split_key(key):
def map_key(x):
if is_number(x):
return int(x)
elif isinstance(x, str):
return x.replace('%s%s' % (FLATTEN_SEPARATOR, FLATTEN_SEPARATOR), FLATTEN_SEPARATOR)
return x
keys = [(map_digits(key.split(separator)), key) for key in d]
return [
map_key(x)
for x in re.split(
r'(?<!%s)%s(?!%s)' % (FLATTEN_SEPARATOR, FLATTEN_SEPARATOR, FLATTEN_SEPARATOR), key
)
]
keys = [(split_key(key), key) for key in d]
keys.sort()
def set_path(path, orig_key, d, value, i=0):

View File

@ -63,6 +63,19 @@ def test_unflatten_dict():
}
}
assert unflatten(
{
'a' + SEP + SEP + 'b': 1,
}
) == {'a' + SEP + 'b': 1}
assert unflatten(
{
'a' + SEP + SEP + 'b': 1,
'a' + SEP + SEP + 'c' + SEP + 'd': 1,
}
) == {'a' + SEP + 'b': 1, 'a' + SEP + 'c': {'d': 1}}
def test_unflatten_array():
assert unflatten(
@ -74,6 +87,13 @@ def test_unflatten_array():
}
) == [{'b': [1, True]}, {'c': [[1], 'a']}]
assert unflatten(
{
'0' + SEP + 'b' + SEP + '0': 1,
'1' + SEP + 'c' + SEP + SEP + '0': 1,
}
) == [{'b': [1]}, {'c' + SEP + '0': 1}]
def test_unflatten_missing_final_index():
with pytest.raises(ValueError) as exc_info: