mapres 3.dev20__py3-none-any.whl → 3.dev21__py3-none-any.whl
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/datamap.py +5 -11
- mapres/evaluator.py +0 -98
- {mapres-3.dev20.dist-info → mapres-3.dev21.dist-info}/METADATA +1 -1
- {mapres-3.dev20.dist-info → mapres-3.dev21.dist-info}/RECORD +7 -7
- {mapres-3.dev20.dist-info → mapres-3.dev21.dist-info}/WHEEL +0 -0
- {mapres-3.dev20.dist-info → mapres-3.dev21.dist-info}/licenses/LICENSE +0 -0
- {mapres-3.dev20.dist-info → mapres-3.dev21.dist-info}/top_level.txt +0 -0
mapres/datamap.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import re
|
|
2
1
|
from dataclasses import dataclass, fields, is_dataclass
|
|
3
2
|
|
|
4
3
|
# syntax identifiers
|
|
@@ -30,15 +29,13 @@ class DataMap:
|
|
|
30
29
|
|
|
31
30
|
Mode metadata (__mode__) controls behavior:
|
|
32
31
|
- None: plain static map
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
32
|
+
- 'dynamic': values may be provided by callables/providers
|
|
33
|
+
- 'config': config-style maps (no dynamic evaluation)
|
|
34
|
+
- 'callable': map exposes callable methods for nested calls
|
|
36
35
|
'''
|
|
37
36
|
__syntax__: str = None
|
|
38
|
-
__mode__: str | None = None
|
|
39
|
-
__recursive__: bool = False
|
|
37
|
+
__mode__: str | None = None # 'dynamic', 'config', 'callable', or None
|
|
40
38
|
__missing_key__: str = 'error' # 'error', 'silent', 'placeholder'
|
|
41
|
-
__ignore_delimiters__: bool = False
|
|
42
39
|
|
|
43
40
|
def as_map(self):
|
|
44
41
|
'''
|
|
@@ -95,14 +92,11 @@ class DataMap:
|
|
|
95
92
|
return out
|
|
96
93
|
|
|
97
94
|
|
|
98
|
-
def datamap(_cls=None, *, syntax=None, mode=None,
|
|
99
|
-
|
|
95
|
+
def datamap(_cls=None, *, syntax=None, mode=None, missing_key=None):
|
|
100
96
|
def wrap(cls):
|
|
101
97
|
cls.__syntax__ = syntax
|
|
102
98
|
cls.__mode__ = mode
|
|
103
|
-
cls.__recursive__ = recursive
|
|
104
99
|
cls.__missing_key__ = missing_key or 'error'
|
|
105
|
-
cls.__ignore_delimiters__ = ignore_delimiters or False
|
|
106
100
|
|
|
107
101
|
namespace = dict(cls.__dict__)
|
|
108
102
|
namespace['__dict__'] = {}
|
mapres/evaluator.py
CHANGED
|
@@ -40,33 +40,12 @@ class Evaluator:
|
|
|
40
40
|
for child in node.children:
|
|
41
41
|
parts.append(self._eval(child))
|
|
42
42
|
out = ''.join(parts)
|
|
43
|
-
|
|
44
|
-
# recursion over full template output
|
|
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
|
-
|
|
60
43
|
return out
|
|
61
44
|
|
|
62
45
|
# identifier
|
|
63
46
|
def _eval_ident(self, node: IdentNode):
|
|
64
47
|
name = node.name
|
|
65
48
|
|
|
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
49
|
# cycle detection
|
|
71
50
|
if name in self._seen:
|
|
72
51
|
raise EvaluationError(f"Cycle detected in identifier '{name}'")
|
|
@@ -98,11 +77,6 @@ class Evaluator:
|
|
|
98
77
|
def _eval_call(self, node: CallNode):
|
|
99
78
|
outer = node.name
|
|
100
79
|
|
|
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
80
|
if outer in self._seen:
|
|
107
81
|
raise EvaluationError(f"Cycle detected in call '{outer}'")
|
|
108
82
|
self._seen.add(outer)
|
|
@@ -147,75 +121,3 @@ class Evaluator:
|
|
|
147
121
|
return None
|
|
148
122
|
cur = cur[p]
|
|
149
123
|
return cur
|
|
150
|
-
|
|
151
|
-
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
|
-
return False
|
|
156
|
-
|
|
157
|
-
def _get_max_depth(self):
|
|
158
|
-
depths = [
|
|
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
|
|
164
|
-
|
|
165
|
-
def _re_resolve(self, text: str) -> str:
|
|
166
|
-
tokens = Tokenizer(text).tokenize()
|
|
167
|
-
ast = Parser(tokens).parse()
|
|
168
|
-
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
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
mapres/__init__.py,sha256=t23ofM-wzpPByYi1rEQonxyU1yyza4ZzwwHDZUa5QqA,1010
|
|
2
2
|
mapres/ast.py,sha256=6PcMkwtNHYD8xEkdyzDgn_mRTj1ZaWSyuHZK3BtXiuo,427
|
|
3
3
|
mapres/cache.py,sha256=hbvsoc6Qw3RhWAEfOOpKHtC7i9EomoUgWzyd4dnH71w,333
|
|
4
|
-
mapres/datamap.py,sha256=
|
|
5
|
-
mapres/evaluator.py,sha256=
|
|
4
|
+
mapres/datamap.py,sha256=R_5G_mE2OZpZ9YVL4tsNXAGS_SkQ6LKlx6Bz2Pr652Y,5021
|
|
5
|
+
mapres/evaluator.py,sha256=KNZ9aygOClM0kgnOf3anigsupLF175EJ07z_17ubZzU,3441
|
|
6
6
|
mapres/exceptions.py,sha256=D2XKnrMkZDyUXQt2PmaKbj08FObWU00yXKGHwNpjvww,222
|
|
7
7
|
mapres/layers.py,sha256=sFc1eUOBg2BoB2cBXIleq8RMYcg5GZpUoCnGh-uKN6U,1380
|
|
8
8
|
mapres/parser.py,sha256=8XLCzYosvh81bN-Jddc1AM4w0X7bsHnBzmA8sq5_72w,4018
|
|
@@ -11,8 +11,8 @@ mapres/tokenizer.py,sha256=js0S1s8MkltdQoH5V1cLjdY0fFqZoGqmtP_OhEJEM6M,6539
|
|
|
11
11
|
mapres/maps/__init__.py,sha256=lIRRfem1Fw4iynuwUQ7BY5qrC4fbJKxqLivao2_Dtm4,239
|
|
12
12
|
mapres/maps/color.py,sha256=noRTGFNo9xLl5YEhX0tttV6i_oDAiptXmRVnkr5EzwM,1348
|
|
13
13
|
mapres/maps/time.py,sha256=TyncycYoIGVZWps32qWlFy2a2hTayvZWVHu9uh2nid8,2050
|
|
14
|
-
mapres-3.
|
|
15
|
-
mapres-3.
|
|
16
|
-
mapres-3.
|
|
17
|
-
mapres-3.
|
|
18
|
-
mapres-3.
|
|
14
|
+
mapres-3.dev21.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
15
|
+
mapres-3.dev21.dist-info/METADATA,sha256=SrQXRywgQfa_pKRb7Egsdagr1pNwn2F9S3bBdpTWdVQ,1476
|
|
16
|
+
mapres-3.dev21.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
17
|
+
mapres-3.dev21.dist-info/top_level.txt,sha256=5LMVQqJdtyjxfzv7wJBOZ-360m0Yc79w_-Y7s3n6cTw,7
|
|
18
|
+
mapres-3.dev21.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|