ssc_codegen 0.24.0__tar.gz → 0.25.1__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 (60) hide show
  1. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/PKG-INFO +2 -2
  2. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/README.md +1 -1
  3. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/pyproject.toml +1 -1
  4. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/jsondef.py +1 -1
  5. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/linting.py +23 -11
  6. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/module_handler.py +12 -7
  7. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/struct_parser.py +7 -1
  8. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/.gitignore +0 -0
  9. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/LICENSE +0 -0
  10. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/__init__.py +0 -0
  11. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/_logging.py +0 -0
  12. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/__init__.py +0 -0
  13. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/array.py +0 -0
  14. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/base.py +0 -0
  15. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/cast.py +0 -0
  16. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/control.py +0 -0
  17. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/extract.py +0 -0
  18. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/helpers.py +0 -0
  19. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/module.py +0 -0
  20. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/predicate_containers.py +0 -0
  21. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/predicate_ops.py +0 -0
  22. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/regex.py +0 -0
  23. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/selectors.py +0 -0
  24. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/string.py +0 -0
  25. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/struct.py +0 -0
  26. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/transform.py +0 -0
  27. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/typedef.py +0 -0
  28. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/types.py +0 -0
  29. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/base.py +0 -0
  30. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/helpers.py +0 -0
  31. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/js_pure.py +0 -0
  32. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/py_bs4.py +0 -0
  33. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/py_helpers.py +0 -0
  34. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/py_lxml.py +0 -0
  35. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/py_parsel.py +0 -0
  36. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/py_render.py +0 -0
  37. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/py_slax.py +0 -0
  38. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/request_spec.py +0 -0
  39. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/__init__.py +0 -0
  40. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/adapter.py +0 -0
  41. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/contexts.py +0 -0
  42. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/expressions.py +0 -0
  43. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/format.py +0 -0
  44. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/predicates.py +0 -0
  45. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/reader.py +0 -0
  46. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/type_checking.py +0 -0
  47. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/document_utils.py +0 -0
  48. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/exceptions.py +0 -0
  49. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/health.py +0 -0
  50. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/kdl/__init__.py +0 -0
  51. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/kdl/dict_reader.py +0 -0
  52. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/kdl/parser.py +0 -0
  53. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/kdl/reader.py +0 -0
  54. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/main.py +0 -0
  55. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/parsers/__init__.py +0 -0
  56. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/parsers/curl.py +0 -0
  57. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/parsers/http.py +0 -0
  58. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/pseudo_selectors.py +0 -0
  59. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/regex_utils.py +0 -0
  60. {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/selector_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ssc_codegen
3
- Version: 0.24.0
3
+ Version: 0.25.1
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
@@ -57,7 +57,7 @@ uv tool install ssc_codegen
57
57
  `books.kdl`:
58
58
 
59
59
  ```kdl
60
- struct Book type=list {
60
+ (list)struct Book {
61
61
  @split-doc { css-all ".product-card" }
62
62
 
63
63
  title { css ".title"; text }
@@ -25,7 +25,7 @@ uv tool install ssc_codegen
25
25
  `books.kdl`:
26
26
 
27
27
  ```kdl
28
- struct Book type=list {
28
+ (list)struct Book {
29
29
  @split-doc { css-all ".product-card" }
30
30
 
31
31
  title { css ".title"; text }
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ssc_codegen"
3
- version = "0.24.0"
3
+ version = "0.25.1"
4
4
  description = "Python-dsl code converter to html parser for web scraping "
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -34,7 +34,7 @@ class JsonDefField(Node):
34
34
  class JsonDef(Node):
35
35
  """
36
36
  JSON mapping definition.
37
- DSL: json Name { ... } / json Name array=#true { ... } / json Name path="a.b" { ... }
37
+ DSL: json Name { ... } / (array)json Name { ... } / json Name path="a.b" { ... }
38
38
  body: list[JsonDefField]
39
39
  """
40
40
 
@@ -680,7 +680,8 @@ def lint_struct_node(
680
680
  )
681
681
  return
682
682
 
683
- struct_type = lint.get_prop(node, "type") or "item"
683
+ raw = node.type_annotation
684
+ struct_type = raw[1:-1] if raw else (lint.get_prop(node, "type") or "item")
684
685
  if struct_type not in _VALID_STRUCT_TYPES:
685
686
  lint.error(
686
687
  node,
@@ -952,15 +953,6 @@ def lint_json_node(node: KdlNode, lint: LintContext, ctx: ParseContext) -> None:
952
953
  hint=f"rename or remove one of the 'json {name}' definitions",
953
954
  )
954
955
 
955
- array_prop = node.properties.get("array")
956
- if array_prop is not None and not isinstance(array_prop.value, bool):
957
- lint.error(
958
- node,
959
- message=f"'array' property must be boolean (#true/#false), got {array_prop.value!r}",
960
- code="E002",
961
- hint="example: json MySchema array=#true { ... }",
962
- )
963
-
964
956
  path_prop = node.properties.get("path")
965
957
  if path_prop is not None:
966
958
  path_val = str(path_prop.value)
@@ -975,9 +967,29 @@ def lint_json_node(node: KdlNode, lint: LintContext, ctx: ParseContext) -> None:
975
967
  # ── field-level checks ───────────────────────────────────────────────────
976
968
 
977
969
  seen_fields: set[str] = set()
978
- for field_node in lint.get_children_nodes(node):
970
+ _lint_json_children(lint.get_children_nodes(node), lint, ctx, seen_fields)
971
+
972
+
973
+ def _lint_json_children(
974
+ children: list[KdlNode],
975
+ lint: LintContext,
976
+ ctx: ParseContext,
977
+ seen_fields: set[str],
978
+ ) -> None:
979
+ """Lint json field children, expanding block define references."""
980
+ for field_node in children:
979
981
  field_name = lint.node_name(field_node)
980
982
  args = lint.get_args(field_node)
983
+
984
+ # Block define expansion
985
+ if not args and field_name in ctx.children_defines:
986
+ lint.push(field_name)
987
+ _lint_json_children(
988
+ ctx.children_defines[field_name], lint, ctx, seen_fields
989
+ )
990
+ lint.pop()
991
+ continue
992
+
981
993
  has_type = False
982
994
  has_skip = False
983
995
  for arg in args:
@@ -47,9 +47,16 @@ def handle_struct(
47
47
  node: KdlNode, module: Module, ctx: ParseContext, lint: LintContext
48
48
  ) -> Struct:
49
49
  lint_struct_node(node, module, ctx, lint)
50
- type_ = node.properties.get(
51
- "type", KdlArg(value="item", span=node.span, is_identifier=True)
52
- ).value
50
+ raw = node.type_annotation
51
+ type_ = (
52
+ raw[1:-1]
53
+ if raw
54
+ else str(
55
+ node.properties.get(
56
+ "type", KdlArg(value="item", span=node.span, is_identifier=True)
57
+ ).value
58
+ )
59
+ )
53
60
  keep_order = node.properties.get(
54
61
  "keep-order", KdlArg(value=False, span=node.span, is_identifier=False)
55
62
  ).value
@@ -83,9 +90,7 @@ def handle_json(
83
90
  node: KdlNode, module: Module, ctx: ParseContext, lint: LintContext
84
91
  ) -> JsonDef:
85
92
  name = str(node.args[0].value) if node.args else ""
86
- is_array = node.properties.get(
87
- "array", KdlArg(value=False, span=node.span, is_identifier=False)
88
- ).value
93
+ is_array = node.type_annotation == "(array)"
89
94
  path = str(
90
95
  node.properties.get(
91
96
  "path", KdlArg(value="", span=node.span, is_identifier=False)
@@ -93,7 +98,7 @@ def handle_json(
93
98
  )
94
99
  json_def = JsonDef(parent=module, name=name, is_array=is_array, path=path)
95
100
  lint_json_node(node, lint, ctx)
96
- parse_json_fields(node.children, json_def)
101
+ parse_json_fields(node.children, json_def, ctx)
97
102
  ctx.json_defs[json_def.name] = json_def
98
103
  if name:
99
104
  lint.json_kdl_nodes[name] = node
@@ -184,8 +184,14 @@ def parse_struct(
184
184
  lint.walk_context = prev_ctx
185
185
 
186
186
 
187
- def parse_json_fields(nodes: Sequence[KdlNode], parent: JsonDef) -> None:
187
+ def parse_json_fields(
188
+ nodes: Sequence[KdlNode], parent: JsonDef, ctx: ParseContext
189
+ ) -> None:
188
190
  for node in nodes:
191
+ # Block define expansion in json context
192
+ if not node.args and node.name in ctx.children_defines:
193
+ parse_json_fields(ctx.children_defines[node.name], parent, ctx)
194
+ continue
189
195
  name = node.name
190
196
  modifiers: list[str] = []
191
197
  type_ = ""
File without changes
File without changes