sysmlpy 0.12.2__tar.gz → 0.16.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 (146) hide show
  1. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/PKG-INFO +96 -2
  2. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/README.md +93 -1
  3. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/pyproject.toml +4 -2
  4. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/__init__.py +7 -3
  5. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr_visitor.py +137 -20
  6. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/definition.py +335 -3
  7. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/classes.py +49 -17
  8. sysmlpy-0.16.0/src/sysmlpy/plantuml.py +706 -0
  9. sysmlpy-0.16.0/src/sysmlpy/store.py +2112 -0
  10. sysmlpy-0.16.0/src/sysmlpy/us_customary_units.txt +36 -0
  11. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/usage.py +604 -6
  12. sysmlpy-0.16.0/src/sysmlpy/validator.py +606 -0
  13. sysmlpy-0.12.2/src/sysmlpy/store.py +0 -547
  14. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/LICENSE +0 -0
  15. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/__main__.py +0 -0
  16. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr/README.md +0 -0
  17. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
  18. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
  19. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
  20. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
  21. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
  22. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
  23. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
  24. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
  25. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  26. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  27. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  28. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/antlr_parser.py +0 -0
  29. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/examples/attribute_values.py +0 -0
  30. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/examples/part_attributes.py +0 -0
  31. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/examples/tuples_sequences.py +0 -0
  32. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/formatting.py +0 -0
  33. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/README.md +0 -0
  34. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
  35. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  36. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  37. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  38. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
  39. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
  40. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
  41. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
  42. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
  43. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
  44. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
  45. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
  46. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
  47. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
  48. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
  49. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/LICENSE +0 -0
  50. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/README.md +0 -0
  51. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/__init__.py +0 -0
  52. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
  53. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
  54. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
  55. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
  56. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
  57. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
  58. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
  59. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
  60. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
  61. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
  62. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
  63. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
  64. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
  65. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
  66. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
  67. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
  68. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
  69. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
  70. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
  71. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
  72. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
  73. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
  74. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
  75. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
  76. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
  77. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
  78. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
  79. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
  80. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
  81. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
  82. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
  83. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
  84. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
  85. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
  86. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
  87. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
  88. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
  89. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/Base.kerml +0 -0
  90. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
  91. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
  92. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
  93. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
  94. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
  95. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
  96. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
  97. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
  98. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
  99. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
  100. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
  101. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
  102. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/Links.kerml +0 -0
  103. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
  104. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
  105. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
  106. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
  107. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
  108. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
  109. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
  110. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
  111. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
  112. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
  113. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
  114. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
  115. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
  116. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
  117. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
  118. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
  119. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
  120. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
  121. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
  122. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
  123. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
  124. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
  125. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Actions.sysml +0 -0
  126. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
  127. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
  128. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
  129. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
  130. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Cases.sysml +0 -0
  131. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Connections.sysml +0 -0
  132. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
  133. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Flows.sysml +0 -0
  134. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
  135. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Items.sysml +0 -0
  136. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
  137. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Parts.sysml +0 -0
  138. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Ports.sysml +0 -0
  139. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
  140. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
  141. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/States.sysml +0 -0
  142. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/SysML.sysml +0 -0
  143. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
  144. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
  145. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/library/systems/Views.sysml +0 -0
  146. {sysmlpy-0.12.2 → sysmlpy-0.16.0}/src/sysmlpy/navigate.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sysmlpy
3
- Version: 0.12.2
3
+ Version: 0.16.0
4
4
  Summary: SysML v2.0 Parser
5
5
  License: MIT License
6
6
 
@@ -32,7 +32,9 @@ Classifier: Programming Language :: Python :: 3
32
32
  Classifier: License :: OSI Approved :: MIT License
33
33
  Classifier: Operating System :: OS Independent
34
34
  Provides-Extra: graph
35
+ Provides-Extra: kuzu
35
36
  Requires-Dist: antlr4-python3-runtime (>=4.13)
37
+ Requires-Dist: kuzu (>=0.7,<0.12) ; extra == "kuzu"
36
38
  Requires-Dist: networkx (>=3.0) ; extra == "graph"
