ssc_codegen 0.29.1__tar.gz → 0.29.3__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 (59) hide show
  1. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/PKG-INFO +1 -1
  2. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/pyproject.toml +1 -1
  3. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/converters/py_bs4.py +32 -10
  4. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/core/reader.py +1 -2
  5. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/main.py +7 -16
  6. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/.gitignore +0 -0
  7. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/LICENSE +0 -0
  8. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/README.md +0 -0
  9. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/__init__.py +0 -0
  10. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/_logging.py +0 -0
  11. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/__init__.py +0 -0
  12. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/array.py +0 -0
  13. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/base.py +0 -0
  14. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/cast.py +0 -0
  15. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/control.py +0 -0
  16. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/extract.py +0 -0
  17. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/helpers.py +0 -0
  18. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/jsondef.py +0 -0
  19. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/module.py +0 -0
  20. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/predicate_containers.py +0 -0
  21. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/predicate_ops.py +0 -0
  22. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/regex.py +0 -0
  23. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/selectors.py +0 -0
  24. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/string.py +0 -0
  25. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/struct.py +0 -0
  26. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/transform.py +0 -0
  27. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/typedef.py +0 -0
  28. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/ast/types.py +0 -0
  29. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/converters/base.py +0 -0
  30. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/converters/helpers.py +0 -0
  31. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/converters/js_pure.py +0 -0
  32. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/converters/py_lxml.py +0 -0
  33. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/converters/py_parsel.py +0 -0
  34. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/converters/py_render.py +0 -0
  35. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/converters/py_slax.py +0 -0
  36. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/converters/request_spec.py +0 -0
  37. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/core/__init__.py +0 -0
  38. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/core/adapter.py +0 -0
  39. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/core/contexts.py +0 -0
  40. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/core/expressions.py +0 -0
  41. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/core/format.py +0 -0
  42. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/core/linting.py +0 -0
  43. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/core/module_handler.py +0 -0
  44. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/core/predicates.py +0 -0
  45. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/core/struct_parser.py +0 -0
  46. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/core/type_checking.py +0 -0
  47. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/document_utils.py +0 -0
  48. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/exceptions.py +0 -0
  49. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/health.py +0 -0
  50. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/kdl/__init__.py +0 -0
  51. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/kdl/dict_reader.py +0 -0
  52. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/kdl/parser.py +0 -0
  53. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/kdl/reader.py +0 -0
  54. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/parsers/__init__.py +0 -0
  55. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/parsers/curl.py +0 -0
  56. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/parsers/http.py +0 -0
  57. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/pseudo_selectors.py +0 -0
  58. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/ssc_codegen/regex_utils.py +0 -0
  59. {ssc_codegen-0.29.1 → ssc_codegen-0.29.3}/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.29.1
3
+ Version: 0.29.3
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ssc_codegen"
3
- version = "0.29.1"
3
+ version = "0.29.3"
4
4
  description = "Python-dsl code converter to html parser for web scraping "
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -1,3 +1,5 @@
1
+ from collections.abc import Callable
2
+
1
3
  from ssc_codegen.converters.base import ConverterContext, BaseConverter
2
4
 
3
5
  from ssc_codegen.ast import VariableType as VT
@@ -1907,16 +1909,36 @@ def pre_error_response(node: a.ErrorResponse, _: ConverterContext):
1907
1909
 
1908
1910
 
1909
1911
  def register_runtime_file(
1910
- converter: BaseConverter, runtime_name: str = "sscgen_runtime"
1911
- ) -> None:
1912
- """Register a runtime module file provider on the converter."""
1912
+ converter: BaseConverter,
1913
+ runtime_name: str = "sscgen_runtime",
1914
+ *,
1915
+ include_fallback: bool = False,
1916
+ ) -> Callable[[list[a.Node]], str]:
1917
+ """Register a runtime module file provider on the converter.
1918
+
1919
+ Returns a callable ``generate_runtime(modules) -> str`` that produces
1920
+ the runtime file content for a list of parsed modules, picking the one
1921
+ with REST structs as the reference AST automatically.
1922
+ """
1923
+
1924
+ def _apply_fallback(content: str) -> str:
1925
+ if not include_fallback:
1926
+ return content
1927
+ return content.replace(
1928
+ "_RE_HEX_ENTITY",
1929
+ 'FALLBACK_HTML_STR = "<html><body></body></html>"\n\n_RE_HEX_ENTITY',
1930
+ 1,
1931
+ )
1913
1932
 
1914
1933
  @converter.file(f"{runtime_name}.py")
1915
1934
  def _runtime_provider(module_ast, meta):
1916
- content = runtime_module_content(module_ast)
1917
- if meta.get("_include_fallback_html"):
1918
- fallback = 'FALLBACK_HTML_STR = "<html><body></body></html>"\n\n'
1919
- content = content.replace(
1920
- "_RE_HEX_ENTITY", fallback + "_RE_HEX_ENTITY", 1
1921
- )
1922
- return content
1935
+ return _apply_fallback(runtime_module_content(module_ast))
1936
+
1937
+ def _generate_runtime(modules: list[a.Node]) -> str:
1938
+ ref = next(
1939
+ (m for m in modules if _module_has_rest(m)),
1940
+ modules[0],
1941
+ )
1942
+ return _apply_fallback(runtime_module_content(ref))
1943
+
1944
+ return _generate_runtime
@@ -85,8 +85,7 @@ class SscReader(Reader[KdlNode, Module]):
85
85
  if node.name == "@doc":
86
86
  module.docstring.value = str(node.args[0].value)
87
87
  elif node.name == "json":
88
- expr = handle_json(node, module, ctx, lint)
89
- module.body.append(expr)
88
+ handle_json(node, module, ctx, lint)
90
89
  elif node.name == "struct":
91
90
  struct = handle_struct(node, module, ctx, lint)
92
91
  typedefs.append(typedef_from_struct(struct, module))
@@ -256,11 +256,14 @@ def generate(
256
256
 
257
257
  _runtime_name = runtime_name or "sscgen_runtime"
258
258
  meta["runtime_module"] = _runtime_name
259
- meta["_include_fallback_html"] = target == Target.PY_LXML
260
- register_runtime_file(converter, _runtime_name)
259
+ generate_runtime = register_runtime_file(
260
+ converter,
261
+ _runtime_name,
262
+ include_fallback=(target == Target.PY_LXML),
263
+ )
261
264
 
262
265
  # Phase 1: parse all KDL files
263
- from ssc_codegen.ast import Module, StructRest
266
+ from ssc_codegen.ast import Module
264
267
 
265
268
  parsed: list[tuple[Path, Module]] = []
266
269
  for kdl_file in kdl_files:
@@ -288,21 +291,9 @@ def generate(
288
291
 
289
292
  # Phase 2: write runtime file once (if -R is used)
290
293
  if separate_runtime and parsed:
291
- from ssc_codegen.converters.py_bs4 import runtime_module_content
292
-
293
- include_fallback = target == Target.PY_LXML
294
- # Pick an AST that has REST structs so the runtime includes helpers
295
- ref_ast = next(
296
- (
297
- ast
298
- for _, ast in parsed
299
- if any(isinstance(n, StructRest) for n in ast.body)
300
- ),
301
- parsed[0][1],
302
- )
303
294
  runtime_path = output / f"{_runtime_name}.py"
304
295
  runtime_path.write_text(
305
- runtime_module_content(ref_ast, include_fallback),
296
+ generate_runtime([ast for _, ast in parsed]),
306
297
  encoding="utf-8",
307
298
  )
308
299
  typer.echo(f" -> {runtime_path}")
File without changes
File without changes
File without changes