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.
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/PKG-INFO +2 -2
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/README.md +1 -1
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/pyproject.toml +1 -1
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/jsondef.py +1 -1
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/linting.py +23 -11
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/module_handler.py +12 -7
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/struct_parser.py +7 -1
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/.gitignore +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/LICENSE +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/__init__.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/_logging.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/__init__.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/array.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/base.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/cast.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/control.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/extract.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/helpers.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/module.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/predicate_containers.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/predicate_ops.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/regex.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/selectors.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/string.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/struct.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/transform.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/typedef.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/ast/types.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/base.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/helpers.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/js_pure.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/py_bs4.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/py_helpers.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/py_lxml.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/py_parsel.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/py_render.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/py_slax.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/converters/request_spec.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/__init__.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/adapter.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/contexts.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/expressions.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/format.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/predicates.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/reader.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/core/type_checking.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/document_utils.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/exceptions.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/health.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/kdl/__init__.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/kdl/dict_reader.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/kdl/parser.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/kdl/reader.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/main.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/parsers/__init__.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/parsers/curl.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/parsers/http.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/pseudo_selectors.py +0 -0
- {ssc_codegen-0.24.0 → ssc_codegen-0.25.1}/ssc_codegen/regex_utils.py +0 -0
- {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.
|
|
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
|
|
60
|
+
(list)struct Book {
|
|
61
61
|
@split-doc { css-all ".product-card" }
|
|
62
62
|
|
|
63
63
|
title { css ".title"; text }
|
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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.
|
|
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(
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|