ssc_codegen 0.8.21__tar.gz → 0.8.23__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.21 → ssc_codegen-0.8.23}/PKG-INFO +1 -1
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/pyproject.toml +1 -1
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/__init__.py +1 -1
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/ast_/__init__.py +1 -1
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/ast_/nodes_string.py +20 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/converters/go_goquery.py +1 -1
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/converters/js_pure.py +23 -2
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/converters/py_base.py +29 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/document.py +33 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/tokens.py +3 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/.gitignore +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/LICENSE +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/README.md +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/_compat.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/ast_/base.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/ast_/nodes_array.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/ast_/nodes_cast.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/ast_/nodes_core.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/ast_/nodes_filter.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/ast_/nodes_selectors.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/ast_/nodes_validate.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/ast_build/__init__.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/ast_build/main.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/ast_build/utils.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/cli/__init__.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/cli/cli_callbacks.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/cli/cli_utils.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/cli/code_callbacks.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/cli/consts.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/cli/main.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/cli/runtime_parse_runners.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/compiler.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/consts.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/converters/__init__.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/converters/base.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/converters/helpers.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/converters/py_bs4.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/converters/py_parsel.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/converters/py_selectolax.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/converters/templates/__init__.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/converters/templates/go_goquery.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/converters/templates/js_pure.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/document_utlis.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/json_struct.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/json_to_scc.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/logs.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/pseudo_selectors.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/schema.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/selector_utils.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/static_checker/__init__.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/static_checker/base.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/static_checker/callbacks.py +0 -0
- {ssc_codegen-0.8.21 → ssc_codegen-0.8.23}/ssc_codegen/str_utils.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.23
|
|
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
|
|
@@ -31,6 +31,6 @@ from .nodes_string import ExprStringTrim, ExprStringRegex, ExprStringSplit, Expr
|
|
|
31
31
|
ExprListStringFormat, ExprListStringReplace, ExprListStringRightTrim, ExprListStringLeftTrim, \
|
|
32
32
|
ExprListStringRegexSub, \
|
|
33
33
|
ExprStringRmPrefix, ExprStringRmSuffix, ExprStringRmPrefixAndSuffix, ExprListStringRmPrefixAndSuffix, \
|
|
34
|
-
ExprListStringRmPrefix, ExprListStringRmSuffix
|
|
34
|
+
ExprListStringRmPrefix, ExprListStringRmSuffix, ExprStringMapReplace, ExprListStringMapReplace
|
|
35
35
|
from .nodes_validate import ExprIsCss, ExprIsEqual, ExprStringIsRegex, ExprIsXpath, ExprIsNotEqual, ExprIsContains, \
|
|
36
36
|
ExprListStringAnyRegex, ExprListStringAllRegex, ExprHasAttr, ExprListHasAttr
|
|
@@ -93,6 +93,26 @@ class ExprListStringReplace(BaseAstNode[KW_STR_REPL, tuple[str, str]]):
|
|
|
93
93
|
ret_type: VariableType = VariableType.LIST_STRING
|
|
94
94
|
|
|
95
95
|
|
|
96
|
+
KW_STR_MAP_REPL = TypedDict(
|
|
97
|
+
"KW_STR_MAP_REPL", {"old": tuple[str, ...], "new": tuple[str, ...]}
|
|
98
|
+
)
|
|
99
|
+
ARGS_STR_MAP_REPL = tuple[tuple[str, ...], tuple[str, ...]]
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass(kw_only=True)
|
|
103
|
+
class ExprStringMapReplace(BaseAstNode[KW_STR_MAP_REPL, ARGS_STR_MAP_REPL]):
|
|
104
|
+
kind: ClassVar[TokenType] = TokenType.EXPR_STRING_MAP_REPLACE
|
|
105
|
+
accept_type: VariableType = VariableType.STRING
|
|
106
|
+
ret_type: VariableType = VariableType.STRING
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@dataclass(kw_only=True)
|
|
110
|
+
class ExprListStringMapReplace(BaseAstNode[KW_STR_MAP_REPL, ARGS_STR_MAP_REPL]):
|
|
111
|
+
kind: ClassVar[TokenType] = TokenType.EXPR_LIST_STRING_MAP_REPLACE
|
|
112
|
+
accept_type: VariableType = VariableType.LIST_STRING
|
|
113
|
+
ret_type: VariableType = VariableType.LIST_STRING
|
|
114
|
+
|
|
115
|
+
|
|
96
116
|
KW_STR_RE = TypedDict(
|
|
97
117
|
"KW_STR_RE", {"pattern": str, "group": int, "ignore_case": bool}
|
|
98
118
|
)
|
|
@@ -102,6 +102,8 @@ from ssc_codegen.ast_ import (
|
|
|
102
102
|
FilterStrLenGt,
|
|
103
103
|
FilterStrLenGe,
|
|
104
104
|
ExprListUnique,
|
|
105
|
+
ExprStringMapReplace,
|
|
106
|
+
ExprListStringMapReplace,
|
|
105
107
|
)
|
|
106
108
|
from ssc_codegen.converters.base import BaseCodeConverter
|
|
107
109
|
from ssc_codegen.converters.helpers import (
|
|
@@ -377,14 +379,14 @@ def pre_str_split(node: ExprStringSplit) -> str:
|
|
|
377
379
|
def pre_str_replace(node: ExprStringReplace) -> str:
|
|
378
380
|
prv, nxt = prev_next_var(node)
|
|
379
381
|
old, new = node.unpack_args()
|
|
380
|
-
return f"let {nxt} = {prv}.
|
|
382
|
+
return f"let {nxt} = {prv}.replaceAll({old!r}, {new!r});"
|
|
381
383
|
|
|
382
384
|
|
|
383
385
|
@CONVERTER(ExprListStringReplace.kind)
|
|
384
386
|
def pre_list_str_replace(node: ExprListStringReplace) -> str:
|
|
385
387
|
prv, nxt = prev_next_var(node)
|
|
386
388
|
old, new = node.unpack_args()
|
|
387
|
-
return f"let {nxt} = {prv}.map(e => e.
|
|
389
|
+
return f"let {nxt} = {prv}.map(e => e.replaceAll({old!r}, {new!r}));"
|
|
388
390
|
|
|
389
391
|
|
|
390
392
|
@CONVERTER(ExprStringRegex.kind)
|
|
@@ -923,3 +925,22 @@ def pre_list_unique(node: ExprListUnique) -> str:
|
|
|
923
925
|
# save order guaranteed
|
|
924
926
|
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#description
|
|
925
927
|
return f"let {nxt} = [...new Set({prv})]; "
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
@CONVERTER(ExprStringMapReplace.kind)
|
|
931
|
+
def pre_str_map_repl(node: ExprStringMapReplace) -> str:
|
|
932
|
+
old_arr, new_arr = node.unpack_args()
|
|
933
|
+
old_arr = list(old_arr) # type: ignore
|
|
934
|
+
new_arr = list(new_arr) # type: ignore
|
|
935
|
+
prv, nxt = prev_next_var(node)
|
|
936
|
+
# py list<str> literal syntax equal js Array<string> literal
|
|
937
|
+
return f"let {nxt} = {old_arr}.reduce((s, v, i) => s.replaceAll(v, {new_arr}[i] ?? ''), {prv});"
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
@CONVERTER(ExprListStringMapReplace.kind)
|
|
941
|
+
def pre_list_str_map_repl(node: ExprListStringMapReplace) -> str:
|
|
942
|
+
old_arr, new_arr = node.unpack_args()
|
|
943
|
+
old_arr = list(old_arr) # type: ignore
|
|
944
|
+
new_arr = list(new_arr) # type: ignore
|
|
945
|
+
prv, nxt = prev_next_var(node)
|
|
946
|
+
return f"let {nxt} = {prv}.map(s => {old_arr}.reduce((s, v, i) => s.replaceAll(v, {new_arr}[i] ?? ''), s));"
|
|
@@ -104,6 +104,8 @@ from ssc_codegen.ast_ import (
|
|
|
104
104
|
FilterStrLenGt,
|
|
105
105
|
FilterStrLenGe,
|
|
106
106
|
ExprListUnique,
|
|
107
|
+
ExprStringMapReplace,
|
|
108
|
+
ExprListStringMapReplace,
|
|
107
109
|
)
|
|
108
110
|
from ssc_codegen.converters.base import (
|
|
109
111
|
BaseCodeConverter,
|
|
@@ -176,6 +178,7 @@ import sys
|
|
|
176
178
|
import json
|
|
177
179
|
from typing import List, Dict, TypedDict, Union, Optional
|
|
178
180
|
from contextlib import suppress
|
|
181
|
+
from functools import reduce
|
|
179
182
|
|
|
180
183
|
if sys.version_info >= (3, 10):
|
|
181
184
|
from types import NoneType
|
|
@@ -273,6 +276,8 @@ class BasePyCodeConverter(BaseCodeConverter):
|
|
|
273
276
|
FilterStrLenGe.kind: pre_filter_str_len_ge,
|
|
274
277
|
FilterStrLenGt.kind: pre_filter_str_len_gt,
|
|
275
278
|
ExprListUnique.kind: pre_list_unique,
|
|
279
|
+
ExprStringMapReplace.kind: pre_str_map_replace,
|
|
280
|
+
ExprListStringMapReplace.kind: pre_list_str_map_replace,
|
|
276
281
|
}
|
|
277
282
|
|
|
278
283
|
self.post_definitions = {
|
|
@@ -1080,3 +1085,27 @@ def pre_list_unique(node: ExprListUnique) -> str:
|
|
|
1080
1085
|
prv, nxt = prev_next_var(node)
|
|
1081
1086
|
# use `dict.fromkeys()` instead `set()` for guarantees insertion order (py 3.7+) reason
|
|
1082
1087
|
return f"{indent}{nxt} = list(dict.fromkeys({prv}))"
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
def pre_str_map_replace(node: ExprStringMapReplace) -> str:
|
|
1091
|
+
indent = (
|
|
1092
|
+
INDENT_DEFAULT_BODY if have_default_expr(node) else INDENT_METHOD_BODY
|
|
1093
|
+
)
|
|
1094
|
+
old_arr, new_arr = node.unpack_args()
|
|
1095
|
+
replacements = dict(zip(old_arr, new_arr))
|
|
1096
|
+
|
|
1097
|
+
prv, nxt = prev_next_var(node)
|
|
1098
|
+
expr = f"reduce(lambda acc, kv: acc.replace(kv[0], kv[1]), {replacements}.items(), {prv})"
|
|
1099
|
+
return f"{indent}{nxt} = {expr}"
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
def pre_list_str_map_replace(node: ExprListStringMapReplace) -> str:
|
|
1103
|
+
indent = (
|
|
1104
|
+
INDENT_DEFAULT_BODY if have_default_expr(node) else INDENT_METHOD_BODY
|
|
1105
|
+
)
|
|
1106
|
+
old_arr, new_arr = node.unpack_args()
|
|
1107
|
+
replacements = dict(zip(old_arr, new_arr))
|
|
1108
|
+
|
|
1109
|
+
prv, nxt = prev_next_var(node)
|
|
1110
|
+
expr = f"[reduce(lambda acc, kv: acc.replace(kv[0], kv[1]), {replacements}.items(), i) for i in {prv}]"
|
|
1111
|
+
return f"{indent}{nxt} = {expr}"
|
|
@@ -76,6 +76,8 @@ from ssc_codegen.ast_ import (
|
|
|
76
76
|
FilterStrLenGt,
|
|
77
77
|
FilterStrLenGe,
|
|
78
78
|
ExprListUnique,
|
|
79
|
+
ExprListStringMapReplace,
|
|
80
|
+
ExprStringMapReplace,
|
|
79
81
|
)
|
|
80
82
|
from ssc_codegen.document_utlis import (
|
|
81
83
|
analyze_re_expression,
|
|
@@ -498,6 +500,37 @@ class ArrayDocument(BaseDocument):
|
|
|
498
500
|
|
|
499
501
|
|
|
500
502
|
class StringDocument(BaseDocument):
|
|
503
|
+
def repl_map(self, replace_table: dict[str, str]) -> Self:
|
|
504
|
+
old_args = tuple(replace_table.keys())
|
|
505
|
+
new_args = tuple(replace_table.values())
|
|
506
|
+
|
|
507
|
+
match self.stack_last_ret:
|
|
508
|
+
case VariableType.LIST_STRING:
|
|
509
|
+
self._add(
|
|
510
|
+
ExprListStringMapReplace(
|
|
511
|
+
kwargs={"old": old_args, "new": new_args}
|
|
512
|
+
)
|
|
513
|
+
)
|
|
514
|
+
case VariableType.STRING:
|
|
515
|
+
self._add(
|
|
516
|
+
ExprStringMapReplace(
|
|
517
|
+
kwargs={"old": old_args, "new": new_args}
|
|
518
|
+
)
|
|
519
|
+
)
|
|
520
|
+
case _:
|
|
521
|
+
LOGGER.warning(
|
|
522
|
+
"repl_map(%s): Expected type(s) %s got %s",
|
|
523
|
+
replace_table,
|
|
524
|
+
(VariableType.LIST_STRING.name, VariableType.STRING.name),
|
|
525
|
+
self.stack_last_ret.name,
|
|
526
|
+
)
|
|
527
|
+
self._add(
|
|
528
|
+
ExprStringMapReplace(
|
|
529
|
+
kwargs={"old": old_args, "new": new_args}
|
|
530
|
+
)
|
|
531
|
+
)
|
|
532
|
+
return self
|
|
533
|
+
|
|
501
534
|
def rm_prefix(self, substr: str) -> Self:
|
|
502
535
|
"""remove prefix from string by substr
|
|
503
536
|
|
|
@@ -131,6 +131,7 @@ class TokenType(IntEnum):
|
|
|
131
131
|
EXPR_STRING_RM_PREFIX = auto()
|
|
132
132
|
EXPR_STRING_RM_SUFFIX = auto()
|
|
133
133
|
EXPR_STRING_RM_PREFIX_AND_SUFFIX = auto()
|
|
134
|
+
EXPR_STRING_MAP_REPLACE = auto()
|
|
134
135
|
|
|
135
136
|
# LIST_STRING
|
|
136
137
|
EXPR_LIST_REGEX_SUB = auto()
|
|
@@ -142,6 +143,8 @@ class TokenType(IntEnum):
|
|
|
142
143
|
EXPR_LIST_STRING_RM_PREFIX = auto()
|
|
143
144
|
EXPR_LIST_STRING_RM_SUFFIX = auto()
|
|
144
145
|
EXPR_LIST_STRING_RM_PREFIX_AND_SUFFIX = auto()
|
|
146
|
+
EXPR_LIST_STRING_MAP_REPLACE = auto()
|
|
147
|
+
|
|
145
148
|
# ARRAY
|
|
146
149
|
EXPR_LIST_ANY_INDEX = auto()
|
|
147
150
|
EXPR_LIST_JOIN = auto()
|
|
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
|