sysmlpy 0.62.0__tar.gz → 0.63.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 (150) hide show
  1. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/PKG-INFO +1 -1
  2. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/pyproject.toml +1 -1
  3. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/__init__.py +5 -1
  4. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/__main__.py +103 -1
  5. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/definition.py +8 -0
  6. sysmlpy-0.63.0/src/sysmlpy/interchange.py +294 -0
  7. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/LICENSE +0 -0
  8. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/README.md +0 -0
  9. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/README.md +0 -0
  10. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
  11. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
  12. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
  13. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
  14. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
  15. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
  16. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
  17. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
  18. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  19. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  20. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  21. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr_parser.py +0 -0
  22. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr_visitor.py +0 -0
  23. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/boxes_view.py +0 -0
  24. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/examples/attribute_values.py +0 -0
  25. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/examples/part_attributes.py +0 -0
  26. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/examples/tuples_sequences.py +0 -0
  27. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/formatting.py +0 -0
  28. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/README.md +0 -0
  29. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
  30. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  31. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  32. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  33. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
  34. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
  35. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
  36. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
  37. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
  38. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
  39. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
  40. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
  41. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
  42. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
  43. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
  44. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/classes.py +0 -0
  45. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/LICENSE +0 -0
  46. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/README.md +0 -0
  47. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/__init__.py +0 -0
  48. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
  49. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
  50. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
  51. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
  52. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
  53. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
  54. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
  55. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
  56. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
  57. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
  58. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
  59. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
  60. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
  61. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
  62. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
  63. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
  64. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
  65. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
  66. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
  67. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
  68. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
  69. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
  70. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
  71. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
  72. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
  73. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
  74. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
  75. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
  76. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
  77. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
  78. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
  79. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
  80. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
  81. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
  82. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
  83. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
  84. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
  85. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Base.kerml +0 -0
  86. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
  87. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
  88. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
  89. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
  90. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
  91. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
  92. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
  93. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
  94. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
  95. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
  96. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
  97. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
  98. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Links.kerml +0 -0
  99. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
  100. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
  101. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
  102. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
  103. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
  104. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
  105. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
  106. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
  107. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
  108. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
  109. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
  110. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
  111. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
  112. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
  113. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
  114. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
  115. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
  116. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
  117. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
  118. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
  119. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
  120. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
  121. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Actions.sysml +0 -0
  122. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
  123. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
  124. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
  125. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
  126. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Cases.sysml +0 -0
  127. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Connections.sysml +0 -0
  128. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
  129. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Flows.sysml +0 -0
  130. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
  131. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Items.sysml +0 -0
  132. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
  133. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Parts.sysml +0 -0
  134. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Ports.sysml +0 -0
  135. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
  136. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
  137. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/States.sysml +0 -0
  138. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/SysML.sysml +0 -0
  139. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
  140. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
  141. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Views.sysml +0 -0
  142. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/navigate.py +0 -0
  143. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/plantuml.py +0 -0
  144. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/project.py +0 -0
  145. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/semantic.py +0 -0
  146. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/store.py +0 -0
  147. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/traceability.py +0 -0
  148. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/us_customary_units.txt +0 -0
  149. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/usage.py +0 -0
  150. {sysmlpy-0.62.0 → sysmlpy-0.63.0}/src/sysmlpy/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sysmlpy
3
- Version: 0.62.0
3
+ Version: 0.63.0
4
4
  Summary:
5
5
  License-File: LICENSE
6
6
  Author: Jon R. Fox (mycr0ft)
@@ -6,7 +6,7 @@ build-backend = "poetry.core.masonry.api"
6
6
 
7
7
  [project]
8
8
  name = "sysmlpy"
9
- version = "0.62.0"
9
+ version = "0.63.0"
10
10
  description = ""
11
11
  authors = [{ name = "Jon R. Fox (mycr0ft)", email = "jon.fox@drfox.com" }]
