shacl2code 0.0.24__tar.gz → 1.0.0__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 (181) hide show
  1. shacl2code-1.0.0/.clang-format +8 -0
  2. shacl2code-1.0.0/.flake8 +15 -0
  3. shacl2code-1.0.0/.github/dependabot.yml +6 -0
  4. {shacl2code-0.0.24 → shacl2code-1.0.0}/.github/workflows/test.yaml +24 -8
  5. {shacl2code-0.0.24 → shacl2code-1.0.0}/.gitignore +12 -1
  6. {shacl2code-0.0.24 → shacl2code-1.0.0}/PKG-INFO +8 -5
  7. {shacl2code-0.0.24 → shacl2code-1.0.0}/README.md +3 -3
  8. {shacl2code-0.0.24 → shacl2code-1.0.0}/pyproject.toml +12 -2
  9. shacl2code-1.0.0/scripts/format.sh +9 -0
  10. shacl2code-1.0.0/src/shacl2code/__init__.py +17 -0
  11. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/context.py +12 -6
  12. shacl2code-1.0.0/src/shacl2code/lang/__init__.py +21 -0
  13. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/common.py +17 -7
  14. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/cpp.py +12 -23
  15. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/golang.py +16 -8
  16. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/jinja.py +1 -0
  17. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/jsonschema.py +6 -5
  18. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/lang.py +1 -0
  19. shacl2code-1.0.0/src/shacl2code/lang/python.py +114 -0
  20. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/Doxyfile.j2 +791 -457
  21. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/Makefile.j2 +114 -0
  22. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/datetime.cpp.j2 +149 -0
  23. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/datetime.hpp.j2 +101 -0
  24. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/decode.cpp.j2 +20 -6
  25. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/decode.hpp.j2 +321 -0
  26. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/encode.cpp.j2 +113 -0
  27. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/encode.hpp.j2 +384 -0
  28. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/errorhandler.cpp.j2 +8 -10
  29. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/errorhandler.hpp.j2 +133 -0
  30. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/exceptions.hpp.j2 +96 -0
  31. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/extensible.cpp.j2 +187 -0
  32. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/extensible.hpp.j2 +178 -0
  33. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/jsonld-header.j2 +12 -4
  34. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/jsonld-source.j2 +90 -59
  35. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/link.cpp.j2 +4 -6
  36. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/link.hpp.j2 +51 -0
  37. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/namedindividual.cpp.j2 +67 -0
  38. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/namedindividual.hpp.j2 +102 -0
  39. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/object.cpp.j2 +304 -0
  40. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/object.hpp.j2 +324 -0
  41. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/objectpath.cpp.j2 +100 -0
  42. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/objectpath.hpp.j2 +164 -0
  43. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/objectset.cpp.j2 +362 -0
  44. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/objectset.hpp.j2 +264 -0
  45. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/prop.hpp.j2 +3 -6
  46. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/property.cpp.j2 +426 -0
  47. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/property.hpp.j2 +460 -0
  48. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/propertyvalue.cpp.j2 +15 -19
  49. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/propertyvalue.hpp.j2 +996 -0
  50. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/ref.hpp.j2 +407 -0
  51. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/refproperty.cpp.j2 +8 -9
  52. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/refproperty.hpp.j2 +203 -0
  53. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/type.cpp.j2 +33 -0
  54. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/type.hpp.j2 +277 -0
  55. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/util.cpp.j2 +9 -10
  56. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/util.hpp.j2 +2 -3
  57. shacl2code-1.0.0/src/shacl2code/lang/templates/cpp/walk.hpp.j2 +74 -0
  58. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/golang/classes.go.j2 +17 -13
  59. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/decode.go.j2 +339 -0
  60. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/encode.go.j2 +75 -0
  61. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/errorhandler.go.j2 +13 -0
  62. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/errors.go.j2 +46 -0
  63. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/extensible.go.j2 +49 -0
  64. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/linkstate.go.j2 +14 -0
  65. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/listproperty.go.j2 +114 -0
  66. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/optional.go.j2 +36 -0
  67. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/path.go.j2 +32 -0
  68. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/property.go.j2 +101 -0
  69. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/ref.go.j2 +93 -0
  70. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/reflistproperty.go.j2 +60 -0
  71. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/refproperty.go.j2 +91 -0
  72. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/shaclobject.go.j2 +129 -0
  73. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/shaclobjectset.go.j2 +488 -0
  74. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/shacltype.go.j2 +213 -0
  75. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/util.go.j2 +28 -0
  76. shacl2code-1.0.0/src/shacl2code/lang/templates/golang/validator.go.j2 +107 -0
  77. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/jsonschema.j2 +31 -17
  78. shacl2code-1.0.0/src/shacl2code/lang/templates/python/__init__.py.j2 +8 -0
  79. shacl2code-1.0.0/src/shacl2code/lang/templates/python/__main__.py.j2 +12 -0
  80. shacl2code-1.0.0/src/shacl2code/lang/templates/python/cmd.py.j2 +75 -0
  81. shacl2code-0.0.24/src/shacl2code/lang/templates/python.j2 → shacl2code-1.0.0/src/shacl2code/lang/templates/python/model.py.j2 +1228 -750
  82. shacl2code-1.0.0/src/shacl2code/lang/templates/python/stub.pyi.j2 +230 -0
  83. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/main.py +8 -6
  84. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/model.py +9 -1
  85. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/urlcontext.py +5 -1
  86. shacl2code-1.0.0/src/shacl2code/version.py +1 -0
  87. {shacl2code-0.0.24 → shacl2code-1.0.0}/testfixtures/testfixtures/httpserver.py +1 -2
  88. {shacl2code-0.0.24 → shacl2code-1.0.0}/testfixtures/testfixtures/jsonvalidation.py +129 -2
  89. {shacl2code-0.0.24 → shacl2code-1.0.0}/testfixtures/testfixtures/timetests.py +2 -1
  90. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/conftest.py +4 -3
  91. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/model/test-context.json +11 -9
  92. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/roundtrip.json +27 -20
  93. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/test_common_jinja.py +0 -1
  94. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/test_common_prefix.py +3 -1
  95. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/test_context.py +3 -1
  96. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/test_cpp.py +207 -161
  97. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/test_golang.py +88 -56
  98. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/test_jsonschema.py +5 -2
  99. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/test_model_source.py +7 -4
  100. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/test_python.py +402 -64
  101. shacl2code-0.0.24/.flake8 +0 -4
  102. shacl2code-0.0.24/src/shacl2code/__init__.py +0 -4
  103. shacl2code-0.0.24/src/shacl2code/lang/__init__.py +0 -13
  104. shacl2code-0.0.24/src/shacl2code/lang/python.py +0 -54
  105. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/Makefile.j2 +0 -90
  106. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/datetime.cpp.j2 +0 -152
  107. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/datetime.hpp.j2 +0 -103
  108. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/decode.hpp.j2 +0 -297
  109. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/encode.cpp.j2 +0 -104
  110. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/encode.hpp.j2 +0 -340
  111. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/errorhandler.hpp.j2 +0 -139
  112. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/exceptions.hpp.j2 +0 -99
  113. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/extensible.cpp.j2 +0 -197
  114. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/extensible.hpp.j2 +0 -188
  115. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/link.hpp.j2 +0 -52
  116. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/namedindividual.cpp.j2 +0 -69
  117. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/namedindividual.hpp.j2 +0 -107
  118. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/object.cpp.j2 +0 -315
  119. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/object.hpp.j2 +0 -339
  120. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/objectpath.cpp.j2 +0 -104
  121. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/objectpath.hpp.j2 +0 -168
  122. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/objectset.cpp.j2 +0 -338
  123. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/objectset.hpp.j2 +0 -225
  124. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/property.cpp.j2 +0 -476
  125. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/property.hpp.j2 +0 -479
  126. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/propertyvalue.hpp.j2 +0 -1034
  127. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/ref.hpp.j2 +0 -429
  128. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/refproperty.hpp.j2 +0 -208
  129. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/type.cpp.j2 +0 -37
  130. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/type.hpp.j2 +0 -290
  131. shacl2code-0.0.24/src/shacl2code/lang/templates/cpp/walk.hpp.j2 +0 -84
  132. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/decode.go.j2 +0 -336
  133. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/encode.go.j2 +0 -75
  134. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/errorhandler.go.j2 +0 -14
  135. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/errors.go.j2 +0 -46
  136. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/extensible.go.j2 +0 -49
  137. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/linkstate.go.j2 +0 -15
  138. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/listproperty.go.j2 +0 -114
  139. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/optional.go.j2 +0 -36
  140. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/path.go.j2 +0 -32
  141. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/property.go.j2 +0 -101
  142. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/ref.go.j2 +0 -93
  143. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/reflistproperty.go.j2 +0 -62
  144. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/refproperty.go.j2 +0 -92
  145. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/shaclobject.go.j2 +0 -130
  146. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/shaclobjectset.go.j2 +0 -367
  147. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/shacltype.go.j2 +0 -180
  148. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/util.go.j2 +0 -29
  149. shacl2code-0.0.24/src/shacl2code/lang/templates/golang/validator.go.j2 +0 -110
  150. shacl2code-0.0.24/src/shacl2code/version.py +0 -1
  151. {shacl2code-0.0.24 → shacl2code-1.0.0}/.github/workflows/coverage-generate.yaml +0 -0
  152. {shacl2code-0.0.24 → shacl2code-1.0.0}/.github/workflows/coverage-report.yaml +0 -0
  153. {shacl2code-0.0.24 → shacl2code-1.0.0}/.github/workflows/publish.yaml +0 -0
  154. {shacl2code-0.0.24 → shacl2code-1.0.0}/.github/workflows/scorecard.yml +0 -0
  155. {shacl2code-0.0.24 → shacl2code-1.0.0}/LICENSE +0 -0
  156. {shacl2code-0.0.24 → shacl2code-1.0.0}/SECURITY.md +0 -0
  157. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/__main__.py +0 -0
  158. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/sources/cpp/json.hpp +0 -0
  159. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/api.hpp.j2 +0 -0
  160. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/header.j2 +0 -0
  161. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/pkgconfig.pc.j2 +0 -0
  162. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/source.j2 +0 -0
  163. {shacl2code-0.0.24 → shacl2code-1.0.0}/src/shacl2code/lang/templates/cpp/validate.j2 +0 -0
  164. {shacl2code-0.0.24 → shacl2code-1.0.0}/testfixtures/testfixtures/__init__.py +0 -0
  165. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/abort.j2 +0 -0
  166. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/bad-id.j2 +0 -0
  167. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/bad-node-kind.ttl +0 -0
  168. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/bad-pattern-class.ttl +0 -0
  169. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/bad-pattern-integer.ttl +0 -0
  170. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/bad-prop-type.ttl +0 -0
  171. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/bad-reference.jsonld +0 -0
  172. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/context-url.j2 +0 -0
  173. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/context.j2 +0 -0
  174. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/links.json +0 -0
  175. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/missing-range.ttl +0 -0
  176. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/model/test.ttl +0 -0
  177. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/python/bad-object-type-inline.json +0 -0
  178. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/python/bad-object-type-ref-after.json +0 -0
  179. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/python/bad-object-type-ref-before.json +0 -0
  180. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/data/raw.j2 +0 -0
  181. {shacl2code-0.0.24 → shacl2code-1.0.0}/tests/test_cli.py +1 -1
