mapres 3.dev23__tar.gz → 3.dev24__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.
Files changed (23) hide show
  1. {mapres-3.dev23/src/mapres.egg-info → mapres-3.dev24}/PKG-INFO +1 -1
  2. {mapres-3.dev23 → mapres-3.dev24}/pyproject.toml +1 -1
  3. {mapres-3.dev23 → mapres-3.dev24}/src/mapres/datamap.py +5 -1
  4. {mapres-3.dev23 → mapres-3.dev24}/src/mapres/evaluator.py +43 -0
  5. {mapres-3.dev23 → mapres-3.dev24/src/mapres.egg-info}/PKG-INFO +1 -1
  6. {mapres-3.dev23 → mapres-3.dev24}/LICENSE +0 -0
  7. {mapres-3.dev23 → mapres-3.dev24}/README.md +0 -0
  8. {mapres-3.dev23 → mapres-3.dev24}/setup.cfg +0 -0
  9. {mapres-3.dev23 → mapres-3.dev24}/src/mapres/__init__.py +0 -0
  10. {mapres-3.dev23 → mapres-3.dev24}/src/mapres/ast.py +0 -0
  11. {mapres-3.dev23 → mapres-3.dev24}/src/mapres/cache.py +0 -0
  12. {mapres-3.dev23 → mapres-3.dev24}/src/mapres/exceptions.py +0 -0
  13. {mapres-3.dev23 → mapres-3.dev24}/src/mapres/layers.py +0 -0
  14. {mapres-3.dev23 → mapres-3.dev24}/src/mapres/maps/__init__.py +0 -0
  15. {mapres-3.dev23 → mapres-3.dev24}/src/mapres/maps/color.py +0 -0
  16. {mapres-3.dev23 → mapres-3.dev24}/src/mapres/maps/time.py +0 -0
  17. {mapres-3.dev23 → mapres-3.dev24}/src/mapres/parser.py +0 -0
  18. {mapres-3.dev23 → mapres-3.dev24}/src/mapres/resolver.py +0 -0
  19. {mapres-3.dev23 → mapres-3.dev24}/src/mapres/tokenizer.py +0 -0
  20. {mapres-3.dev23 → mapres-3.dev24}/src/mapres.egg-info/SOURCES.txt +0 -0
  21. {mapres-3.dev23 → mapres-3.dev24}/src/mapres.egg-info/dependency_links.txt +0 -0
  22. {mapres-3.dev23 → mapres-3.dev24}/src/mapres.egg-info/requires.txt +0 -0
  23. {mapres-3.dev23 → mapres-3.dev24}/src/mapres.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mapres
3
- Version: 3.dev23
3
+ Version: 3.dev24
4
4
  Summary: A powerfull mapping utility
5
5
  Author: iFamished
6
6
  License: MIT
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
 
8
8
  [project]
9
9
  name = "mapres"
10
- version = "3-dev.23"
10
+ version = "3-dev.24"
11
11
  description = "A powerfull mapping utility"
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.9"
@@ -36,6 +36,8 @@ class DataMap:
36
36
  __syntax__: str = None
37
37
  __mode__: str | None = None # 'dynamic', 'config', 'callable', or None
38
38
  __missing_key__: str = 'error' # 'error', 'silent', 'placeholder'
39
+ __recursive__: bool = False
40
+ __max_depth__: int = 10
39
41
 
40
42
  def as_map(self):
41
43
  '''
@@ -92,11 +94,13 @@ class DataMap:
92
94
  return out
93
95
 
94
96
 
95
- def datamap(_cls=None, *, syntax=None, mode=None, missing_key=None):
97
+ def datamap(_cls=None, *, syntax=None, mode=None, missing_key=None, recursive=None, max_depth=None):
96
98
  def wrap(cls):
97
99
  cls.__syntax__ = syntax
98
100
  cls.__mode__ = mode
99
101
  cls.__missing_key__ = missing_key or 'error'
102
+ cls.__recursive__ = recursive or False
103
+ cls.__max_depth__ = max_depth or 10
100
104
 
101
105
  namespace = dict(cls.__dict__)
102
106
  namespace['__dict__'] = {}
@@ -33,6 +33,13 @@ class Evaluator:
33
33
  return self._eval_call(node)
34
34
 
35
35
  raise EvaluationError(f'Unknown AST node: {node}')
36
+
37
+ # re-resolve
38
+ def _re_resolve(self, text: str) -> str:
39
+ tokens = Tokenizer(text).tokenize()
40
+ ast = Parser(tokens).parse()
41
+ return self.evaluate(ast)
42
+
36
43
 
37
44
  # template
38
45
  def _eval_template(self, node: TemplateNode):
@@ -40,6 +47,42 @@ class Evaluator:
40
47
  for child in node.children:
41
48
  parts.append(self._eval(child))
42
49
  out = ''.join(parts)
50
+
51
+ # ---------------------------------------
52
+ # PER-MAP RECURSION (syntax-scoped)
53
+ # ---------------------------------------
54
+ # Find all maps in the layerstack that have recursive=True
55
+ recursive_maps = [
56
+ m for m in self.layerstack.all_maps()
57
+ if getattr(m, '__recursive__', False) is True
58
+ ]
59
+
60
+ # If no maps are recursive, return the first-pass output
61
+ if not recursive_maps:
62
+ return out
63
+
64
+ # Determine max recursion depth across all recursive maps
65
+ max_depth = max(getattr(m, '__max_depth__', 10) for m in recursive_maps)
66
+
67
+ seen = set()
68
+ depth = 0
69
+
70
+ while depth < max_depth:
71
+ # Re-tokenize and re-evaluate the ENTIRE output string
72
+ new_out = self._re_resolve(out)
73
+
74
+ # If stable, stop recursion
75
+ if new_out == out:
76
+ break
77
+
78
+ # Cycle detection
79
+ if new_out in seen:
80
+ raise EvaluationError('Cycle detected in recursive map resolution')
81
+
82
+ seen.add(new_out)
83
+ out = new_out
84
+ depth += 1
85
+
43
86
  return out
44
87
 
45
88
  # identifier
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mapres
3
- Version: 3.dev23
3
+ Version: 3.dev24
4
4
  Summary: A powerfull mapping utility
5
5
  Author: iFamished
6
6
  License: MIT
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes