ssc_codegen 0.10.0__tar.gz → 0.10.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 (61) hide show
  1. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/PKG-INFO +3 -3
  2. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/README.md +2 -2
  3. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/pyproject.toml +1 -1
  4. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/__init__.py +1 -1
  5. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_/__init__.py +1 -1
  6. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_/nodes_cast.py +13 -0
  7. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/go_goquery.py +1 -0
  8. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/js_pure.py +11 -0
  9. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/lua_htmlparser.py +14 -0
  10. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/py_base.py +14 -0
  11. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/document.py +21 -0
  12. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/tokens.py +1 -0
  13. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/.gitignore +0 -0
  14. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/LICENSE +0 -0
  15. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/_compat.py +0 -0
  16. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_/base.py +0 -0
  17. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_/nodes_array.py +0 -0
  18. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_/nodes_core.py +0 -0
  19. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_/nodes_filter.py +0 -0
  20. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_/nodes_selectors.py +0 -0
  21. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_/nodes_string.py +0 -0
  22. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_/nodes_validate.py +0 -0
  23. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_build/__init__.py +0 -0
  24. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_build/main.py +0 -0
  25. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_build/utils.py +0 -0
  26. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_grep_rules/js_rules.yml +0 -0
  27. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/ast_grep_rules/py_rules.yml +0 -0
  28. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/cli/__init__.py +0 -0
  29. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/cli/ast_grep.py +0 -0
  30. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/cli/cli_callbacks.py +0 -0
  31. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/cli/cli_utils.py +0 -0
  32. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/cli/code_callbacks.py +0 -0
  33. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/cli/consts.py +0 -0
  34. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/cli/main.py +0 -0
  35. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/cli/runtime_parse_runners.py +0 -0
  36. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/compiler.py +0 -0
  37. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/__init__.py +0 -0
  38. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/base.py +0 -0
  39. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/helpers.py +0 -0
  40. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/py_bs4.py +0 -0
  41. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/py_lxml.py +0 -0
  42. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/py_parsel.py +0 -0
  43. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/py_selectolax.py +0 -0
  44. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/templates/__init__.py +0 -0
  45. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/templates/go_goquery.py +0 -0
  46. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/templates/js_pure.py +0 -0
  47. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/templates/lua_base.py +0 -0
  48. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/templates/lua_css_compat.py +0 -0
  49. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/templates/lua_re_compat.py +0 -0
  50. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/converters/templates/py_base.py +0 -0
  51. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/document_utlis.py +0 -0
  52. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/json_struct.py +0 -0
  53. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/json_to_scc.py +0 -0
  54. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/logs.py +0 -0
  55. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/pseudo_selectors.py +0 -0
  56. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/schema.py +0 -0
  57. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/selector_utils.py +0 -0
  58. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/static_checker/__init__.py +0 -0
  59. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/static_checker/base.py +0 -0
  60. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/ssc_codegen/static_checker/callbacks.py +0 -0
  61. {ssc_codegen-0.10.0 → ssc_codegen-0.10.1}/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.10.0
3
+ Version: 0.10.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
@@ -247,7 +247,7 @@ You can use any html source:
247
247
 
248
248
  ## See also
249
249
 
250
- - [Brief](docs/brief.md) about css selectors and regular expressions.
250
+ - [Brief](docs/briefing.md) about css selectors and regular expressions.
251
+ - [Quickstart](docs/quickstart.md) about css selectors and regular expressions.
251
252
  - [Tutorial](docs/tutorial.md) basic usage ssc-gen
252
- - [Reference](docs/reference.md) about lib API
253
253
  - [AST reference](docs/ast_reference.md) about generation code from AST
@@ -210,7 +210,7 @@ You can use any html source:
210
210
 
211
211
  ## See also
212
212
 
213
- - [Brief](docs/brief.md) about css selectors and regular expressions.
213
+ - [Brief](docs/briefing.md) about css selectors and regular expressions.
214
+ - [Quickstart](docs/quickstart.md) about css selectors and regular expressions.
214
215
  - [Tutorial](docs/tutorial.md) basic usage ssc-gen
215
- - [Reference](docs/reference.md) about lib API
216
216
  - [AST reference](docs/ast_reference.md) about generation code from AST
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ssc_codegen"
3
- version = "0.10.0"
3
+ version = "0.10.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"
@@ -7,7 +7,7 @@ from ssc_codegen.schema import ItemSchema, DictSchema, ListSchema, FlatListSchem
7
7
 
8
8
  setup_logger()
9
9
 
