mapres 3.dev17__tar.gz → 3.dev19__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mapres-3.dev17/src/mapres.egg-info → mapres-3.dev19}/PKG-INFO +1 -1
- {mapres-3.dev17 → mapres-3.dev19}/pyproject.toml +1 -1
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres/datamap.py +2 -1
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres/evaluator.py +3 -87
- {mapres-3.dev17 → mapres-3.dev19/src/mapres.egg-info}/PKG-INFO +1 -1
- {mapres-3.dev17 → mapres-3.dev19}/LICENSE +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/README.md +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/setup.cfg +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres/__init__.py +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres/ast.py +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres/cache.py +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres/exceptions.py +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres/layers.py +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres/maps/__init__.py +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres/maps/color.py +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres/maps/time.py +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres/parser.py +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres/resolver.py +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres/tokenizer.py +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres.egg-info/SOURCES.txt +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres.egg-info/dependency_links.txt +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres.egg-info/requires.txt +0 -0
- {mapres-3.dev17 → mapres-3.dev19}/src/mapres.egg-info/top_level.txt +0 -0
|
@@ -101,7 +101,8 @@ def datamap(_cls=None, *, syntax=None, mode=None, recursive=None,
|
|
|
101
101
|
def wrap(cls):
|
|
102
102
|
cls.__syntax__ = syntax
|
|
103
103
|
cls.__mode__ = mode
|
|
104
|
-
cls.__recursive__ = recursive
|
|
104
|
+
cls.__recursive__ = recursive if recursive is not None else False
|
|
105
|
+
# cls.__recursive__ = recursive
|
|
105
106
|
cls.__missing_key__ = missing_key or 'error'
|
|
106
107
|
cls.__ignore_delimiters__ = ignore_delimiters or False
|
|
107
108
|
|
|
@@ -41,32 +41,13 @@ class Evaluator:
|
|
|
41
41
|
parts.append(self._eval(child))
|
|
42
42
|
out = ''.join(parts)
|
|
43
43
|
|
|
44
|
-
# recursion
|
|
45
|
-
if self._has_recursive_maps():
|
|
46
|
-
seen = set()
|
|
47
|
-
depth = 0
|
|
48
|
-
max_depth = self._get_max_depth()
|
|
49
|
-
|
|
50
|
-
while depth < max_depth:
|
|
51
|
-
new_out = self._re_resolve(out)
|
|
52
|
-
if new_out == out:
|
|
53
|
-
break
|
|
54
|
-
if new_out in seen:
|
|
55
|
-
raise EvaluationError('Cycle detected in template recursion')
|
|
56
|
-
seen.add(new_out)
|
|
57
|
-
out = new_out
|
|
58
|
-
depth += 1
|
|
59
|
-
|
|
44
|
+
# recursion disabled for now (Mapres 2–style behavior)
|
|
60
45
|
return out
|
|
61
46
|
|
|
62
47
|
# identifier
|
|
63
48
|
def _eval_ident(self, node: IdentNode):
|
|
64
49
|
name = node.name
|
|
65
50
|
|
|
66
|
-
# ignore_delimiters: treat token as literal for this syntax
|
|
67
|
-
if self._syntax_ignores_delimiters(node.syntax):
|
|
68
|
-
return self._literal_from_syntax(name, node.syntax)
|
|
69
|
-
|
|
70
51
|
# cycle detection
|
|
71
52
|
if name in self._seen:
|
|
72
53
|
raise EvaluationError(f"Cycle detected in identifier '{name}'")
|
|
@@ -98,11 +79,6 @@ class Evaluator:
|
|
|
98
79
|
def _eval_call(self, node: CallNode):
|
|
99
80
|
outer = node.name
|
|
100
81
|
|
|
101
|
-
# ignore_delimiters: treat call token as literal
|
|
102
|
-
if self._syntax_ignores_delimiters(node.syntax):
|
|
103
|
-
arg_text = self._eval(node.arg)
|
|
104
|
-
return self._literal_from_syntax(outer, node.syntax, is_call=True, arg_text=arg_text)
|
|
105
|
-
|
|
106
82
|
if outer in self._seen:
|
|
107
83
|
raise EvaluationError(f"Cycle detected in call '{outer}'")
|
|
108
84
|
self._seen.add(outer)
|
|
@@ -148,74 +124,14 @@ class Evaluator:
|
|
|
148
124
|
cur = cur[p]
|
|
149
125
|
return cur
|
|
150
126
|
|
|
127
|
+
# recursion helpers now effectively disabled
|
|
151
128
|
def _has_recursive_maps(self):
|
|
152
|
-
for m in self.layerstack.all_maps():
|
|
153
|
-
if getattr(m, '__recursive__', False) is True:
|
|
154
|
-
return True
|
|
155
129
|
return False
|
|
156
130
|
|
|
157
131
|
def _get_max_depth(self):
|
|
158
|
-
|
|
159
|
-
getattr(m, '__max_depth__', 10)
|
|
160
|
-
for m in self.layerstack.all_maps()
|
|
161
|
-
if getattr(m, '__recursive__', False) is True
|
|
162
|
-
]
|
|
163
|
-
return max(depths) if depths else 0
|
|
132
|
+
return 0
|
|
164
133
|
|
|
165
134
|
def _re_resolve(self, text: str) -> str:
|
|
166
135
|
tokens = Tokenizer(text).tokenize()
|
|
167
136
|
ast = Parser(tokens).parse()
|
|
168
137
|
return self.evaluate(ast)
|
|
169
|
-
|
|
170
|
-
def _syntax_ignores_delimiters(self, syntax_name: str) -> bool:
|
|
171
|
-
for m in self.layerstack.all_maps():
|
|
172
|
-
if getattr(m, '__syntax__', None) == syntax_name:
|
|
173
|
-
if getattr(m, '__ignore_delimiters__', False):
|
|
174
|
-
return True
|
|
175
|
-
return False
|
|
176
|
-
|
|
177
|
-
def _literal_from_syntax(self, name: str, syntax_name: str, is_call: bool = False, arg_text: str | None = None) -> str:
|
|
178
|
-
if not is_call:
|
|
179
|
-
if syntax_name == 'colons':
|
|
180
|
-
return f':{name}:'
|
|
181
|
-
if syntax_name == 'braces':
|
|
182
|
-
return f'{{{{{name}}}}}'
|
|
183
|
-
if syntax_name == 'dollars':
|
|
184
|
-
return f'${{{name}}}'
|
|
185
|
-
if syntax_name == 'angles':
|
|
186
|
-
return f'<{name}>'
|
|
187
|
-
if syntax_name == 'pipes':
|
|
188
|
-
return f'|{name}|'
|
|
189
|
-
if syntax_name == 'percents':
|
|
190
|
-
return f'%{name}%'
|
|
191
|
-
if syntax_name == 'paren_dollars':
|
|
192
|
-
return f'$({name})'
|
|
193
|
-
if syntax_name == 'at_tags':
|
|
194
|
-
return f'@{name}@'
|
|
195
|
-
if syntax_name == 'hash_tags':
|
|
196
|
-
return f'#{name}#'
|
|
197
|
-
return name
|
|
198
|
-
|
|
199
|
-
# call literal: syntax-specific wrapping of name(arg_text)
|
|
200
|
-
arg = arg_text or ''
|
|
201
|
-
inner = f'{name}({arg})'
|
|
202
|
-
|
|
203
|
-
if syntax_name == 'colons':
|
|
204
|
-
return f':{inner}:'
|
|
205
|
-
if syntax_name == 'braces':
|
|
206
|
-
return f'{{{{{inner}}}}}'
|
|
207
|
-
if syntax_name == 'dollars':
|
|
208
|
-
return f'${{{inner}}}'
|
|
209
|
-
if syntax_name == 'angles':
|
|
210
|
-
return f'<{inner}>'
|
|
211
|
-
if syntax_name == 'pipes':
|
|
212
|
-
return f'|{inner}|'
|
|
213
|
-
if syntax_name == 'percents':
|
|
214
|
-
return f'%{inner}%'
|
|
215
|
-
if syntax_name == 'paren_dollars':
|
|
216
|
-
return f'$({inner})'
|
|
217
|
-
if syntax_name == 'at_tags':
|
|
218
|
-
return f'@{inner}@'
|
|
219
|
-
if syntax_name == 'hash_tags':
|
|
220
|
-
return f'#{inner}#'
|
|
221
|
-
return inner
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|