sysmlpy 0.30.2__tar.gz → 0.31.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. sysmlpy-0.30.2/README.md → sysmlpy-0.31.3/PKG-INFO +175 -26
  2. sysmlpy-0.30.2/PKG-INFO → sysmlpy-0.31.3/README.md +150 -72
  3. sysmlpy-0.31.3/pyproject.toml +32 -0
  4. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/__init__.py +1 -1
  5. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/classes.py +2 -3
  6. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/plantuml.py +41 -9
  7. sysmlpy-0.30.2/pyproject.toml +0 -140
  8. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/LICENSE +0 -0
  9. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/__main__.py +0 -0
  10. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr/README.md +0 -0
  11. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
  12. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
  13. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
  14. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
  15. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
  16. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
  17. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
  18. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
  19. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  20. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  21. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  22. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr_parser.py +0 -0
  23. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/antlr_visitor.py +0 -0
  24. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/definition.py +0 -0
  25. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/examples/attribute_values.py +0 -0
  26. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/examples/part_attributes.py +0 -0
  27. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/examples/tuples_sequences.py +0 -0
  28. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/formatting.py +0 -0
  29. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/README.md +0 -0
  30. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
  31. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  32. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  33. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  34. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
  35. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
  36. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
  37. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
  38. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
  39. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
  40. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
  41. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
  42. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
  43. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
  44. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
  45. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/LICENSE +0 -0
  46. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/README.md +0 -0
  47. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/__init__.py +0 -0
  48. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
  49. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
  50. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
  51. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
  52. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
  53. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
  54. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
  55. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
  56. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
  57. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
  58. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
  59. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
  60. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
  61. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
  62. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
  63. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
  64. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
  65. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
  66. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
  67. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
  68. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
  69. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
  70. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
  71. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
  72. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
  73. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
  74. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
  75. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
  76. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
  77. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
  78. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
  79. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
  80. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
  81. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
  82. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
  83. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
  84. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
  85. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/Base.kerml +0 -0
  86. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
  87. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
  88. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
  89. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
  90. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
  91. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
  92. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
  93. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
  94. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
  95. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
  96. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
  97. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
  98. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/Links.kerml +0 -0
  99. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
  100. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
  101. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
  102. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
  103. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
  104. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
  105. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
  106. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
  107. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
  108. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
  109. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
  110. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
  111. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
  112. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
  113. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
  114. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
  115. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
  116. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
  117. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
  118. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
  119. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
  120. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
  121. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Actions.sysml +0 -0
  122. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
  123. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
  124. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
  125. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
  126. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Cases.sysml +0 -0
  127. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Connections.sysml +0 -0
  128. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
  129. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Flows.sysml +0 -0
  130. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
  131. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Items.sysml +0 -0
  132. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
  133. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Parts.sysml +0 -0
  134. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Ports.sysml +0 -0
  135. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
  136. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
  137. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/States.sysml +0 -0
  138. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/SysML.sysml +0 -0
  139. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
  140. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
  141. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/library/systems/Views.sysml +0 -0
  142. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/navigate.py +0 -0
  143. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/project.py +0 -0
  144. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/semantic.py +0 -0
  145. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/store.py +0 -0
  146. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/us_customary_units.txt +0 -0
  147. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/usage.py +0 -0
  148. {sysmlpy-0.30.2 → sysmlpy-0.31.3}/src/sysmlpy/validator.py +0 -0
@@ -1,3 +1,27 @@
1
+ Metadata-Version: 2.4
2
+ Name: sysmlpy
3
+ Version: 0.31.3
4
+ Summary:
5
+ License-File: LICENSE
6
+ Author: Jon R. Fox (mycr0ft)
7
+ Author-email: jon.fox@drfox.com
8
+ Requires-Python: >=3.9,<4.0
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Provides-Extra: graph
17
+ Provides-Extra: kuzu
18
+ Requires-Dist: antlr4-python3-runtime (>=4.13)
19
+ Requires-Dist: kuzu (>=0.7,<0.12) ; extra == "kuzu"
20
+ Requires-Dist: networkx (>=3.0) ; extra == "graph"
21
+ Requires-Dist: pint (>=0.24)
22
+ Requires-Dist: pyyaml (>=6.0)
23
+ Description-Content-Type: text/markdown
24
+
1
25
  # sysmlpy
