sysmlpy 0.69.1__tar.gz → 0.71.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 (158) hide show
  1. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/PKG-INFO +1 -1
  2. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/pyproject.toml +1 -1
  3. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/__init__.py +1 -1
  4. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/semantic.py +371 -0
  5. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/LICENSE +0 -0
  6. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/README.md +0 -0
  7. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/__main__.py +0 -0
  8. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr/README.md +0 -0
  9. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
  10. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
  11. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
  12. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
  13. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
  14. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
  15. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
  16. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
  17. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  18. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  19. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  20. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr_parser.py +0 -0
  21. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/antlr_visitor.py +0 -0
  22. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/boxes_view.py +0 -0
  23. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/definition.py +0 -0
  24. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/evaluator.py +0 -0
  25. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/examples/attribute_values.py +0 -0
  26. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/examples/part_attributes.py +0 -0
  27. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/examples/tuples_sequences.py +0 -0
  28. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/formatting.py +0 -0
  29. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/README.md +0 -0
  30. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
  31. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  32. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  33. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  34. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
  35. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
  36. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
  37. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
  38. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
  39. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
  40. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
  41. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
  42. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
  43. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
  44. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
  45. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/grammar/classes.py +0 -0
  46. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/interchange.py +0 -0
  47. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/LICENSE +0 -0
  48. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/README.md +0 -0
  49. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/__init__.py +0 -0
  50. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
  51. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
  52. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
  53. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
  54. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
  55. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
  56. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
  57. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
  58. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
  59. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
  60. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
  61. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
  62. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
  63. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
  64. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
  65. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
  66. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
  67. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
  68. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
  69. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
  70. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
  71. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
  72. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
  73. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
  74. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
  75. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
  76. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
  77. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
  78. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
  79. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
  80. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
  81. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
  82. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
  83. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
  84. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
  85. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
  86. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
  87. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/Base.kerml +0 -0
  88. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
  89. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
  90. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
  91. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
  92. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
  93. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
  94. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
  95. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
  96. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
  97. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
  98. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
  99. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
  100. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/Links.kerml +0 -0
  101. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
  102. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
  103. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
  104. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
  105. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
  106. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
  107. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
  108. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
  109. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
  110. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
  111. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
  112. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
  113. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
  114. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
  115. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
  116. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
  117. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
  118. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
  119. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
  120. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
  121. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
  122. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
  123. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Actions.sysml +0 -0
  124. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
  125. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
  126. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
  127. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
  128. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Cases.sysml +0 -0
  129. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Connections.sysml +0 -0
  130. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
  131. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Flows.sysml +0 -0
  132. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
  133. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Items.sysml +0 -0
  134. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
  135. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Parts.sysml +0 -0
  136. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Ports.sysml +0 -0
  137. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
  138. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
  139. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/States.sysml +0 -0
  140. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/SysML.sysml +0 -0
  141. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
  142. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
  143. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/library/systems/Views.sysml +0 -0
  144. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/lsp/__init__.py +0 -0
  145. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/lsp/__main__.py +0 -0
  146. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/lsp/protocol.py +0 -0
  147. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/lsp/server.py +0 -0
  148. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/lsp/stdio.py +0 -0
  149. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/navigate.py +0 -0
  150. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/plantuml.py +0 -0
  151. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/project.py +0 -0
  152. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/sim.py +0 -0
  153. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/spreadsheet.py +0 -0
  154. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/store.py +0 -0
  155. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/traceability.py +0 -0
  156. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/us_customary_units.txt +0 -0
  157. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/usage.py +0 -0
  158. {sysmlpy-0.69.1 → sysmlpy-0.71.0}/src/sysmlpy/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sysmlpy
3
- Version: 0.69.1
3
+ Version: 0.71.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.69.1"
9
+ version = "0.71.0"
10
10
  description = ""
11
11
  authors = [{ name = "Jon R. Fox (mycr0ft)", email = "jon.fox@drfox.com" }]
12
12
  readme = "README.md"
@@ -34,7 +34,7 @@ __all__ = [
34
34
  "render_state_transition_view_svg", "boxes_view",
35
35
  ]
36
36
  __author__ = "Jon Fox"
37
- __version__ = "0.69.1"
37
+ __version__ = "0.71.0"
38
38
 
