shacl2code 0.0.25__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 (182) hide show
  1. shacl2code-1.0.1/.clang-format +8 -0
  2. shacl2code-1.0.1/.flake8 +15 -0
  3. {shacl2code-0.0.25 → shacl2code-1.0.1}/.github/workflows/test.yaml +9 -1
  4. {shacl2code-0.0.25 → shacl2code-1.0.1}/.gitignore +7 -1
  5. {shacl2code-0.0.25 → shacl2code-1.0.1}/PKG-INFO +8 -6
  6. {shacl2code-0.0.25 → shacl2code-1.0.1}/README.md +3 -3
  7. {shacl2code-0.0.25 → shacl2code-1.0.1}/pyproject.toml +21 -3
  8. shacl2code-1.0.1/scripts/format.sh +9 -0
  9. shacl2code-1.0.1/src/shacl2code/__init__.py +17 -0
  10. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/context.py +4 -1
  11. shacl2code-1.0.1/src/shacl2code/lang/__init__.py +21 -0
  12. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/common.py +17 -7
  13. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/cpp.py +12 -23
  14. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/golang.py +16 -8
  15. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/jinja.py +1 -0
  16. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/jsonschema.py +6 -5
  17. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/lang.py +1 -0
  18. shacl2code-1.0.1/src/shacl2code/lang/python.py +139 -0
  19. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/datetime.cpp.j2 +149 -0
  20. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/datetime.hpp.j2 +101 -0
  21. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/decode.cpp.j2 +20 -6
  22. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/decode.hpp.j2 +321 -0
  23. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/encode.cpp.j2 +113 -0
  24. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/encode.hpp.j2 +384 -0
  25. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/errorhandler.cpp.j2 +8 -10
  26. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/errorhandler.hpp.j2 +133 -0
  27. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/exceptions.hpp.j2 +96 -0
  28. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/extensible.cpp.j2 +187 -0
  29. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/extensible.hpp.j2 +178 -0
  30. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/jsonld-header.j2 +12 -4
  31. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/jsonld-source.j2 +90 -59
  32. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/link.cpp.j2 +4 -6
  33. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/link.hpp.j2 +51 -0
  34. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/namedindividual.cpp.j2 +67 -0
  35. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/namedindividual.hpp.j2 +102 -0
  36. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/object.cpp.j2 +304 -0
  37. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/object.hpp.j2 +324 -0
  38. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/objectpath.cpp.j2 +100 -0
  39. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/objectpath.hpp.j2 +164 -0
  40. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/objectset.cpp.j2 +362 -0
  41. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/objectset.hpp.j2 +264 -0
  42. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/prop.hpp.j2 +3 -6
  43. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/property.cpp.j2 +426 -0
  44. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/property.hpp.j2 +460 -0
  45. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/propertyvalue.cpp.j2 +15 -19
  46. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/propertyvalue.hpp.j2 +996 -0
  47. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/ref.hpp.j2 +407 -0
  48. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/refproperty.cpp.j2 +8 -9
  49. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/refproperty.hpp.j2 +203 -0
  50. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/type.cpp.j2 +33 -0
  51. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/type.hpp.j2 +277 -0
  52. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/util.cpp.j2 +9 -10
  53. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/util.hpp.j2 +2 -3
  54. shacl2code-1.0.1/src/shacl2code/lang/templates/cpp/walk.hpp.j2 +74 -0
  55. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/golang/classes.go.j2 +17 -13
  56. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/decode.go.j2 +339 -0
  57. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/encode.go.j2 +75 -0
  58. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/errorhandler.go.j2 +13 -0
  59. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/errors.go.j2 +46 -0
  60. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/extensible.go.j2 +49 -0
  61. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/linkstate.go.j2 +14 -0
  62. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/listproperty.go.j2 +114 -0
  63. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/optional.go.j2 +36 -0
  64. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/path.go.j2 +32 -0
  65. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/property.go.j2 +101 -0
  66. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/ref.go.j2 +93 -0
  67. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/reflistproperty.go.j2 +60 -0
  68. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/refproperty.go.j2 +91 -0
  69. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/shaclobject.go.j2 +129 -0
  70. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/shaclobjectset.go.j2 +488 -0
  71. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/shacltype.go.j2 +213 -0
  72. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/util.go.j2 +28 -0
  73. shacl2code-1.0.1/src/shacl2code/lang/templates/golang/validator.go.j2 +107 -0
  74. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/jsonschema.j2 +31 -17
  75. shacl2code-1.0.1/src/shacl2code/lang/templates/python/__init__.py.j2 +15 -0
  76. shacl2code-1.0.1/src/shacl2code/lang/templates/python/__main__.py.j2 +12 -0
  77. shacl2code-1.0.1/src/shacl2code/lang/templates/python/cmd.py.j2 +75 -0
  78. shacl2code-0.0.25/src/shacl2code/lang/templates/python.j2 → shacl2code-1.0.1/src/shacl2code/lang/templates/python/model.py.j2 +1255 -764
  79. shacl2code-1.0.1/src/shacl2code/lang/templates/python/model.pyi.j2 +441 -0
  80. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/main.py +8 -6
  81. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/model.py +18 -10
  82. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/urlcontext.py +5 -1
  83. shacl2code-1.0.1/src/shacl2code/util.py +31 -0
  84. shacl2code-1.0.1/src/shacl2code/version.py +1 -0
  85. {shacl2code-0.0.25 → shacl2code-1.0.1}/testfixtures/testfixtures/httpserver.py +1 -2
  86. {shacl2code-0.0.25 → shacl2code-1.0.1}/testfixtures/testfixtures/jsonvalidation.py +129 -2
  87. {shacl2code-0.0.25 → shacl2code-1.0.1}/testfixtures/testfixtures/timetests.py +2 -1
  88. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/conftest.py +4 -3
  89. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/model/test-context.json +3 -0
  90. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/roundtrip.json +27 -20
  91. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/test_common_jinja.py +0 -1
  92. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/test_common_prefix.py +3 -1
  93. shacl2code-1.0.1/tests/test_convert_version_string.py +33 -0
  94. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/test_cpp.py +123 -132
  95. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/test_golang.py +88 -56
  96. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/test_jsonschema.py +5 -2
  97. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/test_model_source.py +5 -3
  98. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/test_python.py +529 -78
  99. shacl2code-0.0.25/.flake8 +0 -4
  100. shacl2code-0.0.25/src/shacl2code/__init__.py +0 -4
  101. shacl2code-0.0.25/src/shacl2code/lang/__init__.py +0 -13
  102. shacl2code-0.0.25/src/shacl2code/lang/python.py +0 -54
  103. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/datetime.cpp.j2 +0 -152
  104. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/datetime.hpp.j2 +0 -103
  105. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/decode.hpp.j2 +0 -297
  106. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/encode.cpp.j2 +0 -104
  107. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/encode.hpp.j2 +0 -341
  108. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/errorhandler.hpp.j2 +0 -139
  109. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/exceptions.hpp.j2 +0 -99
  110. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/extensible.cpp.j2 +0 -197
  111. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/extensible.hpp.j2 +0 -188
  112. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/link.hpp.j2 +0 -52
  113. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/namedindividual.cpp.j2 +0 -69
  114. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/namedindividual.hpp.j2 +0 -107
  115. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/object.cpp.j2 +0 -315
  116. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/object.hpp.j2 +0 -339
  117. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/objectpath.cpp.j2 +0 -104
  118. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/objectpath.hpp.j2 +0 -168
  119. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/objectset.cpp.j2 +0 -338
  120. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/objectset.hpp.j2 +0 -225
  121. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/property.cpp.j2 +0 -476
  122. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/property.hpp.j2 +0 -479
  123. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/propertyvalue.hpp.j2 +0 -1034
  124. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/ref.hpp.j2 +0 -429
  125. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/refproperty.hpp.j2 +0 -208
  126. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/type.cpp.j2 +0 -37
  127. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/type.hpp.j2 +0 -290
  128. shacl2code-0.0.25/src/shacl2code/lang/templates/cpp/walk.hpp.j2 +0 -84
  129. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/decode.go.j2 +0 -336
  130. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/encode.go.j2 +0 -75
  131. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/errorhandler.go.j2 +0 -14
  132. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/errors.go.j2 +0 -46
  133. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/extensible.go.j2 +0 -49
  134. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/linkstate.go.j2 +0 -15
  135. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/listproperty.go.j2 +0 -114
  136. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/optional.go.j2 +0 -36
  137. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/path.go.j2 +0 -32
  138. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/property.go.j2 +0 -101
  139. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/ref.go.j2 +0 -93
  140. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/reflistproperty.go.j2 +0 -62
  141. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/refproperty.go.j2 +0 -92
  142. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/shaclobject.go.j2 +0 -130
  143. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/shaclobjectset.go.j2 +0 -367
  144. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/shacltype.go.j2 +0 -180
  145. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/util.go.j2 +0 -29
  146. shacl2code-0.0.25/src/shacl2code/lang/templates/golang/validator.go.j2 +0 -110
  147. shacl2code-0.0.25/src/shacl2code/version.py +0 -1
  148. {shacl2code-0.0.25 → shacl2code-1.0.1}/.github/dependabot.yml +0 -0
  149. {shacl2code-0.0.25 → shacl2code-1.0.1}/.github/workflows/coverage-generate.yaml +0 -0
  150. {shacl2code-0.0.25 → shacl2code-1.0.1}/.github/workflows/coverage-report.yaml +0 -0
  151. {shacl2code-0.0.25 → shacl2code-1.0.1}/.github/workflows/publish.yaml +0 -0
  152. {shacl2code-0.0.25 → shacl2code-1.0.1}/.github/workflows/scorecard.yml +0 -0
  153. {shacl2code-0.0.25 → shacl2code-1.0.1}/LICENSE +0 -0
  154. {shacl2code-0.0.25 → shacl2code-1.0.1}/SECURITY.md +0 -0
  155. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/__main__.py +0 -0
  156. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/sources/cpp/json.hpp +0 -0
  157. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/Doxyfile.j2 +0 -0
  158. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/Makefile.j2 +0 -0
  159. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/api.hpp.j2 +0 -0
  160. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/header.j2 +0 -0
  161. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/pkgconfig.pc.j2 +0 -0
  162. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/source.j2 +0 -0
  163. {shacl2code-0.0.25 → shacl2code-1.0.1}/src/shacl2code/lang/templates/cpp/validate.j2 +0 -0
  164. {shacl2code-0.0.25 → shacl2code-1.0.1}/testfixtures/testfixtures/__init__.py +0 -0
  165. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/abort.j2 +0 -0
  166. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/bad-id.j2 +0 -0
  167. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/bad-node-kind.ttl +0 -0
  168. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/bad-pattern-class.ttl +0 -0
  169. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/bad-pattern-integer.ttl +0 -0
  170. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/bad-prop-type.ttl +0 -0
  171. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/bad-reference.jsonld +0 -0
  172. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/context-url.j2 +0 -0
  173. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/context.j2 +0 -0
  174. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/links.json +0 -0
  175. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/missing-range.ttl +0 -0
  176. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/model/test.ttl +0 -0
  177. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/python/bad-object-type-inline.json +0 -0
  178. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/python/bad-object-type-ref-after.json +0 -0
  179. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/python/bad-object-type-ref-before.json +0 -0
  180. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/data/raw.j2 +0 -0
  181. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/test_cli.py +1 -1
  182. {shacl2code-0.0.25 → shacl2code-1.0.1}/tests/test_context.py +0 -0
