ssc_codegen 0.36.2__tar.gz → 0.37.0__tar.gz

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 (88) hide show
  1. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/PKG-INFO +1 -1
  2. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/pyproject.toml +1 -1
  3. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/extract.py +4 -0
  4. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/core/expressions.py +20 -0
  5. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/core/linter.py +20 -1
  6. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/golang/visitor.py +29 -5
  7. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/javascript/visitor.py +3 -4
  8. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/html_libs/bs4.py +6 -0
  9. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/html_libs/lxml.py +16 -0
  10. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/html_libs/parsel.py +8 -0
  11. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/html_libs/slax.py +18 -0
  12. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/.gitignore +0 -0
  13. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/LICENSE +0 -0
  14. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/README.md +0 -0
  15. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/__init__.py +0 -0
  16. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/_logging.py +0 -0
  17. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/__init__.py +0 -0
  18. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/array.py +0 -0
  19. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/base.py +0 -0
  20. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/cast.py +0 -0
  21. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/control.py +0 -0
  22. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/function.py +0 -0
  23. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/helpers.py +0 -0
  24. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/jsondef.py +0 -0
  25. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/module.py +0 -0
  26. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/predicate_containers.py +0 -0
  27. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/predicate_ops.py +0 -0
  28. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/regex.py +0 -0
  29. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/rest.py +0 -0
  30. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/selectors.py +0 -0
  31. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/string.py +0 -0
  32. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/struct.py +0 -0
  33. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/typedef.py +0 -0
  34. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/ast/types.py +0 -0
  35. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/core/__init__.py +0 -0
  36. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/core/contexts.py +0 -0
  37. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/core/format.py +0 -0
  38. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/core/module_handler.py +0 -0
  39. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/core/predicates.py +0 -0
  40. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/core/reader.py +0 -0
  41. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/core/rest_artifacts.py +0 -0
  42. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/core/struct_parser.py +0 -0
  43. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/core/type_checking.py +0 -0
  44. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/exceptions.py +0 -0
  45. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/explore.py +0 -0
  46. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/generation/__init__.py +0 -0
  47. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/generation/builder.py +0 -0
  48. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/generation/runtime.py +0 -0
  49. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/health.py +0 -0
  50. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/main.py +0 -0
  51. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/naming.py +0 -0
  52. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/parsers/__init__.py +0 -0
  53. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/parsers/curl.py +0 -0
  54. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/parsers/http.py +0 -0
  55. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/regex_utils.py +0 -0
  56. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/request_spec.py +0 -0
  57. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/__init__.py +0 -0
  58. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/golang/__init__.py +0 -0
  59. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/golang/http_libs/__init__.py +0 -0
  60. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/golang/http_libs/base.py +0 -0
  61. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/golang/http_libs/nethttp.py +0 -0
  62. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/golang/literals.py +0 -0
  63. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/golang/regex.py +0 -0
  64. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/golang/rest.py +0 -0
  65. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/golang/runtime.py +0 -0
  66. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/javascript/__init__.py +0 -0
  67. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/javascript/http_libs/__init__.py +0 -0
  68. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/javascript/http_libs/axios.py +0 -0
  69. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/javascript/http_libs/base.py +0 -0
  70. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/javascript/http_libs/fetch.py +0 -0
  71. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/javascript/rest.py +0 -0
  72. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/profile.py +0 -0
  73. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/__init__.py +0 -0
  74. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/html_libs/__init__.py +0 -0
  75. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/html_libs/base.py +0 -0
  76. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/http_libs/__init__.py +0 -0
  77. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/http_libs/aiohttp.py +0 -0
  78. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/http_libs/base.py +0 -0
  79. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/http_libs/httpx.py +0 -0
  80. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/http_libs/requests.py +0 -0
  81. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/rest.py +0 -0
  82. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/python/visitor.py +0 -0
  83. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/resolver.py +0 -0
  84. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/targets/spec.py +0 -0
  85. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/traversal/__init__.py +0 -0
  86. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/traversal/context.py +0 -0
  87. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/traversal/utils.py +0 -0
  88. {ssc_codegen-0.36.2 → ssc_codegen-0.37.0}/ssc_codegen/traversal/walker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ssc_codegen
3
- Version: 0.36.2
3
+ Version: 0.37.0
4
4
  Summary: Python-dsl code converter to html parser for web scraping
