Skip to content

Commit b3e2a0c

Browse files
committed
Fixing recursion issue in Python too
1 parent d3418c7 commit b3e2a0c

File tree

2 files changed

+45
-22
lines changed

2 files changed

+45
-22
lines changed

python/flatted.py

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,25 @@ class _String:
2525
def __init__(self, value):
2626
self.value = value
2727

28+
def _resolver(input, lazy, parsed):
29+
ignore = {}
30+
31+
def resolver(output):
32+
keys = _array_keys(output) if _is_array(output) else _object_keys(output) if _is_object(output) else []
33+
for key in keys:
34+
value = output[key]
35+
if isinstance(value, _String):
36+
tmp = input[int(value.value)]
37+
if (_is_array(tmp) or _is_object(tmp)) and tmp not in parsed:
38+
parsed.append(tmp)
39+
output[key] = ignore
40+
lazy.append([output, key, tmp])
41+
else:
42+
output[key] = tmp
43+
44+
return output
45+
46+
return resolver
2847

2948
def _array_keys(value):
3049
keys = []
@@ -56,24 +75,6 @@ def _index(known, input, value):
5675
known.value.append(index)
5776
return index
5877

59-
def _loop(keys, input, known, output):
60-
for key in keys:
61-
value = output[key]
62-
if isinstance(value, _String):
63-
_ref(key, input[int(value.value)], input, known, output)
64-
65-
return output
66-
67-
def _ref(key, value, input, known, output):
68-
if _is_array(value) and value not in known:
69-
known.append(value)
70-
value = _loop(_array_keys(value), input, known, value)
71-
elif _is_object(value) and value not in known:
72-
known.append(value)
73-
value = _loop(_object_keys(value), input, known, value)
74-
75-
output[key] = value
76-
7778
def _relate(known, input, value):
7879
if _is_string(value) or _is_array(value) or _is_object(value):
7980
try:
@@ -128,12 +129,16 @@ def parse(value, *args, **kwargs):
128129
input.append(value)
129130

130131
value = input[0]
132+
lazy = []
133+
revive = _resolver(input, lazy, [value])
131134

132-
if _is_array(value):
133-
return _loop(_array_keys(value), input, [value], value)
135+
value = revive(value)
134136

135-
if _is_object(value):
136-
return _loop(_object_keys(value), input, [value], value)
137+
i = 0
138+
while i < len(lazy):
139+
o, k, r = lazy[i]
140+
i += 1
141+
o[k] = revive(r)
137142

138143
return value
139144

python/test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,22 @@ def stringify(value):
6060
oo = parse('[{"a":"1","b":"0","c":"2"},{"aa":"3"},{"ca":"4","cb":"5","cc":"6","cd":"7","ce":"8","cf":"9"},{"aaa":"10"},{"caa":"4"},{"cba":"5"},{"cca":"2"},{"cda":"4"},"value2","value3","value1"]');
6161
assert oo['a']['aa']['aaa'] == 'value1' and oo == oo['b'] and oo['c']['ca']['caa'] == oo['c']['ca']
6262

63+
64+
AMOUNT = 1000
65+
66+
chain = ['leaf']
67+
for i in range(AMOUNT):
68+
chain = [chain]
69+
70+
str = stringify(chain)
71+
print('stringify', '✅')
72+
73+
parsed = parse(str)
74+
75+
for i in range(AMOUNT):
76+
chain = chain[0]
77+
78+
print(chain)
79+
print('parse', '✅')
80+
6381
print('OK')

0 commit comments

Comments
 (0)