@@ -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
@@ -57,5 +57,13 @@ jobs:
57
57
  uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
58
58
  with:
59
59
  python-version: "3.11"
60
- - uses: psf/black@8a737e727ac5ab2f1d4cf5876720ed276dc8dc4b # 25.1.0
60
+ - uses: psf/black@6305bf1ae645ab7541be4f5028a86239316178eb # 26.1.0
61
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,12 +153,18 @@ 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/
162
168
 
163
169
  # macOS system files
164
170
  .DS_Store
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shacl2code
3
- Version: 0.0.25
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
@@ -23,14 +23,16 @@ Requires-Python: >=3.8
23
23
  Requires-Dist: jinja2>=3.1.2
24
24
  Requires-Dist: rdflib>=7.0.0
25
25
  Provides-Extra: dev
26
+ Requires-Dist: flake8-import-order>=0.19.2; extra == 'dev'
26
27
  Requires-Dist: flake8>=7.0.0; extra == 'dev'
27
- Requires-Dist: jsonschema>=4.21.1; extra == 'dev'
28
+ Requires-Dist: jsonschema>=4.23.0; extra == 'dev'
28
29
  Requires-Dist: mypy>=1.14.1; extra == 'dev'
29
- Requires-Dist: pyrefly>=0.28.1; extra == 'dev'
30
+ Requires-Dist: pyrefly>=0.55.0; extra == 'dev'
30
31
  Requires-Dist: pyright>=1.1.403; extra == 'dev'
