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,77 +0,0 @@
1
- """The built-in _comment_ tag."""
2
-
3
- from __future__ import annotations
4
-
5
- import sys
6
- from typing import TYPE_CHECKING
7
- from typing import Optional
8
- from typing import TextIO
9
-
10
- from liquid import ast
11
- from liquid.exceptions import LiquidSyntaxError
12
- from liquid.tag import Tag
13
- from liquid.token import TOKEN_EOF
14
- from liquid.token import TOKEN_TAG
15
- from liquid.token import Token
16
-
17
- if TYPE_CHECKING:
18
- from liquid.context import RenderContext
19
- from liquid.stream import TokenStream
20
-
21
-
22
- TAG_COMMENT = sys.intern("comment")
23
- TAG_ENDCOMMENT = sys.intern("endcomment")
24
-
25
- END_COMMENTBLOCK = frozenset((TAG_ENDCOMMENT,))
26
-
27
-
28
- class CommentNode(ast.Node):
29
- """The built-in _comment_ tag."""
30
-
31
- __slots__ = ("text",)
32
-
33
- def __init__(self, token: Token, text: Optional[str] = None):
34
- super().__init__(token)
35
- self.text = text
36
-
37
- def __str__(self) -> str:
38
- return f"{{% comment %}}{self.text}{{% endcomment %}}"
39
-
40
- def render_to_output(self, context: RenderContext, buffer: TextIO) -> int: # noqa: ARG002
41
- """Render the node to the output buffer."""
42
- return 0
43
-
44
-
45
- class CommentTag(Tag):
46
- """An implementation of the built-in _comment_ tag that retains comment text.
47
-
48
- Some Liquid markup might be stripped out by the lexer, so comment text is not
49
- guaranteed to be identical to that in the source document.
50
- """
51
-
52
- name = TAG_COMMENT
53
- end = TAG_ENDCOMMENT
54
- node_class = CommentNode
55
-
56
- def parse(self, stream: TokenStream) -> CommentNode:
57
- """Parse tokens from _stream_ into an AST node."""
58
- if stream.current.kind == "COMMENT":
59
- # A `{# #}` style comment
60
- return self.node_class(stream.current, text=stream.current.value)
61
-
62
- # A block `{% comment %}`
63
- token = stream.eat(TOKEN_TAG)
64
- text: list[str] = []
65
-
66
- while True:
67
- if stream.current.kind == TOKEN_EOF:
68
- raise LiquidSyntaxError("comment tag was never closed", token=token)
69
- if (
70
- stream.current.kind == TOKEN_TAG
71
- and stream.current.value == TAG_ENDCOMMENT
72
- ):
73
- break
74
- text.append(stream.current.value)
75
- next(stream)
76
-
77
- return self.node_class(token, text="".join(text))
@@ -1,132 +0,0 @@
1
- """The built-in _cycle_ 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 Optional
9
- from typing import TextIO
10
-
11
- from liquid.ast import Node
12
- from liquid.builtin.expressions import PositionalArgument
13
- from liquid.builtin.expressions import parse_primitive
14
- from liquid.exceptions import LiquidSyntaxError
15
- from liquid.stringify import to_liquid_string
16
- from liquid.tag import Tag
17
- from liquid.token import TOKEN_COLON
18
- from liquid.token import TOKEN_TAG
19
- from liquid.token import Token
20
- from liquid.undefined import is_undefined
21
-
22
- if TYPE_CHECKING:
23
- from liquid.context import RenderContext
24
- from liquid.expression import Expression
25
- from liquid.stream import TokenStream
26
-
27
-
28
- TAG_CYCLE = sys.intern("cycle")
29
-
30
-
31
- class CycleNode(Node):
32
- """The built-in _cycle_ tag."""
33
-
34
- __slots__ = ("group", "args")
35
-
36
- group_by_args: bool = False
37
- """If `True`, use cycle arguments as well as group name when building cycle
38
- context keys."""
39
-
40
- def __init__(
41
- self, token: Token, group: Optional[Expression], args: list[Expression]
42
- ):
43
- super().__init__(token)
44
- self.group = group
45
- self.args = args
46
- self.blank = False
47
-
48
- def __str__(self) -> str:
49
- name = f"{self.group.token.value}: " if self.group else ""
50
- items = ", ".join(str(i) for i in self.args)
51
- return f"{{% cycle {name}{items} %}}"
52
-
53
- def render_to_output(self, context: RenderContext, buffer: TextIO) -> int:
54
- """Render the node to the output buffer."""
55
- if self.group:
56
- _group = self.group.evaluate(context)
57
- group_name = "__UNDEFINED" if is_undefined(_group) else str(_group)
58
- else:
59
- group_name = ""
60
-
61
- args = [arg.evaluate(context) for arg in self.args]
62
-
63
- if self.group_by_args:
64
- key: object = (group_name, tuple(args))
65
- else:
66
- key = group_name if group_name else str(args)
67
-
68
- index = context.cycle(key, len(args))
69
-
70
- if index >= len(args):
71
- return 0
72
-
73
- return buffer.write(
74
- to_liquid_string(args[index], autoescape=context.autoescape)
75
- )
76
-
77
- async def render_to_output_async(
78
- self, context: RenderContext, buffer: TextIO
79
- ) -> int:
80
- """Render the node to the output buffer."""
81
- if self.group:
82
- _group = await self.group.evaluate_async(context)
83
- group_name = "__UNDEFINED" if is_undefined(_group) else str(_group)
84
- else:
85
- group_name = ""
86
-
87
- args = [await arg.evaluate_async(context) for arg in self.args]
88
-
89
- if self.group_by_args:
90
- key: object = (group_name, tuple(args))
91
- else:
92
- key = group_name if group_name else str(args)
93
-
94
- index = context.cycle(key, len(args))
95
-
96
- if index >= len(args):
97
- return 0
98
-
99
- return buffer.write(
100
- to_liquid_string(args[index], autoescape=context.autoescape)
101
- )
102
-
103
- def expressions(self) -> Iterable[Expression]:
104
- """Return this node's expressions."""
105
- if self.group:
106
- yield self.group
107
- yield from self.args
108
-
109
-
110
- class CycleTag(Tag):
111
- """The built-in _cycle_ tag."""
112
-
113
- name = TAG_CYCLE
114
- block = False
115
- node_class = CycleNode
116
-
117
- def parse(self, stream: TokenStream) -> CycleNode:
118
- """Parse tokens from _stream_ into an AST node."""
119
- token = stream.eat(TOKEN_TAG)
120
- tokens = stream.into_inner(tag=token, eat=False)
121
-
122
- group_name: Optional[Expression] = None
123
- if tokens.peek.kind == TOKEN_COLON:
124
- group_name = parse_primitive(self.env, tokens)
125
- tokens.eat(TOKEN_COLON)
126
-
127
- args = PositionalArgument.parse(self.env, tokens)
128
-
129
- if not args:
130
- raise LiquidSyntaxError("expected at least one argument", token=token)
131
-
132
- return self.node_class(token, group_name, [arg.value for arg in args])
@@ -1,59 +0,0 @@
1
- """The built-in _decrement_ 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 import ast
11
- from liquid.builtin.expressions import parse_identifier
12
- from liquid.tag import Tag
13
- from liquid.token import TOKEN_TAG
14
- from liquid.token import Token
15
-
16
- if TYPE_CHECKING:
17
- from liquid.builtin.expressions import Identifier
18
- from liquid.context import RenderContext
19
- from liquid.stream import TokenStream
20
-
21
- TAG_DECREMENT = sys.intern("decrement")
22
-
23
-
24
- class DecrementNode(ast.Node):
25
- """The built-in _decrement_ tag."""
26
-
27
- __slots__ = ("name",)
28
-
29
- def __init__(self, token: Token, name: Identifier):
30
- super().__init__(token)
31
- self.name = name
32
- self.blank = False
33
-
34
- def __str__(self) -> str:
35
- return f"{{% decrement {self.name} %}}"
36
-
37
- def render_to_output(self, context: RenderContext, buffer: TextIO) -> int:
38
- """Render the node to the output buffer."""
39
- return buffer.write(str(context.decrement(self.name)))
40
-
41
- def template_scope(self) -> Iterable[Identifier]:
42
- """Return variables this node adds to the template local scope."""
43
- yield self.name
44
-
45
-
46
- class DecrementTag(Tag):
47
- """The built-in _decrement_ tag."""
48
-
49
- name = TAG_DECREMENT
50
- block = False
51
- node_class = DecrementNode
52
-
53
- def parse(self, stream: TokenStream) -> DecrementNode:
54
- """Parse tokens from _stream_ into an AST node."""
55
- token = stream.eat(TOKEN_TAG)
56
- return self.node_class(
57
- token,
58
- name=parse_identifier(self.env, stream.into_inner(tag=token, eat=False)),
59
- )
@@ -1,68 +0,0 @@
1
- """The built-in _doc_ tag."""
2
-
3
- from __future__ import annotations
4
-
5
- from typing import TYPE_CHECKING
6
- from typing import Optional
7
- from typing import TextIO
8
-
9
- from liquid.ast import Node
10
- from liquid.exceptions import LiquidSyntaxError
11
- from liquid.tag import Tag
12
- from liquid.token import TOKEN_DOC
13
- from liquid.token import TOKEN_EOF
14
- from liquid.token import TOKEN_EXPRESSION
15
- from liquid.token import TOKEN_TAG
16
-
17
- if TYPE_CHECKING:
18
- from liquid import RenderContext
19
- from liquid import TokenStream
20
- from liquid.token import Token
21
-
22
-
23
- class DocNode(Node):
24
- """The built-in _doc_ tag."""
25
-
26
- def __init__(self, token: Token, text: Optional[str] = None):
27
- super().__init__(token)
28
- self.text = text
29
-
30
- def __str__(self) -> str:
31
- return f"{{% doc %}}{self.text}{{% enddoc %}}"
32
-
33
- def render_to_output(self, _: RenderContext, __: TextIO) -> int:
34
- """Render the node to the output buffer."""
35
- return 0
36
-
37
-
38
- class DocTag(Tag):
39
- """The built-in _doc_ tag."""
40
-
41
- block = True
42
- name = "doc"
43
- end = "enddoc"
44
- node_class = DocNode
45
-
46
- def parse(self, stream: TokenStream) -> DocNode:
47
- """Parse tokens from _stream_ into an AST node."""
48
- if stream.current.kind == TOKEN_DOC:
49
- return self.node_class(stream.current, text=stream.current.value)
50
-
51
- # This only happens if the doc tag is malformed
52
- token = stream.eat(TOKEN_TAG)
53
- text: list[str] = []
54
-
55
- if stream.current.kind == TOKEN_EXPRESSION:
56
- raise LiquidSyntaxError("unexpected expression", token=stream.current)
57
-
58
- while True:
59
- if stream.current.is_tag(self.name):
60
- raise LiquidSyntaxError("nested doc tags are not allowed", token=token)
61
- if stream.current.is_tag(self.end):
62
- break
63
- if stream.current.kind == TOKEN_EOF:
64
- raise LiquidSyntaxError("doc tag wad never closed", token=token)
65
- text.append(stream.current.value)
66
- next(stream)
67
-
68
- return self.node_class(token, text="".join(text))
@@ -1,45 +0,0 @@
1
- """The built-in _echo_ tag."""
2
-
3
- from __future__ import annotations
4
-
5
- import sys
6
- from typing import TYPE_CHECKING
7
-
8
- from liquid.builtin.expressions import FilteredExpression
9
- from liquid.builtin.expressions import Nil
10
- from liquid.builtin.output import OutputNode
11
- from liquid.tag import Tag
12
- from liquid.token import TOKEN_EOF
13
- from liquid.token import TOKEN_TAG
14
-
15
- if TYPE_CHECKING:
16
- from liquid.ast import Node
17
- from liquid.expression import Expression
18
- from liquid.stream import TokenStream
19
-
20
- TAG_ECHO = sys.intern("echo")
21
-
22
-
23
- class EchoNode(OutputNode):
24
- """The built-in _echo_ tag."""
25
-
26
- def __str__(self) -> str:
27
- return f"{{% echo {self.expression} %}}"
28
-
29
-
30
- class EchoTag(Tag):
31
- """The built-in _echo_ tag."""
32
-
33
- name = TAG_ECHO
34
- block = False
35
- node_class = EchoNode
36
-
37
- def parse(self, stream: TokenStream) -> Node: # noqa: D102
38
- token = stream.eat(TOKEN_TAG)
39
- if stream.current.kind == TOKEN_EOF:
40
- expr: Expression = Nil(stream.current)
41
- else:
42
- expr = FilteredExpression.parse(
43
- self.env, stream.into_inner(tag=token, eat=False)
44
- )
45
- return self.node_class(token, expr)