python-liquid 2.2.1__py3-none-any.whl → 2.3.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.
liquid/__init__.py CHANGED
@@ -56,7 +56,7 @@ from .tag import Tag
56
56
 
57
57
  from . import future
58
58
 
59
- __version__ = "2.2.1"
59
+ __version__ = "2.3.0"
60
60
 
61
61
  __all__ = (
62
62
  "AwareBoundTemplate",
@@ -123,29 +123,23 @@ class LoopExpression(Expression):
123
123
  ) -> tuple[Iterator[object], int]:
124
124
  offset_key = f"{self.identifier}-{self.iterable}"
125
125
 
126
- if limit is None and offset is None:
127
- context.stopindex(key=offset_key, index=length)
128
- if self.reversed:
129
- return reversed(list(it)), length
130
- return it, length
131
-
132
126
  if offset == "continue":
133
- offset = context.stopindex(key=offset_key)
134
- length = max(length - offset, 0)
135
- elif offset is not None:
136
- assert isinstance(offset, int), f"found {offset!r}"
137
- length = max(length - offset, 0)
127
+ start = context.stopindex(offset_key)
128
+ else:
129
+ start = int(offset or 0)
130
+
131
+ stop = None if limit is None else limit + start
138
132
 
139
- if limit is not None:
140
- length = min(length, limit)
133
+ start_ = min(max(start, 0), length)
134
+ stop_ = min(stop or length, length)
135
+ length_ = max(stop_ - start_, 0)
141
136
 
142
- stop = offset + length if offset else length
143
- context.stopindex(key=offset_key, index=stop)
144
- it = islice(it, offset, stop)
137
+ context.stopindex(key=offset_key, index=stop_)
138
+ it = islice(it, start_, stop_)
145
139
 
146
140
  if self.reversed:
147
- return reversed(list(it)), length
148
- return it, length
141
+ return reversed(list(it)), length_
142
+ return it, length_
149
143
 
150
144
  def evaluate(self, context: RenderContext) -> tuple[Iterator[object], int]:
151
145
  it, length = self._to_iter(self.iterable.evaluate(context), context)
@@ -39,6 +39,12 @@ if TYPE_CHECKING:
39
39
  from liquid import TokenStream
40
40
 
41
41
 
42
+ # MAX_RANGE = (2**53) - 1
43
+ # MIN_RANGE = -(2**53) + 1
44
+ MAX_RANGE = 1024
45
+ MIN_RANGE = -1024
46
+
47
+
42
48
  class Nil(Expression):
43
49
  __slots__ = ()
44
50
 
@@ -249,7 +255,9 @@ class RangeLiteral(Expression):
249
255
  if start > stop:
250
256
  return range(0)
251
257
 
252
- return range(start, stop + 1)
258
+ return range(
259
+ clamp(start, MIN_RANGE, MAX_RANGE), clamp(stop + 1, MIN_RANGE, MAX_RANGE)
260
+ )
253
261
 
254
262
  def evaluate(self, context: RenderContext) -> range:
