mapres 3.dev7__py3-none-any.whl → 3.dev9__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 CHANGED
@@ -27,14 +27,23 @@ class DataMap:
27
27
 
28
28
  Syntax metadata (__syntax__) determines which delimiters
29
29
  this map responds to (angle, brace, colon, percent, pipe, etc).
30
+
31
+ Mode metadata (__mode__) controls behavior:
32
+ - None: plain static map
33
+ - "dynamic": values may be provided by callables/providers
34
+ - "config": config-style maps (no dynamic evaluation)
35
+ - "callable": map exposes callable methods for nested calls
30
36
  '''
31
37
  __syntax__: str = None
32
- __mode__: str | None = None # "dynamic", "config", or None
38
+ __mode__: str | None = None # "dynamic", "config", "callable", or None
33
39
 
34
40
  def as_map(self):
35
41
  '''
36
42
  Convert datamap fields into a dictionary.
37
43
  If mode='dynamic', evaluate provider functions.
44
+
45
+ Callable mode does NOT change as_map() behavior; methods are
46
+ used by the evaluator, not exported as map entries.
38
47
  '''
39
48
  result = {}
40
49
 
@@ -59,15 +68,7 @@ class DataMap:
59
68
 
60
69
  # main decorator factory
61
70
  def datamap(_cls=None, *, syntax=None, mode=None):
62
- '''
63
- @datamap decorator.
64
-
65
- Supports:
66
- @datamap
67
- @datamap(mode='dynamic')
68
- @datamap(syntax='angle')
69
- @datamap(syntax='angle', mode='config')
70
- '''
71
+ '''@datamap decorator'''
71
72
  def wrap(cls):
72
73
  cls.__syntax__ = syntax
73
74
  cls.__mode__ = mode
@@ -90,6 +91,8 @@ class _SyntaxFactory:
90
91
  @datamap.angles
91
92
  @datamap.angles(mode='config')
92
93
  @datamap.angles.config
94
+ @datamap.angles.dynamic
95
+ @datamap.angles.callable
93
96
  '''
94
97
  def __init__(self, syntax_name):
95
98
  self._syntax = syntax_name
@@ -106,24 +109,30 @@ class _SyntaxFactory:
106
109
  def config(self):
107
110
  # Case 3: @datamap.angles.config
108
111
  return datamap(syntax=self._syntax, mode='config')
109
-
112
+
110
113
  @property
111
114
  def dynamic(self):
115
+ # @datamap.angles.dynamic
112
116
  return datamap(syntax=self._syntax, mode='dynamic')
113
117
 
118
+ @property
119
+ def callable(self):
120
+ # @datamap.angles.callable
121
+ return datamap(syntax=self._syntax, mode='callable')
114
122
 
115
123
 
116
124
  # build syntax shortcuts
117
- datamap.braces = _SyntaxFactory(syntax.braces)
118
-
119
- datamap.dollars = _SyntaxFactory(syntax.dollars)
120
- datamap.angles = _SyntaxFactory(syntax.angles)
121
- datamap.percents = _SyntaxFactory(syntax.percents)
122
- datamap.pipes = _SyntaxFactory(syntax.pipes)
123
- datamap.colons = _SyntaxFactory(syntax.colons)
124
- datamap.at_tags = _SyntaxFactory(syntax.at_tags)
125
- datamap.hash_tags = _SyntaxFactory(syntax.hash_tags)
125
+ datamap.braces = _SyntaxFactory(syntax.braces)
126
+ datamap.dollars = _SyntaxFactory(syntax.dollars)
127
+ datamap.angles = _SyntaxFactory(syntax.angles)
128
+ datamap.percents = _SyntaxFactory(syntax.percents)
129
+ datamap.pipes = _SyntaxFactory(syntax.pipes)
130
+ datamap.colons = _SyntaxFactory(syntax.colons)
131
+ datamap.at_tags = _SyntaxFactory(syntax.at_tags)
132
+ datamap.hash_tags = _SyntaxFactory(syntax.hash_tags)
126
133
  datamap.paren_dollars = _SyntaxFactory(syntax.paren_dollars)
127
134
 
128
- # global mode shortcut
129
- datamap.config = datamap(mode='config')
135
+ # global mode shortcuts
136
+ datamap.config = datamap(mode='config')
137
+ datamap.dynamic = datamap(mode='dynamic')
138
+ datamap.callable = datamap(mode='callable')
mapres/parser.py CHANGED
@@ -12,22 +12,23 @@ class Parser:
12
12
  self.i = 0
13
13
  self.n = len(tokens)
14
14
 
15
- def peek(self, k=0) -> Token | None:
15
+ def peek(self, k: int = 0) -> Token | None:
16
16
  idx = self.i + k
17
17
  return self.tokens[idx] if idx < self.n else None
18
18
 
19
- def advance(self, k=1):
19
+ def advance(self, k: int = 1) -> None:
20
20
  self.i += k
21
21
 
22
- def expect(self, type_: TokenType):
22
+ def expect(self, type_: TokenType) -> Token:
23
23
  tok = self.peek()
24
24
  if tok is None or tok.type != type_:
25
25
  raise ParserError(f"Expected {type_}, got {tok}")
