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
liquid/drops/range.py ADDED
@@ -0,0 +1,76 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from .._nothing import NOTHING
6
+ from .._slice import slice_range
7
+ from ..exceptions import ResourceLimitError
8
+ from .iterable import IterableDrop
9
+
10
+ if TYPE_CHECKING:
11
+ from collections.abc import Iterator
12
+
13
+ from .._context import RenderContext
14
+ from .._drop import ContextHint
15
+
16
+
17
+ class Range:
18
+ __slots__ = ("start", "stop")
19
+
20
+ def __init__(self, start: int, stop: int) -> None:
21
+ self.start = start
22
+ self.stop = stop
23
+
24
+ def __liquid_getattr__(self, name: str, context: RenderContext) -> object:
25
+ match name:
26
+ case "first":
27
+ return self.start
28
+ case "last":
29
+ return self.stop
30
+ case "size":
31
+ return len(self)
32
+ case _:
33
+ raise KeyError
34
+
35
+ def __liquid_hasattr__(self, name: str, context: RenderContext) -> bool:
36
+ return name in ("first", "last", "size")
37
+
38
+ def __liquid_iter__(
39
+ self, offset: int, limit: int | None, reversed_: bool
40
+ ) -> IterableDrop[int]:
41
+ it = slice_range(range(self.start, self.stop), offset, limit, reversed_)
42
+ return IterableDrop(it, len(it))
43
+
44
+ def __eq__(self, other: object) -> bool:
45
+ return (
46
+ isinstance(other, Range)
47
+ and self.start == other.start
48
+ and self.stop == other.stop
49
+ )
50
+
51
+ def __len__(self) -> int:
52
+ return 0 if self.stop < self.start else self.stop - self.start + 1
53
+
54
+ def __bool__(self) -> bool:
55
+ return len(self) > 0
56
+
57
+ def __str__(self) -> str:
58
+ return f"{self.start}..{self.stop}"
59
+
60
+ def __liquid__(self, hint: ContextHint, context: RenderContext) -> object:
61
+ match hint:
62
+ case "output" | "string":
63
+ return str(self)
64
+ case "index" | "property" | "object":
65
+ return self
66
+ case "boolean":
67
+ return len(self) > 0
68
+ case "array":
69
+ if len(self) > 1_000_000: # XXX: arbitrary limit
70
+ raise ResourceLimitError("range limit reached")
71
+ return list(self.__liquid_iter__(0, None, False))
72
+ case _:
73
+ return NOTHING
74
+
75
+ def __iter__(self) -> Iterator[int]:
76
+ return iter(range(self.start, self.stop + 1))
liquid/drops/self_.py ADDED
@@ -0,0 +1,45 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from .._nothing import NOTHING
6
+
7
+ if TYPE_CHECKING:
8
+ from .._context import RenderContext
9
+ from .._drop import ContextHint
10
+
11
+
12
+ class Self:
13
+ __slots__ = ("context",)
14
+
15
+ def __init__(self, context: RenderContext) -> None:
16
+ super().__init__()
17
+ self.context = context
18
+
19
+ def __liquid_hasattr__(self, name: str, context: RenderContext) -> bool:
20
+ # Argument context is not necessarily the same as instance context.
21
+ return name in self.context.scope
22
+
23
+ def __liquid_getattr__(self, name: str, context: RenderContext) -> object:
24
+ # Argument context is not necessarily the same as instance context.
25
+ return self.context.resolve(name)
26
+
27
+ def __liquid__(self, hint: ContextHint, context: RenderContext) -> object:
28
+ match hint:
29
+ case "output" | "string":
30
+ return str(self)
31
+ case "object":
32
+ return self
33
+ case "array":
34
+ return [self]
35
+ case _:
36
+ return NOTHING
37
+
38
+ def __eq__(self, other: object) -> bool:
39
+ return isinstance(other, Self) and self.context is other.context
40
+
41
+ def __str__(self) -> str:
42
+ return "Liquid::SelfDrop"
43
+
44
+ def __contains__(self, item: object) -> bool:
45
+ return False
@@ -0,0 +1,142 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from .._nothing import NOTHING
6
+
7
+ if TYPE_CHECKING:
8
+ from .._context import RenderContext
9
+ from .._drop import ContextHint
10
+
11
+
12
+ class TableRowLoop:
13
+ """Table row helper variables."""
14
+
15
+ __slots__ = (
16
+ "col",
17
+ "cols",
18
+ "index",
19
+ "length",
20
+ "row",
21
+ )
22
+
23
+ def __init__(self, length: int, cols: int) -> None:
24
+ self.length = length
25
+ self.cols = cols
26
+
27
+ self.col = 1
28
+ self.index = 0
29
+ self.row = 1
30
+
31
+ def __liquid_hasattr__(self, name: str, context: RenderContext) -> bool:
32
+ return name in (
33
+ "length",
34
+ "index",
35
+ "index0",
36
+ "rindex",
37
+ "rindex0",
38
+ "first",
39
+ "last",
40
+ "col",
41
+ "col0",
42
+ "col_first",
43
+ "col_last",
44
+ "row",
45
+ )
46
+
47
+ def __liquid_getattr__(self, name: str, context: RenderContext) -> object:
48
+ if name == "first":
49
+ return self.index == 0
50
+
51
+ if name == "index":
52
+ return self.index + 1
53
+
54
+ if name == "index0":
55
+ return self.index
56
+
57
+ if name == "last":
58
+ return self.index == self.length - 1
59
+
60
+ if name == "length":
61
+ return self.length
62
+
63
+ if name == "rindex":
64
+ return self.length - self.index
65
+
66
+ if name == "rindex0":
67
+ return self.length - self.index - 1
68
+
69
+ if name == "col":
70
+ return self.col
71
+
72
+ if name == "col_first":
73
+ return self.col == 1
74
+
75
+ if name == "col_last":
76
+ return self.col == self.cols
77
+
78
+ if name == "col0":
79
+ return self.col - 1
80
+
81
+ if name == "row":
82
+ return self.row
83
+
84
+ raise AttributeError
85
+
86
+ def __getitem__(self, key: str) -> int:
87
+ if key == "first":
88
+ return self.index == 0
89
+
90
+ if key == "index":
91
+ return self.index + 1
92
+
93
+ if key == "index0":
94
+ return self.index
95
+
96
+ if key == "last":
97
+ return self.index == self.length - 1
98
+
99
+ if key == "length":
100
+ return self.length
101
+
102
+ if key == "rindex":
103
+ return self.length - self.index
104
+
105
+ if key == "rindex0":
106
+ return self.length - self.index - 1
107
+
108
+ if key == "col":
109
+ return self.col
110
+
111
+ if key == "col_first":
112
+ return self.col == 1
113
+
114
+ if key == "col_last":
115
+ return self.col == self.cols
116
+
117
+ if key == "col0":
118
+ return self.col - 1
119
+
120
+ if key == "row":
121
+ return self.row
122
+
123
+ raise KeyError(key)
124
+
125
+ def __liquid__(self, hint: ContextHint, context: RenderContext) -> object:
126
+ match hint:
127
+ case "output" | "string" | "object":
128
+ return str(self)
129
+ case _:
130
+ return NOTHING
131
+
132
+ def __bool__(self) -> bool:
133
+ return True
134
+
135
+ def step(self) -> None:
136
+ self.index += 1
137
+
138
+ if self.col == self.cols:
139
+ self.col = 1
140
+ self.row += 1
141
+ else:
142
+ self.col += 1
@@ -0,0 +1,228 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Never
4
+
5
+ from .._nothing import Nothing
6
+ from ..exceptions import UndefinedVariableError
7
+ from .iterable import IterableDrop
8
+
9
+ if TYPE_CHECKING:
10
+ from collections.abc import Iterable, Iterator
11
+
12
+ from .._context import RenderContext
13
+ from .._drop import ContextHint
14
+ from ..tokens import Token
15
+
16
+
17
+ class Blank:
18
+ def __liquid__(self, hint: ContextHint, context: RenderContext) -> object:
19
+ match hint:
20
+ case "output" | "string":
21
+ return ""
22
+ case "numeric":
23
+ return 0
24
+ case _:
25
+ return self
26
+
27
+ def __eq__(self, other: object) -> bool:
28
+ if isinstance(other, (Blank, Empty)):
29
+ return False
30
+
31
+ if other is None or other is False or isinstance(other, Undefined):
32
+ return True
33
+
34
+ if isinstance(other, str):
35
+ return not other or other.isspace()
36
+
37
+ if isinstance(other, (list, tuple, dict)):
38
+ return not other
39
+
40
+ return False
41
+
42
+ def __lt__(self, other: object) -> bool:
43
+ return False
44
+
45
+ def __str__(self) -> str:
46
+ return ""
47
+
48
+ def __bool__(self) -> bool:
49
+ return True
50
+
51
+
52
+ BLANK = Blank()
53
+
54
+
55
+ class Empty:
56
+ def __liquid__(self, hint: ContextHint, context: RenderContext) -> object:
57
+ match hint:
58
+ case "output" | "string":
59
+ return ""
60
+ case "numeric":
61
+ return 0
62
+ case _:
63
+ return self
64
+
65
+ def __eq__(self, other: object) -> bool:
66
+ if isinstance(other, Empty):
67
+ return True
68
+
69
+ if other is None or isinstance(other, Blank):
70
+ return False
71
+
72
+ if isinstance(other, (list, tuple, dict, str)):
73
+ return not other
74
+
75
+ return False
76
+
77
+ def __lt__(self, other: object) -> bool:
78
+ return False
79
+
80
+ def __str__(self) -> str:
81
+ return ""
82
+
83
+ def __bool__(self) -> bool:
84
+ return True
85
+
86
+
87
+ EMPTY = Empty()
88
+
89
+
90
+ class Undefined:
91
+ __slots__ = ("path", "source", "template_name", "token")
92
+
93
+ def __init__(
94
+ self, path: str, token: Token, source: str, template_name: str
95
+ ) -> None:
96
+ self.path = path
97
+ self.token = token
98
+ self.source = source
99
+ self.template_name = template_name
100
+
101
+ def poke(self) -> None:
102
+ pass
103
+
104
+ def __liquid_getattr__(self, name: str, context: RenderContext) -> object:
105
+ if name in ("first", "last", "size"):
106
+ return self
107
+ raise AttributeError
108
+
109
+ def __liquid_hasattr__(self, name: str, context: RenderContext) -> bool:
110
+ return name in ("first", "last", "size")
111
+
112
+ def __liquid__(self, hint: ContextHint, context: RenderContext) -> object:
113
+ match hint:
114
+ case "output" | "string":
115
+ return ""
116
+ case "index" | "property" | "object":
117
+ return None
118
+ case "numeric":
119
+ return 0
120
+ case "boolean":
121
+ return False
122
+ case "array":
123
+ return []
124
+
125
+ def __str__(self) -> str:
126
+ return ""
127
+
128
+ def __bool__(self) -> bool:
129
+ return False
130
+
131
+ def __len__(self) -> int:
132
+ return 3
133
+
134
+ def __liquid_iter__(
135
+ self, start: int, end: int | None, reversed_: bool
136
+ ) -> IterableDrop[object]:
137
+ return IterableDrop[object]([], 0)
138
+
139
+ def __eq__(self, other: object) -> bool:
140
+ return other is None or isinstance(other, (Undefined, Nothing, Blank))
141
+
142
+ def __repr__(self) -> str:
143
+ return f"{type(self).__name__}({self.path})"
144
+
145
+
146
+ class StrictUndefined(Undefined):
147
+ def _error(self) -> Never:
148
+ raise UndefinedVariableError(
149
+ f"{self.path} is undefined",
150
+ token=self.token,
151
+ source=self.source,
152
+ name=self.template_name,
153
+ )
154
+
155
+ def __iter__(self) -> Iterator[str]:
156
+ self._error()
157
+
158
+ def __liquid_getattr__(self, name: str, context: RenderContext) -> object:
159
+ self._error()
160
+
161
+ def __liquid_hasattr__(self, name: str, context: RenderContext) -> bool:
162
+ self._error()
163
+
164
+ def __liquid__(self, hint: ContextHint, context: RenderContext) -> object:
165
+ self._error()
166
+
167
+ def __liquid_iter__(
168
+ self, start: int, end: int | None, reversed_: bool
169
+ ) -> IterableDrop[object]:
170
+ self._error()
171
+
172
+ def __len__(self) -> int: # noqa: PLE0303
173
+ self._error()
174
+
175
+ def __getitem__(self, key: object) -> object:
176
+ self._error()
177
+
178
+ def __eq__(self, other: object) -> bool:
179
+ self._error()
180
+
181
+ def __lt__(self, other: object) -> bool:
182
+ self._error()
183
+
184
+ def __le__(self, other: object) -> bool:
185
+ self._error()
186
+
187
+ def __gt__(self, other: object) -> bool:
188
+ self._error()
189
+
190
+ def __ge__(self, other: object) -> bool:
191
+ self._error()
192
+
193
+ def __contains__(self, item: object) -> bool:
194
+ self._error()
195
+
196
+ def __str__(self) -> str: # noqa: PLE0307
197
+ self._error()
198
+
199
+ def __bool__(self) -> bool: # noqa: PLE0304
200
+ self._error()
201
+
202
+ def __int__(self) -> int:
203
+ self._error()
204
+
205
+ def __hash__(self) -> int: # noqa: PLE0309
206
+ self._error()
207
+
208
+ def __reversed__(self) -> Iterable[object]:
209
+ self._error()
210
+
211
+ def poke(self) -> None:
212
+ self._error()
213
+
214
+
215
+ class FalsyStrictUndefined(StrictUndefined):
216
+ def __liquid__(self, hint: ContextHint, context: RenderContext) -> object:
217
+ if hint == "boolean":
218
+ return False
219
+ self._error()
220
+
221
+ def __liquid_hasattr__(self, name: str, context: RenderContext) -> bool:
222
+ return name in ("first", "last", "size")
223
+
224
+ def __eq__(self, other: object) -> bool:
225
+ return other is None or isinstance(other, (Undefined, Nothing, Blank))
226
+
227
+ def __bool__(self) -> bool:
228
+ return False