@@ -0,0 +1,8 @@
1
+ BasedOnStyle: LLVM
2
+
3
+ # Breaking string literals when combined with a column limit can result in some
4
+ # really terribly-formatted source where there are many lines in a row that each
5
+ # consist of string literals that only contain one or two characters each.
6
+ BreakStringLiterals: false
7
+
8
+ ColumnLimit: 100
@@ -0,0 +1,15 @@
1
+ [flake8]
2
+ # E501 line too long - Handled by black
3
+ # E203 whitespace before ':' - Handled by black
4
+ extend-ignore = E501,E203
5
+
6
+ # These execptions are made to keep stub compact / keep imported types info
7
+ # E301: Expected 2 blank lines, found 1
8
+ # E302: Expected 2 blank lines, found 0
9
+ # E305: Expected 2 blank lines after end of function or class
10
+ # E701: Multiple statements on one line (colon)
11
+ # F401: Module imported but unused
12
+ per-file-ignores =
13
+ *.pyi: E301,E302,E305,E701,F401
14
+
15
+ application-import-names = shacl2code,testfixtures
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
@@ -7,15 +7,14 @@ on:
7
7
 
8
8
  jobs:
9
9
  build:
10
- runs-on: ubuntu-latest
10
+ runs-on: ${{ matrix.os }}
11
11
  strategy:
