shacl2code 1.0.0__tar.gz → 1.0.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 (136) hide show
  1. {shacl2code-1.0.0 → shacl2code-1.0.1}/PKG-INFO +3 -2
  2. {shacl2code-1.0.0 → shacl2code-1.0.1}/pyproject.toml +18 -1
  3. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/common.py +1 -1
  4. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/python.py +29 -4
  5. shacl2code-1.0.1/src/shacl2code/lang/templates/python/__init__.py.j2 +15 -0
  6. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/python/model.py.j2 +87 -74
  7. shacl2code-1.0.1/src/shacl2code/lang/templates/python/model.pyi.j2 +441 -0
  8. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/model.py +9 -9
  9. shacl2code-1.0.1/src/shacl2code/util.py +31 -0
  10. shacl2code-1.0.1/src/shacl2code/version.py +1 -0
  11. shacl2code-1.0.1/tests/test_convert_version_string.py +33 -0
  12. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/test_python.py +161 -48
  13. shacl2code-1.0.0/src/shacl2code/lang/templates/python/__init__.py.j2 +0 -8
  14. shacl2code-1.0.0/src/shacl2code/lang/templates/python/stub.pyi.j2 +0 -230
  15. shacl2code-1.0.0/src/shacl2code/version.py +0 -1
  16. {shacl2code-1.0.0 → shacl2code-1.0.1}/.clang-format +0 -0
  17. {shacl2code-1.0.0 → shacl2code-1.0.1}/.flake8 +0 -0
  18. {shacl2code-1.0.0 → shacl2code-1.0.1}/.github/dependabot.yml +0 -0
  19. {shacl2code-1.0.0 → shacl2code-1.0.1}/.github/workflows/coverage-generate.yaml +0 -0
  20. {shacl2code-1.0.0 → shacl2code-1.0.1}/.github/workflows/coverage-report.yaml +0 -0
  21. {shacl2code-1.0.0 → shacl2code-1.0.1}/.github/workflows/publish.yaml +0 -0
  22. {shacl2code-1.0.0 → shacl2code-1.0.1}/.github/workflows/scorecard.yml +0 -0
  23. {shacl2code-1.0.0 → shacl2code-1.0.1}/.github/workflows/test.yaml +0 -0
  24. {shacl2code-1.0.0 → shacl2code-1.0.1}/.gitignore +0 -0
  25. {shacl2code-1.0.0 → shacl2code-1.0.1}/LICENSE +0 -0
  26. {shacl2code-1.0.0 → shacl2code-1.0.1}/README.md +0 -0
  27. {shacl2code-1.0.0 → shacl2code-1.0.1}/SECURITY.md +0 -0
  28. {shacl2code-1.0.0 → shacl2code-1.0.1}/scripts/format.sh +0 -0
  29. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/__init__.py +0 -0
  30. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/__main__.py +0 -0
  31. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/context.py +0 -0
  32. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/__init__.py +0 -0
  33. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/cpp.py +0 -0
  34. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/golang.py +0 -0
  35. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/jinja.py +0 -0
  36. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/jsonschema.py +0 -0
  37. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/lang.py +0 -0
  38. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/sources/cpp/json.hpp +0 -0
  39. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/Doxyfile.j2 +0 -0
  40. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/Makefile.j2 +0 -0
  41. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/api.hpp.j2 +0 -0
  42. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/datetime.cpp.j2 +0 -0
  43. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/datetime.hpp.j2 +0 -0
  44. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/decode.cpp.j2 +0 -0
  45. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/decode.hpp.j2 +0 -0
  46. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/encode.cpp.j2 +0 -0
  47. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/encode.hpp.j2 +0 -0
  48. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/errorhandler.cpp.j2 +0 -0
  49. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/errorhandler.hpp.j2 +0 -0
  50. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/exceptions.hpp.j2 +0 -0
  51. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/extensible.cpp.j2 +0 -0
  52. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/extensible.hpp.j2 +0 -0
  53. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/header.j2 +0 -0
  54. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/jsonld-header.j2 +0 -0
  55. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/jsonld-source.j2 +0 -0
  56. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/link.cpp.j2 +0 -0
  57. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/link.hpp.j2 +0 -0
  58. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/namedindividual.cpp.j2 +0 -0
  59. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/namedindividual.hpp.j2 +0 -0
  60. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/object.cpp.j2 +0 -0
  61. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/object.hpp.j2 +0 -0
  62. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/objectpath.cpp.j2 +0 -0
  63. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/objectpath.hpp.j2 +0 -0
  64. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/objectset.cpp.j2 +0 -0
  65. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/objectset.hpp.j2 +0 -0
  66. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/pkgconfig.pc.j2 +0 -0
  67. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/prop.hpp.j2 +0 -0
  68. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/property.cpp.j2 +0 -0
  69. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/property.hpp.j2 +0 -0
  70. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/propertyvalue.cpp.j2 +0 -0
  71. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/propertyvalue.hpp.j2 +0 -0
  72. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/ref.hpp.j2 +0 -0
  73. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/refproperty.cpp.j2 +0 -0
  74. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/refproperty.hpp.j2 +0 -0
  75. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/source.j2 +0 -0
  76. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/type.cpp.j2 +0 -0
  77. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/type.hpp.j2 +0 -0
  78. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/util.cpp.j2 +0 -0
  79. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/util.hpp.j2 +0 -0
  80. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/validate.j2 +0 -0
  81. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/walk.hpp.j2 +0 -0
  82. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/classes.go.j2 +0 -0
  83. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/decode.go.j2 +0 -0
  84. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/encode.go.j2 +0 -0
  85. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/errorhandler.go.j2 +0 -0
  86. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/errors.go.j2 +0 -0
  87. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/extensible.go.j2 +0 -0
  88. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/linkstate.go.j2 +0 -0
  89. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/listproperty.go.j2 +0 -0
  90. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/optional.go.j2 +0 -0
  91. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/path.go.j2 +0 -0
  92. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/property.go.j2 +0 -0
  93. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/ref.go.j2 +0 -0
  94. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/reflistproperty.go.j2 +0 -0
  95. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/refproperty.go.j2 +0 -0
  96. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/shaclobject.go.j2 +0 -0
  97. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/shaclobjectset.go.j2 +0 -0
  98. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/shacltype.go.j2 +0 -0
  99. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/util.go.j2 +0 -0
  100. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/validator.go.j2 +0 -0
  101. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/jsonschema.j2 +0 -0
  102. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/python/__main__.py.j2 +0 -0
  103. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/lang/templates/python/cmd.py.j2 +0 -0
  104. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/main.py +0 -0
  105. {shacl2code-1.0.0 → shacl2code-1.0.1}/src/shacl2code/urlcontext.py +0 -0
  106. {shacl2code-1.0.0 → shacl2code-1.0.1}/testfixtures/testfixtures/__init__.py +0 -0
  107. {shacl2code-1.0.0 → shacl2code-1.0.1}/testfixtures/testfixtures/httpserver.py +0 -0
  108. {shacl2code-1.0.0 → shacl2code-1.0.1}/testfixtures/testfixtures/jsonvalidation.py +0 -0
  109. {shacl2code-1.0.0 → shacl2code-1.0.1}/testfixtures/testfixtures/timetests.py +0 -0
  110. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/conftest.py +0 -0
  111. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/abort.j2 +0 -0
  112. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/bad-id.j2 +0 -0
  113. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/bad-node-kind.ttl +0 -0
  114. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/bad-pattern-class.ttl +0 -0
  115. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/bad-pattern-integer.ttl +0 -0
  116. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/bad-prop-type.ttl +0 -0
  117. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/bad-reference.jsonld +0 -0
  118. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/context-url.j2 +0 -0
  119. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/context.j2 +0 -0
  120. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/links.json +0 -0
  121. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/missing-range.ttl +0 -0
  122. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/model/test-context.json +0 -0
  123. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/model/test.ttl +0 -0
  124. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/python/bad-object-type-inline.json +0 -0
  125. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/python/bad-object-type-ref-after.json +0 -0
  126. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/python/bad-object-type-ref-before.json +0 -0
  127. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/raw.j2 +0 -0
  128. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/data/roundtrip.json +0 -0
  129. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/test_cli.py +0 -0
  130. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/test_common_jinja.py +0 -0
  131. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/test_common_prefix.py +0 -0
  132. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/test_context.py +0 -0
  133. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/test_cpp.py +0 -0
  134. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/test_golang.py +0 -0
  135. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/test_jsonschema.py +0 -0
  136. {shacl2code-1.0.0 → shacl2code-1.0.1}/tests/test_model_source.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shacl2code
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Convert SHACL model file to code bindings
5
5
  Project-URL: Homepage, https://github.com/JPEWdev/shacl2code