39
39
  from sysmlpy.usage import (
40
40
  Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
@@ -1236,6 +1236,119 @@ class ExpressionIdentifierCollector:
1236
1236
  self._walk(child, results, child_scope)
1237
1237
 
1238
1238
 
1239
+ def _find_named_dicts(node: Any, name: str) -> list:
1240
+ """Locate every dict with ``dict["name"] == name`` in a tree."""
1241
+ out: list = []
1242
+
1243
+ def walk(n: Any) -> None:
1244
+ if isinstance(n, dict):
1245
+ if n.get("name") == name:
1246
+ out.append(n)
1247
+ for v in n.values():
1248
+ if isinstance(v, (dict, list)):
1249
+ walk(v)
1250
+ elif isinstance(n, list):
1251
+ for item in n:
1252
+ if isinstance(item, (dict, list)):
1253
+ walk(item)
1254
+
1255
+ walk(node)
1256
+ return out
1257
+
1258
+
1259
+ def _as_list_dicts(v: Any) -> list:
1260
+ """Normalize an optional-dict-or-list relationship field to a list."""
1261
+ if isinstance(v, list):
1262
+ return [x for x in v if isinstance(x, dict)]
1263
+ if isinstance(v, dict):
1264
+ return [v]
1265
+ return []
1266
+
1267
+
1268
+ def _find_declared_name(d: dict):
1269
+ """Bounded search for ``identification.declaredName`` in a usage/
1270
+ definition dict (the identification nesting varies by shape)."""
1271
+ frontier = [d]
1272
+ for _ in range(4):
1273
+ nxt = []
1274
+ for n in frontier:
1275
+ if not isinstance(n, dict):
1276
+ continue
1277
+ ident = n.get("identification")
1278
+ if isinstance(ident, dict):
1279
+ name = ident.get("declaredName")
1280
+ if name:
1281
+ return name
1282
+ for v in n.values():
1283
+ if isinstance(v, dict):
1284
+ nxt.append(v)
1285
+ elif isinstance(v, list):
1286
+ nxt.extend(x for x in v if isinstance(x, dict))
1287
+ frontier = nxt
1288
+ return None
1289
+
1290
+
1291
+ def _port_direction(port_usage: dict):
1292
+ """The explicit direction keyword on a PortUsage dict, if any.
1293
+
1294
+ The prefix chain is
1295
+ ``OccurrenceUsagePrefix → BasicUsagePrefix → RefPrefix.direction``
1296
+ where ``direction`` is ``{"in": ..., "out": ..., "inout": ...}`` —
1297
+ the present keyword is the non-empty string value.
1298
+ """
1299
+ pre = port_usage.get("prefix")
1300
+ while isinstance(pre, dict):
1301
+ d = pre.get("direction")
1302
+ if isinstance(d, dict):
1303
+ for k in ("in", "out", "inout"):
1304
+ v = d.get(k)
1305
+ if isinstance(v, str) and v.strip():
1306
+ return k
1307
+ return None
1308
+ pre = pre.get("prefix")
1309
+ return None
1310
+
1311
+
1312
+ def _connector_end_chain(end: dict) -> list:
1313
+ """Feature-chain segment names of a ConnectorEnd dict."""
1314
+ ors = end.get("ownedRelationship") if isinstance(end, dict) else None
1315
+ for rel in _as_list_dicts(ors):
1316
+ if rel.get("name") != "OwnedReferenceSubsetting":
1317
+ continue
1318
+ ofc_list = _as_list_dicts(rel.get("ownedRelatedElement"))
1319
+ ofc = ofc_list[0] if ofc_list else {}
1320
+ if ofc.get("name") != "OwnedFeatureChain":
1321
+ continue
1322
+ feat = ofc.get("feature") or {}
1323
+ names = []
1324
+ for chain_rel in _as_list_dicts(feat.get("ownedRelationship")):
1325
+ if chain_rel.get("name") != "OwnedFeatureChaining":
1326
+ continue
1327
+ cf = chain_rel.get("chainingFeature") or {}
1328
+ qn = cf.get("names")
1329
+ if isinstance(qn, list) and qn:
1330
+ names.append(str(qn[-1]))
1331
+ return names
1332
+ return []
1333
+
1334
+
1335
+ def _usage_typed_by(usage: dict):
1336
+ """The last segment of a usage dict's OwnedFeatureTyping, if any.
1337
+
1338
+ The typing rides the declaration/specialization chain, which
1339
+ precedes the body in dict order, so a usage's own typing is found
1340
+ before any nested member's typing.
1341
+ """
1342
+ for rel in _find_named_dicts(usage, "OwnedFeatureTyping"):
1343
+ ft = rel.get("type") or {}
1344
+ qn = ft.get("type") if isinstance(ft, dict) else None
1345
+ if isinstance(qn, dict):
1346
+ names = qn.get("names")
1347
+ if isinstance(names, list) and names:
1348
+ return str(names[-1])
1349
+ return None
1350
+
1351
+
1239
1352
  def _find_payload_parameters(node: Any) -> list:
1240
1353
  """Locate every ``PayloadParameter`` dict in a grammar tree."""
1241
1354
  out: list = []
@@ -2380,6 +2493,9 @@ class SemanticAnalyzer:
2380
2493
  issues.extend(self._check_state_machines(model))
2381
2494
  issues.extend(self._check_trigger_payloads(model, symtab, lib_roots))
2382
2495
  issues.extend(self._check_requirement_coverage(model))
2496
+ issues.extend(self._check_trace_targets(model, symtab, lib_roots))
2497
+ issues.extend(self._check_verify_targets(model, symtab, lib_roots))
2498
+ issues.extend(self._check_connector_directions(model))
2383
2499
 
2384
2500
  # Step 6: Stylistic checks (warnings, not errors)
2385
2501
  if style_checks:
@@ -3083,6 +3199,261 @@ class SemanticAnalyzer:
3083
3199
  ))