10
- VERSION = "0.10.0"
10
+ VERSION = "0.10.1"
11
11
 
12
12
 
13
13
  class __MISSING(object):
@@ -1,6 +1,6 @@
1
1
  from .base import BaseAstNode
2
2
  from .nodes_array import ExprIndex, ExprToListLength, ExprListStringJoin, ExprListUnique
3
- from .nodes_cast import ExprNested, ExprJsonify, ExprToInt, ExprToFloat, ExprToListInt, ExprToListFloat, ExprToBool
3
+ from .nodes_cast import ExprNested, ExprJsonify, ExprToInt, ExprToFloat, ExprToListInt, ExprToListFloat, ExprToBool, ExprJsonifyDynamic
4
4
  from .nodes_core import (ExprReturn,
5
5
  ExprNoReturn,
6
6
  ExprDefaultValueEnd,
@@ -68,3 +68,16 @@ class ExprJsonify(BaseAstNode[KW_EXPR_JSONIFY, ARGS_EXPR_JSONIFY]):
68
68
  kind: ClassVar[TokenType] = TokenType.TO_JSON
69
69
  accept_type: VariableType = VariableType.STRING
70
70
  ret_type: VariableType = VariableType.JSON
71
+
72
+
73
+ KW_EXPR_JSONIFY_DYNAMIC = TypedDict("KW_EXPR_JSONIFY_DYNAMIC", {"query": str})
74
+ ARGS_EXPR_JSONIFY_DYNAMIC = tuple[str]
75
+
76
+
77
+ @dataclass(kw_only=True)
78
+ class ExprJsonifyDynamic(
79
+ BaseAstNode[KW_EXPR_JSONIFY_DYNAMIC, ARGS_EXPR_JSONIFY_DYNAMIC]
80
+ ):
81
+ kind: ClassVar[TokenType] = TokenType.TO_JSON_DYNAMIC
82
+ accept_type: VariableType = VariableType.STRING
83
+ ret_type: VariableType = VariableType.ANY # STUBBED
@@ -267,6 +267,7 @@ CONVERTER.TEST_EXCLUDE_NODES.extend(
267
267
  TokenType.STRUCT_INIT, # defined inside a struct
268
268
  TokenType.EXPR_DEFAULT_END, # emulated by defer func() + rescue
269
269
  TokenType.CLASSVAR, # emulated by type ST struct{ f1: T1, f2: T2, ...}; var ST {f1=V1, f2=V2, ...};
270
+ TokenType.TO_JSON_DYNAMIC, # golang exclude dynamic json structures (DDD aka dict driven development)
270
271
  ]
271
272
  )
272
273
 
@@ -106,6 +106,7 @@ from ssc_codegen.ast_ import (
106
106
  ExprListStringMapReplace,
107
107
  ExprClassVar,
108
108
  )
109
+ from ssc_codegen.ast_.nodes_cast import ExprJsonifyDynamic
109
110
  from ssc_codegen.ast_.nodes_core import ModuleImports
110
111
  from ssc_codegen.ast_.nodes_selectors import (
111
112
  ExprCssElementRemove,
@@ -1064,3 +1065,13 @@ def pre_xpath_remove(node: ExprXpathElementRemove) -> str:
1064
1065
  f"for (let {prv}r = document.evaluate({query}, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null), {prv}i = {prv}r.snapshotLength; {prv}i--; ) {prv}r.snapshotItem({prv}i).remove(); "
1065
1066
  + f"let {nxt} = {prv}; "
1066
1067
  )
1068
+
1069
+
1070
+ @CONVERTER(ExprJsonifyDynamic.kind)
1071
+ def pre_jsonify_dynamic(node: ExprJsonifyDynamic) -> str:
1072
+ prv, nxt = prev_next_var(node)
1073
+ query = node.unpack_args()
1074
+
1075
+ expr = "".join(f"[{i}]" for i in jsonify_query_parse(query))
1076
+
1077
+ return f"let {nxt} = JSON.parse({prv}){expr};"
@@ -110,6 +110,7 @@ from ssc_codegen.ast_ import (
110
110
  ExprStringUnescape,
111
111
  ModuleImports,
112
112
  )
113
+ from ssc_codegen.ast_.nodes_cast import ExprJsonifyDynamic
113
114
  from ssc_codegen.ast_.nodes_core import (
114
115
  CodeEnd,
115
116
  ExprCallStructClassVar,
@@ -1380,3 +1381,16 @@ def pre_code_end(node: CodeEnd) -> str:
1380
1381
  ]
1381
1382
  names = [n.kwargs["name"] + "=" + n.kwargs["name"] for n in classes]
