ssc_codegen 0.8.0__tar.gz → 0.8.2__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.
Potentially problematic release.
This version of ssc_codegen might be problematic. Click here for more details.
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/PKG-INFO +1 -1
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/pyproject.toml +1 -1
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/__init__.py +1 -1
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/ast_build/main.py +23 -6
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/cli/code_callbacks.py +2 -2
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/converters/py_base.py +14 -11
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/converters/py_parsel.py +5 -7
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/schema.py +2 -3
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/str_utils.py +12 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/.gitignore +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/LICENSE +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/README.md +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/_compat.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/ast_/__init__.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/ast_/base.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/ast_/nodes_array.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/ast_/nodes_cast.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/ast_/nodes_core.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/ast_/nodes_selectors.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/ast_/nodes_string.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/ast_/nodes_validate.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/ast_build/__init__.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/ast_build/utils.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/cli/__init__.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/cli/cli_callbacks.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/cli/cli_utils.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/cli/consts.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/cli/main.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/cli/runtime_parse_runners.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/compiler.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/consts.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/converters/__init__.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/converters/base.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/converters/go_goquery.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/converters/helpers.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/converters/js_pure.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/converters/py_bs4.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/converters/py_selectolax.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/converters/templates/__init__.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/converters/templates/go_goquery.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/converters/templates/js_pure.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/document.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/document_utlis.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/json_struct.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/json_to_scc.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/logs.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/selector_utils.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/static_checker/__init__.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/static_checker/base.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/static_checker/callbacks.py +0 -0
- {ssc_codegen-0.8.0 → ssc_codegen-0.8.2}/ssc_codegen/tokens.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ssc_codegen
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.2
|
|
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
|
|
@@ -236,9 +236,18 @@ def _fetch_field_nodes(
|
|
|
236
236
|
parent=st_ref,
|
|
237
237
|
ret_type=ret_type,
|
|
238
238
|
)
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
239
|
+
# TODO: add ast tests
|
|
240
|
+
# in inheritance schemas, child classes use same fields are used as in the parent class
|
|
241
|
+
# avoid duplicate ExprReturn node
|
|
242
|
+
# second case used in ExprDefaultValueWrapper cases
|
|
243
|
+
if (
|
|
244
|
+
document.stack[-1].kind != ExprReturn.kind
|
|
245
|
+
and document.stack[-1].kind != TokenType.EXPR_DEFAULT_END
|
|
246
|
+
):
|
|
247
|
+
document.stack.append(
|
|
248
|
+
ExprReturn(accept_type=ret_type, ret_type=ret_type)
|
|
249
|
+
)
|
|
250
|
+
|
|
242
251
|
_unwrap_default_node(document, ret_type)
|
|
243
252
|
for i in document.stack:
|
|
244
253
|
i.parent = method
|
|
@@ -255,7 +264,6 @@ def _fetch_field_nodes(
|
|
|
255
264
|
cls_name = None
|
|
256
265
|
body_parse_method_expr.append(
|
|
257
266
|
ExprCallStructMethod(
|
|
258
|
-
# parent=method,
|
|
259
267
|
kwargs={
|
|
260
268
|
"name": field_name,
|
|
261
269
|
"type": ret_type,
|
|
@@ -298,9 +306,18 @@ def _try_fetch_split_doc_node(
|
|
|
298
306
|
) -> None:
|
|
299
307
|
if fields.get("__SPLIT_DOC__"):
|
|
300
308
|
split_doc = fields.pop("__SPLIT_DOC__")
|
|
301
|
-
# always sequence of elements
|
|
302
309
|
method = StructPartDocMethod(parent=st_ref)
|
|
303
|
-
|
|
310
|
+
|
|
311
|
+
# in inheritance schemas, child classes use same fields are used as in the parent class
|
|
312
|
+
# second case used in ExprDefaultValueWrapper cases
|
|
313
|
+
if (
|
|
314
|
+
split_doc.stack[-1].kind != ExprReturn.kind
|
|
315
|
+
and split_doc.stack[-1].kind != TokenType.EXPR_DEFAULT_END
|
|
316
|
+
):
|
|
317
|
+
# always returns sequence of elements
|
|
318
|
+
split_doc.stack.append(
|
|
319
|
+
ExprReturn(ret_type=VariableType.LIST_DOCUMENT)
|
|
320
|
+
)
|
|
304
321
|
for i in split_doc.stack:
|
|
305
322
|
i.parent = method
|
|
306
323
|
method.body = split_doc.stack
|
|
@@ -4,8 +4,8 @@ from typing import Callable
|
|
|
4
4
|
from ssc_codegen.str_utils import (
|
|
5
5
|
go_unimport_naive,
|
|
6
6
|
py_optimize_return_naive,
|
|
7
|
-
py_str_format_to_fstring,
|
|
8
7
|
js_pure_optimize_return,
|
|
8
|
+
py_remove_unused_none_type_import,
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
|
|
@@ -31,7 +31,7 @@ class BaseCodeCallback:
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
CB_PY_CODE = BaseCodeCallback(
|
|
34
|
-
py_optimize_return_naive,
|
|
34
|
+
py_optimize_return_naive, py_remove_unused_none_type_import
|
|
35
35
|
)
|
|
36
36
|
CB_GO_CODE = BaseCodeCallback(go_unimport_naive, remove_empty_lines=True)
|
|
37
37
|
CB_DART_CODE = BaseCodeCallback(remove_empty_lines=True)
|
|
@@ -150,7 +150,6 @@ MAGIC_METHODS = {
|
|
|
150
150
|
|
|
151
151
|
# used old style typing for support old python versions (3.8)
|
|
152
152
|
IMPORTS_MIN = """
|
|
153
|
-
from __future__ import annotations
|
|
154
153
|
import re
|
|
155
154
|
import sys
|
|
156
155
|
import json
|
|
@@ -281,7 +280,7 @@ def get_field_method_ret_type(node: StructFieldMethod) -> str:
|
|
|
281
280
|
def pre_docstring(node: Docstring) -> str:
|
|
282
281
|
value, *_ = node.unpack_args()
|
|
283
282
|
if value:
|
|
284
|
-
return '"""' + value + '"""
|
|
283
|
+
return '"""' + value + '"""'
|
|
285
284
|
return ""
|
|
286
285
|
|
|
287
286
|
|
|
@@ -368,7 +367,8 @@ def pre_struct_parser(node: StructParser) -> str:
|
|
|
368
367
|
|
|
369
368
|
|
|
370
369
|
def pre_ret(node: ExprReturn) -> str:
|
|
371
|
-
|
|
370
|
+
prv, _ = prev_next_var(node)
|
|
371
|
+
expr = f"return {prv}"
|
|
372
372
|
if have_default_expr(node):
|
|
373
373
|
return INDENT_DEFAULT_BODY + expr
|
|
374
374
|
return INDENT_METHOD_BODY + expr
|
|
@@ -670,13 +670,12 @@ def pre_str_regex(node: ExprStringRegex) -> str:
|
|
|
670
670
|
)
|
|
671
671
|
prv, nxt = prev_next_var(node)
|
|
672
672
|
pattern, group, ignore_case = node.unpack_args()
|
|
673
|
-
pattern = repr(pattern)
|
|
674
673
|
if ignore_case:
|
|
675
674
|
return (
|
|
676
675
|
indent
|
|
677
|
-
+ f"{nxt} = re.search({pattern}, {prv}, re.IGNORECASE)[{group}]"
|
|
676
|
+
+ f"{nxt} = re.search(r{pattern!r}, {prv}, re.IGNORECASE)[{group}]"
|
|
678
677
|
)
|
|
679
|
-
return indent + f"{nxt} = re.search({pattern}, {prv})[{group}]"
|
|
678
|
+
return indent + f"{nxt} = re.search(r{pattern!r}, {prv})[{group}]"
|
|
680
679
|
|
|
681
680
|
|
|
682
681
|
def pre_str_regex_all(node: ExprStringRegexAll) -> str:
|
|
@@ -686,8 +685,10 @@ def pre_str_regex_all(node: ExprStringRegexAll) -> str:
|
|
|
686
685
|
prv, nxt = prev_next_var(node)
|
|
687
686
|
pattern, ignore_case = node.unpack_args()
|
|
688
687
|
if ignore_case:
|
|
689
|
-
return
|
|
690
|
-
|
|
688
|
+
return (
|
|
689
|
+
indent + f"{nxt} = re.findall(r{pattern!r}, {prv}, re.IGNORECASE)"
|
|
690
|
+
)
|
|
691
|
+
return indent + f"{nxt} = re.findall(r{pattern!r}, {prv})"
|
|
691
692
|
|
|
692
693
|
|
|
693
694
|
def pre_str_regex_sub(node: ExprStringRegexSub) -> str:
|
|
@@ -696,7 +697,7 @@ def pre_str_regex_sub(node: ExprStringRegexSub) -> str:
|
|
|
696
697
|
)
|
|
697
698
|
prv, nxt = prev_next_var(node)
|
|
698
699
|
pattern, repl = node.unpack_args()
|
|
699
|
-
return indent + f"{nxt} = re.sub({pattern!r}, {repl!r}, {prv})"
|
|
700
|
+
return indent + f"{nxt} = re.sub(r{pattern!r}, {repl!r}, {prv})"
|
|
700
701
|
|
|
701
702
|
|
|
702
703
|
def pre_list_str_regex_sub(node: ExprListStringRegexSub) -> str:
|
|
@@ -705,7 +706,9 @@ def pre_list_str_regex_sub(node: ExprListStringRegexSub) -> str:
|
|
|
705
706
|
)
|
|
706
707
|
prv, nxt = prev_next_var(node)
|
|
707
708
|
pattern, repl = node.unpack_args()
|
|
708
|
-
return
|
|
709
|
+
return (
|
|
710
|
+
indent + f"{nxt} = [re.sub(r{pattern!r}, {repl!r}, i) for i in {prv}]"
|
|
711
|
+
)
|
|
709
712
|
|
|
710
713
|
|
|
711
714
|
def pre_index(node: ExprIndex) -> str:
|
|
@@ -777,7 +780,7 @@ def pre_is_regex(node: ExprIsRegex) -> str:
|
|
|
777
780
|
)
|
|
778
781
|
prv, nxt = prev_next_var(node)
|
|
779
782
|
pattern, ignore_case, msg = node.unpack_args()
|
|
780
|
-
expr = indent + f"assert re.search({pattern!r}, {prv}), {msg!r}"
|
|
783
|
+
expr = indent + f"assert re.search(r{pattern!r}, {prv}), {msg!r}"
|
|
781
784
|
if is_last_var_no_ret(node):
|
|
782
785
|
return expr
|
|
783
786
|
# HACK: avoid recalc variables
|
|
@@ -38,7 +38,7 @@ CONVERTER = BasePyCodeConverter()
|
|
|
38
38
|
def pre_init(_node: StructInitMethod) -> str:
|
|
39
39
|
return (
|
|
40
40
|
INDENT_METHOD
|
|
41
|
-
+ "def __init__(self, document: Union[str,
|
|
41
|
+
+ "def __init__(self, document: Union[str, Selector, SelectorList]) -> None:\n"
|
|
42
42
|
+ INDENT_METHOD_BODY
|
|
43
43
|
+ "self._document = Selector(document) if isinstance(document, str) else document"
|
|
44
44
|
)
|
|
@@ -48,7 +48,7 @@ def pre_init(_node: StructInitMethod) -> str:
|
|
|
48
48
|
def pre_struct_pre_validate(_node: StructPreValidateMethod) -> str:
|
|
49
49
|
return (
|
|
50
50
|
INDENT_METHOD
|
|
51
|
-
+ "def _pre_validate(self, v: Union[Selector,
|
|
51
|
+
+ "def _pre_validate(self, v: Union[Selector, SelectorList]) -> None:"
|
|
52
52
|
)
|
|
53
53
|
|
|
54
54
|
|
|
@@ -56,7 +56,7 @@ def pre_struct_pre_validate(_node: StructPreValidateMethod) -> str:
|
|
|
56
56
|
def pre_struct_part_doc_method(_node: StructPartDocMethod) -> str:
|
|
57
57
|
return (
|
|
58
58
|
INDENT_METHOD
|
|
59
|
-
+ "def _split_doc(self, v: Union[Selector,
|
|
59
|
+
+ "def _split_doc(self, v: Union[Selector, SelectorList]) -> SelectorList:"
|
|
60
60
|
)
|
|
61
61
|
|
|
62
62
|
|
|
@@ -67,15 +67,13 @@ def pre_struct_field_method(node: StructFieldMethod) -> str:
|
|
|
67
67
|
name = MAGIC_METHODS.get(name, name)
|
|
68
68
|
return (
|
|
69
69
|
INDENT_METHOD
|
|
70
|
-
+ f"def _parse_{name}(self, v: Union[Selector,
|
|
70
|
+
+ f"def _parse_{name}(self, v: Union[Selector, SelectorList]) -> {type_}:"
|
|
71
71
|
)
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
@CONVERTER.post(ModuleImports.kind)
|
|
75
75
|
def post_imports(_: ModuleImports) -> str:
|
|
76
|
-
return """from parsel import Selector, SelectorList
|
|
77
|
-
from parsel.selector import _SelectorType # noqa
|
|
78
|
-
"""
|
|
76
|
+
return """from parsel import Selector, SelectorList"""
|
|
79
77
|
|
|
80
78
|
|
|
81
79
|
@CONVERTER(ExprCss.kind)
|
|
@@ -86,9 +86,8 @@ class BaseSchema:
|
|
|
86
86
|
].kwargs["schema_name"]
|
|
87
87
|
signature[key] = cls.__NESTED_SCHEMAS__[name].__class_signature__()
|
|
88
88
|
elif field.stack_last_ret == VariableType.JSON:
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
]
|
|
89
|
+
name = [e for e in field.stack if e.kind == TokenType.TO_JSON][0].kwargs["json_struct_name"]
|
|
90
|
+
json_cls = cls.__JSON_SCHEMAS__[name]
|
|
92
91
|
signature[key] = json_struct_to_signature(json_cls)
|
|
93
92
|
else:
|
|
94
93
|
signature[key] = SIGNATURE_MAP[field.stack_last_ret]
|
|
@@ -16,6 +16,7 @@ __all__ = [
|
|
|
16
16
|
"py_str_format_to_fstring",
|
|
17
17
|
"py_optimize_return_naive",
|
|
18
18
|
"js_pure_optimize_return",
|
|
19
|
+
"py_remove_unused_none_type_import",
|
|
19
20
|
]
|
|
20
21
|
|
|
21
22
|
|
|
@@ -178,6 +179,17 @@ RE_JS_METHOD_BLOCK = re.compile(
|
|
|
178
179
|
)
|
|
179
180
|
|
|
180
181
|
|
|
182
|
+
RE_PY_REMOVE_NONE_TYPE_IMPORT = re.compile(
|
|
183
|
+
r"if sys\.version_info >= \(3, 10\):[^)]*\(None\)", flags=re.MULTILINE
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def py_remove_unused_none_type_import(py_code: str) -> str:
|
|
188
|
+
if len(re.findall(r"\bNoneType\b", py_code)) == 2:
|
|
189
|
+
return RE_PY_REMOVE_NONE_TYPE_IMPORT.sub("", py_code)
|
|
190
|
+
return py_code
|
|
191
|
+
|
|
192
|
+
|
|
181
193
|
def js_pure_optimize_return(js_code: str) -> str:
|
|
182
194
|
tmp_code = js_code
|
|
183
195
|
for method_code in RE_JS_METHOD_BLOCK.finditer(tmp_code):
|
|
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
|