3084
3200
  return issues
3085
3201
 
3202
+ def _check_trace_targets(
3203
+ self,
3204
+ model: Any,
3205
+ symtab: "SymbolTable",
3206
+ lib_roots: list,
3207
+ ) -> list[SemanticIssue]:
3208
+ """Resolve ``satisfy <req> by <part>`` targets (Goal 9).
3209
+
3210
+ A typo'd satisfy target is silent today — worse, the Goal 2
3211
+ traceability extractor materializes the dangling edge as a
3212
+ *phantom requirement* in coverage reports, so the real
3213
+ requirement reads uncovered while a fake one appears traced.
3214
+ Each satisfy target reference is resolved against the symbol
3215
+ table in the satisfying part's scope; unresolved targets
3216
+ produce UNRESOLVED_TRACE_TARGET errors.
3217
+ """
3218
+ issues: list[SemanticIssue] = []
3219
+ for element, scope_path in self._walk_usages(model):
3220
+ grammar = getattr(element, "grammar", None)
3221
+ if grammar is None or \
3222
+ grammar.__class__.__name__ != "SatisfyRequirementUsage":
3223
+ continue
3224
+ ors = getattr(grammar, "ors", None)
3225
+ if ors is None:
3226
+ continue
3227
+ try:
3228
+ ref = ors.dump().strip().rstrip(";").strip()
3229
+ except Exception:
3230
+ continue
3231
+ if not ref:
3232
+ continue
3233
+ if self._is_resolved(ref, symtab, scope_path, lib_roots):
3234
+ # Kind check: the target must be a requirement.
3235
+ # (Library-resolved targets yield no element here and
3236
+ # are left alone — conservative by design.)
3237
+ found = self._resolve_element(ref, symtab, scope_path)
3238
+ if found is not None and \
3239
+ type(found).__name__ != "Requirement":
3240
+ issues.append(SemanticIssue(
3241
+ severity="warning",
3242
+ code="TRACE_TARGET_NOT_REQUIREMENT",
3243
+ message=(
3244
+ f"satisfy target '{ref}' resolves to a "
3245
+ f"{type(found).__name__}, not a "
3246
+ "requirement"),
3247
+ element=element,
3248
+ reference=ref,
3249
+ ))
3250
+ continue
3251
+ issues.append(SemanticIssue(
3252
+ severity="error",
3253
+ code="UNRESOLVED_TRACE_TARGET",
3254
+ message=(
3255
+ f"satisfy target '{ref}' in "
3256
+ f"{type(element).__name__} "
3257
+ f"'{getattr(element, 'name', '<anonymous>')}' does "
3258
+ "not resolve to a defined requirement"),
3259
+ element=element,
3260
+ reference=ref,
3261
+ ))
3262
+ return issues
3263
+
3264
+ @staticmethod
3265
+ def _resolve_element(
3266
+ ref_str: str,
3267
+ symtab: "SymbolTable",
3268
+ scope_path: list[str],
3269
+ ):
3270
+ """The model element *ref_str* resolves to, if any.
3271
+
3272
+ Mirrors the symbol-table walk of :meth:`_is_resolved` (without
3273
+ the library-index shortcuts, which resolve to no model
3274
+ element).
3275
+ """
3276
+ current = symtab
3277
+ for scope_name in scope_path:
3278
+ child = current._children.get(scope_name)
3279
+ if child is not None:
3280
+ current = child
3281
+ else:
3282
+ break
3283
+ found = current.lookup(ref_str)
3284
+ if found is not None:
3285
+ return found
3286
+ if "::" in ref_str:
3287
+ parts = ref_str.split("::")
3288
+ table = current
3289
+ for part in parts[:-1]:
3290
+ found = table.lookup(part)
3291
+ if found is None:
3292
+ return None
3293
+ table = table._children.get(part, table)
3294
+ return table.lookup(parts[-1])
3295
+ return None
3296
+
3297
+ def _check_verify_targets(
3298
+ self,
3299
+ model: Any,
3300
+ symtab: "SymbolTable",
3301
+ lib_roots: list,
3302
+ ) -> list[SemanticIssue]:
3303
+ """Resolve ``verify <vc>`` members inside requirements (Goal 9).
3304
+
3305
+ ``verify v1 : VC;`` in a requirement body parses as a
3306
+ VerifyRequirementUsage whose ``ors`` holds the referenced
3307
+ verification-case name. Notably the visitor drops the
3308
+ ``: VC`` typing specialization entirely (``fsp`` is empty), so
3309
+ a typo'd verification-case *type* is invisible — but the
3310
+ member name reference is checkable: resolve it against the
3311
+ symbol table in the requirement's scope. Unresolved targets
3312
+ produce UNRESOLVED_VERIFY_TARGET errors (same contract as
3313
+ UNRESOLVED_TRACE_TARGET for satisfy).
3314
+ """
3315
+ issues: list[SemanticIssue] = []
3316
+ for element, scope_path in self._walk_usages(model):
3317
+ # verify members live inside Requirement grammar trees
3318
+ # (no VerifyRequirementUsage object of their own)
3319
+ if type(element).__name__ != "Requirement":
3320
+ continue
3321
+ grammar = getattr(element, "grammar", None)
3322
+ if grammar is None:
3323
+ continue
3324
+ try:
3325
+ grammar_def = grammar.get_definition()
3326
+ except Exception:
3327
+ continue
3328
+ if not isinstance(grammar_def, dict):
3329
+ continue
3330
+ for vr in _find_named_dicts(grammar_def, "VerifyRequirementUsage"):
3331
+ ors = vr.get("ors")
3332
+ if not isinstance(ors, dict):
3333
+ continue
3334
+ rf = ors.get("referencedFeature") or {}
3335
+ # referencedFeature *is* the QualifiedName node here
3336
+ names = rf.get("names") if isinstance(rf, dict) else None
3337
+ if not names:
3338
+ continue
3339
+ ref = "::".join(str(n) for n in names)
3340
+ if self._is_resolved(ref, symtab, scope_path, lib_roots):
3341
+ continue
3342
+ issues.append(SemanticIssue(
3343
+ severity="error",
3344
+ code="UNRESOLVED_VERIFY_TARGET",
3345
+ message=(
3346
+ f"verify target '{ref}' in requirement "
3347
+ f"'{getattr(element, 'name', '<anonymous>')}' "
3348
+ "does not resolve to a defined element"),
3349
+ element=element,
3350
+ reference=ref,
3351
+ ))
3352
+ return issues
3353
+
3354
+ def _check_connector_directions(self, model: Any) -> list[SemanticIssue]:
3355
+ """Check connection-end port direction compatibility (Goal 9).
3356
+
3357
+ ``connection c connect a.p1 to b.p2;`` — when both end ports
3358
+ carry explicit directions and neither is ``inout``, wiring
3359
+ ``out`` to ``out`` or ``in`` to ``in`` flags
3360
+ CONNECTOR_DIRECTION_MISMATCH (warning — conjugated ports and
3361
+ exotic flow conventions exist, so this is advisory, not an
3362
+ error). Ends without a direction keyword, ``inout`` ends,
3363
+ chains deeper than two segments and unresolvable parts are
3364
+ skipped.
3365
+ """
3366
+ issues: list[SemanticIssue] = []
3367
+ try:
3368
+ from sysmlpy.sim import load_model_grammar
3369
+ visit = load_model_grammar(model)
3370
+ except Exception:
3371
+ return issues
3372
+
3373
+ scope_ports: dict = {} # def/usage name -> {port: direction}
3374
+ part_typing: dict = {} # part usage name -> typed-by name
3375
+ connections: list = [] # (name, scope_stack, [chain, ...])
3376
+
3377
+ def walk2(node, scope_stack):
3378
+ if isinstance(node, dict):
3379
+ nm = node.get("name")
3380
+ declared = _find_declared_name(node)
3381
+ new_stack = scope_stack
3382
+ if declared and isinstance(nm, str) and (
3383
+ nm.endswith("Usage") or nm.endswith("Definition")):
3384
+ if nm != "PortUsage":
3385
+ new_stack = scope_stack + [declared]
3386
+ if nm == "PortUsage":
3387
+ d = _port_direction(node)
3388
+ if d and scope_stack:
3389
+ scope_ports.setdefault(
3390
+ scope_stack[-1], {})[declared] = d
3391
+ elif nm == "ConnectionUsage":
3392
+ chains = []
3393
+ part = node.get("part") or {}
3394
+ bp = part.get("part") or {}
3395
+ for rel in _as_list_dicts(
3396
+ bp.get("ownedRelationship")):
3397
+ if rel.get("name") != "ConnectorEndMember":
3398
+ continue
3399
+ ends = _as_list_dicts(
3400
+ rel.get("ownedRelatedElement"))
3401
+ if not ends:
3402
+ continue
3403
+ chain = _connector_end_chain(ends[0])
3404
+ if chain:
3405
+ chains.append(chain)
3406
+ if len(chains) == 2:
3407
+ connections.append((declared, new_stack, chains))
3408
+ elif nm.endswith("Usage"):
3409
+ t = _usage_typed_by(node)
3410
+ if t:
3411
+ part_typing[declared] = t
3412
+ for k, v in node.items():
3413
+ if isinstance(v, (dict, list)):
3414
+ walk2(v, new_stack)
3415
+ elif isinstance(node, list):
3416
+ for x in node:
3417
+ walk2(x, scope_stack)
3418
+
3419
+ walk2(visit, [])
3420
+
3421
+ def end_direction(chain, scope_stack):
3422
+ if len(chain) == 2:
3423
+ part_name, port_name = chain
3424
+ t = part_typing.get(part_name)
3425
+ if t and port_name in scope_ports.get(t, {}):
3426
+ return scope_ports[t][port_name]
3427
+ return scope_ports.get(part_name, {}).get(port_name)
3428
+ if len(chain) == 1:
3429
+ port_name = chain[0]
3430
+ for scope in reversed(scope_stack):
3431
+ if port_name in scope_ports.get(scope, {}):
3432
+ return scope_ports[scope][port_name]
3433
+ t = part_typing.get(scope)
3434
+ if t and port_name in scope_ports.get(t, {}):
3435
+ return scope_ports[t][port_name]
3436
+ return None
3437
+
3438
+ for cname, cstack, chains in connections:
3439
+ d1 = end_direction(chains[0], cstack)
3440
+ d2 = end_direction(chains[1], cstack)
3441
+ if not d1 or not d2:
3442
+ continue
3443
+ if d1 == "inout" or d2 == "inout":
3444
+ continue
3445
+ if d1 == d2:
3446
+ issues.append(SemanticIssue(
3447
+ severity="warning",
3448
+ code="CONNECTOR_DIRECTION_MISMATCH",
3449
+ message=(
3450
+ f"Connection '{cname}' binds two '{d1}' ports "
3451
+ f"({chains[0][-1]} -> {chains[1][-1]}); a "
3452
+ "connection normally pairs 'out' with 'in'"),
3453
+ reference=cname,
3454
+ ))
3455
+ return issues
3456
+
3086
3457
  def _check_state_machines(self, model: Any) -> list[SemanticIssue]:
3087
3458
  """OCL well-formedness for ``state def`` machines (Goal 9).
3088
3459
 
File without changes
File without changes
File without changes
File without changes
File without changes