omlish 0.0.0.dev371__py3-none-any.whl → 0.0.0.dev372__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.
omlish/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev371'
2
- __revision__ = 'c37d96ddcd83d914205dd76b0f859b9ca93b0397'
1
+ __version__ = '0.0.0.dev372'
2
+ __revision__ = '033823538cee9fc13c4075a41150dafd56975200'
3
3
 
4
4
 
5
5
  #
omlish/text/minja.py CHANGED
@@ -15,6 +15,9 @@ from ..lite.check import check
15
15
  from ..lite.maybes import Maybe
16
16
 
17
17
 
18
+ MinjaTemplateFragmentKind = ta.Literal['expr', 'stmt', 'for', 'if', 'elif'] # ta.TypeAlias
19
+
20
+
18
21
  ##
19
22
 
20
23
 
@@ -90,6 +93,9 @@ class MinjaTemplateCompiler:
90
93
  params: ta.Sequence[ta.Union[str, MinjaTemplateParam]],
91
94
  *,
92
95
  indent: str = DEFAULT_INDENT,
96
+ fragment_processor: ta.Optional[ta.Callable[[MinjaTemplateFragmentKind, str], str]] = None,
97
+ strict_strings: bool = False,
98
+ stringifier: ta.Optional[ta.Callable[[ta.Any], str]] = None,
93
99
  ) -> None:
94
100
  super().__init__()
95
101
 
@@ -103,8 +109,25 @@ class MinjaTemplateCompiler:
103
109
  check.unique(p.name for p in self._params)
104
110
  self._indent_str: str = check.non_empty_str(indent)
105
111
 
112
+ if fragment_processor is None:
113
+ fragment_processor = lambda _, s: s # noqa
114
+ self._fragment_processor = fragment_processor
115
+
116
+ if stringifier is None:
117
+ if strict_strings:
118
+ stringifier = self._strict_stringify
119
+ else:
120
+ stringifier = lambda o: str(o)
121
+ self._stringifier = stringifier
122
+
106
123
  self._stack: ta.List[ta.Literal['for', 'if']] = []
107
124
 
125
+ @staticmethod
126
+ def _strict_stringify(o: ta.Any) -> str:
127
+ if not isinstance(o, str):
128
+ raise TypeError(o)
129
+ return o
130
+
108
131
  #
109
132
 