12
12
  readme = "README.md"
@@ -19,6 +19,7 @@ __all__ = [
19
19
  "as_traceability_matrix_view",
20
20
  "as_sequence_view", "as_case_view", "as_browser_view",
21
21
  "extract_traceability", "TraceabilityReport", "RequirementTrace",
22
+ "to_interchange", "from_interchange", "interchange_to_json_text",
22
23
  "analyze", "AnalysisResult", "SemanticIssue", "SemanticAnalyzer",
23
24
  "SysMLSyntaxError", "PartialParseError",
24
25
  "loads_partial", "load_partial",
@@ -27,7 +28,7 @@ __all__ = [
27
28
  "render_state_transition_view_svg", "boxes_view",
28
29
  ]
29
30
  __author__ = "Jon Fox"
30
- __version__ = "0.62.0"
31
+ __version__ = "0.63.0"
31
32
 
32
33
  from sysmlpy.usage import (
33
34
  Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
@@ -47,6 +48,9 @@ from sysmlpy.traceability import (
47
48
  extract_traceability, TraceabilityReport, RequirementTrace,
48
49
  as_traceability_matrix_view,
49
50
  )
51
+ from sysmlpy.interchange import (
52
+ to_interchange, from_interchange, interchange_to_json_text,
53
+ )
50
54
 
51
55
 
52
56
  class PartialParseError(Exception):
@@ -31,7 +31,7 @@ import sysmlpy
31
31
  from sysmlpy import loads
32
32
 
33
33
  # Subcommand table, also used to detect the legacy flat invocation form.
34
- SUBCOMMANDS = ("parse", "analyze", "view", "trace", "format", "fmt")
34
+ SUBCOMMANDS = ("parse", "analyze", "view", "trace", "export", "import", "format", "fmt")
35
35
 
36
36
 
37
37
  # ---------------------------------------------------------------------------
@@ -317,6 +317,71 @@ def cmd_trace(args) -> int:
317
317
  return 0
318
318
 
319
319
 
320
+ def cmd_export(args) -> int:
321
+ """SysML text → JSON interchange document (v0.63.0, Goal 3)."""
322
+ from sysmlpy.interchange import to_interchange, interchange_to_json_text
323
+
324
+ paths = [Path(f) for f in args.files]
325
+ for p in _missing_files(paths):
326
+ print(f"Error: File '{p}' not found.", file=sys.stderr)
327
+ return 2
328
+
329
+ try:
330
+ model = sysmlpy.load_files(paths, library=args.library)
331
+ except Exception as e:
332
+ print(f"Parse error: {e}", file=sys.stderr)
333
+ return 2
334
+
335
+ try:
336
+ document = to_interchange(model)
337
+ except Exception as e:
338
+ print(f"Error: export failed on this model: {e}", file=sys.stderr)
339
+ return 1
340
+
341
+ output = interchange_to_json_text(document, indent=None if args.compact else 2)
342
+ if args.output:
343
+ Path(args.output).write_text(output + "\n", encoding="utf-8")
344
+ print(f"Wrote {args.output}")
345
+ else:
346
+ print(output)
347
+ return 0
348
+
349
+
350
+ def cmd_import(args) -> int:
351
+ """JSON interchange document → SysML text (v0.63.0, Goal 3)."""
352
+ from sysmlpy.interchange import from_interchange
353
+
354
+ path = Path(args.file)
355
+ if not path.exists():
356
+ print(f"Error: File '{path}' not found.", file=sys.stderr)
357
+ return 2
358
+
359
+ try:
360
+ content = path.read_text(encoding="utf-8")
361
+ except OSError as e:
362
+ print(f"Error reading file: {e}", file=sys.stderr)
363
+ return 2
364
+
365
+ try:
366
+ model = from_interchange(content)
367
+ except ValueError as e:
368
+ print(f"Error: invalid interchange document: {e}", file=sys.stderr)
369
+ return 2
370
+ except json.JSONDecodeError as e:
371
+ print(f"Error: not valid JSON: {e}", file=sys.stderr)
372
+ return 2
373
+
374
+ output = model.dump()
375
+ if args.output:
376
+ if not output.endswith("\n"):
377
+ output += "\n"
378
+ Path(args.output).write_text(output, encoding="utf-8")
379
+ print(f"Wrote {args.output}")
380
+ else:
381
+ print(output)
382
+ return 0
383
+
384
+
320
385
  # ---------------------------------------------------------------------------
321
386
  # legacy flat invocation (kept for backward compatibility)
322
387
  # ---------------------------------------------------------------------------
@@ -541,6 +606,43 @@ def build_parser() -> argparse.ArgumentParser:
541
606
  )
542
607
  p_trace.set_defaults(func=cmd_trace)
543
608
 
609
+ p_export = sub.add_parser(
610
+ "export",
611
+ help="Export SysML to the JSON interchange format",
612
+ description="Load the files as one merged model and emit a "
613
+ "JSON-LD-style partition interchange document "
614
+ "(flat @graph of elements with @id/@type). Exit 2 "
615
+ "on parse failure.",
616
+ )
617
+ p_export.add_argument("files", nargs="+", help="SysML v2 file(s)")
618
+ p_export.add_argument(
619
+ "-o", "--output",
620
+ help="Write the JSON document to a file instead of stdout",
621
+ )
622
+ p_export.add_argument(
623
+ "--compact", action="store_true",
624
+ help="Emit compact JSON (no indentation)",
625
+ )
626
+ p_export.add_argument(
627
+ "-l", "--library",
628
+ help="Path to SysML v2 library files to use for parsing",
629
+ )
630
+ p_export.set_defaults(func=cmd_export)
631
+
632
+ p_import = sub.add_parser(
633
+ "import",
634
+ help="Import a JSON interchange document as SysML text",
635
+ description="Rebuild a model from a JSON interchange document "
636
+ "(sysmlpy export format) and print or write the "
637
+ "equivalent SysML v2 text. Exit 2 on invalid input.",
638
+ )
639
+ p_import.add_argument("file", help="Interchange JSON file")
640
+ p_import.add_argument(
641
+ "-o", "--output",
642
+ help="Write the SysML text to a file instead of stdout",
643
+ )
644
+ p_import.set_defaults(func=cmd_import)
645
+
544
646
  return parser
545
647
 
546
648
 
@@ -93,7 +93,15 @@ class Model(Searchable):
93
93
  raise ValueError("Base Model must be encapsulated by a package.")
94
94
 
95
95
  definition = load_grammar_antlr(s, library=library)["ownedRelationship"]
96
+ return self._load_definition(definition)
96
97
 
98
+ def _load_definition(self: type[ModelType], definition) -> ModelType:
99
+ """Build the model from a parsed definition-dict member list.
100
+
101
+ Shared by :meth:`load` (fresh parse) and the JSON interchange
102
+ importer (v0.63.0 — ``from_interchange`` feeds the rebuilt dict
103
+ straight into this path).
104
+ """
97
105
  member_grammar = []
98
106
  found_package = False
99
107
  for member in definition:
@@ -0,0 +1,294 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """SysML v2 JSON interchange for sysmlpy (v0.63.0 — Adoption Roadmap Goal 3).
4
+
5
+ Exports a loaded model to a JSON-LD-style *partition interchange*
6
+ document in the style of the SysML v2 spec's JSON exchange format, and
7
+ imports such a document back into a live :class:`~sysmlpy.definition.Model`
8
+ — losslessly, with deterministic element identifiers.
9
+
10
+ Document shape::
11
+
12
+ {
13
+ "@context": {"@version": 1.1, "@vocab": "..."},
14
+ "@id": "id:root",
15
+ "@graph": [
16
+ {"@id": "id:pkg-1", "@type": "Package", "declaredName": "P",
17
+ "ownedRelationship": [{"@id": "id:rel-1"}]},
18
+ {"@id": "id:rel-1", "@type": "OwningMembership",
19
+ "ownedRelatedElement": {"@id": "id:part-1"}},
20
+ {"@id": "id:part-1", "@type": "PartDefinition", ...},
21
+ ...
22
+ ]
23
+ }
24
+
25
+ Design notes:
26
+
27
+ - **Flat graph.** Every element (packages, relationships, declarations,
28
+ bodies, ...) appears exactly once in ``@graph``; structural properties
29
+ reference other elements by ``{"@id": ...}``. Scalars (``declaredName``,
30
+ ``declaredShortName``, keywords, ...) are kept inline. ``null`` values
31
+ are preserved so the export/rebuild is shape-exact.
32
+ - **``@type``** is the SysML v2 abstract-syntax metaclass name, exactly
33
+ as the parser's internal dictionary uses it (``Package``,
34
+ ``OwningMembership``, ``PartDefinition``, ...).
35
+ - **Deterministic ``@id``s.** Element identifiers are ``uuid5`` derived
36
+ from the element's position in the model tree, so exporting the same
37
+ model twice yields byte-identical JSON (diff-friendly, ties into
38
+ semantic model diff — roadmap Goal 8).
39
+ - **Round-trip.** ``from_interchange(to_interchange(model))`` rebuilds
40
+ the internal dictionary shape-exactly and constructs a live ``Model``
41
+ through the same grammar-class path as a fresh parse
42
+ (``Model._load_definition``).
43
+
44
+ The ``@vocab`` IRI space is sysmlpy-owned; mapping every property to the
45
+ normative OMG JSON-LD context is tracked as follow-up work.
46
+
47
+ Public surface:
48
+
49
+ - :func:`to_interchange` — ``Model`` or SysML text → interchange dict
50
+ - :func:`from_interchange` — interchange dict / JSON text → ``Model``
51
+ - :func:`interchange_to_json_text` / convenience formatting helpers
52
+ """
53
+
54
+ from __future__ import annotations
55
+
56
+ import json as _json
57
+ import uuid as _uuid
58
+
59
+ __all__ = [
60
+ "INTERCHANGE_CONTEXT",
61
+ "INTERCHANGE_NAMESPACE",
62
+ "to_interchange",
63
+ "from_interchange",
64
+ "interchange_to_json_text",
65
+ ]
66
+
67
+ #: JSON-LD context emitted with every document. Property names are the
68
+ #: SysML v2 abstract-syntax property names used by the parser; the
69
+ #: vocabulary IRI is sysmlpy-owned (normative OMG context mapping is
70
+ #: tracked as follow-up work).
71
+ INTERCHANGE_CONTEXT = {
72
+ "@version": 1.1,
73
+ "@vocab": "https://github.com/mycr0ft/sysmlpy/interchange#",
74
+ }
75
+
76
+ #: UUID namespace for deterministic element identifiers.
77
+ INTERCHANGE_NAMESPACE = _uuid.uuid5(
78
+ _uuid.NAMESPACE_URL, "https://github.com/mycr0ft/sysmlpy/interchange"
79
+ )
80
+
81
+ _REF_KEYS = ("@id", "@type")
82
+
83
+
84
+ # ---------------------------------------------------------------------------
85
+ # export
86
+ # ---------------------------------------------------------------------------
87
+
88
+
89
+ def _child_id(parent_id: str, key: str, index: int) -> str:
90
+ """Deterministic identifier for the child at ``parent.key[index]``."""
91
+ return "sysml:" + str(
92
+ _uuid.uuid5(INTERCHANGE_NAMESPACE, f"{parent_id}|{key}|{index}")
93
+ )
94
+
95
+
96
+ def _flatten(node: dict, parent_id: str, key: str, index: int,
97
+ graph: list) -> str:
98
+ """Recursively flatten a visitor-dict node into the graph.
99
+
100
+ Returns the ``@id`` assigned to this node.
101
+ """
102
+ elem_id = _child_id(parent_id, key, index)
103
+ elem = {"@id": elem_id, "@type": node.get("name")}
104
+ for k, v in node.items():
105
+ if k == "name":
106
+ continue # captured as @type
107
+ elem[k] = _flatten_value(v, elem_id, k, graph)
108
+ graph.append(elem)
109
+ return elem_id
110
+
111
+
112
+ def _flatten_value(v, elem_id: str, key: str, graph: list):
113
+ """Flatten one property value: dicts become @id refs, scalars inline."""
114
+ if v is None or isinstance(v, (str, int, float, bool)):
115
+ return v
116
+ if isinstance(v, dict):
117
+ return {"@id": _flatten(v, elem_id, key, 0, graph)}
118
+ if isinstance(v, list):
119
+ out = []
120
+ for i, item in enumerate(v):
121
+ if isinstance(item, dict):
122
+ out.append({"@id": _flatten(item, elem_id, key, i, graph)})
123
+ else:
124
+ out.append(item)
125
+ return out
126
+ # Unknown value type — keep it inline (best effort).
127
+ return v
128
+
129
+
130
+ def to_interchange(source) -> dict:
131
+ """Export a model to the SysML v2 JSON interchange representation.
132
+
133
+ Parameters
134
+ ----------
135
+ source : Model or str
136
+ Either a loaded model (``sysmlpy.loads(...)`` / ``load_files(...)``
137
+ / programmatically built) or SysML v2 source text (parsed fresh).
138
+
139
+ Returns
140
+ -------
141
+ dict
142
+ JSON-LD-style document: ``@context``, root ``@id`` and a flat
143
+ ``@graph`` of elements.
144
+ """
145
+ from sysmlpy.definition import Model
146
+
147
+ if isinstance(source, Model):
148
+ # Export from the *raw parser dict*, not the grammar classes'
149
+ # ``get_definition()`` output: the class serialization normalizes
150
+ # the tree (adds ``ownedRelationship`` keys, unwraps
151
+ # ``OccurrenceUsageElement``), which changes how classes
152
+ # re-dispatch on import (e.g. satisfy wrappers were lost).
153
+ # ``dump()`` is the canonical serialization — re-parsing it gives
154
+ # the same dictionary shape a fresh parse produces.
155
+ try:
156
+ text = source.dump()
157
+ except ValueError:
158
+ text = "" # empty model (dump raises "no elements to output")
159
+ if not text.strip():
160
+ root_dict = {
161
+ "name": "PackageBodyElement",
162
+ "ownedRelationship": [],
163
+ }
164
+ else:
165
+ from sysmlpy import load_grammar
166
+ root_dict = load_grammar(text)
167
+ elif isinstance(source, str):
168
+ from sysmlpy import load_grammar
169
+ root_dict = load_grammar(source)
170
+ else:
171
+ raise TypeError(
172
+ "to_interchange expects a Model or SysML text, "
173
+ f"not {source.__class__.__name__}"
174
+ )
175
+
176
+ graph: list = []
177
+ root_id = _flatten(root_dict, "root", "ownedRelationship", 0, graph)
178
+ return {
179
+ "@context": dict(INTERCHANGE_CONTEXT),
180
+ "@id": root_id,
181
+ "@graph": graph,
182
+ }
183
+
184
+
185
+ def interchange_to_json_text(document: dict, *, indent: int = 2) -> str:
186
+ """Serialize an interchange document to a JSON string."""
187
+ return _json.dumps(document, indent=indent)
188
+
189
+
190
+ # ---------------------------------------------------------------------------
191
+ # import
192
+ # ---------------------------------------------------------------------------
193
+
194
+
195
+ def _is_ref(v) -> bool:
196
+ return isinstance(v, dict) and set(v.keys()) == {"@id"}
197
+
198
+
199
+ def _rebuild(ref: dict, by_id: dict, stack: tuple = ()) -> dict:
200
+ """Rebuild the internal-dict node referenced by ``ref``."""
201
+ elem_id = ref["@id"]
202
+ if elem_id in stack:
203
+ raise ValueError(f"Cyclic element reference detected: {elem_id}")
204
+ elem = by_id.get(elem_id)
205
+ if elem is None:
206
+ raise ValueError(f"Interchange document references unknown @id: {elem_id}")
207
+ node = {"name": elem.get("@type")}
208
+ for k, v in elem.items():
209
+ if k in _REF_KEYS:
210
+ continue
211
+ node[k] = _rebuild_value(v, by_id, stack + (elem_id,))
212
+ return node
213
+
214
+
215
+ def _rebuild_value(v, by_id: dict, stack: tuple):
216
+ if _is_ref(v):
217
+ return _rebuild(v, by_id, stack)
218
+ if isinstance(v, list):
219
+ return [
220
+ _rebuild(i, by_id, stack) if _is_ref(i) else i for i in v
221
+ ]
222
+ return v
223
+
224
+
225
+ def from_interchange(data) -> "Model":
226
+ """Import a SysML v2 JSON interchange document into a live Model.
227
+
228
+ Parameters
229
+ ----------
230
+ data : dict or str
231
+ The interchange document (as produced by :func:`to_interchange`),
232
+ either as a dict or as a JSON string.
233
+
234
+ Returns
235
+ -------
236
+ Model
237
+ """
238
+ from sysmlpy.definition import Model
239
+
240
+ if isinstance(data, str):
241
+ data = _json.loads(data)
242
+ if not isinstance(data, dict):
243
+ raise ValueError(
244
+ "Interchange document must be a dict or JSON string, "
245
+ f"got {type(data).__name__}"
246
+ )
247
+ graph = data.get("@graph")
248
+ if not isinstance(graph, list):
249
+ raise ValueError("Interchange document has no @graph array")
250
+ by_id = {}
251
+ for elem in graph:
252
+ if not isinstance(elem, dict) or "@id" not in elem:
253
+ raise ValueError("Every @graph element needs an @id")
254
+ by_id[elem["@id"]] = elem
255
+
256
+ root_ref = data.get("@id")
257
+ if root_ref is None:
258
+ # Fall back to the first element that is not referenced by others.
259
+ referenced = {
260
+ v["@id"]
261
+ for elem in graph
262
+ for v in _walk_refs(elem)
263
+ }
264
+ roots = [e["@id"] for e in graph if e["@id"] not in referenced]
265
+ if not roots:
266
+ raise ValueError("Cannot determine root element of document")
267
+ root_ref = roots[0]
268
+
269
+ root = _rebuild({"@id": root_ref}, by_id)
270
+ relationships = root.get("ownedRelationship")
271
+ if relationships is None:
272
+ raise ValueError(
273
+ "Root element carries no ownedRelationship — not a model document"
274
+ )
275
+
276
+ model = Model()
277
+ return model._load_definition(relationships)
278
+
279
+
280
+ def _walk_refs(elem: dict):
281
+ """Yield every ``{"@id": ...}`` ref reachable from *elem*'s properties."""
282
+ for v in elem.values():
283
+ yield from _walk_refs_value(v)
284
+
285
+
286
+ def _walk_refs_value(v):
287
+ if _is_ref(v):
288
+ yield v
289
+ elif isinstance(v, list):
290
+ for item in v:
291
+ yield from _walk_refs_value(item)
292
+ elif isinstance(v, dict):
293
+ for item in v.values():
294
+ yield from _walk_refs_value(item)
File without changes
File without changes
File without changes
File without changes