12
12
  matrix:
13
- python-version:
14
- - "3.8"
15
- - "3.9"
16
- - "3.10"
17
- - "3.11"
18
- - "3.12"
13
+ os: [ubuntu-latest]
14
+ python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
15
+ include:
16
+ - os: macos-latest
17
+ python-version: "3.10"
19
18
  steps:
20
19
  - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
21
20
  - name: Setup Python ${{ matrix.python-version }}
@@ -31,7 +30,16 @@ jobs:
31
30
  python -m pip install --upgrade pip
32
31
  pip install build
33
32
  npm install -g jsonld-cli
33
+ - name: Install Linux packages
34
+ if: runner.os == 'Linux'
35
+ run: |
36
+ sudo apt update
34
37
  sudo apt install -y build-essential doxygen graphviz
38
+ - name: Install macOS packages
39
+ if: runner.os == 'macOS'
40
+ run: |
41
+ brew update
42
+ brew install doxygen gcc go graphviz
35
43
  - name: Build package
36
44
  run: |
37
45
  python -m build
@@ -49,5 +57,13 @@ jobs:
49
57
  uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
50
58
  with:
51
59
  python-version: "3.11"
52
- - uses: psf/black@8a737e727ac5ab2f1d4cf5876720ed276dc8dc4b # 25.1.0
60
+ - uses: psf/black@6305bf1ae645ab7541be4f5028a86239316178eb # 26.1.0
53
61
  - uses: py-actions/flake8@84ec6726560b6d5bd68f2a5bed83d62b52bb50ba # v2.3.0