31
32
  Requires-Dist: pyshacl>=0.25.0; extra == 'dev'
32
33
  Requires-Dist: pytest-cov>=4.1; extra == 'dev'
33
34
  Requires-Dist: pytest>=7.4; extra == 'dev'
35
+ Requires-Dist: types-jsonschema>=4.23.0; extra == 'dev'
34
36
  Description-Content-Type: text/markdown
35
37
 
36
38
  # Convert SHACL Model to code bindings
@@ -54,19 +56,19 @@ python3 -m pip install shacl2code
54
56
  `shacl2code` can generate bindings from either a local file:
55
57
 
56
58
  ```shell
57
- shacl2code generate -i model.jsonld python -o out.py
59
+ shacl2code generate -i model.jsonld python -o out
58
60
  ```
59
61
 
60
62
  Or from a URL:
61
63
 
62
64
  ```shell
63
- shacl2code generate -i https://example.com/rdf/model.jsonld python -o out.py
65
+ shacl2code generate -i https://example.com/rdf/model.jsonld python -o out
64
66
  ```
65
67
 
66
68
  Or from stdin:
67
69
 
68
70
  ```shell
69
- cat model.jsonld | shacl2code generate -i - python -o - > out.py
71
+ cat model.jsonld | shacl2code generate -i - python -o out
70
72
  ```