26
26
  self.advance()
27
27
  return tok
28
28
 
29
+ # top-level template parse
29
30
  def parse(self) -> TemplateNode:
30
- children = []
31
+ children: list[Node] = []
31
32
  while self.peek() is not None:
32
33
  tok = self.peek()
33
34
  if tok.type is TokenType.TEXT:
@@ -37,6 +38,23 @@ class Parser:
37
38
  children.append(self.parse_token())
38
39
  return TemplateNode(children)
39
40
 
41
+ # nested template parse (for IDENT(...))
42
+ def parse_until(self, stop_types: tuple[TokenType, ...]) -> TemplateNode:
43
+ children: list[Node] = []
44
+ while True:
45
+ tok = self.peek()
46
+ if tok is None or tok.type in stop_types:
47
+ break
48
+
49
+ if tok.type is TokenType.TEXT:
50
+ children.append(TextNode(tok.value))
51
+ self.advance()
52
+ else:
53
+ children.append(self.parse_token())
54
+
55
+ return TemplateNode(children)
56
+
57
+ # dispatch by opening delimiter
40
58
  def parse_token(self) -> Node:
41
59
  tok = self.peek()
42
60
 
@@ -60,21 +78,23 @@ class Parser:
60
78
 
61
79
  raise ParserError(f"Unexpected token {tok}")
62
80
 
63
- # --- core pattern: IDENT or IDENT(arg) ---
64
-
65
- def _parse_ident_or_call(self, closing_type, syntax_name: str) -> Node:
81
+ # core pattern: IDENT or IDENT(arg)
82
+ def _parse_ident_or_call(self, closing_type: TokenType, syntax_name: str) -> Node:
66
83
  ident_tok = self.expect(TokenType.IDENT)
67
84
  name = ident_tok.value
68
85
 
69
- # single-argument nested form: IDENT LPAREN Template RPAREN
86
+ # IDENT(arg)
70
87
  if self.peek() and self.peek().type is TokenType.LPAREN:
71
88
  self.advance() # consume '('
72
- arg = self.parse() # nested Template
89
+
90
+ # parse only until RPAREN
91
+ arg = self.parse_until((TokenType.RPAREN,))
92
+
73
93
  self.expect(TokenType.RPAREN)
74
94
  self.expect(closing_type)
75
95
  return CallNode(name=name, arg=arg, syntax=syntax_name)
76
96
 
77
- # simple identifier: IDENT
97
+ # IDENT
78
98
  self.expect(closing_type)
79
99
  return IdentNode(name=name, syntax=syntax_name)
80
100
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mapres
3
- Version: 3.dev7
3
+ Version: 3.dev9
4
4
  Summary: A powerfull mapping utility
5
5
  Author: iFamished
6
6
  License: MIT
@@ -1,18 +1,18 @@
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=HAflZFD9eh2VRkR9_2aDtXxY3r_A5ZUnpxNJ_VqmFBE,3837
4
+ mapres/datamap.py,sha256=0kfxBSAaIXwT8srkcurPbXBbbpmc_HbAzL-iJ45pKNc,4439
5
5
  mapres/evaluator.py,sha256=-MsLxUlmYIOz5IOR5KT8IclJXtABGukLoQVmqkOTqTA,3780
6
6
  mapres/exceptions.py,sha256=jirHKK5yCffSCWWkgZY_gTSIOaFCmXOe5NJJf60HeeQ,130
7
7
  mapres/layers.py,sha256=sFc1eUOBg2BoB2cBXIleq8RMYcg5GZpUoCnGh-uKN6U,1380
8
- mapres/parser.py,sha256=xCnR290-A_XI8Yr8u1V-K_Of8exhGFOz5aT6gjAeBGA,3405
8
+ mapres/parser.py,sha256=8XLCzYosvh81bN-Jddc1AM4w0X7bsHnBzmA8sq5_72w,4018
9
9
  mapres/resolver.py,sha256=LOAnuNc1RW97eBXughkEPK90MntMSYa7yC8s1EJPVvA,3134
10
10
  mapres/tokenizer.py,sha256=zw1jhnfypak1bLSTlyo9Xj4UoOF9DJ3y1qqu2OzudiI,5702
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.dev7.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
15
- mapres-3.dev7.dist-info/METADATA,sha256=SKkg3oOxbjMyfSJ_OqfFL9f0OPGuYZpn0i6D6Z9T8mw,1475
16
- mapres-3.dev7.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
17
- mapres-3.dev7.dist-info/top_level.txt,sha256=5LMVQqJdtyjxfzv7wJBOZ-360m0Yc79w_-Y7s3n6cTw,7
18
- mapres-3.dev7.dist-info/RECORD,,
14
+ mapres-3.dev9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
15
+ mapres-3.dev9.dist-info/METADATA,sha256=3M3CykjX6zFjyaLuIWocVAsrt-QLttcW1JGR_G-6dX8,1475
16
+ mapres-3.dev9.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
17
+ mapres-3.dev9.dist-info/top_level.txt,sha256=5LMVQqJdtyjxfzv7wJBOZ-360m0Yc79w_-Y7s3n6cTw,7
18
+ mapres-3.dev9.dist-info/RECORD,,