62
+ - name: Install dependencies
63
+ run: |
64
+ python -m pip install --upgrade pip
65
+ pip install clang-format
66
+ - name: Check code formatting
67
+ run: |
68
+ ./scripts/format.sh
69
+ git diff --exit-code
@@ -153,9 +153,20 @@ dmypy.json
153
153
  # Cython debug symbols
154
154
  cython_debug/
155
155
 
156
+ # Ruff
157
+ .ruff_cache/
158
+
156
159
  # PyCharm
157
160
  # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
158
161
  # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
159
162
  # and can be added to the global gitignore or merged into this file. For a more nuclear
160
163
  # option (not recommended) you can uncomment the following to ignore the entire idea folder.
161
- #.idea/
164
+ .idea/
165
+
166
+ # VS Code
167
+ .vscode/
168
+
169
+ # macOS system files
170
+ .DS_Store
171
+ .DS_Store?
172
+ .Trashes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shacl2code
3
- Version: 0.0.24
3
+ Version: 1.0.0
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
@@ -16,15 +16,18 @@ Classifier: Programming Language :: Python :: 3.9
16
16
  Classifier: Programming Language :: Python :: 3.10
17
17
  Classifier: Programming Language :: Python :: 3.11
18
18
  Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
19
21
  Classifier: Topic :: Software Development :: Build Tools
20
22
  Requires-Python: >=3.8
21
23
  Requires-Dist: jinja2>=3.1.2
22
24
  Requires-Dist: rdflib>=7.0.0
23
25
  Provides-Extra: dev
26
+ Requires-Dist: flake8-import-order>=0.19.2; extra == 'dev'
24
27
  Requires-Dist: flake8>=7.0.0; extra == 'dev'
25
28
  Requires-Dist: jsonschema>=4.21.1; extra == 'dev'
26
29
  Requires-Dist: mypy>=1.14.1; extra == 'dev'
27
- Requires-Dist: pyrefly>=0.28.1; extra == 'dev'
30
+ Requires-Dist: pyrefly>=0.55.0; extra == 'dev'
28
31
  Requires-Dist: pyright>=1.1.403; extra == 'dev'
29
32
  Requires-Dist: pyshacl>=0.25.0; extra == 'dev'
30
33
  Requires-Dist: pytest-cov>=4.1; extra == 'dev'
@@ -52,19 +55,19 @@ python3 -m pip install shacl2code
52
55
  `shacl2code` can generate bindings from either a local file:
53
56
 
54
57
  ```shell
55
- shacl2code generate -i model.jsonld python -o out.py
58
+ shacl2code generate -i model.jsonld python -o out
56
59
  ```
57
60
 
58
61
  Or from a URL:
59
62
 
60
63
  ```shell
61
- shacl2code generate -i https://example.com/rdf/model.jsonld python -o out.py
64
+ shacl2code generate -i https://example.com/rdf/model.jsonld python -o out
62
65
  ```
63
66
 
64
67
  Or from stdin:
65
68
 
66
69
  ```shell
67
- cat model.jsonld | shacl2code generate -i - python -o - > out.py
70
+ cat model.jsonld | shacl2code generate -i - python -o out
68
71
  ```
69
72
 
70
73
  For more information, run:
@@ -19,19 +19,19 @@ python3 -m pip install shacl2code
19
19
  `shacl2code` can generate bindings from either a local file:
20
20
 
21
21
  ```shell
22
- shacl2code generate -i model.jsonld python -o out.py
22
+ shacl2code generate -i model.jsonld python -o out
23
23
  ```
24
24
 
25
25
  Or from a URL:
26
26
 
27
27
  ```shell
28
- shacl2code generate -i https://example.com/rdf/model.jsonld python -o out.py
28
+ shacl2code generate -i https://example.com/rdf/model.jsonld python -o out
29
29
  ```
30
30
 
31
31
  Or from stdin:
32
32
 
33
33
  ```shell
34
- cat model.jsonld | shacl2code generate -i - python -o - > out.py
34
+ cat model.jsonld | shacl2code generate -i - python -o out
35
35
  ```
36
36
 
37
37
  For more information, run:
@@ -21,15 +21,18 @@ classifiers = [
21
21
  "Programming Language :: Python :: 3.10",
22
22
  "Programming Language :: Python :: 3.11",
23
23
  "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Programming Language :: Python :: 3.14",
24
26
  ]
25
27
  license = "MIT"
26
28
 
27
29
  [project.optional-dependencies]
