python-liquid 2.3.6__py3-none-any.whl → 3.0.0__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.
Files changed (212) hide show
  1. liquid/__about__.py +1 -0
  2. liquid/__init__.py +161 -187
  3. liquid/_base_tag.py +66 -0
  4. liquid/{utils/chain_map.py → _chain_map.py} +18 -19
  5. liquid/_context.py +465 -0
  6. liquid/_drop.py +108 -0
  7. liquid/_filter.py +174 -0
  8. liquid/_io.py +18 -0
  9. liquid/_lax_parser_mixin.py +100 -0
  10. liquid/_lexer.py +93 -0
  11. liquid/_lexer_extended.py +623 -0
  12. liquid/_lexer_legacy.py +536 -0
  13. liquid/_loader.py +84 -0
  14. liquid/{utils/lru_cache.py → _lru_cache.py} +28 -36
  15. liquid/_markup.py +253 -0
  16. liquid/_messages.py +292 -0
  17. liquid/_missing.py +3 -0
  18. liquid/_nothing.py +28 -0
  19. liquid/_parser.py +460 -0
  20. liquid/_parser_extended.py +293 -0
  21. liquid/_parser_legacy.py +819 -0
  22. liquid/_resource_limits.py +50 -0
  23. liquid/_slice.py +41 -0
  24. liquid/_static_analysis.py +503 -0
  25. liquid/_strftime.py +186 -0
  26. liquid/_template.py +536 -0
  27. liquid/drops/__init__.py +20 -0
  28. liquid/drops/forloop.py +78 -0
  29. liquid/drops/iterable.py +25 -0
  30. liquid/drops/range.py +76 -0
  31. liquid/drops/self_.py +45 -0
  32. liquid/drops/tablerowloop.py +142 -0
  33. liquid/drops/undefined.py +228 -0
  34. liquid/environment.py +717 -551
  35. liquid/exceptions.py +67 -214
  36. liquid/expressions.py +1184 -0
  37. liquid/filters/__init__.py +134 -0
  38. liquid/filters/abs.py +7 -0
  39. liquid/filters/append.py +5 -0
  40. liquid/filters/at_least.py +9 -0
  41. liquid/filters/at_most.py +9 -0
  42. liquid/filters/babel.py +560 -0
  43. liquid/filters/base64.py +26 -0
  44. liquid/filters/capitalize.py +5 -0
  45. liquid/filters/ceil.py +8 -0
  46. liquid/filters/compact.py +25 -0
  47. liquid/filters/concat.py +11 -0
  48. liquid/filters/date.py +27 -0
  49. liquid/filters/default.py +25 -0
  50. liquid/filters/divided_by.py +21 -0
  51. liquid/filters/downcase.py +5 -0
  52. liquid/filters/escape.py +56 -0
  53. liquid/filters/find.py +56 -0
  54. liquid/filters/first.py +19 -0
  55. liquid/filters/floor.py +8 -0
  56. liquid/filters/html.py +23 -0
  57. liquid/filters/index.py +12 -0
  58. liquid/filters/join.py +13 -0
  59. liquid/filters/json_.py +30 -0
  60. liquid/filters/last.py +17 -0
  61. liquid/filters/map.py +5 -0
  62. liquid/filters/minus.py +13 -0
  63. liquid/filters/modulo.py +18 -0
  64. liquid/filters/newline_to_br.py +16 -0
  65. liquid/filters/plus.py +13 -0
  66. liquid/filters/prepend.py +5 -0
  67. liquid/filters/reject.py +19 -0
  68. liquid/filters/remove.py +36 -0
  69. liquid/filters/replace.py +32 -0
  70. liquid/filters/reverse.py +5 -0
  71. liquid/filters/round.py +35 -0
  72. liquid/filters/size.py +25 -0
  73. liquid/filters/slice.py +39 -0
  74. liquid/filters/sort.py +148 -0
  75. liquid/filters/split.py +34 -0
  76. liquid/filters/squish.py +9 -0
  77. liquid/filters/strip.py +13 -0
  78. liquid/filters/strip_html.py +19 -0
  79. liquid/filters/strip_newlines.py +17 -0
  80. liquid/filters/sum.py +21 -0
  81. liquid/filters/times.py +13 -0
  82. liquid/filters/translate.py +380 -0
  83. liquid/filters/truncate.py +39 -0
  84. liquid/filters/uniq.py +11 -0
  85. liquid/filters/upcase.py +5 -0
  86. liquid/filters/url.py +18 -0
  87. liquid/filters/where.py +18 -0
  88. liquid/loaders/__init__.py +17 -0
  89. liquid/loaders/caching_file_system_loader.py +64 -0
  90. liquid/loaders/choice_loader.py +93 -0
  91. liquid/loaders/dict_loader.py +56 -0
  92. liquid/{builtin/loaders → loaders}/file_system_loader.py +51 -55
  93. liquid/{builtin/loaders → loaders}/mixins.py +39 -51
  94. liquid/loaders/package_loader.py +110 -0
  95. liquid/tags/__init__.py +61 -0
  96. liquid/tags/assign.py +68 -0
  97. liquid/tags/capture.py +83 -0
  98. liquid/tags/case.py +199 -0
  99. liquid/tags/comment.py +56 -0
  100. liquid/tags/cycle.py +131 -0
  101. liquid/tags/decrement.py +55 -0
  102. liquid/tags/doc.py +56 -0
  103. liquid/tags/echo.py +65 -0
  104. liquid/tags/else_.py +53 -0
  105. liquid/tags/error.py +51 -0
  106. liquid/tags/extends.py +448 -0
  107. liquid/tags/for_.py +421 -0
  108. liquid/tags/if_.py +156 -0
  109. liquid/tags/ifchanged.py +69 -0
  110. liquid/tags/include.py +223 -0
  111. liquid/tags/increment.py +55 -0
  112. liquid/tags/inline_comment.py +70 -0
  113. liquid/tags/liquid.py +56 -0
  114. liquid/tags/macro.py +281 -0
  115. liquid/tags/output.py +58 -0
  116. liquid/tags/raw.py +60 -0
  117. liquid/tags/render.py +245 -0
  118. liquid/tags/tablerow.py +254 -0
  119. liquid/tags/template_comment.py +56 -0
  120. liquid/tags/translate.py +316 -0
  121. liquid/tags/unless.py +121 -0
  122. liquid/tags/with_.py +83 -0
  123. liquid/tokens.py +370 -0
  124. {python_liquid-2.3.6.dist-info → python_liquid-3.0.0.dist-info}/METADATA +32 -39
  125. python_liquid-3.0.0.dist-info/RECORD +128 -0
  126. {python_liquid-2.3.6.dist-info → python_liquid-3.0.0.dist-info}/WHEEL +1 -1
  127. {python_liquid-2.3.6.dist-info → python_liquid-3.0.0.dist-info}/licenses/LICENSE +1 -1
  128. liquid/analyze_tags.py +0 -214
  129. liquid/ast.py +0 -252
  130. liquid/builtin/__init__.py +0 -203
  131. liquid/builtin/content.py +0 -41
  132. liquid/builtin/drops/__init__.py +0 -3
  133. liquid/builtin/drops/drops.py +0 -13
  134. liquid/builtin/expressions/__init__.py +0 -47
  135. liquid/builtin/expressions/_tokenize.py +0 -186
  136. liquid/builtin/expressions/arguments.py +0 -207
  137. liquid/builtin/expressions/filtered.py +0 -387
  138. liquid/builtin/expressions/logical.py +0 -672
  139. liquid/builtin/expressions/loop.py +0 -275
  140. liquid/builtin/expressions/path.py +0 -163
  141. liquid/builtin/expressions/primitive.py +0 -417
  142. liquid/builtin/filters/__init__.py +0 -0
  143. liquid/builtin/filters/array.py +0 -329
  144. liquid/builtin/filters/extra.py +0 -83
  145. liquid/builtin/filters/math.py +0 -129
  146. liquid/builtin/filters/misc.py +0 -137
  147. liquid/builtin/filters/string.py +0 -416
  148. liquid/builtin/illegal.py +0 -28
  149. liquid/builtin/loaders/__init__.py +0 -0
  150. liquid/builtin/loaders/caching_file_system_loader.py +0 -61
  151. liquid/builtin/loaders/choice_loader.py +0 -94
  152. liquid/builtin/loaders/dict_loader.py +0 -64
  153. liquid/builtin/loaders/package_loader.py +0 -132
  154. liquid/builtin/output.py +0 -74
  155. liquid/builtin/tags/__init__.py +0 -0
  156. liquid/builtin/tags/assign_tag.py +0 -75
  157. liquid/builtin/tags/capture_tag.py +0 -98
  158. liquid/builtin/tags/case_tag.py +0 -287
  159. liquid/builtin/tags/comment_tag.py +0 -77
  160. liquid/builtin/tags/cycle_tag.py +0 -132
  161. liquid/builtin/tags/decrement_tag.py +0 -59
  162. liquid/builtin/tags/doc_tag.py +0 -68
  163. liquid/builtin/tags/echo_tag.py +0 -45
  164. liquid/builtin/tags/for_tag.py +0 -337
  165. liquid/builtin/tags/if_tag.py +0 -209
  166. liquid/builtin/tags/ifchanged_tag.py +0 -94
  167. liquid/builtin/tags/include_tag.py +0 -251
  168. liquid/builtin/tags/increment_tag.py +0 -60
  169. liquid/builtin/tags/inline_comment_tag.py +0 -47
  170. liquid/builtin/tags/liquid_tag.py +0 -183
  171. liquid/builtin/tags/render_tag.py +0 -371
  172. liquid/builtin/tags/tablerow_tag.py +0 -320
  173. liquid/builtin/tags/unless_tag.py +0 -218
  174. liquid/context.py +0 -615
  175. liquid/expression.py +0 -41
  176. liquid/extra/__init__.py +0 -98
  177. liquid/extra/filters/__init__.py +0 -33
  178. liquid/extra/filters/_json.py +0 -33
  179. liquid/extra/filters/array.py +0 -60
  180. liquid/extra/filters/babel.py +0 -552
  181. liquid/extra/filters/html.py +0 -32
  182. liquid/extra/filters/translate.py +0 -448
  183. liquid/extra/tags/__init__.py +0 -17
  184. liquid/extra/tags/_with.py +0 -80
  185. liquid/extra/tags/extends_tag.py +0 -576
  186. liquid/extra/tags/macro_tag.py +0 -270
  187. liquid/extra/tags/snippet_tag.py +0 -107
  188. liquid/extra/tags/translate_tag.py +0 -388
  189. liquid/filter.py +0 -230
  190. liquid/future/__init__.py +0 -3
  191. liquid/future/environment.py +0 -30
  192. liquid/future/filters/__init__.py +0 -1
  193. liquid/future/tags/__init__.py +0 -1
  194. liquid/lex.py +0 -260
  195. liquid/limits.py +0 -66
  196. liquid/loader.py +0 -141
  197. liquid/messages.py +0 -357
  198. liquid/mode.py +0 -12
  199. liquid/output.py +0 -35
  200. liquid/parser.py +0 -119
  201. liquid/span.py +0 -35
  202. liquid/static_analysis.py +0 -443
  203. liquid/stream.py +0 -148
  204. liquid/stringify.py +0 -31
  205. liquid/tag.py +0 -47
  206. liquid/template.py +0 -658
  207. liquid/token.py +0 -145
  208. liquid/undefined.py +0 -218
  209. liquid/utils/__init__.py +0 -15
  210. liquid/utils/html.py +0 -57
  211. liquid/utils/text.py +0 -28
  212. python_liquid-2.3.6.dist-info/RECORD +0 -96