2
26
  [![PyPI version](https://badge.fury.io/py/sysmlpy.svg)](https://badge.fury.io/py/sysmlpy)[![PyPI status](https://img.shields.io/pypi/status/sysmlpy.svg)](https://pypi.python.org/pypi/sysmlpy/)[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)
3
27
 
@@ -14,6 +38,10 @@ The project had diverged so much from sysml2py that a new name, sysmlpy, was sel
14
38
 
15
39
  ![Lines of Code Over Time](loc_history.svg)
16
40
 
41
+ **v0.31.0:** Documentation overhaul — all docs rewritten to showcase the modern public API. New Model Parsing and Model Navigation sections. Semantic Analysis updated with `AnalysisResult`. Grammar round-trip: 77/77 (100%). 211 core tests passing.
42
+
43
+ **v0.31.1:** Fixed `pyproject.toml` for CI compatibility — removed duplicate version and invalid `allow_zero_version` from `[project]` table.
44
+
17
45
  **v0.28.0:** Complete Gap 4 coverage — Block Definition Diagram (BDD), Internal Block Diagram (IBD), Parametric Diagram, and Package Diagram views. All 6 specialized SysML v2 view types now implemented (144 PlantUML tests). IBD shows flow/connection arrows with endpoint extraction. Parametric view extracts constraint parameters with types. Package diagram renders nested folder-style hierarchy.
18
46
 
19
47
  **v0.27.0:** General View (GV), Package View, and three GridView specializations (Tabular View, Data Value Tabular View, Relationship Matrix View) with PlantUML, Markdown, and HTML output. 108 PlantUML tests. All 68+ `NotImplementedError` stubs in `grammar/classes.py` replaced with graceful handling.
@@ -57,44 +85,60 @@ Documentation can be found [here.](https://mycr0ft.github.io/sysmlpy/)
57
85
 
58
86
  ### Basic Usage
59
87
 
60
- The code below will create a part called Stage 1, with a shortname of <'3.1'>
61
- referencing a specific requirement or document. It has a mass attribute of 100
62
- kg. It has a thrust attribute of 1000 N. These attributes are created and placed
63
- as a child of the part. Next, we recall the part value for thrust and add 199 N.
64
- Finally, we can dump the output from this class.
65
- ```
66
- from sysmlpy import Attribute, Part, ureg
88
+ Build models programmatically using the public API:
89
+
90
+ ```python
91
+ from sysmlpy import Part, Item, Attribute, ureg
92
+
93
+ # Create a sensor part with children
94
+ sensor = Part(name="sensor")
95
+ camera = Part(name="camera")
96
+ lens = Item(name="lens")
97
+ mass = Attribute(name="mass")
98
+ mass.set_value(100 * ureg.kilogram)
67
99
 
68
- a = Attribute(name='mass')
69
- a.set_value(100 * ureg.kilogram)
70
- b = Attribute(name='thrust')
71
- b.set_value(1000 * ureg.newton)
72
- c = Part(name="Stage_1", shortname="'3.1'")
73
- c._set_child(a)
74
- c._set_child(b)
75
- v = "Stage_1.thrust"
76
- c._get_child(v).set_value(c._get_child(v).get_value() + 199 * ureg.newton)
77
- print(c.dump())
100
+ camera.add_child(mass)
101
+ sensor.add_child(camera)
102
+ sensor.add_child(lens)
103
+
104
+ print(sensor.dump())
105
+ # → part sensor {
106
+ # → part camera {
107
+ # → attribute mass = 100 [kilogram];
108
+ # → }
109
+ # → item lens;
110
+ # → }
111
+
112
+ # Navigate children by name
113
+ found = sensor.find_one("camera")
114
+ print(found.name) # → camera
115
+
116
+ # Iterate over children
117
+ for child in sensor:
118
+ print(child.name)
119
+
120
+ # Check containment
121
+ "camera" in sensor # → True
78
122
  ```
79
123
 
80
124
  It will output the following:
81
125
  ```
82
- part <'3.1'> Stage_1 {
126
+ part <'3.1'> Stage_1 {
83
127
  attribute mass= 100 [kilogram];
84
128
  attribute thrust= 1199.0 [newton];
85
- }
129
+ }
86
130
  ```
87
131
 
88
132
  The package is able to handle Items, Parts, and Attributes.
89
133
 
90
- ```
134
+ ```python
91
135
  a = Part(name='camera')
92
136
  b = Item(name='lens')
93
137
  d = Attribute(name='mass')
94
138
  c = Part(name='sensor')
95
- c._set_child(a)
96
- c._set_child(b)
97
- a._set_child(d)
139
+ c.add_child(a)
140
+ c.add_child(b)
141
+ a.add_child(d)
98
142
  print(c.dump())
99
143
  ```
100
144
 
@@ -158,6 +202,87 @@ print(r3.dump())
158
202
  # → ref :>> payload : Person;
159
203
  ```
160
204
 
205
+ ## Model Parsing
206
+
207
+ ```python
208
+ from sysmlpy import loads, parse
209
+
210
+ # loads() — raises on syntax error
211
+ model = loads("package P { part def Engine; }")
212
+
213
+ # parse() — returns (model, errors) tuple, never raises
214
+ model, errors = parse("package P { part def Engine; }")
215
+ assert errors == []
216
+
217
+ model, errors = parse("invalid @@ syntax")
218
+ assert model is None
219
+ assert len(errors) > 0
220
+ ```
221
+
222
+ ## Model Navigation
223
+
224
+ Every parsed model element supports search, iteration, and containment checks:
225
+
226
+ ```python
227
+ from sysmlpy import loads, Part
228
+
229
+ model = loads("""
230
+ package Vehicle {
231
+ part def Engine;
232
+ part engine1 : Engine { attribute mass = 100 [kg]; }
233
+ part chassis { part wheel1; part wheel2; }
234
+ }
235
+ """)
236
+
237
+ # find() — returns list of matching elements (empty list if none)
238
+ parts = model.find(sysml_type="part")
239
+ assert len(parts) >= 3
240
+
241
+ # find_one() — returns single element or None
242
+ engine = model.find_one("engine1")
243
+ assert engine is not None
244
+
245
+ missing = model.find_one("DoesNotExist")
246
+ assert missing is None # no IndexError!
247
+
248
+ # find_one() raises LookupError if multiple matches
249
+ # model.find_one("wheel") → LookupError: 2 matches
250
+
251
+ # Container protocol — iterate, length, containment
252
+ for child in model:
253
+ print(child.name)
254
+
255
+ len(model) # → number of direct children
256
+ "Vehicle" in model # → True (checks child names)
257
+
258
+ # __str__ returns SysML text
259
+ print(str(model))
260
+ # → package Vehicle { ... }
261
+
262
+ # Typed property accessors
263
+ model.packages # direct Package children
264
+ model.parts # direct Part children
265
+ model.actions # direct Action children
266
+ ```
267
+
268
+ All search methods accept `sysml_type=` (keyword string or class) and `recursive=`:
269
+
270
+ ```python
271
+ from sysmlpy import Part
272
+
273
+ # By string keyword
274
+ model.find(sysml_type="action")
275
+
276
+ # By class
277
+ model.find(sysml_type=Part)
278
+
279
+ # Non-recursive (direct children only)
280
+ model.find("engine1", recursive=False)
281
+
282
+ # Legacy type= keyword still works (emits DeprecationWarning)
283
+ model.find(type="action")
284
+ ```
285
+
161
286
  ## Grammar Round-Trip
162
287
 
163
288
  `loads()` parses SysML v2 text and `classtree()` converts the result back to text. This round-trip is the basis for the grammar test suite.
@@ -193,7 +318,7 @@ tree = classtree(model)
193
318
  print(tree.dump())
194
319
  ```
195
320
 
196
- **61 of 77 grammar round-trip tests pass** (61/77). All 61 non-control-flow tests pass (100%). The 16 deferred tests require action control-flow node classes (`IfNode`, `WhileLoopNode`, `ControlNode`, `SendNode`, `AcceptNode`, `TerminateNode`) not yet ported to `grammar/classes.py`. Covered categories: packages, parts, items, ports, interfaces, binding connectors, flow connections, all action forms (definition, shorthand, succession, decomposition), expressions, calculations, constraints, state definitions, requirements, analysis cases, and trade studies.
321
+ **All 77 grammar round-trip tests pass** (100%). Covered categories: packages, parts, items, ports, interfaces, binding connectors, flow connections, all action forms (definition, shorthand, succession, decomposition), expressions, calculations, constraints, state definitions, requirements, analysis cases, control flow (if/else, while, loop, fork, join, decision, send, accept, terminate), and trade studies.
197
322
 
198
323
  ## Semantic Analysis
199
324
 
@@ -213,10 +338,33 @@ model = loads("""
213
338
  }
214
339
  """)
215
340
 
216
- issues = analyze(model)
217
- for issue in issues:
341
+ result = analyze(model)
342
+
343
+ # Iterate issues (backward-compatible with list)
344
+ for issue in result:
218
345
  print(f"[{issue.severity}] {issue.code}: {issue.message}")
219
346
  # → [error] UNDEFINED_SYMBOL: Undefined symbol 'Wheel' referenced in Part 'myWheel'
347
+
348
+ # Separated by severity
349
+ for err in result.errors:
350
+ print(f"ERROR: {err.message}")
351
+
352
+ for warn in result.warnings:
353
+ print(f"WARNING: {warn.message}")
354
+
355
+ # Boolean check: True when no errors (warnings are OK)
356
+ if result:
357
+ print("Model is semantically valid!")
358
+ else:
359
+ print(f"Found {len(result.errors)} error(s) — fix before proceeding")
360
+
361
+ # Raise on errors
362
+ result.raise_on_errors() # ValueError if any errors exist
363
+
364
+ # Strict mode: raise immediately on any error
365
+ result = analyze(model, strict=True)
366
+ # → ValueError: Semantic errors found:
367
+ # [UNDEFINED_SYMBOL] Undefined symbol 'Wheel' referenced in Part 'myWheel'
220
368
  ```
221
369
 
222
370
  ### Symbol Resolution
@@ -654,3 +802,4 @@ See [`docs/plantuml-examples/`](docs/plantuml-examples/) for all rendered exampl
654
802
 
655
803
  ## License
656
804
  sysmlpy is released under the MIT license, hence allowing commercial use of the library.
805
+
@@ -1,48 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: sysmlpy
3
- Version: 0.30.2
4
- Summary: SysML v2.0 Parser
5
- License: MIT License
6
-
7
- Copyright (c) 2023-2026 Westfall-io
8
- Copyright (c) 2026 Jon R. Fox
9
-
10
- Permission is hereby granted, free of charge, to any person obtaining a copy
11
- of this software and associated documentation files (the "Software"), to deal
12
- in the Software without restriction, including without limitation the rights
13
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
- copies of the Software, and to permit persons to whom the Software is
15
- furnished to do so, subject to the following conditions:
16
-
17
- The above copyright notice and this permission notice shall be included in all
18
- copies or substantial portions of the Software.
19
-
20
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
- SOFTWARE.
27
- License-File: LICENSE
28
- Author: Jon R. Fox (mycr0ft)
29
- Author-email: jon.fox@drfox.com
30
- Requires-Python: >=3.7
31
- Classifier: Development Status :: 3 - Alpha
32
- Classifier: Programming Language :: Python :: 3
33
- Classifier: License :: OSI Approved :: MIT License
34
- Classifier: Operating System :: OS Independent
35
- Provides-Extra: graph
36
- Provides-Extra: kuzu
37
- Requires-Dist: antlr4-python3-runtime (>=4.13)
38
- Requires-Dist: kuzu (>=0.7,<0.12) ; extra == "kuzu"
39
- Requires-Dist: networkx (>=3.0) ; extra == "graph"
40
- Requires-Dist: pint (>=0.24)
41
- Requires-Dist: pyyaml (>=6.0)
42
- Project-URL: Bug Tracker, https://github.com/mycr0ft/sysmlpy/issues
43
- Project-URL: Homepage, https://github.com/mycr0ft/sysmlpy
44
- Description-Content-Type: text/markdown
45
-
46
1
  # sysmlpy
47
2
  [![PyPI version](https://badge.fury.io/py/sysmlpy.svg)](https://badge.fury.io/py/sysmlpy)[![PyPI status](https://img.shields.io/pypi/status/sysmlpy.svg)](https://pypi.python.org/pypi/sysmlpy/)[![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)
48
3
 
@@ -59,6 +14,10 @@ The project had diverged so much from sysml2py that a new name, sysmlpy, was sel
59
14
 
60
15
  ![Lines of Code Over Time](loc_history.svg)
61
16
 
17
+ **v0.31.0:** Documentation overhaul — all docs rewritten to showcase the modern public API. New Model Parsing and Model Navigation sections. Semantic Analysis updated with `AnalysisResult`. Grammar round-trip: 77/77 (100%). 211 core tests passing.
18
+
19
+ **v0.31.1:** Fixed `pyproject.toml` for CI compatibility — removed duplicate version and invalid `allow_zero_version` from `[project]` table.
20
+
62
21
  **v0.28.0:** Complete Gap 4 coverage — Block Definition Diagram (BDD), Internal Block Diagram (IBD), Parametric Diagram, and Package Diagram views. All 6 specialized SysML v2 view types now implemented (144 PlantUML tests). IBD shows flow/connection arrows with endpoint extraction. Parametric view extracts constraint parameters with types. Package diagram renders nested folder-style hierarchy.
63
22
 
64
23
  **v0.27.0:** General View (GV), Package View, and three GridView specializations (Tabular View, Data Value Tabular View, Relationship Matrix View) with PlantUML, Markdown, and HTML output. 108 PlantUML tests. All 68+ `NotImplementedError` stubs in `grammar/classes.py` replaced with graceful handling.
@@ -102,44 +61,60 @@ Documentation can be found [here.](https://mycr0ft.github.io/sysmlpy/)
102
61
 
103
62
  ### Basic Usage
104
63
 
105
- The code below will create a part called Stage 1, with a shortname of <'3.1'>
106
- referencing a specific requirement or document. It has a mass attribute of 100
107
- kg. It has a thrust attribute of 1000 N. These attributes are created and placed
108
- as a child of the part. Next, we recall the part value for thrust and add 199 N.
109
- Finally, we can dump the output from this class.
110
- ```
111
- from sysmlpy import Attribute, Part, ureg
64
+ Build models programmatically using the public API:
65
+
66
+ ```python
67
+ from sysmlpy import Part, Item, Attribute, ureg
68
+
69
+ # Create a sensor part with children
70
+ sensor = Part(name="sensor")
71
+ camera = Part(name="camera")
72
+ lens = Item(name="lens")
73
+ mass = Attribute(name="mass")
74
+ mass.set_value(100 * ureg.kilogram)
112
75
 
113
- a = Attribute(name='mass')
114
- a.set_value(100 * ureg.kilogram)
115
- b = Attribute(name='thrust')
116
- b.set_value(1000 * ureg.newton)
117
- c = Part(name="Stage_1", shortname="'3.1'")
118
- c._set_child(a)
119
- c._set_child(b)
120
- v = "Stage_1.thrust"
121
- c._get_child(v).set_value(c._get_child(v).get_value() + 199 * ureg.newton)
122
- print(c.dump())
76
+ camera.add_child(mass)
77
+ sensor.add_child(camera)
78
+ sensor.add_child(lens)
79
+
80
+ print(sensor.dump())
81
+ # → part sensor {
82
+ # → part camera {
83
+ # → attribute mass = 100 [kilogram];
84
+ # → }
85
+ # → item lens;
86
+ # → }
87
+
88
+ # Navigate children by name
89
+ found = sensor.find_one("camera")
90
+ print(found.name) # → camera
91
+
92
+ # Iterate over children
93
+ for child in sensor:
94
+ print(child.name)
95
+
96
+ # Check containment
97
+ "camera" in sensor # → True
123
98
  ```
124
99
 
125
100
  It will output the following:
126
101
  ```
127
- part <'3.1'> Stage_1 {
102
+ part <'3.1'> Stage_1 {
128
103
  attribute mass= 100 [kilogram];
129
104
  attribute thrust= 1199.0 [newton];
130
- }
105
+ }
131
106
  ```
132
107
 
133
108
  The package is able to handle Items, Parts, and Attributes.
134
109
 
135
- ```
110
+ ```python
136
111
  a = Part(name='camera')
137
112
  b = Item(name='lens')
138
113
  d = Attribute(name='mass')
139
114
  c = Part(name='sensor')
140
- c._set_child(a)
141
- c._set_child(b)
142
- a._set_child(d)
115
+ c.add_child(a)
116
+ c.add_child(b)
117
+ a.add_child(d)
143
118
  print(c.dump())
144
119
  ```
145
120
 
@@ -203,6 +178,87 @@ print(r3.dump())
203
178
  # → ref :>> payload : Person;
204
179
  ```
205
180
 
181
+ ## Model Parsing
182
+
183
+ ```python
184
+ from sysmlpy import loads, parse
185
+
186
+ # loads() — raises on syntax error
187
+ model = loads("package P { part def Engine; }")
188
+
189
+ # parse() — returns (model, errors) tuple, never raises
190
+ model, errors = parse("package P { part def Engine; }")
191
+ assert errors == []
192
+
193
+ model, errors = parse("invalid @@ syntax")
194
+ assert model is None
195
+ assert len(errors) > 0
196
+ ```
197
+
198
+ ## Model Navigation
199
+
200
+ Every parsed model element supports search, iteration, and containment checks:
201
+
202
+ ```python
203
+ from sysmlpy import loads, Part
204
+
205
+ model = loads("""
206
+ package Vehicle {
207
+ part def Engine;
208
+ part engine1 : Engine { attribute mass = 100 [kg]; }
209
+ part chassis { part wheel1; part wheel2; }
210
+ }
211
+ """)
212
+
213
+ # find() — returns list of matching elements (empty list if none)
214
+ parts = model.find(sysml_type="part")
215
+ assert len(parts) >= 3
216
+
217
+ # find_one() — returns single element or None
218
+ engine = model.find_one("engine1")
219
+ assert engine is not None
220
+
221
+ missing = model.find_one("DoesNotExist")
222
+ assert missing is None # no IndexError!
223
+
224
+ # find_one() raises LookupError if multiple matches
225
+ # model.find_one("wheel") → LookupError: 2 matches
226
+
227
+ # Container protocol — iterate, length, containment
228
+ for child in model:
229
+ print(child.name)
230
+
231
+ len(model) # → number of direct children
232
+ "Vehicle" in model # → True (checks child names)
233
+
234
+ # __str__ returns SysML text
235
+ print(str(model))
236
+ # → package Vehicle { ... }
237
+
238
+ # Typed property accessors
239
+ model.packages # direct Package children
240
+ model.parts # direct Part children
241
+ model.actions # direct Action children
242
+ ```
243
+
244
+ All search methods accept `sysml_type=` (keyword string or class) and `recursive=`:
245
+
246
+ ```python
247
+ from sysmlpy import Part
248
+
249
+ # By string keyword
250
+ model.find(sysml_type="action")
251
+
252
+ # By class
253
+ model.find(sysml_type=Part)
254
+
255
+ # Non-recursive (direct children only)
256
+ model.find("engine1", recursive=False)
257
+
258
+ # Legacy type= keyword still works (emits DeprecationWarning)
259
+ model.find(type="action")
260
+ ```
261
+
206
262
  ## Grammar Round-Trip
207
263
 
208
264
  `loads()` parses SysML v2 text and `classtree()` converts the result back to text. This round-trip is the basis for the grammar test suite.
@@ -238,7 +294,7 @@ tree = classtree(model)
238
294
  print(tree.dump())
239
295
  ```
240
296
 
241
- **61 of 77 grammar round-trip tests pass** (61/77). All 61 non-control-flow tests pass (100%). The 16 deferred tests require action control-flow node classes (`IfNode`, `WhileLoopNode`, `ControlNode`, `SendNode`, `AcceptNode`, `TerminateNode`) not yet ported to `grammar/classes.py`. Covered categories: packages, parts, items, ports, interfaces, binding connectors, flow connections, all action forms (definition, shorthand, succession, decomposition), expressions, calculations, constraints, state definitions, requirements, analysis cases, and trade studies.
297
+ **All 77 grammar round-trip tests pass** (100%). Covered categories: packages, parts, items, ports, interfaces, binding connectors, flow connections, all action forms (definition, shorthand, succession, decomposition), expressions, calculations, constraints, state definitions, requirements, analysis cases, control flow (if/else, while, loop, fork, join, decision, send, accept, terminate), and trade studies.
242
298
 
243
299
  ## Semantic Analysis
244
300
 
@@ -258,10 +314,33 @@ model = loads("""
258
314
  }
259
315
  """)
260
316
 
261
- issues = analyze(model)
262
- for issue in issues:
317
+ result = analyze(model)
318
+
319
+ # Iterate issues (backward-compatible with list)
320
+ for issue in result:
263
321
  print(f"[{issue.severity}] {issue.code}: {issue.message}")
264
322
  # → [error] UNDEFINED_SYMBOL: Undefined symbol 'Wheel' referenced in Part 'myWheel'
323
+
324
+ # Separated by severity
325
+ for err in result.errors:
326
+ print(f"ERROR: {err.message}")
327
+
328
+ for warn in result.warnings:
329
+ print(f"WARNING: {warn.message}")
330
+
331
+ # Boolean check: True when no errors (warnings are OK)
332
+ if result:
333
+ print("Model is semantically valid!")
334
+ else:
335
+ print(f"Found {len(result.errors)} error(s) — fix before proceeding")
336
+
337
+ # Raise on errors
338
+ result.raise_on_errors() # ValueError if any errors exist
339
+
340
+ # Strict mode: raise immediately on any error
341
+ result = analyze(model, strict=True)
342
+ # → ValueError: Semantic errors found:
343
+ # [UNDEFINED_SYMBOL] Undefined symbol 'Wheel' referenced in Part 'myWheel'
265
344
  ```
266
345
 
267
346
  ### Symbol Resolution
@@ -699,4 +778,3 @@ See [`docs/plantuml-examples/`](docs/plantuml-examples/) for all rendered exampl
699
778
 
700
779
  ## License
701
780
  sysmlpy is released under the MIT license, hence allowing commercial use of the library.
702
-
@@ -0,0 +1,32 @@
1
+ [build-system]
2
+ #requires = ["setuptools>=61.0"]
3
+ #build-backend = "setuptools.build_meta"
4
+ requires = ["poetry-core"]
5
+ build-backend = "poetry.core.masonry.api"
6
+
7
+ [project]
8
+ name = "sysmlpy"
9
+ version = "0.31.3"
10
+ description = ""
11
+ authors = [{ name = "Jon R. Fox (mycr0ft)", email = "jon.fox@drfox.com" }]
12
+ readme = "README.md"
13
+ packages = [{ include = "sysmlpy", from = "src" }]
14
+
15
+ [tool.poetry.dependencies]
16
+ python = "^3.9"
17
+ pint = ">=0.24"
18
+ pyyaml = ">=6.0"
19
+ antlr4-python3-runtime = ">=4.13"
20
+ networkx = { version = ">=3.0", optional = true }
21
+ kuzu = { version = ">=0.7,<0.12", optional = true }
22
+
23
+ [tool.poetry.extras]
24
+ graph = ["networkx"]
25
+ kuzu = ["kuzu"]
26
+
27
+ [tool.poetry.scripts]
28
+ sysmlpy = "sysmlpy.__main__:main"
29
+
30
+ [tool.poetry.group.dev.dependencies]
31
+ pytest = ">=8.0,<9.0"
32
+
@@ -21,7 +21,7 @@ __all__ = [
21
21
  "SysMLSyntaxError",
22
22
  ]
23
23
  __author__ = "Jon Fox"
24
- __version__ = "0.30.2"
24
+ __version__ = "0.31.3"
25
25
 
26
26
  from sysmlpy.usage import (
27
27
  Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
@@ -2555,8 +2555,7 @@ class ActionDefinition:
2555
2555
  output.append(self.prefix.dump())
2556
2556
  output.append(self.keyword)
2557
2557
  output.append(self.declaration.dump())
2558
- output.append(self.body.dump())
2559
- return " ".join(output)
2558
+ return " ".join(filter(None, output)) + self.body.dump()
2560
2559
 
2561
2560
  def get_definition(self):
2562
2561
  output = {"name": self.__class__.__name__, "prefix": None}
@@ -4611,7 +4610,7 @@ class Definition:
4611
4610
  self.body = DefinitionBody()
4612
4611
 
4613
4612
  def dump(self):
4614
- return " ".join([self.declaration.dump(), self.body.dump()])
4613
+ return "".join([self.declaration.dump(), self.body.dump()])
4615
4614
 
4616
4615
  def get_definition(self):
4617
4616
  return {