28
30
  dev = [
29
31
  "flake8 >= 7.0.0",
32
+ "flake8-import-order >= 0.19.2",
30
33
  "jsonschema >= 4.21.1",
31
34
  "mypy >= 1.14.1", # latest version for Python 3.8 is 1.14.x
32
- "pyrefly >= 0.28.1",
35
+ "pyrefly >= 0.55.0",
33
36
  "pyright >= 1.1.403",
34
37
  "pyshacl >= 0.25.0",
35
38
  "pytest >= 7.4",
@@ -56,12 +59,19 @@ addopts = [
56
59
  "--import-mode=importlib",
57
60
  "--cov=shacl2code",
58
61
  ]
62
+ # Suppress 3rd-party warnings to reduce log noise. Remove after libraries get updated.
63
+ filterwarnings = [
64
+ "ignore:.*ConjunctiveGraph is deprecated.*:DeprecationWarning", # From rdflib
65
+ "ignore:.*Dataset.default_context is deprecated.*:DeprecationWarning", # From rdflib, pyshacl
66
+ "ignore:.*Dataset.contexts is deprecated.*:DeprecationWarning", # From rdflib
67
+ ]
59
68
  pythonpath = [
60
69
  "testfixtures"
61
70
  ]
62
71
 
63
72
  [tool.coverage.run]
64
73
  relative_files = true
74
+ patch = ["subprocess"]
65
75
 
66
76
  [tool.black]
67
- include = '(\.pyi?$)|(python\.j2$)'
77
+ include = '(\.pyi?(\.j2)?$)|(main\.py\.j2$)'
@@ -0,0 +1,9 @@
1
+ #! /bin/sh
2
+
3
+ set -e
4
+
5
+ THIS_DIR=$(dirname "$0")
6
+ cd $THIS_DIR/..
7
+
8
+ clang-format -i $(git ls-files '*.cpp.j2' '*.cpp' '*.hpp.j2' '*.hpp', '*.h', '*.h.j2')
9
+ gofmt -w $(git ls-files '*.go.j2' '*.go')
@@ -0,0 +1,17 @@
1
+ # Copyright (c) 2024 Joshua Watt
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ from .main import main
6
+ from .model import Model, ModelException
7
+ from .urlcontext import ContextData, UrlContext
8
+ from .version import VERSION
9
+
10
+ __all__ = [
11
+ "VERSION",
12
+ "ContextData",
13
+ "Model",
14
+ "ModelException",
15
+ "UrlContext",
16
+ "main",
17
+ ]
@@ -13,7 +13,10 @@ def foreach_context(contexts):
13
13
 
14
14
 
15
15
  class Context(object):
16
- def __init__(self, contexts=[]):
16
+ def __init__(self, contexts=None):
17
+ if contexts is None:
18
+ contexts = [] # pragma: no cover
19
+
17
20
  self.contexts = [c for c in contexts if c]
18
21
  self.__vocabs = []
19
22
  self.__expanded_iris = {}
@@ -45,11 +48,11 @@ class Context(object):
45
48
  contexts = []
46
49
 
47
50
  for v in self.__vocabs:
48
- for name, value in foreach_context(self.contexts):
51
+ for _, value in foreach_context(self.contexts):
49
52
  if (
50
53
  isinstance(value, dict)
51
- and value["@type"] == "@vocab"
52
- and v == self.expand_iri(value["@id"])
54
+ and value.get("@type", "") == "@vocab"
55
+ and v == self.expand_iri(value.get("@id", ""))
53
56
  ):
54
57
  if "@context" in value:
55
58
  contexts.insert(0, value["@context"])
@@ -93,7 +96,7 @@ class Context(object):
93
96
  continue
94
97
 
95
98
  if isinstance(value, dict):
96
- value = value["@id"]
99
+ value = value.get("@id", "")
97
100
 
98
101
  if term == self.expand_iri(value):
99
102
  if exact and name not in possible:
@@ -248,7 +251,10 @@ class Context(object):
248
251
  continue
249
252
 
250
253
  if isinstance(value, dict):
251
- value = value["@id"]
254
+ value = value.get("@id", "")
255
+
256
+ if not value:
257
+ continue
252
258
 
253
259
  if term == name:
254
260
  if exact:
@@ -0,0 +1,21 @@
1
+ #
2
+ # Copyright (c) 2024 Joshua Watt
3
+ #
4
+ # SPDX-License-Identifier: MIT
5
+
6
+ # All renderers must be imported here to be registered
7
+ from .cpp import CppRender
8
+ from .golang import GoLangRender
9
+ from .jinja import JinjaRender
10
+ from .jsonschema import JsonSchemaRender
11
+ from .lang import LANGUAGES
12
+ from .python import PythonRender
13
+
14
+ __all__ = [
15
+ "LANGUAGES",
16
+ "CppRender",
17
+ "GoLangRender",
18
+ "JinjaRender",
19
+ "JsonSchemaRender",
20
+ "PythonRender",
21
+ ]
@@ -2,15 +2,20 @@
2
2
  # Copyright (c) 2024 Joshua Watt
3
3
  #
4
4
  # SPDX-License-Identifier: MIT
5
+ """Common code for language renderers"""
5
6
 
6
- import sys
7
7
  import os
8
- from pathlib import Path
8
+ import sys
9
9
  from contextlib import contextmanager
10
+ from pathlib import Path
11
+
10
12
  import jinja2
11
13
  from jinja2 import Environment, FileSystemLoader, TemplateRuntimeError
14
+
12
15
  from markupsafe import Markup
16
+
13
17
  from rdflib.namespace import SH
18
+
14
19
  from ..model import SHACL2CODE
15
20
  from ..version import VERSION
16
21
 
@@ -40,14 +45,19 @@ class JinjaTemplateRender(object):
40
45
  def __init__(self, args):
41
46
  self.spdx_license = args.license
42
47
 
43
- def get_additional_render_args(self):
48
+ def get_additional_render_args(self, model):
44
49
  return {}
45
50
 
46
51
  def get_extra_env(self):
47
52
  return {}
48
53
 
49
- def render(self, template, output, *, extra_env={}, render_args={}):
50
- def abort_helper(msg):
54
+ def render(self, template, output, *, extra_env=None, render_args=None):
55
+ if extra_env is None:
56
+ extra_env = {} # pragma: no cover
57
+ if render_args is None:
58
+ render_args = {} # pragma: no cover
59
+
60
+ def abort_helper(msg: str):
51
61
  raise TemplateRuntimeError(msg)
52
62
 
53
63
  env = Environment(loader=FileSystemLoader([template.parent, THIS_DIR.parent]))
@@ -60,7 +70,7 @@ class JinjaTemplateRender(object):
60
70
  template = env.get_template(template.name)
61
71
 
62
72
  render = template.render(
63
- disclaimer=f"This file was automatically generated by {os.path.basename(sys.argv[0])}. DO NOT MANUALLY MODIFY IT",
73
+ disclaimer=f"This file was auto-generated by {os.path.basename(sys.argv[0])} {VERSION}. DO NOT MANUALLY MODIFY IT",
64
74
  spdx_license=self.spdx_license,
65
75
  **render_args,
66
76
  )
@@ -121,7 +131,7 @@ class JinjaTemplateRender(object):
121
131
  "abstract_classes": abstract_classes,
122
132
  "enums": enums,
123
133
  "context": model.context,
124
- **self.get_additional_render_args(),
134
+ **self.get_additional_render_args(model),
125
135
  }