255
263
  return self._make_range(
@@ -415,3 +423,8 @@ def parse_string_or_path(
415
423
  def is_empty(obj: object) -> bool:
416
424
  """Return True if _obj_ is considered empty."""
417
425
  return isinstance(obj, (list, dict, str)) and not obj
426
+
427
+
428
+ def clamp(n: int, min_value: int, max_value: int) -> int:
429
+ """Clamp _n_ between _min_value_ and _max_value_."""
430
+ return max(min_value, min(n, max_value))
@@ -29,6 +29,9 @@ class FileSystemLoader(BaseLoader):
29
29
  ext: A default file extension. Should include a leading period.
30
30
  reject_symlinks: When `True`, reject paths to symlinks that resolve to files
31
31
  outside the search path. Defaults to `False`.
32
+
33
+ Raise:
34
+ ValueError if `ext` is not a valid suffix.
32
35
  """
33
36
 
34
37
  def __init__(
@@ -48,6 +51,10 @@ class FileSystemLoader(BaseLoader):
48
51
  self.ext = ext
49
52
  self.reject_symlinks = reject_symlinks
50
53
 
54
+ # Raise a ValueError early if `ext` is invalid.
55
+ if ext:
56
+ Path("x").with_suffix(ext)
57
+
51
58
  def resolve_path(self, template_name: str) -> Path:
52
59
  """Return a path to the template identified by _template_name_.
53
60
 
@@ -57,6 +64,9 @@ class FileSystemLoader(BaseLoader):
57
64
  """
58
65
  template_path = Path(template_name)
59
66
 
67
+ if not template_path.name:
68
+ raise TemplateNotFoundError(template_name)
69
+
60
70
  if self.ext and not template_path.suffix:
61
71
  template_path = template_path.with_suffix(self.ext)
62
72
 
@@ -66,7 +76,11 @@ class FileSystemLoader(BaseLoader):
66
76
  for base in self.search_path:
67
77
  source_path = base.joinpath(template_path)
68
78
 
69
- if not source_path.exists() or not source_path.is_file():
79
+ try:
80
+ if not source_path.exists() or not source_path.is_file():
81
+ continue
82
+ except OSError:
83
+ # "File name too long", for example
70
84
  continue
71
85
 
72
86
  if self.reject_symlinks:
@@ -11,6 +11,7 @@ from typing import TextIO
11
11
  from liquid.ast import Node
12
12
  from liquid.builtin.expressions import PositionalArgument
13
13
  from liquid.builtin.expressions import parse_primitive
14
+ from liquid.exceptions import LiquidSyntaxError
14
15
  from liquid.stringify import to_liquid_string
15
16
  from liquid.tag import Tag
16
17
  from liquid.token import TOKEN_COLON
@@ -124,4 +125,8 @@ class CycleTag(Tag):
124
125
  tokens.eat(TOKEN_COLON)
125
126
 
126
127
  args = PositionalArgument.parse(self.env, tokens)
128
+
129
+ if not args:
130
+ raise LiquidSyntaxError("expected at least one argument", token=token)
131
+
127
132
  return self.node_class(token, group_name, [arg.value for arg in args])
@@ -127,7 +127,8 @@ class LiquidTag(Tag):
127
127
  self._tokenize(
128
128
  token_.value,
129
129
  token=token_,
130
- )
130
+ ),
131
+ block_depth_carry=stream.block_depth,
131
132
  ),
132
133
  end=(),
133
134
  )
liquid/context.py CHANGED
@@ -175,7 +175,12 @@ class RenderContext:
175
175
  """
176
176
  it = iter(path)
177
177
  root = next(it)
178
- assert isinstance(root, str)
178
+
179
+ if not isinstance(root, str):
180
+ if default == UNDEFINED:
181
+ hint = f"{root} is undefined"
182
+ return self.env.undefined(str(root), hint=hint, token=token)
183
+ return default
179
184
 
180
185
  try:
181
186
  obj = self.scope[root]
@@ -316,7 +321,7 @@ class RenderContext:
316
321
  """Return the index of the next item in the cycle."""
317
322
  namespace: dict[object, int] = self.tag_namespace["cycles"]
318
323
  idx = namespace.setdefault(key, 0)
319
- namespace[key] = (idx + 1) % length
324
+ namespace[key] = (idx + 1) % (length or 1) # Just in case.
320
325
  return idx
321
326
 
322
327
  def ifchanged(self, val: str) -> bool:
liquid/environment.py CHANGED
@@ -18,6 +18,7 @@ from . import builtin
18
18
  from .analyze_tags import InnerTagMap
19
19
  from .analyze_tags import TagAnalysis
20
20
  from .builtin import DictLoader
21
+ from .exceptions import BlockNestingError
21
22
  from .exceptions import LiquidError
22
23
  from .exceptions import LiquidSyntaxError
23
24
  from .exceptions import TemplateInheritanceError
@@ -79,6 +80,10 @@ class Environment:
79
80
  template loaded from this environment.
80
81
  """
81
82
 
83
+ block_nesting_limit: ClassVar[int] = 30
84
+ """The maximum markup block nesting depth allowed before a `BlockNestingError`
85
+ exception is raised."""
86
+
82
87
  context_depth_limit: ClassVar[int] = 30
83
88
  """The maximum number of times a render context can be extended or wrapped before
84
89
  raising a `ContextDepthError`."""
@@ -275,7 +280,7 @@ class Environment:
275
280
  """
276
281
  try:
277
282
  nodes = self._parse(source)
278
- except (LiquidSyntaxError, TemplateInheritanceError) as err:
283
+ except (LiquidSyntaxError, TemplateInheritanceError, BlockNestingError) as err:
279
284
  err.template_name = path
280
285
  raise err
281
286
  except Exception as err: # noqa: BLE001
liquid/exceptions.py CHANGED
@@ -191,6 +191,10 @@ class ResourceLimitError(LiquidError):
191
191
  """Base class for exceptions relating to resource limits."""
192
192
 
193
193
 
194
+ class BlockNestingError(ResourceLimitError):
195
+ """The exception raised when block nesting limit is reached."""
196
+
197
+
194
198
  class ContextDepthError(ResourceLimitError):
195
199
  """Exception raised when the maximum context depth is reached.
196
200
 
@@ -35,16 +35,20 @@ class WithNode(Node):
35
35
  self.block = block
36
36
  self.blank = self.block.blank
37
37
 
38
- def render_to_output(self, context: RenderContext, buffer: TextIO) -> int:
39
- namespace = dict(arg.evaluate(context) for arg in self.args)
40
-
41
- with context.extend(namespace):
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}):
42
44
  return self.block.render(context, buffer)
43
45
 
44
46
  async def render_to_output_async(
45
- self, context: RenderContext, buffer: TextIO
47
+ self,
48
+ context: RenderContext,
49
+ buffer: TextIO,
46
50
  ) -> int:
47
- namespace = dict([await arg.evaluate_async(context) for arg in self.args])
51
+ namespace = {a.name: await a.value.evaluate_async(context) for a in self.args}
48
52
  with context.extend(namespace):
49
53
  return await self.block.render_async(context, buffer)
50
54
 
@@ -54,21 +58,16 @@ class WithNode(Node):
54
58
  *,
55
59
  include_partials: bool = True, # noqa: ARG002
56
60
  ) -> Iterable[Node]:
57
- """Return this node's children."""
58
61
  yield self.block
59
62
 
60
63
  def expressions(self) -> Iterable[Expression]:
61
- """Return this node's expressions."""
62
64
  yield from (arg.value for arg in self.args)
63
65
 
64
66
  def block_scope(self) -> Iterable[Identifier]:
65
- """Return variables this node adds to the node's block scope."""
66
67
  yield from (Identifier(p.name, token=p.token) for p in self.args)
67
68
 
68
69
 
69
70
  class WithTag(Tag):
70
- """The extra _with_ tag."""
71
-
72
71
  name = TAG_WITH
73
72
  end = TAG_ENDWITH
74
73
  node_class = WithNode
@@ -76,8 +75,6 @@ class WithTag(Tag):
76
75
  def parse(self, stream: TokenStream) -> Node:
77
76
  token = stream.eat(TOKEN_TAG)
78
77
  args = KeywordArgument.parse(self.env, stream.into_inner(tag=token))
79
-
80
- # Parse the block
81
78
  block = get_parser(self.env).parse_block(stream, (TAG_ENDWITH, TOKEN_EOF))
82
79
  stream.expect(TOKEN_TAG, value=TAG_ENDWITH)
83
80
  return self.node_class(token, args=args, block=block)
liquid/parser.py CHANGED
@@ -9,6 +9,7 @@ from typing import Iterator
9
9
 
10
10
  from .ast import BlockNode
11
11
  from .ast import Node
12
+ from .exceptions import BlockNestingError
12
13
  from .exceptions import LiquidError
13
14
  from .token import TOKEN_COMMENT
14
15
  from .token import TOKEN_CONTENT
@@ -69,6 +70,10 @@ class Parser:
69
70
  output = tags[TOKEN_OUTPUT]
70
71
 
71
72
  nodes: list[Node] = []
73
+ stream.block_depth += 1
74
+
75
+ if stream.block_depth > self.env.block_nesting_limit:
76
+ raise BlockNestingError("block nesting limit reached", token=None)
72
77
 
73
78
  while stream.current.kind != TOKEN_EOF:
74
79
  if stream.current.kind == TOKEN_TAG and stream.current.value in end:
@@ -92,6 +97,7 @@ class Parser:
92
97
 
93
98
  next(stream)
94
99
 
100
+ stream.block_depth -= 1
95
101
  return BlockNode(stream.current, nodes)
96
102
 
97
103
 
liquid/stream.py CHANGED
@@ -18,12 +18,10 @@ class TokenStream:
18
18
 
19
19
  eof = Token(TOKEN_EOF, TOKEN_EOF, -1, "")
20
20
 
21
- def __init__(
22
- self,
23
- tokens: Iterator[Token],
24
- ):
21
+ def __init__(self, tokens: Iterator[Token], block_depth_carry: int = 0):
25
22
  self.tokens = list(tokens)
26
23
  self.pos = 0
24
+ self.block_depth = block_depth_carry
27
25
 
28
26
  def __next__(self) -> Token:
29
27
  return self.next_token()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-liquid
3
- Version: 2.2.1
3
+ Version: 2.3.0
4
4
  Summary: A Python engine for the Liquid template language.
5
5
  Project-URL: Change Log, https://github.com/jg-rp/liquid/blob/main/CHANGES.md
6
6
  Project-URL: Documentation, https://jg-rp.github.io/liquid/
@@ -1,9 +1,9 @@
1
- liquid/__init__.py,sha256=YIN6_DEfW6bv9bhNED8Pnl0Ryt3_uCPt1dvMIuw_Yfk,7696
1
+ liquid/__init__.py,sha256=AAejVPvOWNpGawkdw3_4krnVAmu4SWjcJzbi0N5lhyw,7696
2
2
  liquid/analyze_tags.py,sha256=Uc1nueKLRiIejs2JyQIC7u2pxp9l-5HJAMWlg-Qj1m8,7615
3
3
  liquid/ast.py,sha256=4ZqSbuW4mv9IvoIMPk3OICUaOI1vPh8P8uFCrXI_3XA,8140
4
- liquid/context.py,sha256=gSJI1mj7mdcUfiQ09_XCEj5JxAosCGEX85Uuzl9apeI,21505
5
- liquid/environment.py,sha256=1X5WsOHcFvKAjljQcG3F-cQ9sfxzaiD-N3jGJOG5yHU,23940
6
- liquid/exceptions.py,sha256=FOc4KAOijF4WHrBGepvi0ycAYT5hu0rhdpsVb2C-ZHs,8336
4
+ liquid/context.py,sha256=fEuMsj9MVguX3Kzy9_k99TWekOwAToL0RtbGm9yZ71o,21718
5
+ liquid/environment.py,sha256=7lq5Y6jAaN6dzWMbqXYnUcSBuOke768xoPidP-WK2Y4,24157
6
+ liquid/exceptions.py,sha256=NNEWqVdY2QCjCvTtfqnV0_b1C0jL96IHOn6NlnabBXY,8451
7
7
  liquid/expression.py,sha256=Ozgajah2R5eg1yWA4ITFGaMFoOLt8GIjkE1NKqbBEzk,1143
8
8
  liquid/filter.py,sha256=3NtqGk6nHNwe6ux3X6ZIzzcEMJNA_SaMrBmMQA8hf-I,6735
9
9
  liquid/lex.py,sha256=PrnnUWhXZO6novkO0KE-p4virh5cNJsg7m85sg2IUiw,8004
@@ -12,11 +12,11 @@ liquid/loader.py,sha256=R_RniSRszCXmRVZgXlu9WjV130cWvspVcC3vIVpf-qg,4381
12
12
  liquid/messages.py,sha256=r6OcJG4-dLEULc9JtQ-mh3Jf6nNZ9Aa2reun7zYiUyc,11861
13
13
  liquid/mode.py,sha256=pgMF9oEl5nT5Q3Poi1gfWG9ozSXX5B6f4sfzOQX_Gow,206
14
14
  liquid/output.py,sha256=1rgPmXGWUTut-aBBbHs-TCCZ2UGUhmbJYRmCsnqIOCk,1000
15
- liquid/parser.py,sha256=F8aC__UiUzz39lxhPr3sl67l-V-mrxkdn-4MAaCTWRE,3824
15
+ liquid/parser.py,sha256=vh24F3c-fJj_IlbugoDHd3Smhkc_Ns8jpGk9otvlq7s,4072
16
16
  liquid/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  liquid/span.py,sha256=Z7Xb5V_h3WLvVmZUBebZeZkJFHKa33Bfcqq3S60SMSk,1122
18
18
  liquid/static_analysis.py,sha256=iPUqxiufXyK5EoPZQ9WNRKAzkqBYiX1HaSfX8oZhL9c,14537
19
- liquid/stream.py,sha256=jbIATQRY1azN5BX91FfnhL3mgBcYDJ3ZlEjI9kfmfaA,4889
19
+ liquid/stream.py,sha256=WAP9iPanapyY6ObQvw5ksa-5iLxNPjxRLYjkG6JmxpE,4939
20
20
  liquid/stringify.py,sha256=TkRO0KbZVCY3usNV6EXfG6CbtWhuLoI7joxcrEArSNE,892
21
21
  liquid/tag.py,sha256=h5jexl6NjUQnM2py4s5db1ksh0s8vi31YHud5kHJt1E,1189
22
22
  liquid/template.py,sha256=ne1abyNX8Tytl-d-vAROxtn-hHt_-O4nrn0eb2b_5fU,24062
@@ -33,9 +33,9 @@ liquid/builtin/expressions/_tokenize.py,sha256=p7RbeOg8iwXDnW0fIL4_7FSrBulkPYrCm
33
33
  liquid/builtin/expressions/arguments.py,sha256=hlZh7LLFT5UismTo7mTlVjM87_ihUJo0BYuCxyTwKMI,6448
34
34
  liquid/builtin/expressions/filtered.py,sha256=FqPNZLjwDdlCfivtBa7e0wuQYwcJdKUl3_UY9AS3zG4,13073
35
35
  liquid/builtin/expressions/logical.py,sha256=S8T9IgsuWgv0s7GYcGvIJFOqYMiMFRpat7zF3nCZHR0,20388
36
- liquid/builtin/expressions/loop.py,sha256=sRVq_KQjuEglBqSePIqtZu_7AVfMcK95PIgiBP8gniQ,8884
36
+ liquid/builtin/expressions/loop.py,sha256=ki3kMBuDyT21NZ_VrK19avsGbwBfz0VrrJo-mFox57Q,8594
37
37
  liquid/builtin/expressions/path.py,sha256=m1J33uIuEFlUaRXR_-G6qcsClOm0B5jbTZ0Pdt1P7Ak,5703
38
- liquid/builtin/expressions/primitive.py,sha256=Gzaeb-dF84zsMn5ZYhe-FOosnSbkkM2C6JLqjLvK5ns,11352
38
+ liquid/builtin/expressions/primitive.py,sha256=AlG828WqP3bZuwQTBJTx6RP2FvBra_aoEsq_J4uR4Tk,11684
39
39
  liquid/builtin/filters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
40
  liquid/builtin/filters/array.py,sha256=dMuT15EASXU4ejmNBmawdi92u0f7y_JhqVaGoP48zlg,9843
41
41
  liquid/builtin/filters/extra.py,sha256=m13_1nbZyRBl3CZV9WWGLlUZueRPt8cKPEHRAioqM_o,2710
@@ -46,7 +46,7 @@ liquid/builtin/loaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
46
46
  liquid/builtin/loaders/caching_file_system_loader.py,sha256=V4OLa6UGT-RELGiV4eu02TeLL4P_JIE2kMYMrO3qy8U,2158
47
47
  liquid/builtin/loaders/choice_loader.py,sha256=FE23RLMOiWmsRGZv9t6QmlG7bgMEUSblnucAv3j0SBM,2816
48
48
  liquid/builtin/loaders/dict_loader.py,sha256=8TdMJqaYPLwllmIiEmuZNXqH6UOOsi4HuJ2t5sztOOw,1785
49
- liquid/builtin/loaders/file_system_loader.py,sha256=6CzmJnktLE9n6y8YYEtUZFa4nDsZ6vsAWIDwCg6_vE0,4528
49
+ liquid/builtin/loaders/file_system_loader.py,sha256=kKPUmznPgNFq3fRDeoOTbWjNwxuLrYPAteZ_Do1-Mks,4924
50
50
  liquid/builtin/loaders/mixins.py,sha256=4Hj5wWGMOi3LqA9ZJYsUb4LFbG0a5DDb9H975G8nn58,5209
51
51
  liquid/builtin/loaders/package_loader.py,sha256=XP7LT3aMClgfBlI8OMyHOERlXTXEWmqFH7HskCnY3cs,3659
52
52
  liquid/builtin/tags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -54,7 +54,7 @@ liquid/builtin/tags/assign_tag.py,sha256=VTfkPbF-i0KLqMmaacBItFQHaBTP7ECWR-RvVh9
54
54
  liquid/builtin/tags/capture_tag.py,sha256=7bOG7qVwcqRx1eStb96AZKQ9tKLBjmzaYAe27LJTIm4,3037
55
55
  liquid/builtin/tags/case_tag.py,sha256=8ZN3pWP6axr-y7XAGIDjOkTDis0KSxpw7m1ITSElOVw,9040
56
56
  liquid/builtin/tags/comment_tag.py,sha256=BMvee7nVBim_iDScKWbcUBCxNXzbBvguYfQUG3GM1y8,2250
57
- liquid/builtin/tags/cycle_tag.py,sha256=tbgnEiwENXIfRAKRsVg18KRsZwaNLOLZeuLy-0Xm5c0,3789
57
+ liquid/builtin/tags/cycle_tag.py,sha256=Vl3DuDBkfpDKk2hxcLM99gFW1-OjWC2APHr23iGXkVE,3943
58
58
  liquid/builtin/tags/decrement_tag.py,sha256=WgkwWqjJgzjfEKffTKNw0ao6N0JxniadxGO_n1k8oZE,1660
59
59
  liquid/builtin/tags/doc_tag.py,sha256=luc2QI-4N7KF49vWak6dNm5Hs9jwlXTAfUlEsr6ZCNM,2055
60
60
  liquid/builtin/tags/echo_tag.py,sha256=VvYth9VuA-A9bsfGUOLlM4QxL_frsgWena3yBrrLKPI,1174
@@ -64,7 +64,7 @@ liquid/builtin/tags/ifchanged_tag.py,sha256=VpJNDhT7MFXcNmRrYiWcJ9whhaRXh81oe_ph
64
64
  liquid/builtin/tags/include_tag.py,sha256=eAnjcbJ2-e0382TkrV2WJ9dACFWi_UNUeKG-QRuiOig,9220
65
65
  liquid/builtin/tags/increment_tag.py,sha256=SV2nrbE90l4iz36WCROqGE0RkkzztWUpU1_Pyp2DDQo,1662
66
66
  liquid/builtin/tags/inline_comment_tag.py,sha256=hLLtvaI-VpJxzFeoLTwDTj46g13A1ke6blqVo2MP0Cs,1357
67
- liquid/builtin/tags/liquid_tag.py,sha256=vQh2T8_3uBfTTgp6PNqi_bOhbRNv45eoo9yoOXcNyz8,5465
67
+ liquid/builtin/tags/liquid_tag.py,sha256=o3ybbBmjIY94y_PpOUbgSwktENrGJ-jhZ124-rTlM4Q,5524
68
68
  liquid/builtin/tags/render_tag.py,sha256=iYWjKYQBmGHQVQ9OZgPZvVhraygFdmPzITin7cKJI5E,14309
69
69
  liquid/builtin/tags/tablerow_tag.py,sha256=qE5hIrlJXdKiLJ0u1YLgjnqt6GedWujfcfIO0b9x0d8,8947
70
70
  liquid/builtin/tags/unless_tag.py,sha256=udlHvVxILJsYfDaWRkj6Ynmnz2-2FF5RfkP0eizXt7k,6932
@@ -76,7 +76,7 @@ liquid/extra/filters/babel.py,sha256=K0kvw8r5Xy4NwvX4qv-lym14rZ25gB4fCnHqj-IVagI
76
76
  liquid/extra/filters/html.py,sha256=j6ghLorvxlVwAtyfVJlmB1tnroGJb8hD-uxUVALVSEQ,929
77
77
  liquid/extra/filters/translate.py,sha256=PDEgvmdOvg45ChAKLsaqtamOqaBWOFh4XzQC8igXIyE,13019
78
78
  liquid/extra/tags/__init__.py,sha256=iqB5oOPYhZey-dyljrgAjGeni4lK8Q9-rW2cGRHa4hw,383
79
- liquid/extra/tags/_with.py,sha256=QLlpY3oW8prCmutEXv1uUCMo_hloLd-sEbiMkMIbtXM,2627
79
+ liquid/extra/tags/_with.py,sha256=gZ3SjoQoSVFFsayMZQJimwwRpHK4c_tsuKU7wZvL0Hk,2432
80
80
  liquid/extra/tags/extends_tag.py,sha256=3PL1y1FHaeh6L4rA_Xz6wP6l5oHdiOY_u42ivS6c3xE,17893
81
81
  liquid/extra/tags/macro_tag.py,sha256=ErjPxOVB50KKn2qi7-2Icmrbx5Uldv2vUSj49TCs4bY,8749
82
82
  liquid/extra/tags/snippet_tag.py,sha256=8tFZWDvwhRId5IV0mNKhkFswJx3eTeAYs7-nAwiorNY,3155
@@ -90,7 +90,7 @@ liquid/utils/chain_map.py,sha256=nxkw3wwF6ddlGarIuL7Ii2elm4dU80LySgdQx1oift0,151
90
90
  liquid/utils/html.py,sha256=TmqOOpRMsy7fqZLj7X5ybd_XQnWW2YDAVDwTP1Gwf40,1706
91
91
  liquid/utils/lru_cache.py,sha256=p7bXOGaUwJpLsREI2lGSzK6lLna5W_k_zNXKWnPJdos,4022
92
92
  liquid/utils/text.py,sha256=1SwDECNMaqnnZ05je_AZZgxqzZd6U-mvq5jNU3W1-Qk,841
93
- python_liquid-2.2.1.dist-info/METADATA,sha256=ttOrZWxcSER0sxi5fw52WvjFIqb07SMBFMj18TLp2gk,6745
94
- python_liquid-2.2.1.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
95
- python_liquid-2.2.1.dist-info/licenses/LICENSE,sha256=yAFURzud5ERNHt1rZIPnTLJ92ep7q8y5yG9g5DUMR_E,1075
96
- python_liquid-2.2.1.dist-info/RECORD,,
93
+ python_liquid-2.3.0.dist-info/METADATA,sha256=OALhkJp1Zn90MKHRGuDDMzV9bOb1kbKN38q-2sqFMmY,6745
94
+ python_liquid-2.3.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
95
+ python_liquid-2.3.0.dist-info/licenses/LICENSE,sha256=yAFURzud5ERNHt1rZIPnTLJ92ep7q8y5yG9g5DUMR_E,1075
96
+ python_liquid-2.3.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.30.1
2
+ Generator: hatchling 1.29.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any