6
6
  Project-URL: Repository, https://github.com/JPEWdev/shacl2code.git
@@ -25,13 +25,14 @@ Requires-Dist: rdflib>=7.0.0
25
25
  Provides-Extra: dev
26
26
  Requires-Dist: flake8-import-order>=0.19.2; extra == 'dev'
27
27
  Requires-Dist: flake8>=7.0.0; extra == 'dev'
28
- Requires-Dist: jsonschema>=4.21.1; extra == 'dev'
28
+ Requires-Dist: jsonschema>=4.23.0; extra == 'dev'
29
29
  Requires-Dist: mypy>=1.14.1; extra == 'dev'
30
30
  Requires-Dist: pyrefly>=0.55.0; extra == 'dev'
31
31
  Requires-Dist: pyright>=1.1.403; extra == 'dev'
32
32
  Requires-Dist: pyshacl>=0.25.0; extra == 'dev'
33
33
  Requires-Dist: pytest-cov>=4.1; extra == 'dev'
34
34
  Requires-Dist: pytest>=7.4; extra == 'dev'
35
+ Requires-Dist: types-jsonschema>=4.23.0; extra == 'dev'
35
36
  Description-Content-Type: text/markdown
36
37
 
37
38
  # Convert SHACL Model to code bindings
@@ -30,13 +30,14 @@ license = "MIT"
30
30
  dev = [
31
31
  "flake8 >= 7.0.0",
32
32
  "flake8-import-order >= 0.19.2",
33
- "jsonschema >= 4.21.1",
33
+ "jsonschema >= 4.23.0", # latest version for Python 3.8 is 4.23.x
34
34
  "mypy >= 1.14.1", # latest version for Python 3.8 is 1.14.x
35
35
  "pyrefly >= 0.55.0",
36
36
  "pyright >= 1.1.403",
37
37
  "pyshacl >= 0.25.0",
38
38
  "pytest >= 7.4",
39
39
  "pytest-cov >= 4.1",
40
+ "types-jsonschema >= 4.23.0",
40
41
  ]