126
136
 
127
137
  env = {
@@ -2,15 +2,16 @@
2
2
  # Copyright (c) 2024 Joshua Watt
3
3
  #
4
4
  # SPDX-License-Identifier: MIT
5
-
6
- from .common import JinjaTemplateRender
7
- from .lang import language, TEMPLATE_DIR
8
- from ..version import VERSION
5
+ """C++ language binding renderer"""
9
6
 
10
7
  import re
11
8
  import textwrap
12
9
  from pathlib import Path
13
10
 
11
+ from .common import JinjaTemplateRender
12
+ from .lang import TEMPLATE_DIR, language
13
+ from ..version import VERSION
14
+
14
15
 
15
16
  def varname(*name):
16
17
  name = "_".join(name)
@@ -144,14 +145,10 @@ class CppRender(JinjaTemplateRender):
144
145
  for s in self.HEADERS:
145
146
  guard = f"_{self.macro_prefix}_{id_str(s).upper()}"
146
147
  yield self.basename.parent / s, t / (s + ".j2"), {
147
- "guard_begin": comment_wrap(
148
- textwrap.dedent(
149
- f"""\
148
+ "guard_begin": comment_wrap(textwrap.dedent(f"""\
150
149
  #ifndef {guard}
151
150
  #define {guard}
152
- """
153
- )
154
- ),
151
+ """)),
155
152
  "guard_end": comment_wrap(f"#endif // {guard}"),
156
153
  }
157
154
 
@@ -188,33 +185,25 @@ class CppRender(JinjaTemplateRender):
188
185
  "prop_is_list": prop_is_list,
189
186
  "parent_cpp_classes": parent_cpp_classes,
190
187
  "macro_prefix": self.macro_prefix,
191
- "api_def_begin": comment_wrap(
192
- textwrap.dedent(
193
- f"""\
188
+ "api_def_begin": comment_wrap(textwrap.dedent(f"""\
194
189
  #ifndef DOXYGEN_SKIP
195
190
  #include "api.hpp"
196
191
  // These are so that we don't have to use Jinja templates below since that messes up the formatting
197
192
  #define EXPORT {self.macro_prefix}_API
198
193
  #define LOCAL {self.macro_prefix}_LOCAL
199
194
  #endif // DOXYGEN_SKIP
200
- """
201
- )
202
- ),
203
- "api_def_end": comment_wrap(
204
- textwrap.dedent(
205
- """\
195
+ """)),
196
+ "api_def_end": comment_wrap(textwrap.dedent("""\
206
197
  #undef EXPORT
207
198
  #undef LOCAL
208
- """
209
- )
210
- ),
199
+ """)),
211
200
  "ns_begin": comment_wrap(
212
201
  "\n".join(f"namespace {n} {{" for n in self.namespace.split("::"))
213
202
  ),
214
203
  "ns_end": comment_wrap("\n".join("}" for n in self.namespace.split("::"))),
215
204
  }
