ssc_codegen 0.8.3__tar.gz → 0.8.5__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.

Files changed (51) hide show
  1. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/PKG-INFO +2 -1
  2. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/pyproject.toml +25 -1
  3. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/__init__.py +1 -1
  4. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/ast_build/utils.py +13 -2
  5. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/cli/main.py +7 -0
  6. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/converters/js_pure.py +5 -0
  7. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/selector_utils.py +14 -5
  8. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/.gitignore +0 -0
  9. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/LICENSE +0 -0
  10. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/README.md +0 -0
  11. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/_compat.py +0 -0
  12. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/ast_/__init__.py +0 -0
  13. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/ast_/base.py +0 -0
  14. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/ast_/nodes_array.py +0 -0
  15. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/ast_/nodes_cast.py +0 -0
  16. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/ast_/nodes_core.py +0 -0
  17. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/ast_/nodes_selectors.py +0 -0
  18. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/ast_/nodes_string.py +0 -0
  19. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/ast_/nodes_validate.py +0 -0
  20. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/ast_build/__init__.py +0 -0
  21. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/ast_build/main.py +0 -0
  22. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/cli/__init__.py +0 -0
  23. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/cli/cli_callbacks.py +0 -0
  24. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/cli/cli_utils.py +0 -0
  25. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/cli/code_callbacks.py +0 -0
  26. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/cli/consts.py +0 -0
  27. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/cli/runtime_parse_runners.py +0 -0
  28. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/compiler.py +0 -0
  29. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/consts.py +0 -0
  30. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/converters/__init__.py +0 -0
  31. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/converters/base.py +0 -0
  32. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/converters/go_goquery.py +0 -0
  33. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/converters/helpers.py +0 -0
  34. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/converters/py_base.py +0 -0
  35. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/converters/py_bs4.py +0 -0
  36. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/converters/py_parsel.py +0 -0
  37. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/converters/py_selectolax.py +0 -0
  38. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/converters/templates/__init__.py +0 -0
  39. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/converters/templates/go_goquery.py +0 -0
  40. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/converters/templates/js_pure.py +0 -0
  41. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/document.py +0 -0
  42. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/document_utlis.py +0 -0
  43. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/json_struct.py +0 -0
  44. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/json_to_scc.py +0 -0
  45. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/logs.py +0 -0
  46. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/schema.py +0 -0
  47. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/static_checker/__init__.py +0 -0
  48. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/static_checker/base.py +0 -0
  49. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/static_checker/callbacks.py +0 -0
  50. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/ssc_codegen/str_utils.py +0 -0
  51. {ssc_codegen-0.8.3 → ssc_codegen-0.8.5}/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
3
+ Version: 0.8.5
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
@@ -26,6 +26,7 @@ Requires-Dist: ichrome>=4.0.4
26
26
  Requires-Dist: jinja2>=3.1.6
27
27
  Requires-Dist: lxml>=5.3.0
28
28
  Requires-Dist: parsel>=1.10.0
29
+ Requires-Dist: soupsieve>=2.6
29
30
  Requires-Dist: typer>=0.15.1
30
31
  Requires-Dist: typing-extensions; python_version < '3.11'
31
32
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ssc_codegen"
3
- version = "0.8.3"
3
+ version = "0.8.5"
4
4
  description = "Python-dsl code converter to html parser for web scraping "
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -12,6 +12,7 @@ dependencies = [
12
12
  "jinja2>=3.1.6",
13
13
  "lxml>=5.3.0",
14
14
  "parsel>=1.10.0",
15
+ "soupsieve>=2.6",
15
16
  "typer>=0.15.1",
16
17
  "typing_extensions;python_version<'3.11'",
17
18
  ]
@@ -84,3 +85,26 @@ exclude = [
84
85
  [[tool.mypy.overrides]]
85
86
  module="tests.*"
86
87
  disallow_untyped_defs = false
88
+
89
+
90
+ [tool.coverage.report]
91
+ exclude_also = [
92
+ 'def __repr__',
93
+ 'if self.debug:',
94
+ 'if settings.DEBUG',
95
+ 'raise AssertionError',
96
+ 'raise NotImplementedError',
97
+ 'if 0:',
98
+ 'if __name__ == .__main__.:',
99
+ 'if TYPE_CHECKING:',
100
+ 'class .*\bProtocol\):',
101
+ '@(abc\.)?abstractmethod',
102
+ ]
103
+
104
+ [tool.coverage.run]
105
+ source = ["ssc_codegen"]
106
+ omit = [
107
+ "*/.venv/*",
108
+ "*/scripts/*",
109
+ "*/tests/*"
110
+ ]
@@ -7,7 +7,7 @@ from ssc_codegen.schema import ItemSchema, DictSchema, ListSchema, FlatListSchem
7
7
 
8
8
  setup_logger()
9
9
 
10
- VERSION = "0.8.3"
10
+ VERSION = "0.8.5"
11
11
 
12
12
 
13
13
  class __MISSING(object):
@@ -1,5 +1,6 @@
1
1
  import json
2
2
  import logging
3
+ import sys
3
4
  from pathlib import Path
4
5
  from types import ModuleType
5
6
  from typing import Any, Type
@@ -87,10 +88,20 @@ def extract_json_structs_from_module(module: ModuleType) -> list[Type[Json]]:
87
88
  ]