71
73
 
72
74
  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:
@@ -29,13 +29,15 @@ license = "MIT"
29
29
  [project.optional-dependencies]
30
30
  dev = [
31
31
  "flake8 >= 7.0.0",
32
- "jsonschema >= 4.21.1",
32
+ "flake8-import-order >= 0.19.2",
33
+ "jsonschema >= 4.23.0", # latest version for Python 3.8 is 4.23.x
33
34
  "mypy >= 1.14.1", # latest version for Python 3.8 is 1.14.x
34
- "pyrefly >= 0.28.1",
35
+ "pyrefly >= 0.55.0",
35
36
  "pyright >= 1.1.403",
36
37
  "pyshacl >= 0.25.0",
37
38
  "pytest >= 7.4",
38
39
  "pytest-cov >= 4.1",
40
+ "types-jsonschema >= 4.23.0",
39
41
  ]
40
42
 
41
43
  [project.urls]
@@ -53,6 +55,22 @@ build-backend = "hatchling.build"
53
55
  [tool.hatch.version]
54
56
  path = "src/shacl2code/version.py"
55
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
+
56
74
  [tool.pytest.ini_options]
57
75
  addopts = [
58
76
  "--import-mode=importlib",
@@ -73,4 +91,4 @@ relative_files = true
73
91
  patch = ["subprocess"]
74
92
 
75
93
  [tool.black]
76
- include = '(\.pyi?$)|(python\.j2$)'
94
+ 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 = {}
@@ -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) -> None:
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,139 @@
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
+ from ..util import convert_version_string
13
+
14
+ DATATYPE_CLASSES = {
15
+ "http://www.w3.org/2001/XMLSchema#string": "StringProp",
16
+ "http://www.w3.org/2001/XMLSchema#anyURI": "AnyURIProp",
17
+ "http://www.w3.org/2001/XMLSchema#integer": "IntegerProp",
18
+ "http://www.w3.org/2001/XMLSchema#positiveInteger": "PositiveIntegerProp",
19
+ "http://www.w3.org/2001/XMLSchema#nonNegativeInteger": "NonNegativeIntegerProp",
20
+ "http://www.w3.org/2001/XMLSchema#boolean": "BooleanProp",
21
+ "http://www.w3.org/2001/XMLSchema#decimal": "FloatProp",
22
+ "http://www.w3.org/2001/XMLSchema#dateTime": "DateTimeProp",
23
+ "http://www.w3.org/2001/XMLSchema#dateTimeStamp": "DateTimeStampProp",
24
+ }
25
+
26
+ DATATYPE_PYTHON_TYPES = {
27
+ "http://www.w3.org/2001/XMLSchema#string": "str",
28
+ "http://www.w3.org/2001/XMLSchema#anyURI": "str",
29
+ "http://www.w3.org/2001/XMLSchema#integer": "int",
30
+ "http://www.w3.org/2001/XMLSchema#positiveInteger": "int",
31
+ "http://www.w3.org/2001/XMLSchema#nonNegativeInteger": "int",
32
+ "http://www.w3.org/2001/XMLSchema#boolean": "bool",
33
+ "http://www.w3.org/2001/XMLSchema#decimal": "float",
34
+ "http://www.w3.org/2001/XMLSchema#dateTime": "datetime",
35
+ "http://www.w3.org/2001/XMLSchema#dateTimeStamp": "datetime",
36
+ }
37
+
38
+
39
+ def varname(*name):
40
+ """Make a valid Python variable name."""
41
+ name = "_".join(name)
42
+ # Any invalid characters at the beginning of the name are removed (except "@")
43
+ name = re.sub(r"^[^a-zA-Z0-9_@]*", "", name)
44
+ # Any other invalid characters are replaced with "_" (including "@")
45
+ name = re.sub(r"[^a-zA-Z0-9_]", "_", name)
46
+ # Consolidate runs of "_" to a single one
47
+ name = re.sub(r"__+", "_", name)
48
+ # Add a _ to anything that is a python keyword
49
+ while keyword.iskeyword(name):
50
+ name = name + "_"
51
+ return name
52
+
53
+
54
+ @language("python")
55
+ class PythonRender(JinjaTemplateRender):
56
+ """Render Python Language Bindings."""
57
+
58
+ HELP = "Python Language Bindings"
59
+
60
+ FILES = (
61
+ "__init__.py",
62
+ "model.py",
63
+ "model.pyi",
64
+ )
65
+
66
+ def __init__(self, args):
67
+ super().__init__(args)
68
+ self.__output = args.output
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 = ""
76
+
77
+ @classmethod
78
+ def get_arguments(cls, parser):
79
+ parser.add_argument(
80
+ "--output",
81
+ "-o",
82
+ type=Path,
83
+ help="Output directory",
84
+ required=True,
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
+ )
92
+ parser.add_argument(
93
+ "--use-slots",
94
+ choices=("auto", "yes", "no"),
95
+ default="auto",
96
+ help=(
97
+ "Use __slot__ to reduce memory usage. "
98
+ "Slots prevents multiple inheritance. Default is %(default)s"
99
+ ),
100
+ )
101
+ parser.add_argument(
102
+ "--version",
103
+ help="Specify model version",
104
+ )
105
+
106
+ def get_outputs(self):
107
+ t = TEMPLATE_DIR / "python"
108
+ self.__output.mkdir(parents=True, exist_ok=True)
109
+
110
+ def get_file(name):
111
+ return self.__output / name, t / (name + ".j2"), {}
112
+
113
+ for s in self.FILES:
114
+ yield get_file(s)
115
+
116
+ if self.__include_main:
117
+ yield get_file("cmd.py")
118
+ yield get_file("__main__.py")
119
+
120
+ def get_extra_env(self):
121
+ return {
122
+ "varname": varname,
123
+ "DATATYPE_CLASSES": DATATYPE_CLASSES,
124
+ "DATATYPE_PYTHON_TYPES": DATATYPE_PYTHON_TYPES,
125
+ }
126
+
127
+ def get_additional_render_args(self, model):
128
+ if self.__use_slots == "auto":
129
+ use_slots = all(len(cls.parent_ids) <= 1 for cls in model.classes)
130
+ elif self.__use_slots == "yes":
131
+ use_slots = True
132
+ else:
133
+ use_slots = False
134
+ return {
135
+ "use_slots": use_slots,
136
+ "include_main": self.__include_main,
137
+ "version_str": self.__version_str,
138
+ "version": self.__version,
139
+ }