216
205
 
217
- def get_additional_render_args(self):
206
+ def get_additional_render_args(self, model):
218
207
  return {
219
208
  "basename": self.basename.name,
220
209
  "namespace": self.namespace,
@@ -2,13 +2,14 @@
2
2
  # Copyright (c) 2024 Joshua Watt
3
3
  #
4
4
  # SPDX-License-Identifier: MIT
5
+ """Go schema renderer"""
5
6
 
6
- from .common import JinjaTemplateRender
7
- from .lang import language, TEMPLATE_DIR
8
-
7
+ import re
8
+ import textwrap
9
9
  from pathlib import Path
10
10
 
11
- import re
11
+ from .common import JinjaTemplateRender
12
+ from .lang import TEMPLATE_DIR, language
12
13
 
13
14
  GO_KEYWORDS = (
14
15
  "break",
@@ -158,9 +159,9 @@ def prop_decode_func(cls, prop, classes):
158
159
  raise Exception("Unknown data type " + prop.datatype) # pragma: no cover
159
160
 
160
161
  if prop_is_list(prop):
161
- return f"DecodeList[{prop_go_type(prop, classes)}](value, path, {prop_ctx_name(cls, prop)}, {func}, obj.{varname(prop.varname)}())"
162
+ return f"DecodeList[{prop_go_type(prop, classes)}](value, path, {prop_ctx_name(cls, prop)}, {func}, obj.{varname(prop.varname)}(), state)"
162
163
 
163
- return f"{func}(value, path, {prop_ctx_name(cls, prop)}, obj.{varname(prop.varname)}())"
164
+ return f"{func}(value, path, {prop_ctx_name(cls, prop)}, obj.{varname(prop.varname)}(), state)"
164
165
 
165
166
 
166
167
  def prop_encode_func(cls, prop, classes):
@@ -236,7 +237,14 @@ class GoLangRender(JinjaTemplateRender):
236
237
  super().__init__(args)
237
238
  self.__output = args.output
238
239
  self.__render_args = {
239
- "package": args.package,
240
+ # This variable adds as many lines are get commented out in jinja,
241
+ # to keep the line numbers in the generated code the same as the
242
+ # template
243
+ "go_package": textwrap.dedent(f"""
244
+ */
245
+
246
+ package {args.package}
247
+ /*"""),
240
248
  }
241
249
 
242
250
  @classmethod
@@ -275,5 +283,5 @@ class GoLangRender(JinjaTemplateRender):
275
283
  "prop_encode_func": prop_encode_func,
276
284
  }
277
285
 
278
- def get_additional_render_args(self):
286
+ def get_additional_render_args(self, model):
279
287
  return self.__render_args
@@ -2,6 +2,7 @@
2
2
  # Copyright (c) 2024 Joshua Watt
3
3
  #
4
4
  # SPDX-License-Identifier: MIT
5
+ """Jinja template renderer (for testing)"""
5
6
 
6
7
  from pathlib import Path
7
8
 
@@ -2,12 +2,13 @@
2
2
  # Copyright (c) 2024 Joshua Watt
3
3
  #
4
4
  # SPDX-License-Identifier: MIT
5
+ """JSON Schema renderer"""
5
6
 
6
- from .common import BasicJinjaRender
7
- from .lang import language, TEMPLATE_DIR
8
-
9
- import re
10
7
  import keyword
8
+ import re
9
+
10
+ from .common import BasicJinjaRender
11
+ from .lang import TEMPLATE_DIR, language
11
12
 
12
13
 
13
14
  def varname(*name):
@@ -47,5 +48,5 @@ class JsonSchemaRender(BasicJinjaRender):
47
48
  "varname": varname,
48
49
  }
49
50
 
50
- def get_additional_render_args(self):
51
+ def get_additional_render_args(self, model):
51
52
  return self.__render_args
@@ -2,6 +2,7 @@
2
2
  # Copyright (c) 2024 Joshua Watt
3
3
  #
4
4
  # SPDX-License-Identifier: MIT
5
+ """Language renderers"""
5
6
 
6
7
  from pathlib import Path
7
8
 