41
42
 
42
43
  [project.urls]
@@ -54,6 +55,22 @@ build-backend = "hatchling.build"
54
55
  [tool.hatch.version]
55
56
  path = "src/shacl2code/version.py"
56
57
 
58
+ [tool.mypy]
59
+ disallow_incomplete_defs = true
60
+ # disallow_untyped_defs = true
61
+ extra_checks = true
62
+ mypy_path = ["testfixtures"]
63
+ pretty = true
64
+ show_column_numbers = true
65
+ # strict = true
66
+ strict_bytes = true
67
+ # strict_equality = true
68
+ # strict_equality_for_none = true
69
+ warn_redundant_casts = true
70
+ # warn_return_any = true
71
+ # warn_unreachable = true
72
+ # warn_unused_ignores = true
73
+
57
74
  [tool.pytest.ini_options]
58
75
  addopts = [
59
76
  "--import-mode=importlib",
@@ -57,7 +57,7 @@ class JinjaTemplateRender(object):
57
57
  if render_args is None:
58
58
  render_args = {} # pragma: no cover
59
59
 
60
- def abort_helper(msg: str):
60
+ def abort_helper(msg: str) -> None:
61
61
  raise TemplateRuntimeError(msg)
62
62
 
63
63
  env = Environment(loader=FileSystemLoader([template.parent, THIS_DIR.parent]))
@@ -9,6 +9,7 @@ from pathlib import Path
9
9
 
10
10
  from .common import JinjaTemplateRender
11
11
  from .lang import TEMPLATE_DIR, language
12
+ from ..util import convert_version_string
12
13
 
13
14
  DATATYPE_CLASSES = {
14
15
  "http://www.w3.org/2001/XMLSchema#string": "StringProp",
@@ -58,16 +59,20 @@ class PythonRender(JinjaTemplateRender):
58
59
 
59
60
  FILES = (
60
61
  "__init__.py",
61
- "__main__.py",
62
- "cmd.py",
63
62
  "model.py",
64
- "stub.pyi",
63
+ "model.pyi",
65
64
  )
66
65
 
67
66
  def __init__(self, args):
68
67
  super().__init__(args)
69
68
  self.__output = args.output
70
69
  self.__use_slots = args.use_slots
70
+ self.__include_main = args.include_main == "yes"
71
+ self.__version_str = args.version
72
+ if args.version:
73
+ self.__version = repr(convert_version_string(args.version))
74
+ else:
75
+ self.__version = ""
71
76
 
72
77
  @classmethod
73
78
  def get_arguments(cls, parser):
@@ -78,6 +83,12 @@ class PythonRender(JinjaTemplateRender):
78
83
  help="Output directory",
79
84
  required=True,
80
85
  )
86
+ parser.add_argument(
87
+ "--include-main",
88
+ choices=("yes", "no"),
89
+ default="yes",
90
+ help="Generate a main function for the module. Default is '%(default)s'",
91
+ )
81
92
  parser.add_argument(
82
93
  "--use-slots",
83
94
  choices=("auto", "yes", "no"),
@@ -87,13 +98,24 @@ class PythonRender(JinjaTemplateRender):
87
98
  "Slots prevents multiple inheritance. Default is %(default)s"
88
99
  ),
89
100
  )