37
39
  Requires-Dist: pint (>=0.24)
38
40
  Requires-Dist: pyyaml (>=6.0)
@@ -56,7 +58,9 @@ The project had diverged so much from sysml2py that a new name, sysmlpy, was sel
56
58
 
57
59
  ![Lines of Code Over Time](loc_history.svg)
58
60
 
59
- **v0.12.0:** 100% conformance test pass rate (123/123). Storage abstraction layer with in-memory and NetworkX graph backends. Convenience functions: find_all, count, traverse, to_dict, to_graph, path_between.
61
+ **v0.14.0:** 100% conformance test pass rate (123/123). Storage abstraction layer with in-memory and NetworkX graph backends. Convenience functions: find_all, count, traverse, to_dict, to_graph, path_between.
62
+
63
+ **v0.14.1:** ISQ unit validation (300+ type-to-dimension mappings), US Customary unit support (21 custom definitions), PlantUML diagram generation with stereotype-based styling, strict import visibility enforcement, and comprehensive API documentation.
60
64
 
61
65
  ## Requirements
62
66
  sysmlpy requires the following Python packages:
@@ -66,6 +70,8 @@ sysmlpy requires the following Python packages:
66
70
 
67
71
  ### Optional Dependencies
68
72
  - [networkx](https://networkx.org/) — graph analysis backend (install with `pip install sysmlpy[graph]`)
73
+ - [kuzu](https://kuzudb.com/) — embedded graph database with disk persistence and Cypher queries (install with `pip install sysmlpy[kuzu]`)
74
+ - [PlantUML](https://plantuml.com/) **v1.2020.0+** — diagram rendering (requires Java + PlantUML JAR or [PlantUML server](https://www.plantuml.com/plantuml)). The generator uses `<style>` blocks and `skinparam` stereotype selectors introduced in v1.2020.
69
75
 
70
76
  ## Installation
71
77
 
@@ -221,6 +227,94 @@ print(tree.dump())
221
227
 
222
228
  **61% of the 56 grammar round-trip tests currently pass** (34/56), covering packages, parts, items, ports, interfaces, binding connectors, flow connections, all action forms (definition, shorthand, succession, decomposition), expressions, calculations, and constraints.
223
229
 
230
+ ## PlantUML Visualizations
231
+
232
+ Generate SysML v2 structure diagrams from parsed models using the built-in PlantUML generator. Definitions render with sharp corners and usage elements with rounded corners. Relationships are differentiated by arrow style, thickness, and color — following the [official SysML v2 Pilot Implementation](https://github.com/Systems-Modeling/SysML-v2-Release) approach.
233
+
234
+ ```python
235
+ from sysmlpy import loads
236
+ from sysmlpy.plantuml import PlantUMLGenerator
237
+
238
+ text = """package Vehicle {
239
+ part def Wheel {
240
+ attribute radius : LengthValue;
241
+ attribute pressure : PressureValue;
242
+ }
243
+
244
+ part def BrakeSystem {
245
+ attribute padThickness : LengthValue;
246
+ }
247
+
248
+ part def VehicleAssembly {
249
+ part frontLeft : Wheel;
250
+ part frontRight : Wheel;
251
+ part brakes : BrakeSystem;
252
+ }
253
+
254
+ part myVehicle : VehicleAssembly;
255
+ }"""
256
+
257
+ model = loads(text)
258
+ gen = PlantUMLGenerator(model, title="Vehicle Structure")
259
+ print(gen.generate())
260
+ ```
261
+
262
+ Produces PlantUML source that renders as:
263
+
264
+ ```plantuml
265
+ @startuml
266
+ skinparam RoundCorner 0
267
+ skinparam rectangle<<(D,#8B4513) part def>> {
268
+ RoundCorner 0
269
+ BackgroundColor #FFF8F0
270
+ BorderColor #8B4513
271
+ }
272
+ skinparam rectangle<<(P,#32CD32) part>> {
273
+ RoundCorner 15
274
+ BackgroundColor #F0FFF0
275
+ BorderColor #32CD32
276
+ }
277
+
278
+ title Vehicle Structure
279
+
280
+ rectangle "Wheel" as Wheel <<(D,#8B4513) part def>>
281
+ rectangle "BrakeSystem" as BrakeSystem <<(D,#8B4513) part def>>
282
+ rectangle "VehicleAssembly" as VehicleAssembly <<(D,#8B4513) part def>>
283
+ rectangle "myVehicle" as myVehicle <<(P,#32CD32) part>>
284
+
285
+ VehicleAssembly *-- frontLeft : owns
286
+ VehicleAssembly *-- frontRight : owns
287
+ VehicleAssembly *-- brakes : owns
288
+ myVehicle --:|> VehicleAssembly : types
289
+
290
+ legend right
291
+ <b>Legend</b>
292
+ |= Element |= Notation |
293
+ | <<(D,#8B4513) part def>> | Definition (type) |
294
+ | <<(P,#32CD32) part>> | Usage (instance) |
295
+ | --:|> | Feature typing |
296
+ | *-- | Composite containment |
297
+ endlegend
298
+ @enduml
299
+ ```
300
+
301
+ ### Filtering and Focus
302
+
303
+ The generator supports filtering to highlight specific elements:
304
+
305
+ ```python
306
+ # Show only elements related to 'myVehicle'
307
+ gen = PlantUMLGenerator(model, focus="myVehicle")
308
+
309
+ # Show a custom set of elements
310
+ gen = PlantUMLGenerator(model, elements=["Wheel", "BrakeSystem"])
311
+
312
+ # Limit nesting depth
313
+ gen = PlantUMLGenerator(model, max_depth=2)
314
+ ```
315
+
316
+ See [`docs/plantuml-examples/`](docs/plantuml-examples/) for 9 rendered examples covering usage vs definition, relationships, vehicle structure, requirements, interconnections, state machines, and activity diagrams.
317
+
224
318
  ## Conformance
225
319
 
226
320
  **100% of 123 OMG XPect conformance tests pass** (123/123).
@@ -14,7 +14,9 @@ The project had diverged so much from sysml2py that a new name, sysmlpy, was sel
14
14
 
15
15
  ![Lines of Code Over Time](loc_history.svg)
16
16
 
17
- **v0.12.0:** 100% conformance test pass rate (123/123). Storage abstraction layer with in-memory and NetworkX graph backends. Convenience functions: find_all, count, traverse, to_dict, to_graph, path_between.
17
+ **v0.14.0:** 100% conformance test pass rate (123/123). Storage abstraction layer with in-memory and NetworkX graph backends. Convenience functions: find_all, count, traverse, to_dict, to_graph, path_between.
18
+
19
+ **v0.14.1:** ISQ unit validation (300+ type-to-dimension mappings), US Customary unit support (21 custom definitions), PlantUML diagram generation with stereotype-based styling, strict import visibility enforcement, and comprehensive API documentation.
18
20
 
19
21
  ## Requirements
20
22
  sysmlpy requires the following Python packages:
@@ -24,6 +26,8 @@ sysmlpy requires the following Python packages:
24
26
 
25
27
  ### Optional Dependencies
26
28
  - [networkx](https://networkx.org/) — graph analysis backend (install with `pip install sysmlpy[graph]`)
29
+ - [kuzu](https://kuzudb.com/) — embedded graph database with disk persistence and Cypher queries (install with `pip install sysmlpy[kuzu]`)
30
+ - [PlantUML](https://plantuml.com/) **v1.2020.0+** — diagram rendering (requires Java + PlantUML JAR or [PlantUML server](https://www.plantuml.com/plantuml)). The generator uses `<style>` blocks and `skinparam` stereotype selectors introduced in v1.2020.
27
31
 
28
32
  ## Installation
29
33
 
@@ -179,6 +183,94 @@ print(tree.dump())
179
183
 
180
184
  **61% of the 56 grammar round-trip tests currently pass** (34/56), covering packages, parts, items, ports, interfaces, binding connectors, flow connections, all action forms (definition, shorthand, succession, decomposition), expressions, calculations, and constraints.
181
185
 
186
+ ## PlantUML Visualizations
187
+
188
+ Generate SysML v2 structure diagrams from parsed models using the built-in PlantUML generator. Definitions render with sharp corners and usage elements with rounded corners. Relationships are differentiated by arrow style, thickness, and color — following the [official SysML v2 Pilot Implementation](https://github.com/Systems-Modeling/SysML-v2-Release) approach.
189
+
190
+ ```python
191
+ from sysmlpy import loads
192
+ from sysmlpy.plantuml import PlantUMLGenerator
193
+
194
+ text = """package Vehicle {
195
+ part def Wheel {
196
+ attribute radius : LengthValue;
197
+ attribute pressure : PressureValue;
198
+ }
199
+
200
+ part def BrakeSystem {
201
+ attribute padThickness : LengthValue;
202
+ }
203
+
204
+ part def VehicleAssembly {
205
+ part frontLeft : Wheel;
206
+ part frontRight : Wheel;
207
+ part brakes : BrakeSystem;
208
+ }
209
+
210
+ part myVehicle : VehicleAssembly;
211
+ }"""
212
+
213
+ model = loads(text)
214
+ gen = PlantUMLGenerator(model, title="Vehicle Structure")
215
+ print(gen.generate())
216
+ ```
217
+
218
+ Produces PlantUML source that renders as:
219
+
220
+ ```plantuml
221
+ @startuml
222
+ skinparam RoundCorner 0
223
+ skinparam rectangle<<(D,#8B4513) part def>> {
224
+ RoundCorner 0
225
+ BackgroundColor #FFF8F0
226
+ BorderColor #8B4513
227
+ }
228
+ skinparam rectangle<<(P,#32CD32) part>> {
229
+ RoundCorner 15
230
+ BackgroundColor #F0FFF0
231
+ BorderColor #32CD32
232
+ }
233
+
234
+ title Vehicle Structure
235
+
236
+ rectangle "Wheel" as Wheel <<(D,#8B4513) part def>>
237
+ rectangle "BrakeSystem" as BrakeSystem <<(D,#8B4513) part def>>
238
+ rectangle "VehicleAssembly" as VehicleAssembly <<(D,#8B4513) part def>>
239
+ rectangle "myVehicle" as myVehicle <<(P,#32CD32) part>>
240
+
241
+ VehicleAssembly *-- frontLeft : owns
242
+ VehicleAssembly *-- frontRight : owns
243
+ VehicleAssembly *-- brakes : owns
244
+ myVehicle --:|> VehicleAssembly : types
245
+
246
+ legend right
247
+ <b>Legend</b>
248
+ |= Element |= Notation |
249
+ | <<(D,#8B4513) part def>> | Definition (type) |
250
+ | <<(P,#32CD32) part>> | Usage (instance) |
251
+ | --:|> | Feature typing |
252
+ | *-- | Composite containment |
253
+ endlegend
254
+ @enduml
255
+ ```
256
+
257
+ ### Filtering and Focus
258
+
259
+ The generator supports filtering to highlight specific elements:
260
+
261
+ ```python
262
+ # Show only elements related to 'myVehicle'
263
+ gen = PlantUMLGenerator(model, focus="myVehicle")
264
+
265
+ # Show a custom set of elements
266
+ gen = PlantUMLGenerator(model, elements=["Wheel", "BrakeSystem"])
267
+
268
+ # Limit nesting depth
269
+ gen = PlantUMLGenerator(model, max_depth=2)
270
+ ```
271
+
272
+ See [`docs/plantuml-examples/`](docs/plantuml-examples/) for 9 rendered examples covering usage vs definition, relationships, vehicle structure, requirements, interconnections, state machines, and activity diagrams.
273
+
182
274
  ## Conformance
183
275
 
184
276
  **100% of 123 OMG XPect conformance tests pass** (123/123).
@@ -6,7 +6,7 @@ build-backend = "poetry.core.masonry.api"
6
6
 
7
7
  [project]
8
8
  name = "sysmlpy"
9
- version = "0.12.2"
9
+ version = "0.16.0"
10
10
  description = "SysML v2.0 Parser"
11
11
  authors = [
12
12
  { name="Jon R. Fox (mycr0ft)", email="jon.fox@drfox.com" },
@@ -114,7 +114,7 @@ build_command = "pip install poetry && poetry build"
114
114
 
115
115
  [tool.poetry]
116
116
  name = "sysmlpy"
117
- version = "0.12.2"
117
+ version = "0.16.0"
118
118
  description = ""
119
119
  authors = ["Jon R. Fox (mycr0ft) <jon.fox@drfox.com>"]
120
120
  readme = "README.md"
@@ -126,9 +126,11 @@ pint = ">=0.24"
126
126
  pyyaml = ">=6.0"
127
127
  antlr4-python3-runtime = ">=4.13"
128
128
  networkx = { version = ">=3.0", optional = true }
129
+ kuzu = { version = ">=0.7,<0.12", optional = true }
129
130
 
130
131
  [tool.poetry.extras]
131
132
  graph = ["networkx"]
133
+ kuzu = ["kuzu"]
132
134
 
133
135
  [tool.poetry.scripts]
134
136
  sysmlpy = "sysmlpy.__main__:main"
@@ -10,10 +10,11 @@ Uses the ANTLR4 parser for full SysML v2 grammar support.
10
10
  __all__ = [
11
11
  "load", "loads", "load_grammar", "load_antlr", "load_grammar_antlr",
12
12
  "Searchable",
13
- "Store", "InMemoryStore", "NetworkXStore", "create_store", "new_id",
13
+ "Store", "InMemoryStore", "NetworkXStore", "KuzuStore", "CayleyStore", "create_store", "new_id",
14
+ "to_plantuml", "PlantUMLGenerator",
14
15
  ]
15
16
  __author__ = "Jon Fox"
16
- __version__ = "0.12.2"
17
+ __version__ = "0.15.0"
17
18
 
18
19
  from sysmlpy.usage import (
19
20
  Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
@@ -25,7 +26,7 @@ from sysmlpy.usage import (
25
26
 
26
27
  from sysmlpy.definition import Model, Package
27
28
  from sysmlpy.navigate import Searchable
28
- from sysmlpy.store import Store, InMemoryStore, NetworkXStore, create_store, new_id
29
+ from sysmlpy.store import Store, InMemoryStore, NetworkXStore, KuzuStore, CayleyStore, create_store, new_id
29
30
 
30
31
  from sysmlpy.usage import ureg
31
32
 
@@ -224,3 +225,6 @@ def load_antlr(fp):
224
225
  return loads(fp.read())
225
226
 
226
227
 
228
+ from sysmlpy.plantuml import to_plantuml, PlantUMLGenerator
229
+
230
+
@@ -4959,6 +4959,8 @@ def _make_calculation_usage_dict(ctx, prefix=None):
4959
4959
  name = None
4960
4960
  shortname = None
4961
4961
  typed_by = None
4962
+ redefined_feature = None
4963
+
4962
4964
  if ctx is not None:
4963
4965
  cud = None
4964
4966
  # Try both actionUsageDeclaration and calculationUsageDeclaration
@@ -4971,6 +4973,21 @@ def _make_calculation_usage_dict(ctx, prefix=None):
4971
4973
  if cud and hasattr(cud, 'usageDeclaration') and cud.usageDeclaration():
4972
4974
  ud = cud.usageDeclaration()
4973
4975
 
4976
+ # Check for redefinitions in featureSpecializationPart
4977
+ if ud and hasattr(ud, 'featureSpecializationPart') and ud.featureSpecializationPart():
4978
+ fsp = ud.featureSpecializationPart()
4979
+ if hasattr(fsp, 'featureSpecialization') and fsp.featureSpecialization():
4980
+ specs = fsp.featureSpecialization()
4981
+ if not isinstance(specs, list):
4982
+ specs = [specs]
4983
+ for spec in specs:
4984
+ if hasattr(spec, 'redefinitions') and spec.redefinitions():
4985
+ redef_text = spec.redefinitions().getText()
4986
+ # Extract name from :>>name
4987
+ if redef_text.startswith(':>>'):
4988
+ redefined_feature = redef_text[3:].strip()
4989
+ name = redefined_feature
4990
+
4974
4991
  if ud and hasattr(ud, 'identification') and ud.identification():
4975
4992
  ident = ud.identification()
4976
4993
  if hasattr(ident, 'name'):
@@ -4992,7 +5009,37 @@ def _make_calculation_usage_dict(ctx, prefix=None):
4992
5009
  body_parts = _visit_calculation_body_items(ctx)
4993
5010
  occ_prefix = _get_occurrence_usage_prefix(ctx) if ctx else None
4994
5011
 
4995
- return {
5012
+ # Build declaration
5013
+ declaration = {
5014
+ "name": "CalculationUsageDeclaration",
5015
+ "declaration": {
5016
+ "name": "UsageDeclaration",
5017
+ "declaration": {
5018
+ "name": "FeatureDeclaration",
5019
+ "identification": {
5020
+ "name": "Identification",
5021
+ "declaredShortName": shortname,
5022
+ "declaredName": name
5023
+ },
5024
+ "specialization": specialization
5025
+ }
5026
+ },
5027
+ "valuepart": None
5028
+ }
5029
+
5030
+ # Build ownedRelationship for redefinitions
5031
+ owned_relationship = []
5032
+ if redefined_feature:
5033
+ owned_relationship.append({
5034
+ "name": "OwnedReferenceSubsetting",
5035
+ "referencedFeature": {
5036
+ "name": "QualifiedName",
5037
+ "names": [redefined_feature]
5038
+ },
5039
+ "ownedRelatedElement": []
5040
+ })
5041
+
5042
+ result = {
4996
5043
  "name": "PackageMember",
4997
5044
  "prefix": None,
4998
5045
  "ownedRelatedElement": {
@@ -5004,22 +5051,7 @@ def _make_calculation_usage_dict(ctx, prefix=None):
5004
5051
  "ownedRelationship": {
5005
5052
  "name": "CalculationUsage",
5006
5053
  "prefix": occ_prefix or prefix,
5007
- "declaration": {
5008
- "name": "CalculationUsageDeclaration",
5009
- "declaration": {
5010
- "name": "UsageDeclaration",
5011
- "declaration": {
5012
- "name": "FeatureDeclaration",
5013
- "identification": {
5014
- "name": "Identification",
5015
- "declaredShortName": shortname,
5016
- "declaredName": name
5017
- },
5018
- "specialization": specialization
5019
- }
5020
- },
5021
- "valuepart": None
5022
- },
5054
+ "declaration": declaration,
5023
5055
  "body": {
5024
5056
  "name": "CalculationBody",
5025
5057
  "part": body_parts
@@ -5029,6 +5061,11 @@ def _make_calculation_usage_dict(ctx, prefix=None):
5029
5061
  }
5030
5062
  }
5031
5063
  }
5064
+
5065
+ if owned_relationship:
5066
+ result["ownedRelatedElement"]["ownedRelatedElement"]["ownedRelatedElement"]["ownedRelationship"]["ownedRelationship"] = owned_relationship
5067
+
5068
+ return result
5032
5069
 
5033
5070
 
5034
5071
  def _make_nested_calculation_usage_dict(ctx, prefix=None):
@@ -10691,9 +10728,33 @@ def _make_nested_analysis_case_usage_dict(ctx, prefix=None):
10691
10728
  if ctx is None:
10692
10729
  return None
10693
10730
 
10694
- name, shortname = _get_usage_identification(ctx)
10731
+ # Extract name and specialization from constraintUsageDeclaration
10732
+ name = None
10733
+ shortname = None
10734
+ specialization = None
10735
+
10736
+ if hasattr(ctx, 'constraintUsageDeclaration') and ctx.constraintUsageDeclaration():
10737
+ cud = ctx.constraintUsageDeclaration()
10738
+ if hasattr(cud, 'usageDeclaration') and cud.usageDeclaration():
10739
+ ud = cud.usageDeclaration()
10740
+ if hasattr(ud, 'identification') and ud.identification():
10741
+ ident = ud.identification()
10742
+ if hasattr(ident, 'name'):
10743
+ name_list = ident.name()
10744
+ if name_list and isinstance(name_list, list):
10745
+ if len(name_list) == 2:
10746
+ shortname = name_list[0].getText()
10747
+ name = name_list[1].getText()
10748
+ elif len(name_list) == 1:
10749
+ name_text = name_list[0].getText()
10750
+ name, shortname = _extract_name_shortname(name_text)
10751
+
10752
+ # Extract specialization (typing) from constraintUsageDeclaration
10753
+ typed_by = _get_action_usage_typed_by(cud)
10754
+ if typed_by:
10755
+ specialization = _build_specialization(typed_by)
10756
+
10695
10757
  occ_prefix = _get_occurrence_usage_prefix(ctx) if ctx else None
10696
- specialization = _build_full_specialization_from_ctx(ctx)
10697
10758
 
10698
10759
  # Get body items from caseBody
10699
10760
  body_items = []
@@ -10809,7 +10870,63 @@ def _visit_case_body_item(cbi):
10809
10870
  if cbi is None:
10810
10871
  return None
10811
10872
 
10812
- # Handle nonOccurrenceUsageMember (in/out params, subject)
10873
+ # Handle subjectMember
10874
+ if hasattr(cbi, 'subjectMember') and cbi.subjectMember():
10875
+ sm = cbi.subjectMember()
10876
+ if isinstance(sm, list):
10877
+ sm = sm[0]
10878
+ if sm:
10879
+ inner = _visit_subject_member_dict(sm)
10880
+ if inner:
10881
+ return {
10882
+ "name": "CaseBodyItem",
10883
+ "item": None,
10884
+ "ownedRelationship": inner
10885
+ }
10886
+
10887
+ # Handle objectiveMember
10888
+ if hasattr(cbi, 'objectiveMember') and cbi.objectiveMember():
10889
+ om = cbi.objectiveMember()
10890
+ if isinstance(om, list):
10891
+ om = om[0]
10892
+ if om:
10893
+ inner = _visit_objective_member_dict(om)
10894
+ if inner:
10895
+ return {
10896
+ "name": "CaseBodyItem",
10897
+ "item": None,
10898
+ "ownedRelationship": inner
10899
+ }
10900
+
10901
+ # Handle returnParameterMember
10902
+ if hasattr(cbi, 'returnParameterMember') and cbi.returnParameterMember():
10903
+ rpm = cbi.returnParameterMember()
10904
+ if isinstance(rpm, list):
10905
+ rpm = rpm[0]
10906
+ if rpm:
10907
+ inner = _visit_return_parameter_member(rpm)
10908
+ if inner:
10909
+ return {
10910
+ "name": "CaseBodyItem",
10911
+ "item": inner,
10912
+ "ownedRelationship": None
10913
+ }
10914
+
10915
+ # Handle actionBodyItem (for nested calc/action usages)
10916
+ if hasattr(cbi, 'actionBodyItem') and cbi.actionBodyItem():
10917
+ abi = cbi.actionBodyItem()
10918
+ if isinstance(abi, list):
10919
+ abi = abi[0]
10920
+ if abi:
10921
+ inner = _visit_action_body_item(abi)
10922
+ if inner:
10923
+ return {
10924
+ "name": "CaseBodyItem",
10925
+ "item": inner,
10926
+ "ownedRelationship": None
10927
+ }
10928
+
10929
+ # Handle nonOccurrenceUsageMember (in/out params)
10813
10930
  if hasattr(cbi, 'nonOccurrenceUsageMember') and cbi.nonOccurrenceUsageMember():
10814
10931
  nom = cbi.nonOccurrenceUsageMember()
10815
10932
  if isinstance(nom, list):