@@ -0,0 +1,114 @@
1
+ # Copyright (c) 2024 Joshua Watt
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ """Python language binding renderer"""
5
+
6
+ import keyword
7
+ import re
8
+ from pathlib import Path
9
+
10
+ from .common import JinjaTemplateRender
11
+ from .lang import TEMPLATE_DIR, language
12
+
13
+ DATATYPE_CLASSES = {
14
+ "http://www.w3.org/2001/XMLSchema#string": "StringProp",
15
+ "http://www.w3.org/2001/XMLSchema#anyURI": "AnyURIProp",
16
+ "http://www.w3.org/2001/XMLSchema#integer": "IntegerProp",
17
+ "http://www.w3.org/2001/XMLSchema#positiveInteger": "PositiveIntegerProp",
18
+ "http://www.w3.org/2001/XMLSchema#nonNegativeInteger": "NonNegativeIntegerProp",
19
+ "http://www.w3.org/2001/XMLSchema#boolean": "BooleanProp",
20
+ "http://www.w3.org/2001/XMLSchema#decimal": "FloatProp",
21
+ "http://www.w3.org/2001/XMLSchema#dateTime": "DateTimeProp",
22
+ "http://www.w3.org/2001/XMLSchema#dateTimeStamp": "DateTimeStampProp",
23
+ }
24
+
25
+ DATATYPE_PYTHON_TYPES = {
26
+ "http://www.w3.org/2001/XMLSchema#string": "str",
27
+ "http://www.w3.org/2001/XMLSchema#anyURI": "str",
28
+ "http://www.w3.org/2001/XMLSchema#integer": "int",
29
+ "http://www.w3.org/2001/XMLSchema#positiveInteger": "int",
30
+ "http://www.w3.org/2001/XMLSchema#nonNegativeInteger": "int",
31
+ "http://www.w3.org/2001/XMLSchema#boolean": "bool",
32
+ "http://www.w3.org/2001/XMLSchema#decimal": "float",
33
+ "http://www.w3.org/2001/XMLSchema#dateTime": "datetime",
34
+ "http://www.w3.org/2001/XMLSchema#dateTimeStamp": "datetime",
35
+ }
36
+
37
+
38
+ def varname(*name):
39
+ """Make a valid Python variable name."""
40
+ name = "_".join(name)
41
+ # Any invalid characters at the beginning of the name are removed (except "@")
42
+ name = re.sub(r"^[^a-zA-Z0-9_@]*", "", name)
43
+ # Any other invalid characters are replaced with "_" (including "@")
44
+ name = re.sub(r"[^a-zA-Z0-9_]", "_", name)
45
+ # Consolidate runs of "_" to a single one
46
+ name = re.sub(r"__+", "_", name)
47
+ # Add a _ to anything that is a python keyword
48
+ while keyword.iskeyword(name):
49
+ name = name + "_"
50
+ return name
51
+
52
+
53
+ @language("python")
54
+ class PythonRender(JinjaTemplateRender):
55
+ """Render Python Language Bindings."""
56
+
57
+ HELP = "Python Language Bindings"
58
+
59
+ FILES = (
60
+ "__init__.py",
61
+ "__main__.py",
62
+ "cmd.py",
63
+ "model.py",
64
+ "stub.pyi",
65
+ )
66
+
67
+ def __init__(self, args):
68
+ super().__init__(args)
69
+ self.__output = args.output
70
+ self.__use_slots = args.use_slots
71
+
72
+ @classmethod
73
+ def get_arguments(cls, parser):
74
+ parser.add_argument(
75
+ "--output",
76
+ "-o",
77
+ type=Path,
78
+ help="Output directory",
79
+ required=True,
80
+ )
81
+ parser.add_argument(
82
+ "--use-slots",
83
+ choices=("auto", "yes", "no"),
84
+ default="auto",
85
+ help=(
86
+ "Use __slot__ to reduce memory usage. "
87
+ "Slots prevents multiple inheritance. Default is %(default)s"
88
+ ),
89
+ )
90
+
91
+ def get_outputs(self):
92
+ t = TEMPLATE_DIR / "python"
93
+ self.__output.mkdir(parents=True, exist_ok=True)
94
+
95
+ for s in self.FILES:
96
+ yield self.__output / s, t / (s + ".j2"), {}
97
+
98
+ def get_extra_env(self):
99
+ return {
100
+ "varname": varname,
101
+ "DATATYPE_CLASSES": DATATYPE_CLASSES,
102
+ "DATATYPE_PYTHON_TYPES": DATATYPE_PYTHON_TYPES,
103
+ }
104
+
105
+ def get_additional_render_args(self, model):
106
+ if self.__use_slots == "auto":
107
+ use_slots = all(len(cls.parent_ids) <= 1 for cls in model.classes)
108
+ elif self.__use_slots == "yes":
109
+ use_slots = True
110
+ else:
111
+ use_slots = False
112
+ return {
113
+ "use_slots": use_slots,
114
+ }