Skip to content

Commit fba4e8f

Browse files
Merge pull request #89 from WebReflection/python-fix
Fixing recursion issue in Python too
2 parents c4b46db + 5fe8648 commit fba4e8f

File tree

3 files changed

+66
-33
lines changed

3 files changed

+66
-33
lines changed

php/test.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,26 @@ public static function assert($condition, $message) {
112112
'parse is correct'
113113
);
114114

115+
$AMOUNT = 1000;
116+
117+
$chain = array();
118+
$chain[] = 'leaf';
119+
120+
for ($i = 0; $i < $AMOUNT; $i++) {
121+
$curr = $chain;
122+
$chain = array();
123+
$chain[] = $curr;
124+
}
125+
126+
$str = Flatted::stringify($chain);
127+
$parsed = Flatted::parse($str);
128+
129+
for ($i = 0; $i < $AMOUNT; $i++) {
130+
$chain = $chain[0];
131+
}
132+
133+
var_dump($chain);
134+
115135
echo "OK\n";
116136

117-
?>
137+
?>

python/flatted.py

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

28-
2928
def _array_keys(value):
30-
keys = []
31-
i = 0
32-
for _ in value:
33-
keys.append(i)
34-
i += 1
35-
return keys
29+
for i in range(len(value)):
30+
yield i
3631

3732
def _object_keys(value):
38-
keys = []
3933
for key in value:
40-
keys.append(key)
41-
return keys
34+
yield key
4235

4336
def _is_array(value):
4437
return isinstance(value, (list, tuple))
@@ -56,24 +49,6 @@ def _index(known, input, value):
5649
known.value.append(index)
5750
return index
5851

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-
7752
def _relate(known, input, value):
7853
if _is_string(value) or _is_array(value) or _is_object(value):
7954
try:
@@ -83,6 +58,22 @@ def _relate(known, input, value):
8358

8459
return value
8560

61+
def _resolver(input, lazy, parsed):
62+
def resolver(output):
63+
keys = _array_keys(output) if _is_array(output) else _object_keys(output) if _is_object(output) else []
64+
for key in keys:
65+
value = output[key]
66+
if isinstance(value, _String):
67+
tmp = input[int(value.value)]
68+
output[key] = tmp
69+
if (_is_array(tmp) or _is_object(tmp)) and tmp not in parsed:
70+
parsed.append(tmp)
71+
lazy.append([output, key])
72+
73+
return output
74+
75+
return resolver
76+
8677
def _transform(known, input, value):
8778
if _is_array(value):
8879
output = []
@@ -128,12 +119,16 @@ def parse(value, *args, **kwargs):
128119
input.append(value)
129120

130121
value = input[0]
122+
lazy = []
123+
revive = _resolver(input, lazy, [value])
131124

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

135-
if _is_object(value):
136-
return _loop(_object_keys(value), input, [value], value)
127+
i = 0
128+
while i < len(lazy):
129+
o, k = lazy[i]
130+
i += 1
131+
o[k] = revive(o[k])
137132

138133
return value
139134

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 = 1500
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)