@@ -1,448 +0,0 @@
1
- """Translation filters."""
2
-
3
- import re
4
- from gettext import NullTranslations
5
- from typing import Any
6
- from typing import Optional
7
- from typing import cast
8
-
9
- from markupsafe import Markup
10
-
11
- from liquid import Expression
12
- from liquid import RenderContext
13
- from liquid.builtin.expressions import Filter
14
- from liquid.builtin.expressions import KeywordArgument
15
- from liquid.builtin.expressions import PositionalArgument
16
- from liquid.builtin.expressions import StringLiteral
17
- from liquid.filter import int_arg
18
- from liquid.messages import MESSAGES
19
- from liquid.messages import MessageText
20
- from liquid.messages import TranslatableFilter
21
- from liquid.messages import Translations
22
- from liquid.stringify import to_liquid_string
23
-
24
- __all__ = [
25
- "Translate",
26
- "GetText",
27
- "NGetText",
28
- "PGetText",
29
- "NPGetText",
30
- ]
31
-
32
-
33
- class BaseTranslateFilter:
34
- """Base class for the default translation filters.
35
-
36
- Args:
37
- translations_var: The name of a render context variable that resolves to a
38
- gettext `Translations` class. Defaults to `"translations"`.
39
- default_translations: A fallback translations class to use if
40
- `translations_var` can not be resolves. Defaults to `NullTranslations`.
41
- message_interpolation: If `True` (default), perform printf-style string
42
- interpolation on the translated message, using keyword arguments passed to
43
- the filter function.
44
- autoescape_message: If `True` and the current environment has `autoescape`
45
- set to `True`, the filter's left value will be escaped before translation.
46
- Defaults to `False`.
47
- """
48
-
49
- name = "base"
50
- re_vars = re.compile(r"(?<!%)%\((\w+)\)s")
51
- with_context = True
52
-
53
- def __init__(
54
- self,
55
- *,
56
- translations_var: str = "translations",
57
- default_translations: Optional[Translations] = None,
58
- message_interpolation: bool = True,
59
- autoescape_message: bool = False,
60
- ) -> None:
61
- self.translations_var = translations_var
62
- self.default_translations = default_translations or NullTranslations()
63
- self.message_interpolation = message_interpolation
64
- self.autoescape_message = autoescape_message
65
-
66
- def format_message(
67
- self, context: RenderContext, message_text: str, message_vars: dict[str, Any]
68
- ) -> str:
69
- """Return the message string formatted with the given message variables."""
70
- with context.extend(namespace=message_vars):
71
- _vars = {
72
- k: to_liquid_string(
73
- context.resolve(k), autoescape=context.env.autoescape
74
- )
75
- for k in self.re_vars.findall(message_text)
76
- }
77
-
78
- # Missing variables get replaced by the current `Undefined` type and we're
79
- # converting all values to a string, so a KeyError or a ValueError should
80
- # be impossible.
81
- return message_text % _vars
82
-
83
- def _resolve_translations(self, context: RenderContext) -> Translations:
84
- return cast(
85
- Translations,
86
- context.resolve(self.translations_var, default=self.default_translations),
87
- )
88
-
89
-
90
- class Translate(BaseTranslateFilter, TranslatableFilter):
91
- """A Liquid filter for translating strings to other languages.
92
-
93
- Depending on the keyword arguments provided when the resulting filter
94
- is called, it could behave like gettext, ngettext, pgettext or npgettext.
95
- """
96
-
97
- name = "t"
98
-
99
- def __call__(
100
- self,
101
- __left: object,
102
- __message_context: object = None,
103
- *,
104
- context: RenderContext,
105
- **kwargs: Any,
106
- ) -> str:
107
- """Apply the filter and return the result."""
108
- autoescape = context.env.autoescape
109
- __left = to_liquid_string(
110
- __left,
111
- autoescape=autoescape and self.autoescape_message,
112
- )
113
-
114
- translations = self._resolve_translations(context)
115
-
116
- plural = kwargs.pop("plural", None)
117
- n = _count(kwargs.get("count"))
118
-
119
- if plural is not None and n is not None:
120
- plural = to_liquid_string(
121
- plural,
122
- autoescape=autoescape and self.autoescape_message,
123
- )
124
-
125
- if __message_context is not None:
126
- text = translations.npgettext(
127
- to_liquid_string(
128
- __message_context,
129
- autoescape=autoescape and self.autoescape_message,
130
- ),
131
- __left,
132
- plural,
133
- n,
134
- )
135
- else:
136
- text = translations.ngettext(__left, plural, n)
137
- elif __message_context is not None:
138
- text = translations.pgettext(
139
- to_liquid_string(
140
- __message_context,
141
- autoescape=autoescape and self.autoescape_message,
142
- ),
143
- __left,
144
- )
145
- else:
146
- text = translations.gettext(__left)
147
-
148
- if autoescape:
149
- text = Markup(text)
150
-
151
- if self.message_interpolation:
152
- text = self.format_message(context, text, kwargs)
153
-
154
- return text
155
-
156
- def message( # noqa: D102
157
- self,
158
- left: Expression,
159
- _filter: Filter,
160
- lineno: int,
161
- ) -> Optional[MessageText]:
162
- if not isinstance(left, StringLiteral):
163
- return None
164
-
165
- if not _filter.args:
166
- return MessageText(
167
- lineno=lineno,
168
- funcname="gettext",
169
- message=(left.value,),
170
- )
171
-
172
- if isinstance(_filter.args[0], PositionalArgument):
173
- _context: Optional[Expression] = _filter.args[0].value
174
- else:
175
- _context = None
176
-
177
- plural: Optional[Expression] = None
178
- for arg in _filter.args:
179
- if isinstance(arg, KeywordArgument) and arg.name == "plural":
180
- plural = arg.value
181
-
182
- # Translate our filters into standard *gettext argument specs.
183
-
184
- if isinstance(plural, StringLiteral):
185
- if isinstance(_context, StringLiteral):
186
- funcname = "npgettext"
187
- message: MESSAGES = ((_context.value, "c"), left.value, plural.value)
188
- else:
189
- funcname = "ngettext"
190
- message = (left.value, plural.value)
191
- elif plural is not None:
192
- # Don't attempt to extract any messages if plural is given
193
- # but not a string literal
194
- return None
195
- elif isinstance(_context, StringLiteral):
196
- funcname = "pgettext"
197
- message = ((_context.value, "c"), left.value)
198
- else:
199
- funcname = "gettext"
200
- message = (left.value,)
201
-
202
- return MessageText(
203
- lineno=lineno,
204
- funcname=funcname,
205
- message=message,
206
- )
207
-
208
-
209
- class GetText(BaseTranslateFilter, TranslatableFilter):
210
- """A Liquid filter equivalent of `gettext.gettext`."""
211
-
212
- name = "gettext"
213
-
214
- def __call__( # noqa: D102
215
- self,
216
- __left: object,
217
- *,
218
- context: RenderContext,
219
- **kwargs: Any,
220
- ) -> str:
221
- autoescape = context.env.autoescape
222
- __left = to_liquid_string(
223
- __left,
224
- autoescape=autoescape and self.autoescape_message,
225
- )
226
-
227
- translations = self._resolve_translations(context)
228
- text = translations.gettext(__left)
229
-
230
- if autoescape:
231
- text = Markup(text)
232
-
233
- if self.message_interpolation:
234
- text = self.format_message(context, text, kwargs)
235
-
236
- return text
237
-
238
- def message( # noqa: D102
239
- self,
240
- left: Expression,
241
- _filter: Filter,
242
- lineno: int,
243
- ) -> Optional[MessageText]:
244
- if not isinstance(left, StringLiteral):
245
- return None
246
-
247
- return MessageText(
248
- lineno=lineno,
249
- funcname=self.name,
250
- message=(left.value,),
251
- )
252
-
253
-
254
- class NGetText(BaseTranslateFilter, TranslatableFilter):
255
- """A Liquid filter equivalent of `gettext.ngettext`."""
256
-
257
- name = "ngettext"
258
-
259
- def __call__(
260
- self,
261
- __left: object,
262
- __plural: str,
263
- __count: object,
264
- *,
265
- context: RenderContext,
266
- **kwargs: Any,
267
- ) -> str:
268
- """Apply the filter and return the result."""
269
- autoescape = context.env.autoescape
270
- __left = to_liquid_string(
271
- __left,
272
- autoescape=autoescape and self.autoescape_message,
273
- )
274
-
275
- __plural = to_liquid_string(
276
- __plural,
277
- autoescape=autoescape and self.autoescape_message,
278
- )
279
-
280
- __count = int_arg(__count, default=1)
281
-
282
- translations = self._resolve_translations(context)
283
- text = translations.ngettext(__left, __plural, __count)
284
-
285
- if autoescape:
286
- text = Markup(text)
287
-
288
- if self.message_interpolation:
289
- text = self.format_message(context, text, kwargs)
290
-
291
- return text
292
-
293
- def message( # noqa: D102
294
- self,
295
- left: Expression,
296
- _filter: Filter,
297
- lineno: int,
298
- ) -> Optional[MessageText]:
299
- if len(_filter.args) < 1:
300
- return None
301
-
302
- plural = _filter.args[0].value
303
-
304
- if not isinstance(left, StringLiteral) or not isinstance(plural, StringLiteral):
305
- return None
306
-
307
- return MessageText(
308
- lineno=lineno,
309
- funcname=self.name,
310
- message=(left.value, plural.value),
311
- )
312
-
313
-
314
- class PGetText(BaseTranslateFilter, TranslatableFilter):
315
- """A Liquid filter equivalent of `gettext.pgettext`."""
316
-
317
- name = "pgettext"
318
-
319
- def __call__( # noqa: D102
320
- self,
321
- __left: object,
322
- __message_context: str,
323
- *,
324
- context: RenderContext,
325
- **kwargs: Any,
326
- ) -> str:
327
- autoescape = context.env.autoescape
328
- __left = to_liquid_string(
329
- __left,
330
- autoescape=autoescape and self.autoescape_message,
331
- )
332
-
333
- __message_context = to_liquid_string(
334
- __message_context,
335
- autoescape=autoescape and self.autoescape_message,
336
- )
337
-
338
- translations = self._resolve_translations(context)
339
- text = translations.pgettext(__message_context, __left)
340
-
341
- if autoescape:
342
- text = Markup(text)
343
-
344
- if self.message_interpolation:
345
- text = self.format_message(context, text, kwargs)
346
-
347
- return text
348
-
349
- def message( # noqa: D102
350
- self, left: Expression, _filter: Filter, lineno: int
351
- ) -> Optional[MessageText]:
352
- if len(_filter.args) < 1:
353
- return None
354
-
355
- ctx = _filter.args[0].value
356
-
357
- if not isinstance(left, StringLiteral) or not isinstance(ctx, StringLiteral):
358
- return None
359
-
360
- return MessageText(
361
- lineno=lineno,
362
- funcname=self.name,
363
- message=((ctx.value, "c"), left.value),
364
- )
365
-
366
-
367
- class NPGetText(BaseTranslateFilter, TranslatableFilter):
368
- """A Liquid filter equivalent of `gettext.npgettext`."""
369
-
370
- name = "npgettext"
371
-
372
- def __call__( # noqa: D102
373
- self,
374
- __left: object,
375
- __message_context: str,
376
- __plural: str,
377
- __count: object,
378
- *,
379
- context: RenderContext,
380
- **kwargs: Any,
381
- ) -> str:
382
- autoescape = context.env.autoescape
383
- __left = to_liquid_string(
384
- __left,
385
- autoescape=autoescape and self.autoescape_message,
386
- )
387
-
388
- __message_context = to_liquid_string(
389
- __message_context,
390
- autoescape=autoescape and self.autoescape_message,
391
- )
392
-
393
- __plural = to_liquid_string(
394
- __plural,
395
- autoescape=autoescape and self.autoescape_message,
396
- )
397
-
398
- __count = int_arg(__count, default=1)
399
-
400
- translations = self._resolve_translations(context)
401
- text = translations.npgettext(
402
- __message_context,
403
- __left,
404
- __plural,
405
- __count,
406
- )
407
-
408
- if autoescape:
409
- text = Markup(text)
410
-
411
- if self.message_interpolation:
412
- text = self.format_message(context, text, kwargs)
413
-
414
- return text
415
-
416
- def message( # noqa: D102
417
- self,
418
- left: Expression,
419
- _filter: Filter,
420
- lineno: int,
421
- ) -> Optional[MessageText]:
422
- if len(_filter.args) < 2: # noqa: PLR2004
423
- return None
424
-
425
- ctx = _filter.args[0].value
426
- plural = _filter.args[1].value
427
-
428
- if (
429
- not isinstance(left, StringLiteral)
430
- or not isinstance(plural, StringLiteral)
431
- or not isinstance(ctx, StringLiteral)
432
- ):
433
- return None
434
-
435
- return MessageText(
436
- lineno=lineno,
437
- funcname=self.name,
438
- message=((ctx.value, "c"), left.value, plural.value),
439
- )
440
-
441
-
442
- def _count(val: Any) -> Optional[int]:
443
- if val in (None, False, True):
444
- return None
445
- try:
446
- return int(val)
447
- except ValueError:
448
- return None
@@ -1,17 +0,0 @@
1
- from ._with import WithTag # noqa: D104
2
- from .extends_tag import BlockTag
3
- from .extends_tag import ExtendsTag
4
- from .macro_tag import CallTag
5
- from .macro_tag import MacroTag
6
- from .snippet_tag import SnippetTag
7
- from .translate_tag import TranslateTag
8
-
9
- __all__ = (
10
- "WithTag",
11
- "BlockTag",
12
- "ExtendsTag",
13
- "CallTag",
14
- "MacroTag",
15
- "SnippetTag",
16
- "TranslateTag",
17
- )
@@ -1,80 +0,0 @@
1
- """The extra _with_ tag."""
2
-
3
- from __future__ import annotations
4
-
5
- import sys
6
- from typing import TYPE_CHECKING
7
- from typing import Iterable
8
- from typing import TextIO
9
-
10
- from liquid.ast import BlockNode
11
- from liquid.ast import Node
12
- from liquid.builtin.expressions import Identifier
13
- from liquid.builtin.expressions import KeywordArgument
14
- from liquid.parser import get_parser
15
- from liquid.tag import Tag
16
- from liquid.token import TOKEN_EOF
17
- from liquid.token import TOKEN_TAG
18
- from liquid.token import Token
19
-
20
- if TYPE_CHECKING:
21
- from liquid.context import RenderContext
22
- from liquid.expression import Expression
23
- from liquid.stream import TokenStream
24
-
25
- TAG_WITH = sys.intern("with")
26
- TAG_ENDWITH = sys.intern("endwith")
27
-
28
-
29
- class WithNode(Node):
30
- __slots__ = ("args", "block")
31
-
32
- def __init__(self, token: Token, args: list[KeywordArgument], block: BlockNode):
33
- super().__init__(token)
34
- self.args = args
35
- self.block = block
36
- self.blank = self.block.blank
37
-
38
- def render_to_output(
39
- self,
40
- context: RenderContext,
41
- buffer: TextIO,
42
- ) -> int:
43
- with context.extend({a.name: a.value.evaluate(context) for a in self.args}):
44
- return self.block.render(context, buffer)
45
-
46
- async def render_to_output_async(
47
- self,
48
- context: RenderContext,
49
- buffer: TextIO,
50
- ) -> int:
51
- namespace = {a.name: await a.value.evaluate_async(context) for a in self.args}
52
- with context.extend(namespace):
53
- return await self.block.render_async(context, buffer)
54
-
55
- def children(
56
- self,
57
- static_context: RenderContext, # noqa: ARG002
58
- *,
59
- include_partials: bool = True, # noqa: ARG002
60
- ) -> Iterable[Node]:
61
- yield self.block
62
-
63
- def expressions(self) -> Iterable[Expression]:
64
- yield from (arg.value for arg in self.args)
65
-
66
- def block_scope(self) -> Iterable[Identifier]:
67
- yield from (Identifier(p.name, token=p.token) for p in self.args)
68
-
69
-
70
- class WithTag(Tag):
71
- name = TAG_WITH
72
- end = TAG_ENDWITH
73
- node_class = WithNode
74
-
75
- def parse(self, stream: TokenStream) -> Node:
76
- token = stream.eat(TOKEN_TAG)
77
- args = KeywordArgument.parse(self.env, stream.into_inner(tag=token))
78
- block = get_parser(self.env).parse_block(stream, (TAG_ENDWITH, TOKEN_EOF))
79
- stream.expect(TOKEN_TAG, value=TAG_ENDWITH)
80
- return self.node_class(token, args=args, block=block)