1382
1383
  return "return {" + ", ".join(names) + "}"
1384
+
1385
+
1386
+ @CONVERTER(ExprJsonifyDynamic.kind)
1387
+ def pre_jsonify_dynamic(node: ExprJsonifyDynamic) -> str:
1388
+ prv, nxt = prev_next_var(node)
1389
+ query = node.unpack_args()
1390
+ # lua index starts by 1, fix query
1391
+ expr = "".join(
1392
+ f"[{int(i) + 1}]" if i.isdigit() else f"[{i}]"
1393
+ for i in jsonify_query_parse(query)
1394
+ )
1395
+
1396
+ return f"local {nxt} = json.decode({prv}){expr}; "
@@ -107,6 +107,7 @@ from ssc_codegen.ast_ import (
107
107
  ExprStringMapReplace,
108
108
  ExprListStringMapReplace,
109
109
  )
110
+ from ssc_codegen.ast_.nodes_cast import ExprJsonifyDynamic
110
111
  from ssc_codegen.ast_.nodes_core import ExprClassVar
111
112
  from ssc_codegen.ast_.nodes_string import (
112
113
  ExprListStringUnescape,
@@ -270,6 +271,7 @@ class BasePyCodeConverter(BaseCodeConverter):
270
271
  ExprToListLength.kind: pre_to_len,
271
272
  ExprToBool.kind: pre_to_bool,
272
273
  ExprJsonify.kind: pre_jsonify,
274
+ ExprJsonifyDynamic.kind: pre_to_json_dynamic,
273
275
  # FILTER,
274
276
  ExprFilter.kind: pre_expr_filter,
275
277
  FilterAnd.kind: pre_filter_and,
@@ -1269,3 +1271,15 @@ def pre_list_str_unescape(node: ExprListStringUnescape) -> str:
1269
1271
  prv, nxt = prev_next_var(node)
1270
1272
  # ssc_unescape(s: str) -> str
1271
1273
  return f"{indent}{nxt} = [ssc_unescape(i) for i in {prv}]"
1274
+
1275
+
1276
+ def pre_to_json_dynamic(node: ExprJsonifyDynamic) -> str:
1277
+ indent = (
1278
+ INDENT_DEFAULT_BODY if have_default_expr(node) else INDENT_METHOD_BODY
1279
+ )
1280
+ prv, nxt = prev_next_var(node)
1281
+ query = node.unpack_args()
1282
+
1283
+ expr = "".join(f"[{i}]" for i in jsonify_query_parse(query))
1284
+
1285
+ return f"{indent}{nxt} = json.loads({prv}){expr}"
@@ -80,6 +80,7 @@ from ssc_codegen.ast_ import (
80
80
  ExprListStringMapReplace,
81
81
  ExprStringMapReplace,
82
82
  )
83
+ from ssc_codegen.ast_.nodes_cast import ExprJsonifyDynamic
83
84
  from ssc_codegen.ast_.nodes_core import ExprClassVar
84
85
  from ssc_codegen.ast_.nodes_selectors import (
85
86
  ExprCssElementRemove,
@@ -1759,6 +1760,26 @@ class BooleanDocument(BaseDocument):
1759
1760
 
1760
1761
 
1761
1762
  class JsonDocument(BaseDocument):
1763
+ def jsonify_dynamic(self, start_query: str = "") -> Self:
1764
+ """marshal json to dynamic object wout annotated type/struct
1765
+
1766
+ - accept STRING, return ANY
1767
+ """
1768
+ if self.stack_last_ret != VariableType.STRING:
1769
+ LOGGER.warning(
1770
+ "jsonify_dynamic(): Expected type(s) %s got %s",
1771
+ VariableType.STRING.name,
1772
+ self.stack_last_ret.name,
1773
+ )
1774
+ self._add(
1775
+ ExprJsonifyDynamic(
1776
+ kwargs={
1777
+ "query": start_query,
1778
+ }
1779
+ )
1780
+ )
1781
+ return self
1782
+
1762
1783
  def jsonify(self, struct: Type[Json], start_query: str = "") -> Self:
1763
1784
  """marshal json string to object
1764
1785
 
@@ -215,6 +215,7 @@ class TokenType(IntEnum):
215
215
 
216
216
  # JSON OP
217
217
  TO_JSON = auto()
218
+ TO_JSON_DYNAMIC = auto()
218
219
  # STRUCTS
219
220
  JSON_STRUCT = auto()
220
221
  JSON_FIELD = auto()
File without changes
File without changes