110
133
  _TAG_PAT = re.compile(
@@ -166,7 +189,7 @@ class MinjaTemplateCompiler:
166
189
 
167
190
  #
168
191
 
169
- _RENDER_FN_NAME = '__render'
192
+ _RENDER_FN_NAME = '__minja__render'
170
193
 
171
194
  class Rendered(ta.NamedTuple):
172
195
  src: str
@@ -177,7 +200,8 @@ class MinjaTemplateCompiler:
177
200
  lines: ta.List[str] = []
178
201
 
179
202
  ns: ta.Dict[str, ta.Any] = {
180
- '__StringIO': io.StringIO,
203
+ '__minja__StringIO': io.StringIO,
204
+ '__minja__stringify': self._stringifier,
181
205
  }
182
206
 
183
207
  parts = self._split_tags(self._src)
@@ -195,36 +219,36 @@ class MinjaTemplateCompiler:
195
219
  lines.append(self._indent(f'{p.name},'))
196
220
  lines.append('):')
197
221
 
198
- lines.append(self._indent('__output = __StringIO()'))
222
+ lines.append(self._indent('__minja__output = __minja__StringIO()'))
199
223
 
200
224
  for g, s in parts:
201
225
  if g == '{':
202
226
  expr = s.strip()
203
- lines.append(self._indent(f'__output.write(str({expr}))'))
227
+ lines.append(self._indent(f'__minja__output.write(__minja__stringify({self._fragment_processor("expr", expr)}))')) # noqa
204
228
 
205
229
  elif g == '%':
206
230
  stmt = s.strip()
207
231
 
208
232
  if stmt.startswith('for '):
209
- lines.append(self._indent(stmt + ':'))
233
+ lines.append(self._indent(f'for {self._fragment_processor("for", stmt[4:])}:'))
210
234
  self._stack.append('for')
211
235
  elif stmt.startswith('endfor'):
212
236
  check.equal(self._stack.pop(), 'for')
213
237
 
214
238
  elif stmt.startswith('if '):
215
- lines.append(self._indent(stmt + ':'))
239
+ lines.append(self._indent(f'if {self._fragment_processor("if", stmt[3:])}:'))
216
240
  self._stack.append('if')
217
241
  elif stmt.startswith('elif '):
218
242
  check.equal(self._stack[-1], 'if')
219
- lines.append(self._indent(stmt + ':', -1))
243
+ lines.append(self._indent(f'elif {self._fragment_processor("elif", stmt[5:])}:', -1))
220
244
  elif stmt.strip() == 'else':
221
245
  check.equal(self._stack[-1], 'if')
222
246
  lines.append(self._indent('else:', -1))
223
- elif stmt.startswith('endif'):
247
+ elif stmt.strip() == 'endif':
224
248
  check.equal(self._stack.pop(), 'if')
225
249
 
226
250
  else:
227
- lines.append(self._indent(stmt))
251
+ lines.append(self._indent(self._fragment_processor('stmt', stmt)))
228
252
 
229
253
  elif g == '#':
230
254
  pass
@@ -232,14 +256,14 @@ class MinjaTemplateCompiler:
232
256
  elif not g:
233
257
  if s:
234
258
  safe_text = s.replace('"""', '\\"""')
235
- lines.append(self._indent(f'__output.write("""{safe_text}""")'))
259
+ lines.append(self._indent(f'__minja__output.write("""{safe_text}""")'))
236
260
 
237
261
  else:
238
262
  raise KeyError(g)
239
263
 
240
264
  check.empty(self._stack)
241
265
 
242
- lines.append(self._indent('return __output.getvalue()'))
266
+ lines.append(self._indent('return __minja__output.getvalue()'))
243
267
 
244
268
  return self.Rendered('\n'.join(lines), ns)
245
269
 
@@ -258,16 +282,22 @@ class MinjaTemplateCompiler:
258
282
  exec(src, glo)
259
283
  return glo[name]
260
284
 
261
- #
262
-
263
- @cached_nullary
264
- def compile(self) -> MinjaTemplate:
285
+ def compile(
286
+ self,
287
+ ns: ta.Optional[ta.Mapping[str, ta.Any]] = None,
288
+ ) -> MinjaTemplate:
265
289
  rendered = self.render()
266
290
 
291
+ ns = dict(ns or {})
292
+ for k, v in rendered.ns.items():
293
+ if k in ns:
294
+ raise KeyError(k)
295
+ ns[k] = v
296
+
267
297
  render_fn = self._make_fn(
268
298
  self._RENDER_FN_NAME,
269
299
  rendered.src,
270
- rendered.ns,
300
+ ns,
271
301
  )
272
302
 
273
303
  return MinjaTemplate(
@@ -282,8 +312,15 @@ class MinjaTemplateCompiler:
282
312
  def compile_minja_template(
283
313
  src: str,
284
314
  params: ta.Sequence[ta.Union[str, MinjaTemplateParam]] = (),
315
+ *,
316
+ ns: ta.Optional[ta.Mapping[str, ta.Any]] = None,
317
+ **kwargs: ta.Any,
285
318
  ) -> MinjaTemplate:
286
- return MinjaTemplateCompiler(src, params).compile()
319
+ return MinjaTemplateCompiler(
320
+ src,
321
+ params,
322
+ **kwargs,
323
+ ).compile(ns)
287
324
 
288
325
 
289
326
  def render_minja_template(src: str, **kwargs: ta.Any) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omlish
3
- Version: 0.0.0.dev371
3
+ Version: 0.0.0.dev372
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=aT8yZ-Zh-9wfHl5Ym5ouiWC1i0cy7Q7RlhzavB6VLPI,8587
2
- omlish/__about__.py,sha256=IuPF6dQwqBF37vj4nM3a2rfw3IW2B0qdP0SrL4-B5BI,3478
2
+ omlish/__about__.py,sha256=jyzuqevR3mhnjpJ83sR8GtV3f2_ERBb1HkzWCrzvnSA,3478
3
3
  omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
4
4
  omlish/c3.py,sha256=rer-TPOFDU6fYq_AWio_AmA-ckZ8JDY5shIzQ_yXfzA,8414
5
5
  omlish/cached.py,sha256=MLap_p0rdGoDIMVhXVHm1tsbcWobJF0OanoodV03Ju8,542
@@ -804,7 +804,7 @@ omlish/text/glyphsplit.py,sha256=ZX9mhwTtmUE8rJpuD1jBO1CTc6xzmBCtbfiHmp5vMM8,381
804
804
  omlish/text/indent.py,sha256=BWVVaHs_B1ppwHJJIxKCDG3iCutkYy5e1qr59Z_Suzg,1524
805
805
  omlish/text/linecache.py,sha256=hRYlEhD63ZfA6_ZOTkQIcnON-3W56QMAhcG3vEJqj9M,1858
806
806
  omlish/text/mangle.py,sha256=k7mYavVgxJ2ENV2wfjw3c9u3hqH5NeVpjoxYbyaYC0Y,2796
807
- omlish/text/minja.py,sha256=eyOA_zUCzyqaBfiPX-hV2xdK9_cqlDEhbVTkZUTZgQo,7521
807
+ omlish/text/minja.py,sha256=wz4ZkjPTvlVkLBkWyTCoyERyiofBMvDXZZcNsGtk8gU,8999
808
808
  omlish/text/parts.py,sha256=MpiCUyfpcL4PLb2Etj8V7Yj4qofhy0xVwBrIL6RfNdg,6646
809
809
  omlish/text/random.py,sha256=8feS5JE_tSjYlMl-lp0j93kCfzBae9AM2cXlRLebXMA,199
810
810
  omlish/text/templating.py,sha256=Nf5BVDgrYBf0WmYwV6SnHPDvl9XVMu8v7MX78pInLTw,3325
@@ -888,9 +888,9 @@ omlish/typedvalues/marshal.py,sha256=AtBz7Jq-BfW8vwM7HSxSpR85JAXmxK2T0xDblmm1HI0
888
888
  omlish/typedvalues/of_.py,sha256=UXkxSj504WI2UrFlqdZJbu2hyDwBhL7XVrc2qdR02GQ,1309
889
889
  omlish/typedvalues/reflect.py,sha256=PAvKW6T4cW7u--iX80w3HWwZUS3SmIZ2_lQjT65uAyk,1026
890
890
  omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
891
- omlish-0.0.0.dev371.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
892
- omlish-0.0.0.dev371.dist-info/METADATA,sha256=oPFYGURgWGkPAhtJkRCmiXVNzNFuNn8sXTBZAHZh1TI,4416
893
- omlish-0.0.0.dev371.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
894
- omlish-0.0.0.dev371.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
895
- omlish-0.0.0.dev371.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
896
- omlish-0.0.0.dev371.dist-info/RECORD,,
891
+ omlish-0.0.0.dev372.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
892
+ omlish-0.0.0.dev372.dist-info/METADATA,sha256=UoYYCvg_GPym2iiE9ijIaZnB7CxyH_k7EHwVpEQvCYY,4416
893
+ omlish-0.0.0.dev372.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
894
+ omlish-0.0.0.dev372.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
895
+ omlish-0.0.0.dev372.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
896
+ omlish-0.0.0.dev372.dist-info/RECORD,,