101
+ parser.add_argument(
102
+ "--version",
103
+ help="Specify model version",
104
+ )
90
105
 
91
106
  def get_outputs(self):
92
107
  t = TEMPLATE_DIR / "python"
93
108
  self.__output.mkdir(parents=True, exist_ok=True)
94
109
 
110
+ def get_file(name):
111
+ return self.__output / name, t / (name + ".j2"), {}
112
+
95
113
  for s in self.FILES:
96
- yield self.__output / s, t / (s + ".j2"), {}
114
+ yield get_file(s)
115
+
116
+ if self.__include_main:
117
+ yield get_file("cmd.py")
118
+ yield get_file("__main__.py")
97
119
 
98
120
  def get_extra_env(self):
99
121
  return {
@@ -111,4 +133,7 @@ class PythonRender(JinjaTemplateRender):
111
133
  use_slots = False
112
134
  return {
113
135
  "use_slots": use_slots,
136
+ "include_main": self.__include_main,
137
+ "version_str": self.__version_str,
138
+ "version": self.__version,
114
139
  }
@@ -0,0 +1,15 @@
1
+ #! /usr/bin/env python3
2
+ #
3
+ # {{ disclaimer }}
4
+ #
5
+ # SPDX-License-Identifier: {{ spdx_license }}
6
+
7
+ from .model import * # noqa: F401, F403
8
+
9
+ # fmt: off
10
+ """Format Guard{{ '"' }}{{ '"' }}{{ '"' }}
11
+ {%- if include_main %}
12
+ from .cmd import main # noqa: F401, I100, I202
13
+ {%- endif %}
14
+ {{ '"' }}{{ '"' }}{{ '"' }}Format Guard"""
15
+ # fmt on
@@ -21,22 +21,26 @@ from contextlib import contextmanager
21
21
  from dataclasses import dataclass
22
22
  from datetime import datetime, timedelta, timezone
23
23
  from enum import Enum
24
- from typing import Generic, TYPE_CHECKING, TypeVar, Union, cast, overload
25
-
26
- if TYPE_CHECKING:
27
- from typing import (
28
- Any,
29
- BinaryIO,
30
- Callable,
31
- Dict,
32
- Iterable,
33
- Iterator,
34
- List,
35
- Optional,
36
- Set,
37
- Tuple,
38
- Type,
39
- )
24
+ from typing import (
25
+ Any,
26
+ BinaryIO,
27
+ Callable,
28
+ ClassVar,
29
+ Dict,
30
+ Generic,
31
+ Iterable,
32
+ Iterator,
33
+ List,
34
+ Optional,
35
+ Set,
36
+ TYPE_CHECKING,
37
+ Tuple,
38
+ Type,
39
+ TypeVar,
40
+ Union,
41
+ cast,
42
+ overload,
43
+ )
40
44
 
41
45
  T_PropV = TypeVar("T_PropV")
42
46
 
@@ -60,7 +64,7 @@ class Property(ABC, Generic[T_PropV]):
60
64
  class
61
65
  """
62
66
 
63
- VALID_TYPES: Union[Type[Any], Tuple[Type[Any], ...]] = ()
67
+ VALID_TYPES: ClassVar[Union[Type[Any], Tuple[Type[Any], ...]]] = ()
64
68
 
65
69
  __slots__ = ("pattern",)
66
70
 
@@ -713,6 +717,11 @@ def is_blank_node(s: Any) -> bool:
713
717
  # fmt: off
714
718
  """Format Guard{{ '"' }}{{ '"' }}{{ '"' }}
715
719
  _USE_SLOTS = {{ use_slots }}
720
+ {% if version_str %}
721
+ VERSION_STRING = "{{ version_str }}"
722
+ {% endif %}{% if version %}
723
+ VERSION = {{ version }}
724
+ {% endif %}
716
725
  {{ '"' }}{{ '"' }}{{ '"' }}Format Guard"""
717
726
  # fmt: on
718
727
 
@@ -740,7 +749,7 @@ class SHACLObjectMeta(type):
740
749
  """Metaclass for SHACLObject that processes PROPERTIES, slots, and named individuals at class creation time."""
741
750
 
742
751
  def __new__(cls, name, bases, attrs):
743
- def check_base_prop(name):
752
+ def check_base_prop(name: str) -> bool:
744
753
  return any(hasattr(b, name) or name in b._EXTRA_SLOTS for b in bases)
745
754
 
746
755
  is_base = name == "SHACLObject"
@@ -755,7 +764,8 @@ class SHACLObjectMeta(type):
755
764
  py_properties = {}
756
765
  iri_properties = {}
757
766
  compact_properties = {}
758
- for p in attrs.get("PROPERTIES", []):
767
+ props: List[ClassProp] = attrs.get("PROPERTIES", [])
768
+ for p in props:
759
769
  if not is_base:
760
770
  for b in bases:
761
771
  if p.pyname in b._OBJ_PY_PROPS or p.pyname in b._EXTRA_SLOTS:
@@ -879,65 +889,65 @@ T_SHACLObject = TypeVar("T_SHACLObject", bound="SHACLObject")
879
889
  class SHACLObject(metaclass=SHACLObjectMeta):
880
890
  """Base class for all SHACL-defined objects, providing property access, encoding, and decoding."""
881
891
 
882
- CLASSES: Dict[str, Type] = {}
892
+ CLASSES: ClassVar[Dict[str, Type[SHACLObject]]] = {}
883
893
 
884
894
  # Class properties that can be set in derived classes:
885
895
 
886
896
  # A dictionary of Named Individuals. The key is the python name of the
887
897
  # individual and the value is the IRI of the individual (not inherited)
888
- NAMED_INDIVIDUALS: Dict[str, str] = {}
898
+ NAMED_INDIVIDUALS: ClassVar[Dict[str, str]] = {}
889
899
 
890
900
  # If True, class member variables will be automatically created for the class
891
901
  # from the NAMED_INDIVIDUALS dictionary
892
902
  # NOTE: This variable is not present in the class
893
- AUTO_NAMED_INDIVIDUALS: bool = True
903
+ AUTO_NAMED_INDIVIDUALS: ClassVar[bool] = True
894
904
 
895
905
  # The type of ID the object is allowed to have (inherited from parent)
896
- NODE_KIND = NodeKind.BlankNodeOrIRI
906
+ NODE_KIND: ClassVar[NodeKind] = NodeKind.BlankNodeOrIRI
897
907
 
898
908
  # An alternate IRI for the ID property, besides "@id" (inherited from
899
909
  # parent)
900
- ID_ALIAS: Optional[str] = None
910
+ ID_ALIAS: ClassVar[Optional[str]] = None
901
911
 
902
912
  # If True, this class is abstract and cannot be implemented (not inherited
903
913
  # from parent)
904
- IS_ABSTRACT: bool = True
914
+ IS_ABSTRACT: ClassVar[bool] = True
905
915
 
906
916
  # If True, this class is deprecated and will raise a warning when created
907
917
  # (not inherited from parent)
908
- IS_DEPRECATED: bool = False
918
+ IS_DEPRECATED: ClassVar[bool] = False
909
919
 
910
920
  # The fully qualified Type IRI for the object. Required
911
921
  # NOTE: This variable is not present in the class. Use get_type() instead
912
- TYPE: str = ""
922
+ TYPE: ClassVar[str] = ""
913
923
 
914
924
  # The compacted Type IRI of the object. Must match how the TYPE property
915
925
  # would be compacted by the context. Not inherited from parent
916
926
  # NOTE: This variable is not present in the class. Use get_compact_type()
917
927
  # instead
918
- COMPACT_TYPE: Optional[str] = None
928
+ COMPACT_TYPE: ClassVar[Optional[str]] = None
919
929
 
920
930
  # A list of properties for this object. Each entry must be a ClassProp
921
931
  # object. Properties are automatically inherited from parent classes and do
922
932
  # not need to be re-listed here.
923
933
  # NOTE: The variable is not present in the class
924
- PROPERTIES = [
934
+ PROPERTIES: ClassVar[List[ClassProp]] = [
925
935
  ClassProp("_id", lambda: StringProp(), "@id"),
926
936
  ]
927
937
 
928
938
  # Internal variables
929
- _EXTRA_SLOTS: Union[Set[str], Tuple[str, ...]] = (
939
+ _EXTRA_SLOTS: ClassVar[Union[Set[str], Tuple[str, ...]]] = (
930
940
  "_extensible",
931
941
  "_metadata",
932
942
  "_birth_index",
933
943
  )
934
- _OBJ_PY_PROPS: Dict[str, ClassProp] = {}
935
- _OBJ_IRI_PROPS: Dict[str, ClassProp] = {}
936
- _OBJ_COMPACT_PROPS: Dict[str, ClassProp] = {}
937
- _NEEDS_REG: bool = True
938
- _next_birth_index: int = 0
939
- _TYPE: str
940
- _COMPACT_TYPE: Optional[str]
944
+ _OBJ_PY_PROPS: ClassVar[Dict[str, ClassProp]] = {}
945
+ _OBJ_IRI_PROPS: ClassVar[Dict[str, ClassProp]] = {}
946
+ _OBJ_COMPACT_PROPS: ClassVar[Dict[str, ClassProp]] = {}
947
+ _NEEDS_REG: ClassVar[bool] = True
948
+ _next_birth_index: ClassVar[int] = 0
949
+ _TYPE: ClassVar[str]
950
+ _COMPACT_TYPE: ClassVar[Optional[str]]
941
951
  _extensible: Dict[str, Any]
942
952
 
943
953
  # Instance variables
@@ -1035,7 +1045,7 @@ class SHACLObject(metaclass=SHACLObjectMeta):
1035
1045
  )
1036
1046
  object.__setattr__(self, p.pyname, p.prop.set(value))
1037
1047
 
1038
- def __del(self, p: ClassProp):
1048
+ def __del(self, p: ClassProp) -> None:
1039
1049
  object.__setattr__(self, p.pyname, p.prop.init())
1040
1050
 
1041
1051
  def __get_attr(self, name: str) -> ClassProp:
@@ -1272,7 +1282,7 @@ class SHACLObject(metaclass=SHACLObjectMeta):
1272
1282
  ),
1273
1283
  )
1274
1284
 
1275
- def __str__(self):
1285
+ def __str__(self) -> str:
1276
1286
  parts = [
1277
1287
  f"{self.__class__.__name__}(",
1278
1288
  ]
@@ -1281,10 +1291,10 @@ class SHACLObject(metaclass=SHACLObjectMeta):
1281
1291
  parts.append(")")
1282
1292
  return "".join(parts)
1283
1293
 
1284
- def __hash__(self):
1294
+ def __hash__(self) -> int:
1285
1295
  return super().__hash__()
1286
1296
 
1287
- def __eq__(self, other):
1297
+ def __eq__(self, other: object) -> bool:
1288
1298
  return super().__eq__(other)
1289
1299
 
1290
1300
  @staticmethod
@@ -1347,7 +1357,7 @@ class SHACLExtensibleObject(SHACLObject):
1347
1357
  return obj
1348
1358
 
1349
1359
  def _decode_properties(self, decoder: Decoder, state: DecodeState) -> None:
1350
- def decode_value(d):
1360
+ def decode_value(d: Decoder) -> Any:
1351
1361
  if not d.is_list():
1352
1362
  return d.read_value()
1353
1363
 
@@ -1372,6 +1382,7 @@ class SHACLExtensibleObject(SHACLObject):
1372
1382
  )
1373
1383
 
1374
1384
  with decoder.read_property(key) as prop_d:
1385
+ assert prop_d is not None
1375
1386
  self._ext_data[expanded_key] = decode_value(prop_d)
1376
1387
 
1377
1388
  def _encode_properties(self, encoder: Encoder, state: EncodeState) -> None:
@@ -1519,7 +1530,7 @@ class SHACLObjectSet(object):
1519
1530
 
1520
1531
  self.obj_by_id[obj._id] = obj
1521
1532
 
1522
- def add(self, obj: SHACLObject) -> SHACLObject:
1533
+ def add(self, obj: T_SHACLObject) -> T_SHACLObject:
1523
1534
  """
1524
1535
  Add object to object set
1525
1536
 
@@ -1781,7 +1792,7 @@ class SHACLObjectSet(object):
1781
1792
  elif objects:
1782
1793
  objects[0].encode(encoder, state)
1783
1794
 
1784
- def decode(self, decoder: Decoder, state: DecodeState):
1795
+ def decode(self, decoder: Decoder, state: DecodeState) -> None:
1785
1796
  """Decode objects from the decoder and add them to this set, then link all references."""
1786
1797
  self.create_index()
1787
1798
  for obj_d in decoder.read_list():
@@ -1931,7 +1942,7 @@ class Decoder(ABC):
1931
1942
  raise NotImplementedError("Subclasses must implement read_iri method")
1932
1943
 
1933
1944
  @abstractmethod
1934
- def read_enum(self, e) -> Optional[str]:
1945
+ def read_enum(self, e: EnumProp) -> Optional[str]:
1935
1946
  """
1936
1947
  Consumes the next item as an Enum value string
1937
1948
 
@@ -2087,7 +2098,7 @@ class JSONLDDecoder(Decoder):
2087
2098
  return self.data
2088
2099
  return None
2089
2100
 
2090
- def read_enum(self, e) -> Optional[str]:
2101
+ def read_enum(self, e: EnumProp) -> Optional[str]:
2091
2102
  if isinstance(self.data, str):
2092
2103
  return self.data
2093
2104
  return None
@@ -2442,7 +2453,7 @@ class JSONLDSerializer(object):
2442
2453
  objectset: SHACLObjectSet,
2443
2454
  f: BinaryIO,
2444
2455
  force_at_graph: bool = False,
2445
- **kwargs,
2456
+ **kwargs: Any,
2446
2457
  ) -> str:
2447
2458
  """
2448
2459
  Write a SHACLObjectSet to a JSON LD file
@@ -2582,7 +2593,7 @@ class JSONLDInlineSerializer(object):
2582
2593
  objectset: SHACLObjectSet,
2583
2594
  f: BinaryIO,
2584
2595
  force_at_graph: bool = False,
2585
- ):
2596
+ ) -> str:
2586
2597
  """
2587
2598
  Write a SHACLObjectSet to a JSON LD file
2588
2599
 
@@ -2607,7 +2618,7 @@ def encode_context(encoder: Encoder, objectset: SHACLObjectSet) -> None:
2607
2618
  if not context:
2608
2619
  return
2609
2620
 
2610
- def write_context(e, ctx):
2621
+ def write_context(e: Encoder, ctx: Union[str, Dict[str, str]]) -> None:
2611
2622
  if isinstance(ctx, str):
2612
2623
  e.write_string(ctx)
2613
2624
  else:
@@ -2627,7 +2638,7 @@ def encode_context(encoder: Encoder, objectset: SHACLObjectSet) -> None:
2627
2638
 
2628
2639
 
2629
2640
  def decode_context(decoder: Decoder, objectset: SHACLObjectSet) -> None:
2630
- def _decode_ctx(d: Decoder):
2641
+ def _decode_ctx(d: Decoder) -> None:
2631
2642
  if not d.is_object():
2632
2643
  return
2633
2644
 
@@ -2650,7 +2661,7 @@ try:
2650
2661
  from rdflib.term import IdentifiedNode
2651
2662
 
2652
2663
  if TYPE_CHECKING:
2653
- from rdflib import Graph
2664
+ from rdflib import Graph # noqa: I300
2654
2665
  from rdflib.term import Node
2655
2666
 
2656
2667
  class RDFDecoder(Decoder):
@@ -2718,7 +2729,7 @@ try:
2718
2729
  return v.n3()
2719
2730
  return None
2720
2731
 
2721
- def read_enum(self, e) -> Optional[str]:
2732
+ def read_enum(self, e: EnumProp) -> Optional[str]:
2722
2733
  v = self.__read_node()
2723
2734
  if isinstance(v, URIRef):
2724
2735
  return v.toPython()
@@ -2792,7 +2803,7 @@ try:
2792
2803
 
2793
2804
  return typ.toPython(), self.__class__(self.graph, s)
2794
2805
 
2795
- def read_object_id(self, alias=None) -> Optional[Any]:
2806
+ def read_object_id(self, alias: Optional[str] = None) -> Optional[Any]:
2796
2807
  if isinstance(self.subject, BNode):
2797
2808
  return self.subject.n3()
2798
2809
  if not isinstance(self.subject, IdentifiedNode):
@@ -2830,29 +2841,31 @@ try:
2830
2841
  raise TypeError("Subject and predicate of URIRef value cannot be None")
2831
2842
  self.graph.add((self.subject, self.predicate, URIRef(v)))
2832
2843
 
2833
- def write_string(self, v):
2844
+ def write_string(self, v: str) -> None:
2834
2845
  self.__add_literal(v)
2835
2846
 
2836
- def write_datetime(self, v):
2847
+ def write_datetime(self, v: str) -> None:
2837
2848
  self.__add_literal(v)
2838
2849
 
2839
- def write_integer(self, v):
2850
+ def write_integer(self, v: int) -> None:
2840
2851
  self.__add_literal(v)
2841
2852
 
2842
- def write_iri(self, v, compact=None):
2853
+ def write_iri(self, v: str, compact: Optional[str] = None) -> None:
2843
2854
  self.__add_uriref(v)
2844
2855
 
2845
- def write_enum(self, v, e, compact=None):
2856
+ def write_enum(self, v: str, e: Any, compact: Optional[str] = None) -> None:
2846
2857
  self.__add_uriref(v)
2847
2858
 
2848
- def write_bool(self, v):
2859
+ def write_bool(self, v: bool) -> None:
2849
2860
  self.__add_literal(v)
2850
2861
 
2851
- def write_float(self, v):
2862
+ def write_float(self, v: float) -> None:
2852
2863
  self.__add_literal(v)
2853
2864
 
2854
2865
  @contextmanager
2855
- def write_property(self, iri: str, compact: Optional[str] = None):
2866
+ def write_property(
2867
+ self, iri: str, compact: Optional[str] = None
2868
+ ) -> Iterator[Encoder]:
2856
2869
  yield self.__class__(self.graph, self.subject, URIRef(iri))
2857
2870
 
2858
2871
  @contextmanager
@@ -2864,7 +2877,7 @@ try:
2864
2877
  _id: str,
2865
2878
  compact_id: Optional[str],
2866
2879
  needs_id: bool,
2867
- ):
2880
+ ) -> Iterator[Encoder]:
2868
2881
  obj: Node
2869
2882
  if _id.startswith("_:"):
2870
2883
  obj = BNode(_id[2:])
@@ -2879,19 +2892,19 @@ try:
2879
2892
  yield self.__class__(self.graph, obj)
2880
2893
 
2881
2894
  @contextmanager
2882
- def write_list(self):
2895
+ def write_list(self) -> Iterator["RDFEncoder"]:
2883
2896
  yield self
2884
2897
 
2885
2898
  @contextmanager
2886
- def write_list_item(self):
2899
+ def write_list_item(self) -> Iterator["RDFEncoder"]:
2887
2900
  yield self
2888
2901
 
2889
2902
  @contextmanager
2890
- def write_object_list(self):
2903
+ def write_object_list(self) -> Iterator["RDFEncoder"]:
2891
2904
  yield self
2892
2905
 
2893
2906
  @contextmanager
2894
- def write_dict(self):
2907
+ def write_dict(self) -> Iterator["RDFEncoder"]:
2895
2908
  yield self
2896
2909
 
2897
2910
  class RDFSerializer(object):
@@ -2940,22 +2953,22 @@ class {{ varname(*class.clsname) }}(
2940
2953
  {%- endfor %}
2941
2954
  {{ '"' }}{{ '"' }}{{ '"' }}
2942
2955
  {% endif %}
2943
- TYPE = "{{ class._id }}"
2956
+ TYPE: ClassVar[str] = "{{ class._id }}"
2944
2957
  {%- if context.compact_iri(class._id) != class._id %}
2945
- COMPACT_TYPE = "{{ context.compact_iri(class._id) }}"
2958
+ COMPACT_TYPE: ClassVar[Optional[str]] = "{{ context.compact_iri(class._id) }}"
2946
2959
  {%- endif %}
2947
- NODE_KIND: NodeKind = NodeKind.{{ class.node_kind.split("#")[-1] }}
2960
+ NODE_KIND: ClassVar[NodeKind] = NodeKind.{{ class.node_kind.split("#")[-1] }}
2948
2961
  {%- if class.id_property %}
2949
- ID_ALIAS: Optional[str] = "{{ class.id_property }}"
2962
+ ID_ALIAS: ClassVar[Optional[str]] = "{{ class.id_property }}"
2950
2963
  {%- endif %}
2951
2964
  {%- if class.is_abstract %}
2952
- IS_ABSTRACT: bool = True
2965
+ IS_ABSTRACT: ClassVar[bool] = True
2953
2966
  {%- endif %}
2954
2967
  {%- if class.deprecated %}
2955
- IS_DEPRECATED: bool = True
2968
+ IS_DEPRECATED: ClassVar[bool] = True
2956
2969
  {%- endif %}
2957
2970
  {%- if class.named_individuals %}
2958
- NAMED_INDIVIDUALS: Dict[str, str] = {
2971
+ NAMED_INDIVIDUALS: ClassVar[Dict[str, str]] = {
2959
2972
  {%- for member in class.named_individuals %}
2960
2973
  {%- if member.comment %}
2961
2974
  {%- for l in member.comment.split("\n") %}
@@ -2968,7 +2981,7 @@ class {{ varname(*class.clsname) }}(
2968
2981
  {%- endif %}
2969
2982
 
2970
2983
  {%- if class.properties %}
2971
- PROPERTIES = [
2984
+ PROPERTIES: ClassVar[List[ClassProp]] = [
2972
2985
  {%- for prop in class.properties %}
2973
2986
  {%- set is_list = prop.max_count is none or prop.max_count != 1 %}
2974
2987
  {%- if prop.comment %}