5
5
  Project-URL: Documentation, https://github.com/vypivshiy/selector_schema_codegen#readme
6
6
  Project-URL: Issues, https://github.com/vypivshiy/selector_schema_codegen/issues
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ssc_codegen"
3
- version = "0.36.2"
3
+ version = "0.37.0"
4
4
  description = "Python-dsl code converter to html parser for web scraping "
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -27,8 +27,12 @@ class Raw(Node):
27
27
  Extracts raw HTML string from element(s).
28
28
  DOCUMENT → STRING, LIST_DOCUMENT → LIST_STRING.
29
29
  accept/ret set by builder from cursor type.
30
+
31
+ mode="outer" (default) — outer HTML (element tag included).
32
+ mode="inner" — inner HTML (children only).
30
33
  """
31
34
 
35
+ mode: str = "outer"
32
36
  accept_type_info: TypeInfo = field(
33
37
  default_factory=lambda: TypeInfo(base=VariableType.DOCUMENT)
34
38
  )
@@ -717,11 +717,31 @@ def _expr_raw(
717
717
  else:
718
718
  accept_ti = TypeInfo(base=VariableType.DOCUMENT)
719
719
  is_arr = False
720
+ mode = "outer"
721
+ if len(node.args) > 1:
722
+ lint.error(
723
+ node,
724
+ message="'raw' accepts at most 1 argument",
725
+ code="E001",
726
+ hint="example: raw or raw outer or raw inner",
727
+ )
728
+ elif node.args:
729
+ val = str(node.args[0].value)
730
+ if val not in ("outer", "inner"):
731
+ lint.error(
732
+ node,
733
+ message=f"invalid 'raw' mode {val!r} — expected 'outer' or 'inner'",
734
+ code="E001",
735
+ hint="example: raw or raw outer or raw inner",
736
+ )
737
+ else:
738
+ mode = val
720
739
  return Raw(
721
740
  parent=parent,
722
741
  accept_type_info=accept_ti,
723
742
  ret_type_info=TypeInfo(base=VariableType.STRING, is_array=is_arr),
724
743
  is_array=is_arr,
744
+ mode=mode,
725
745
  )
726
746
 
727
747
 
@@ -87,7 +87,6 @@ _DEFINE_NAME_RE = _re.compile(r"^[A-Z_][A-Z0-9_-]*\Z")
87
87
  _NO_ARGS_OPS: frozenset[str] = frozenset(
88
88
  {
89
89
  "text",
90
- "raw",
91
90
  "normalize-space",
92
91
  "lower",
93
92
  "upper",
@@ -1157,6 +1156,26 @@ def lint_pipeline_op(node: KdlNode, lint: LintContext) -> None:
1157
1156
  if name == "attr":
1158
1157
  lint_require_args(node, lint, min_count=1, example='attr "href"')
1159
1158
 
1159
+ elif name == "raw":
1160
+ args = _node_args(node)
1161
+ if len(args) > 1:
1162
+ lint.error(
1163
+ node,
1164
+ message="'raw' accepts at most 1 argument",
1165
+ code="E001",
1166
+ hint="example: raw or raw outer or raw inner",
1167
+ )
1168
+ elif args and args[0] not in ("outer", "inner"):
1169
+ lint.error(
1170
+ node,
1171
+ message=(
1172
+ f"invalid 'raw' mode {args[0]!r}"
1173
+ " — expected 'outer' or 'inner'"
1174
+ ),
1175
+ code="E001",
1176
+ hint="example: raw or raw outer or raw inner",
1177
+ )
1178
+
1160
1179
  elif name in _TRIM_OPS:
1161
1180
  args = _node_args(node)
1162
1181
  if len(args) > 1:
@@ -230,15 +230,17 @@ def _gofmt(source: str) -> str:
230
230
  if not gofmt:
231
231
  return source
232
232
  try:
233
+ # Pass UTF-8 explicitly — Windows text-mode defaults to the OEM
234
+ # codepage (cp1251/cp437), corrupting non-ASCII bytes in @doc
235
+ # comments and source strings.
233
236
  proc = subprocess.run(
234
237
  [gofmt],
235
- input=source,
238
+ input=source.encode("utf-8"),
236
239
  capture_output=True,
237
- text=True,
238
240
  timeout=10,
239
241
  )
240
242
  if proc.returncode == 0 and proc.stdout:
241
- return proc.stdout
243
+ return proc.stdout.decode("utf-8")
242
244
  except (subprocess.SubprocessError, OSError):
243
245
  pass
244
246
  return source
@@ -1156,14 +1158,28 @@ class GoVisitor(BaseWalker):
1156
1158
  ]
1157
1159
 
1158
1160
  def visit_raw(self, node: Raw, ctx: WalkContext) -> list[str]:
1161
+ # goquery: Html() method = inner HTML (jQuery semantics);
1162
+ # goquery.OuterHtml(sel) package func = outer HTML.
1163
+ if node.mode == "inner":
1164
+ if not node.is_array:
1165
+ return [
1166
+ f"{ctx.indent}_html, _ := {ctx.prv}.Html()",
1167
+ f"{ctx.indent}{ctx.nxt} := _html",
1168
+ ]
1169
+ return [
1170
+ f"{ctx.indent}{ctx.nxt} := {ctx.prv}.Map(func(_ int, s *goquery.Selection) string {{",
1171
+ f"{ctx.indent}\t_h, _ := s.Html()",
1172
+ f"{ctx.indent}\treturn _h",
1173
+ f"{ctx.indent}}})",
1174
+ ]
1159
1175
  if not node.is_array:
1160
1176
  return [
1161
- f"{ctx.indent}_html, _ := {ctx.prv}.Html()",
1177
+ f"{ctx.indent}_html, _ := goquery.OuterHtml({ctx.prv})",
1162
1178
  f"{ctx.indent}{ctx.nxt} := _html",
1163
1179
  ]
1164
1180
  return [
1165
1181
  f"{ctx.indent}{ctx.nxt} := {ctx.prv}.Map(func(_ int, s *goquery.Selection) string {{",
1166
- f"{ctx.indent}\t_h, _ := s.Html()",
1182
+ f"{ctx.indent}\t_h, _ := goquery.OuterHtml(s)",
1167
1183
  f"{ctx.indent}\treturn _h",
1168
1184
  f"{ctx.indent}}})",
1169
1185
  ]
@@ -1357,6 +1373,14 @@ class GoVisitor(BaseWalker):
1357
1373
  if at and at.base == VT.STRING and not at.is_array:
1358
1374
  idx = f"len({ctx.prv})-{abs(i)}" if i < 0 else str(i)
1359
1375
  return [f"{ctx.indent}{ctx.nxt} := string({ctx.prv}[{idx}])"]
1376
+ if at and at.base == VT.DOCUMENT:
1377
+ # *goquery.Selection is not indexable in Go — use .Eq().
1378
+ # Negative index → Length() + i (i is negative, e.g. -1 → last).
1379
+ if i < 0:
1380
+ idx = f"{ctx.prv}.Length() + {i}"
1381
+ else:
1382
+ idx = str(i)
1383
+ return [f"{ctx.indent}{ctx.nxt} := {ctx.prv}.Eq({idx})"]
1360
1384
  if i < 0:
1361
1385
  return [f"{ctx.indent}{ctx.nxt} := {ctx.prv}[len({ctx.prv})+{i}]"]
1362
1386
  return [f"{ctx.indent}{ctx.nxt} := {ctx.prv}[{i}]"]
@@ -827,11 +827,10 @@ class JsVisitor(BaseWalker):
827
827
  ]
828
828
 
829
829
  def visit_raw(self, node: Raw, ctx: WalkContext) -> list[str]:
830
+ prop = "innerHTML" if node.mode == "inner" else "outerHTML"
830
831
  if not node.is_array:
831
- return [f"{ctx.indent}let {ctx.nxt} = {ctx.prv}.outerHTML;"]
832
- return [
833
- f"{ctx.indent}let {ctx.nxt} = {ctx.prv}.map(el => el.outerHTML);"
834
- ]
832
+ return [f"{ctx.indent}let {ctx.nxt} = {ctx.prv}.{prop};"]
833
+ return [f"{ctx.indent}let {ctx.nxt} = {ctx.prv}.map(el => el.{prop});"]
835
834
 
836
835
  def visit_attr(self, node: Attr, ctx: WalkContext) -> list[str]:
837
836
  keys = node.keys
@@ -116,6 +116,12 @@ class Bs4DomSpelling(DomSpelling):
116
116
  return [f"{ctx.indent}{ctx.nxt} = {ctx.prv}.text"]
117
117
 
118
118
  def raw(self, ctx: ConverterContext, node: Raw) -> list[str]:
119
+ if node.mode == "inner":
120
+ if node.accept_type_info.is_array:
121
+ return [
122
+ f"{ctx.indent}{ctx.nxt} = [i.decode_contents() for i in {ctx.prv}]"
123
+ ]
124
+ return [f"{ctx.indent}{ctx.nxt} = {ctx.prv}.decode_contents()"]
119
125
  if node.accept_type_info.is_array:
120
126
  return [f"{ctx.indent}{ctx.nxt} = [str(i) for i in {ctx.prv}]"]
121
127
  return [f"{ctx.indent}{ctx.nxt} = str({ctx.prv})"]
@@ -165,6 +165,22 @@ class LxmlDomSpelling(DomSpelling):
165
165
  return [f"{ctx.indent}{ctx.nxt} = {ctx.prv}.text_content()"]
166
166
 
167
167
  def raw(self, ctx: ConverterContext, node: Raw) -> list[str]:
168
+ if node.mode == "inner":
169
+ self._builder.require_std(
170
+ "std_inner_html",
171
+ code="""
172
+ def std_inner_html(el):
173
+ parts = [el.text or ""]
174
+ for child in el.iterchildren():
175
+ parts.append(html.tostring(child, encoding="unicode"))
176
+ return "".join(parts)
177
+ """,
178
+ )
179
+ if node.accept_type_info.is_array:
180
+ return [
181
+ f"{ctx.indent}{ctx.nxt} = [std_inner_html(i) for i in {ctx.prv}]"
182
+ ]
183
+ return [f"{ctx.indent}{ctx.nxt} = std_inner_html({ctx.prv})"]
168
184
  if node.accept_type_info.is_array:
169
185
  return [
170
186
  f"{ctx.indent}{ctx.nxt} = [html.tostring(i, encoding='unicode') for i in {ctx.prv}]"
@@ -159,6 +159,14 @@ class ParselDomSpelling(DomSpelling):
159
159
  ]
160
160
 
161
161
  def raw(self, ctx: ConverterContext, node: Raw) -> list[str]:
162
+ if node.mode == "inner":
163
+ if node.accept_type_info.is_array:
164
+ return [
165
+ f"{ctx.indent}{ctx.nxt} = [''.join(i.xpath('node()').getall()) for i in {ctx.prv}]"
166
+ ]
167
+ return [
168
+ f"{ctx.indent}{ctx.nxt} = ''.join({ctx.prv}.xpath('node()').getall())"
169
+ ]
162
170
  if node.accept_type_info.is_array:
163
171
  return [f"{ctx.indent}{ctx.nxt} = {ctx.prv}.getall()"]
164
172
  return [f"{ctx.indent}{ctx.nxt} = {ctx.prv}.get()"]
@@ -119,6 +119,24 @@ class SlaxDomSpelling(DomSpelling):
119
119
  return [f"{ctx.indent}{ctx.nxt} = {ctx.prv}.text()"]
120
120
 
121
121
  def raw(self, ctx: ConverterContext, node: Raw) -> list[str]:
122
+ if node.mode == "inner":
123
+ self._builder.require_std(
124
+ "std_inner_html",
125
+ code="""
126
+ def std_inner_html(node):
127
+ parts = []
128
+ child = node.child
129
+ while child:
130
+ parts.append(child.html)
131
+ child = child.next
132
+ return "".join(parts)
133
+ """,
134
+ )
135
+ if node.accept_type_info.is_array:
136
+ return [
137
+ f"{ctx.indent}{ctx.nxt} = [std_inner_html(i) for i in {ctx.prv}]"
138
+ ]
139
+ return [f"{ctx.indent}{ctx.nxt} = std_inner_html({ctx.prv})"]
122
140
  if node.accept_type_info.is_array:
123
141
  return [f"{ctx.indent}{ctx.nxt} = [i.html for i in {ctx.prv}]"]
124
142
  return [f"{ctx.indent}{ctx.nxt} = {ctx.prv}.html"]
File without changes
File without changes
File without changes