88
89
 
89
90
 
90
- def exec_module_code(path: str | Path) -> ModuleType:
91
+ def exec_module_code(path: str | Path, add_sys_path: bool = True) -> ModuleType:
92
+ # apologize, input - real python file
91
93
  if isinstance(path, str):
92
94
  path = Path(path)
93
95
  module = ModuleType("_")
94
- code = Path(path.resolve()).read_text()
96
+ abs_path = path.resolve()
97
+ # required for correct imports (eg: constants)
98
+ # TODO: calculate configs dirs depth
99
+ if add_sys_path and str(abs_path.parent) not in sys.path:
100
+ sys.path.append(str(abs_path.parent))
101
+
102
+ if add_sys_path and str(abs_path.parent.parent) not in sys.path:
103
+ sys.path.append(str(abs_path.parent.parent))
104
+
105
+ code = Path(abs_path).read_text()
95
106
  exec(code, module.__dict__)
96
107
  return module
@@ -100,6 +100,13 @@ def generate_code(
100
100
  LOGGER.info("TOGGLE debug generated tokens")
101
101
  converter.debug_instructions = True
102
102
  for file_cfg in ssc_files:
103
+ # check ssc-gen files
104
+ if (
105
+ file_cfg.suffix != ".py"
106
+ and "ssc_codegen" not in file_cfg.read_text()
107
+ ):
108
+ LOGGER.info("Skip %s (not ssc-gen config)", file_cfg.name)
109
+ continue
103
110
  name = file_cfg.name.split(".")[0]
104
111
  out_file = f"{prefix}{name}{suffix}"
105
112
  LOGGER.info("Make AST %s...", file_cfg.name)
@@ -146,6 +146,11 @@ def pre_part_doc(_node: StructPartDocMethod) -> str:
146
146
  return "_splitDoc(v) " + BRACKET_START
147
147
 
148
148
 
149
+ @CONVERTER.post(StructPartDocMethod.kind)
150
+ def post_part_doc(_node: StructPartDocMethod) -> str:
151
+ return BRACKET_END
152
+
153
+
149
154
  @CONVERTER(StructParser.kind)
150
155
  def pre_struct_parser(node: StructParser) -> str:
151
156
  name = node.kwargs["name"]
@@ -5,6 +5,12 @@ from cssselect import HTMLTranslator, SelectorSyntaxError
5
5
  from lxml import etree
6
6
  from lxml.etree import XPathSyntaxError
7
7
 
8
+ # cssselect not support CSS4 standard syntax
9
+ # used for particularly provide CSS 4 API
10
+ # https://facelessuser.github.io/soupsieve/selectors/
11
+ from soupsieve import compile as css_compile
12
+ from soupsieve.util import SelectorSyntaxError as SoupSieveSelectorSyntaxError
13
+
8
14
 
9
15
  def css_to_xpath(query: str, prefix: str = "descendant-or-self::") -> str:
10
16
  """convert css to XPATH selector"""
@@ -24,6 +30,10 @@ def xpath_to_css(query: str) -> str:
24
30
  EG FAIL:
25
31
  //p[contains(@class, "star-rating")]
26
32
 
33
+
34
+ NOTE:
35
+ cssselect not fully support CSS4 standard
36
+
27
37
  """
28
38
  # https://stackoverflow.com/a/18421383
29
39
  css = re.sub(
@@ -41,8 +51,8 @@ def xpath_to_css(query: str) -> str:
41
51
 
42
52
  def validate_css_query(query: str) -> None:
43
53
  try:
44
- HTMLTranslator().css_to_xpath(query.strip('"'))
45
- except SelectorSyntaxError:
54
+ css_compile(query.strip('"'))
55
+ except SoupSieveSelectorSyntaxError:
46
56
  # maybe is XPATH?
47
57
  with suppress(XPathSyntaxError):
48
58
  etree.XPath(query) # type: ignore
@@ -57,10 +67,9 @@ def validate_xpath_query(query: str) -> None:
57
67
  etree.XPath(query.strip('"'))
58
68
  # etree.XPath accept CSS-like queries without throw exception, check it!
59
69
  is_css = False
60
- with suppress(SelectorSyntaxError):
61
- HTMLTranslator().css_to_xpath(query.strip('"'))
70
+ with suppress(SoupSieveSelectorSyntaxError):
71
+ css_compile(query.strip('"'))
62
72
  is_css = True
63
-
64
73
  if is_css:
65
74
  msg = f"`{query}` looks like CSS query, not XPATH"
66
75
  raise SelectorSyntaxError(msg)
File without changes
File without changes
File without changes