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,387 +0,0 @@
1
- """Built-in filtered expressions."""
2
-
3
- from __future__ import annotations
4
-
5
- from typing import TYPE_CHECKING
6
- from typing import Union
7
-
8
- from liquid import Mode
9
- from liquid.exceptions import FilterArgumentError
10
- from liquid.exceptions import LiquidSyntaxError
11
- from liquid.exceptions import LiquidTypeError
12
- from liquid.exceptions import UnknownFilterError
13
- from liquid.expression import Expression
14
- from liquid.token import TOKEN_ASSIGN
15
- from liquid.token import TOKEN_COLON
16
- from liquid.token import TOKEN_COMMA
17
- from liquid.token import TOKEN_DPIPE
18
- from liquid.token import TOKEN_ELSE
19
- from liquid.token import TOKEN_EOF
20
- from liquid.token import TOKEN_FALSE
21
- from liquid.token import TOKEN_FLOAT
22
- from liquid.token import TOKEN_IF
23
- from liquid.token import TOKEN_INTEGER
24
- from liquid.token import TOKEN_LBRACKET
25
- from liquid.token import TOKEN_LPAREN
26
- from liquid.token import TOKEN_NIL
27
- from liquid.token import TOKEN_NULL
28
- from liquid.token import TOKEN_PIPE
29
- from liquid.token import TOKEN_RANGE_LITERAL
30
- from liquid.token import TOKEN_STRING
31
- from liquid.token import TOKEN_TRUE
32
- from liquid.token import TOKEN_WORD
33
-
34
- from .arguments import KeywordArgument
35
- from .arguments import PositionalArgument
36
- from .logical import BooleanExpression
37
- from .primitive import parse_primitive
38
-
39
- if TYPE_CHECKING:
40
- from liquid import Environment
41
- from liquid import RenderContext
42
- from liquid import TokenStream
43
- from liquid.token import Token
44
-
45
-
46
- FILTER_TOKENS = set( # noqa: C405
47
- [
48
- TOKEN_INTEGER,
49
- TOKEN_FLOAT,
50
- TOKEN_STRING,
51
- TOKEN_FALSE,
52
- TOKEN_TRUE,
53
- TOKEN_NIL,
54
- TOKEN_NULL,
55
- TOKEN_RANGE_LITERAL,
56
- TOKEN_LBRACKET,
57
- TOKEN_LPAREN,
58
- TOKEN_WORD,
59
- ]
60
- )
61
-
62
-
63
- class FilteredExpression(Expression):
64
- """An expression for the built-in `assign` tag and output statement."""
65
-
66
- __slots__ = ("left", "filters")
67
-
68
- def __init__(
69
- self,
70
- token: Token,
71
- left: Expression,
72
- filters: list[Filter] | None = None,
73
- ) -> None:
74
- super().__init__(token=token)
75
- self.left = left
76
- self.filters = filters
77
-
78
- def __str__(self) -> str:
79
- filters = (
80
- " | " + " | ".join(str(f) for f in self.filters) if self.filters else ""
81
- )
82
- return f"{self.left}{filters}"
83
-
84
- def evaluate(self, context: RenderContext) -> object:
85
- rv = self.left.evaluate(context)
86
- if self.filters:
87
- for f in self.filters:
88
- rv = f.evaluate(rv, context)
89
- return rv
90
-
91
- async def evaluate_async(self, context: RenderContext) -> object:
92
- rv = await self.left.evaluate_async(context)
93
- if self.filters:
94
- for f in self.filters:
95
- rv = await f.evaluate_async(rv, context)
96
- return rv
97
-
98
- def children(self) -> list[Expression]:
99
- children = [self.left]
100
- if self.filters:
101
- for filter_ in self.filters:
102
- children.extend(filter_.children())
103
- return children
104
-
105
- @staticmethod
106
- def parse(
107
- env: Environment, tokens: TokenStream
108
- ) -> Union[FilteredExpression, TernaryFilteredExpression]:
109
- """Parse a filtered expression from _tokens_."""
110
- left = parse_primitive(env, tokens)
111
- filters = Filter.parse(env, tokens, delim=(TOKEN_PIPE,))
112
-
113
- if tokens.current.kind == TOKEN_IF:
114
- if not env.ternary_expressions:
115
- raise LiquidSyntaxError(
116
- "disallowed ternary expression", token=tokens.current
117
- )
118
-
119
- return TernaryFilteredExpression.parse(
120
- env, FilteredExpression(left.token, left, filters), tokens
121
- )
122
-
123
- tokens.eat(TOKEN_EOF)
124
- return FilteredExpression(left.token, left, filters)
125
-
126
-
127
- class TernaryFilteredExpression(Expression):
128
- __slots__ = ("left", "condition", "alternative", "filters", "tail_filters")
129
-
130
- def __init__(
131
- self,
132
- token: Token,
133
- left: FilteredExpression,
134
- condition: Expression,
135
- alternative: Expression | None = None,
136
- filters: list[Filter] | None = None,
137
- tail_filters: list[Filter] | None = None,
138
- ) -> None:
139
- super().__init__(token=token)
140
- self.left = left
141
- self.condition = condition
142
- self.alternative = alternative
143
- self.filters = filters
144
- self.tail_filters = tail_filters
145
-
146
- def __str__(self) -> str:
147
- buf = [f"{self.left} if {self.condition}"]
148
-
149
- if self.alternative:
150
- buf.append(f" else {self.alternative}")
151
-
152
- if self.filters:
153
- buf.append(" | " + " | ".join(str(f) for f in self.filters))
154
-
155
- if self.tail_filters:
156
- buf.append(" || " + " | ".join(str(f) for f in self.tail_filters))
157
-
158
- return "".join(buf)
159
-
160
- def evaluate(self, context: RenderContext) -> object:
161
- rv: object = None
162
-
163
- if self.condition.evaluate(context):
164
- rv = self.left.evaluate(context)
165
- elif self.alternative:
166
- rv = self.alternative.evaluate(context)
167
- if self.filters:
168
- for f in self.filters:
169
- rv = f.evaluate(rv, context)
170
-
171
- if self.tail_filters:
172
- for f in self.tail_filters:
173
- rv = f.evaluate(rv, context)
174
-
175
- return rv
176
-
177
- async def evaluate_async(self, context: RenderContext) -> object:
178
- rv: object = None
179
-
180
- if await self.condition.evaluate_async(context):
181
- rv = await self.left.evaluate_async(context)
182
- elif self.alternative:
183
- rv = await self.alternative.evaluate_async(context)
184
- if self.filters:
185
- for f in self.filters:
186
- rv = await f.evaluate_async(rv, context)
187
-
188
- if self.tail_filters:
189
- for f in self.tail_filters:
190
- rv = await f.evaluate_async(rv, context)
191
-
192
- return rv
193
-
194
- def children(self) -> list[Expression]:
195
- children = self.left.children()
196
- children.append(self.condition)
197
-
198
- if self.alternative:
199
- children.append(self.alternative)
200
-
201
- if self.filters:
202
- for filter_ in self.filters:
203
- children.extend(filter_.children())
204
-
205
- if self.tail_filters:
206
- for filter_ in self.tail_filters:
207
- children.extend(filter_.children())
208
-
209
- return children
210
-
211
- @staticmethod
212
- def parse(
213
- env: Environment, expr: FilteredExpression, tokens: TokenStream
214
- ) -> TernaryFilteredExpression:
215
- """Parse a ternary expression from _tokens_."""
216
- tokens.eat(TOKEN_IF)
217
- condition = BooleanExpression.parse(env, tokens, inline=True)
218
- alternative: Expression | None = None
219
- filters: list[Filter] | None = None
220
- tail_filters: list[Filter] | None = None
221
-
222
- if tokens.current.kind == TOKEN_ELSE:
223
- next(tokens) # else
224
- alternative = parse_primitive(env, tokens)
225
-
226
- if tokens.current.kind == TOKEN_PIPE:
227
- filters = Filter.parse(env, tokens, delim=(TOKEN_PIPE,))
228
-
229
- if tokens.current.kind == TOKEN_DPIPE:
230
- tail_filters = Filter.parse(env, tokens, delim=(TOKEN_PIPE, TOKEN_DPIPE))
231
-
232
- tokens.eat(TOKEN_EOF)
233
- return TernaryFilteredExpression(
234
- expr.token, expr, condition, alternative, filters, tail_filters
235
- )
236
-
237
-
238
- class Filter:
239
- __slots__ = ("name", "args", "token")
240
-
241
- def __init__(
242
- self,
243
- token: Token,
244
- name: str,
245
- arguments: list[KeywordArgument | PositionalArgument],
246
- ) -> None:
247
- self.token = token
248
- self.name = name
249
- self.args = arguments
250
-
251
- def __str__(self) -> str:
252
- if self.args:
253
- return f"{self.name}: {', '.join(str(arg) for arg in self.args)}"
254
- return self.name
255
-
256
- def validate_filter_arguments(self, env: Environment) -> None:
257
- try:
258
- func = env.filters[self.name]
259
- except KeyError as err:
260
- raise UnknownFilterError(
261
- f"unknown filter '{self.name}'", token=self.token
262
- ) from err
263
-
264
- if hasattr(func, "validate"):
265
- func.validate(env, self.token, self.name, self.args)
266
-
267
- def evaluate(self, left: object, context: RenderContext) -> object:
268
- func = context.filter(self.name, token=self.token)
269
- positional_args, keyword_args = self.evaluate_args(context)
270
- try:
271
- return func(left, *positional_args, **keyword_args)
272
- except TypeError as err:
273
- raise LiquidTypeError(f"{self.name}: {err}", token=self.token) from err
274
- except (LiquidTypeError, FilterArgumentError) as err:
275
- err.token = self.token
276
- raise err
277
-
278
- async def evaluate_async(self, left: object, context: RenderContext) -> object:
279
- func = context.filter(self.name, token=self.token)
280
- positional_args, keyword_args = await self.evaluate_args_async(context)
281
-
282
- try:
283
- if hasattr(func, "filter_async"):
284
- return await func.filter_async(left, *positional_args, **keyword_args)
285
- return func(left, *positional_args, **keyword_args)
286
- except TypeError as err:
287
- raise LiquidTypeError(f"{self.name}: {err}", token=self.token) from err
288
- except (LiquidTypeError, FilterArgumentError) as err:
289
- err.token = self.token
290
- raise err
291
-
292
- def evaluate_args(
293
- self, context: RenderContext
294
- ) -> tuple[list[object], dict[str, object]]:
295
- positional_args: list[object] = []
296
- keyword_args: dict[str, object] = {}
297
- for arg in self.args:
298
- name, value = arg.evaluate(context)
299
- if name:
300
- keyword_args[name] = value
301
- else:
302
- positional_args.append(value)
303
-
304
- return positional_args, keyword_args
305
-
306
- async def evaluate_args_async(
307
- self, context: RenderContext
308
- ) -> tuple[list[object], dict[str, object]]:
309
- positional_args: list[object] = []
310
- keyword_args: dict[str, object] = {}
311
- for arg in self.args:
312
- name, value = await arg.evaluate_async(context)
313
- if name:
314
- keyword_args[name] = value
315
- else:
316
- positional_args.append(value)
317
-
318
- return positional_args, keyword_args
319
-
320
- def children(self) -> list[Expression]:
321
- return [arg.value for arg in self.args]
322
-
323
- @staticmethod
324
- def parse(
325
- env: Environment, tokens: TokenStream, *, delim: tuple[str, ...]
326
- ) -> list[Filter]:
327
- """Parse filters from _tokens_."""
328
- filters: list[Filter] = []
329
- argument_separators = (
330
- (TOKEN_COLON, TOKEN_ASSIGN) if env.keyword_assignment else (TOKEN_COLON,)
331
- )
332
-
333
- while tokens.current.kind in delim:
334
- next(tokens)
335
- token = tokens.eat(TOKEN_WORD)
336
- args: list[Union[KeywordArgument, PositionalArgument]] = []
337
-
338
- if tokens.current.kind != TOKEN_COLON:
339
- # No arguments
340
- filters.append(Filter(token, token.value, args))
341
- continue
342
-
343
- tokens.eat(TOKEN_COLON)
344
- while True:
345
- tok = tokens.current
346
- if tok.kind == TOKEN_WORD:
347
- if tokens.peek.kind in argument_separators:
348
- next(tokens) # word
349
- next(tokens) # : or =
350
- args.append(
351
- KeywordArgument(
352
- tok, tok.value, parse_primitive(env, tokens)
353
- )
354
- )
355
- else:
356
- args.append(PositionalArgument(parse_primitive(env, tokens)))
357
-
358
- if tokens.current.kind in FILTER_TOKENS:
359
- raise LiquidSyntaxError(
360
- "expected a comma separated list of arguments, "
361
- f"found {tokens.current.kind}",
362
- token=tokens.current,
363
- )
364
- elif tok.kind in FILTER_TOKENS:
365
- args.append(PositionalArgument(parse_primitive(env, tokens)))
366
-
367
- # There should be a comma between filter tokens.
368
- if tokens.current.kind in FILTER_TOKENS:
369
- raise LiquidSyntaxError(
370
- "expected a comma separated list of arguments, "
371
- f"found {tokens.current.kind}",
372
- token=tokens.current,
373
- )
374
- elif tok.kind == TOKEN_COMMA:
375
- if env.mode == Mode.STRICT and tokens.peek.kind == TOKEN_COMMA:
376
- raise LiquidSyntaxError(
377
- "expected a comma separated list of arguments, "
378
- f"found {tokens.peek.kind}",
379
- token=tokens.peek,
380
- )
381
- next(tokens)
382
- else:
383
- break
384
-
385
- filters.append(Filter(token, token.value, args))
386
-
387
- return filters