sysmlpy 0.95.0__tar.gz → 0.96.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/PKG-INFO +111 -3
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/README.md +109 -2
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/pyproject.toml +1 -1
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/__init__.py +89 -2
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr_visitor.py +27 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/definition.py +39 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/dfa_cache.py +14 -1
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/classes.py +27 -2
- sysmlpy-0.96.1/src/sysmlpy/kerml/KerMLLexer.g4 +11 -0
- sysmlpy-0.96.1/src/sysmlpy/kerml/KerMLLexer.interp +482 -0
- sysmlpy-0.96.1/src/sysmlpy/kerml/KerMLLexer.py +751 -0
- sysmlpy-0.96.1/src/sysmlpy/kerml/KerMLLexer.tokens +302 -0
- sysmlpy-0.96.1/src/sysmlpy/kerml/KerMLParser.g4 +16 -0
- sysmlpy-0.96.1/src/sysmlpy/kerml/KerMLParser.interp +519 -0
- sysmlpy-0.96.1/src/sysmlpy/kerml/KerMLParser.py +15048 -0
- sysmlpy-0.96.1/src/sysmlpy/kerml/KerMLParser.tokens +305 -0
- sysmlpy-0.96.1/src/sysmlpy/kerml/KerMLParserVisitor.py +973 -0
- sysmlpy-0.96.1/src/sysmlpy/kerml/README.md +45 -0
- sysmlpy-0.96.1/src/sysmlpy/kerml/__init__.py +18 -0
- sysmlpy-0.96.1/src/sysmlpy/kerml/kerml.py +117 -0
- sysmlpy-0.96.1/src/sysmlpy/kerml/kerml_visitor.py +482 -0
- sysmlpy-0.96.1/src/sysmlpy/mdtables.py +243 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/plantuml.py +249 -15
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/semantic.py +90 -1
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/traceability.py +4 -2
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/usage.py +312 -5
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/LICENSE +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/__main__.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr/README.md +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/antlr_parser.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/boxes_view.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/diff.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/evaluator.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/examples/attribute_values.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/examples/part_attributes.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/examples/tuples_sequences.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/formatting.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/README.md +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/interchange.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/ipython_magic.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/LICENSE +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/README.md +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/__init__.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/Base.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/Links.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Actions.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Cases.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Connections.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Flows.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Items.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Parts.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Ports.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/States.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/SysML.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/library/systems/Views.sysml +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/lsp/__init__.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/lsp/__main__.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/lsp/protocol.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/lsp/server.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/lsp/stdio.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/navigate.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/project.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/repl.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/reqif_io.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/sim.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/spreadsheet.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/store.py +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/us_customary_units.txt +0 -0
- {sysmlpy-0.95.0 → sysmlpy-0.96.1}/src/sysmlpy/validator.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sysmlpy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.96.1
|
|
4
4
|
Summary:
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Author: Jon R. Fox (mycr0ft)
|
|
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
16
17
|
Provides-Extra: cayley
|
|
17
18
|
Provides-Extra: graph
|
|
18
19
|
Provides-Extra: jupyter
|
|
@@ -136,6 +137,40 @@ and the mapping to this implementation — is in the
|
|
|
136
137
|
[sysml-copier](https://github.com/mycr0ft/sysml-copier) template's
|
|
137
138
|
`docs/sysml-magics.md`.
|
|
138
139
|
|
|
140
|
+
## Interactive REPL
|
|
141
|
+
|
|
142
|
+
`sysmlpy repl [FILE ...]` is a terminal session in the same spirit: each
|
|
143
|
+
submission is a SysML declaration, an expression, or a `%command`, and
|
|
144
|
+
declarations accumulate into a session model with the same
|
|
145
|
+
member-granularity merge as the Jupyter magics (a re-declared member
|
|
146
|
+
replaces its prior definition, sibling members are kept, and a
|
|
147
|
+
`note:` line says so). Submissions continue onto a `...>` line while
|
|
148
|
+
brackets stay open; a line that is not a declaration evaluates as an
|
|
149
|
+
expression. Ctrl-D or `%quit` exits; `%reset` discards the session.
|
|
150
|
+
|
|
151
|
+
| Command | Purpose |
|
|
152
|
+
|---------|---------|
|
|
153
|
+
| `%list [NAME]` | Packages (with member counts), or elements matching NAME with qualified names |
|
|
154
|
+
| `%show NAME` | `repr()` of the first element named NAME |
|
|
155
|
+
| `%dump` | Round-tripped SysML text of the session model |
|
|
156
|
+
| `%eval EXPR` | Evaluate an expression against the session model |
|
|
157
|
+
| `%set NAME=VALUE` | Bind a what-if value (number / bool / string / unit) |
|
|
158
|
+
| `%bindings` | Show current what-if bindings |
|
|
159
|
+
| `%calc NAME a, b` | Invoke a calc def with positional literal arguments |
|
|
160
|
+
| `%check` | Check the model's constraints (pass/fail report) |
|
|
161
|
+
| `%values` | Collected attribute values |
|
|
162
|
+
| `%sim [FOCUS]` | Start a simulator session on a state machine |
|
|
163
|
+
| `%send TRIGGER` / `%step` / `%state` | Drive / advance / inspect that session |
|
|
164
|
+
| `%view NAME [KIND]` | Render a view: `gv` `pkg` `afv` `iv` `stv` `tab` `dvt` `matrix` |
|
|
165
|
+
| `%load PATH` / `%save PATH` | Merge a file into the session / write the session out |
|
|
166
|
+
| `%reset` / `%quit` | Discard everything / leave the REPL |
|
|
167
|
+
| `%help` | Command summary |
|
|
168
|
+
|
|
169
|
+
Files given on the command line (`sysmlpy repl model.sysml`) are loaded
|
|
170
|
+
into the session before the first prompt. The session core is the same
|
|
171
|
+
Python API surface used throughout the library, so anything you build in
|
|
172
|
+
a REPL session maps one-to-one onto a `ReplSession` scripted from Python.
|
|
173
|
+
|
|
139
174
|
## Command-Line Tools
|
|
140
175
|
|
|
141
176
|
sysmlpy ships a CLI (`sysmlpy`, plus `sysmlpy-lsp` for editor support).
|
|
@@ -404,7 +439,79 @@ tree = classtree(model)
|
|
|
404
439
|
print(tree.dump())
|
|
405
440
|
```
|
|
406
441
|
|
|
407
|
-
**All
|
|
442
|
+
**All 168 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), trade studies, views, viewpoints, render states, portion usages, and annotations.
|
|
443
|
+
|
|
444
|
+
### Doc comments, interface ends, and flows (v0.96.1)
|
|
445
|
+
|
|
446
|
+
These constructs are easy to lose between the parser and the API — v0.96.1 makes them first-class and round-trip-safe:
|
|
447
|
+
|
|
448
|
+
- **`doc /* ... */` comments** — on a package, on any part/item/port/action/... usage or definition, and inside interface bodies — are captured as a `.doc` attribute (a plain string) and re-emitted by `dump()`/`classtree()`, even when the comment shares its body with ports, attributes, or other members.
|
|
449
|
+
- **Interface ends** — `end <name>;` and `end <name> ::> part.port;` members of an interface body — are captured as `Interface.ends` (name, type, multiplicity tuples) and `Interface.iface_connections` (`::>` target paths), and survive a dump round-trip.
|
|
450
|
+
- **`flow <source> to <target>;`** — parses into a `Flow` child of the owning part, re-emits in the dump, and renders as a flow edge in the Interconnection View.
|
|
451
|
+
|
|
452
|
+
```python
|
|
453
|
+
from sysmlpy import loads, as_interconnection_view
|
|
454
|
+
from sysmlpy.formatting import classtree
|
|
455
|
+
|
|
456
|
+
text = """package WaterSystem {
|
|
457
|
+
doc /* package doc: the coffee water loop */
|
|
458
|
+
|
|
459
|
+
part def WaterTank {
|
|
460
|
+
doc /* stores the water */
|
|
461
|
+
port waterOut;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
part def Brewer {
|
|
465
|
+
doc /* heats and brews */
|
|
466
|
+
port waterInlet;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
interface def WaterSupply {
|
|
470
|
+
doc /* the supply contract */
|
|
471
|
+
end supplierPort;
|
|
472
|
+
end consumerPort;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
part def CoffeeMachine {
|
|
476
|
+
doc /* makes coffee */
|
|
477
|
+
part waterTank : WaterTank;
|
|
478
|
+
part brewer : Brewer;
|
|
479
|
+
|
|
480
|
+
interface waterLine : WaterSupply {
|
|
481
|
+
doc /* internal plumbing */
|
|
482
|
+
end supplierPort ::> waterTank.waterOut;
|
|
483
|
+
end consumerPort ::> brewer.waterInlet;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
flow waterTank.waterOut to brewer.waterInlet;
|
|
487
|
+
}
|
|
488
|
+
}"""
|
|
489
|
+
|
|
490
|
+
model = loads(text)
|
|
491
|
+
package = model.children[0]
|
|
492
|
+
|
|
493
|
+
# doc text on every element
|
|
494
|
+
assert package.doc == "package doc: the coffee water loop"
|
|
495
|
+
tank = package.find("WaterTank")[0]
|
|
496
|
+
assert tank.doc == "stores the water"
|
|
497
|
+
|
|
498
|
+
# interface ends: names and ::> targets
|
|
499
|
+
machine = package.find("CoffeeMachine")[0]
|
|
500
|
+
water_line = next(c for c in machine.children if type(c).__name__ == "Interface")
|
|
501
|
+
assert [e[0] for e in water_line.ends] == ["supplierPort", "consumerPort"]
|
|
502
|
+
assert water_line.iface_connections == [
|
|
503
|
+
("supplierPort", "waterTank.waterOut"),
|
|
504
|
+
("consumerPort", "brewer.waterInlet"),
|
|
505
|
+
]
|
|
506
|
+
|
|
507
|
+
# flows show up in the Interconnection View
|
|
508
|
+
assert "flow" in as_interconnection_view(model)
|
|
509
|
+
|
|
510
|
+
# and everything survives the dump round-trip (docs included)
|
|
511
|
+
assert "stores the water" in classtree(model).dump()
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
See `examples/doc_ends_flows.py` for the full walk through the parse → grammar → API layers.
|
|
408
515
|
|
|
409
516
|
## Semantic Analysis
|
|
410
517
|
|
|
@@ -458,7 +565,8 @@ result = analyze(model, strict=True)
|
|
|
458
565
|
- **Undefined symbol detection** — catches references to non-existent types, features, and packages
|
|
459
566
|
- **Qualified name resolution** — `P::A` and `Outer::Inner::DeepPart` resolve through scope chains
|
|
460
567
|
- **Inheritance resolution** — subsetting/redefinition references resolve through supertype chains
|
|
461
|
-
- **
|
|
568
|
+
- **KerML parser** — OMG-KEBNF-generated ANTLR4 grammar for the Kernel Modeling Language (`sysmlpy.kerml`): `parse` / `parse_file` / `parse_to_dict`; all 130 `.kerml` corpus files (OMG examples + standard libraries) parse, and the library symbol index is backed by real parses (2,986 symbols)
|
|
569
|
+
- **Library symbol index** — scans 94 files (36 parsed `.kerml` + 58 `.sysml`) from the bundled standard library (~2,986 symbols)
|
|
462
570
|
|
|
463
571
|
### Import Resolution
|
|
464
572
|
|
|
@@ -101,6 +101,40 @@ and the mapping to this implementation — is in the
|
|
|
101
101
|
[sysml-copier](https://github.com/mycr0ft/sysml-copier) template's
|
|
102
102
|
`docs/sysml-magics.md`.
|
|
103
103
|
|
|
104
|
+
## Interactive REPL
|
|
105
|
+
|
|
106
|
+
`sysmlpy repl [FILE ...]` is a terminal session in the same spirit: each
|
|
107
|
+
submission is a SysML declaration, an expression, or a `%command`, and
|
|
108
|
+
declarations accumulate into a session model with the same
|
|
109
|
+
member-granularity merge as the Jupyter magics (a re-declared member
|
|
110
|
+
replaces its prior definition, sibling members are kept, and a
|
|
111
|
+
`note:` line says so). Submissions continue onto a `...>` line while
|
|
112
|
+
brackets stay open; a line that is not a declaration evaluates as an
|
|
113
|
+
expression. Ctrl-D or `%quit` exits; `%reset` discards the session.
|
|
114
|
+
|
|
115
|
+
| Command | Purpose |
|
|
116
|
+
|---------|---------|
|
|
117
|
+
| `%list [NAME]` | Packages (with member counts), or elements matching NAME with qualified names |
|
|
118
|
+
| `%show NAME` | `repr()` of the first element named NAME |
|
|
119
|
+
| `%dump` | Round-tripped SysML text of the session model |
|
|
120
|
+
| `%eval EXPR` | Evaluate an expression against the session model |
|
|
121
|
+
| `%set NAME=VALUE` | Bind a what-if value (number / bool / string / unit) |
|
|
122
|
+
| `%bindings` | Show current what-if bindings |
|
|
123
|
+
| `%calc NAME a, b` | Invoke a calc def with positional literal arguments |
|
|
124
|
+
| `%check` | Check the model's constraints (pass/fail report) |
|
|
125
|
+
| `%values` | Collected attribute values |
|
|
126
|
+
| `%sim [FOCUS]` | Start a simulator session on a state machine |
|
|
127
|
+
| `%send TRIGGER` / `%step` / `%state` | Drive / advance / inspect that session |
|
|
128
|
+
| `%view NAME [KIND]` | Render a view: `gv` `pkg` `afv` `iv` `stv` `tab` `dvt` `matrix` |
|
|
129
|
+
| `%load PATH` / `%save PATH` | Merge a file into the session / write the session out |
|
|
130
|
+
| `%reset` / `%quit` | Discard everything / leave the REPL |
|
|
131
|
+
| `%help` | Command summary |
|
|
132
|
+
|
|
133
|
+
Files given on the command line (`sysmlpy repl model.sysml`) are loaded
|
|
134
|
+
into the session before the first prompt. The session core is the same
|
|
135
|
+
Python API surface used throughout the library, so anything you build in
|
|
136
|
+
a REPL session maps one-to-one onto a `ReplSession` scripted from Python.
|
|
137
|
+
|
|
104
138
|
## Command-Line Tools
|
|
105
139
|
|
|
106
140
|
sysmlpy ships a CLI (`sysmlpy`, plus `sysmlpy-lsp` for editor support).
|
|
@@ -369,7 +403,79 @@ tree = classtree(model)
|
|
|
369
403
|
print(tree.dump())
|
|
370
404
|
```
|
|
371
405
|
|
|
372
|
-
**All
|
|
406
|
+
**All 168 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), trade studies, views, viewpoints, render states, portion usages, and annotations.
|
|
407
|
+
|
|
408
|
+
### Doc comments, interface ends, and flows (v0.96.1)
|
|
409
|
+
|
|
410
|
+
These constructs are easy to lose between the parser and the API — v0.96.1 makes them first-class and round-trip-safe:
|
|
411
|
+
|
|
412
|
+
- **`doc /* ... */` comments** — on a package, on any part/item/port/action/... usage or definition, and inside interface bodies — are captured as a `.doc` attribute (a plain string) and re-emitted by `dump()`/`classtree()`, even when the comment shares its body with ports, attributes, or other members.
|
|
413
|
+
- **Interface ends** — `end <name>;` and `end <name> ::> part.port;` members of an interface body — are captured as `Interface.ends` (name, type, multiplicity tuples) and `Interface.iface_connections` (`::>` target paths), and survive a dump round-trip.
|
|
414
|
+
- **`flow <source> to <target>;`** — parses into a `Flow` child of the owning part, re-emits in the dump, and renders as a flow edge in the Interconnection View.
|
|
415
|
+
|
|
416
|
+
```python
|
|
417
|
+
from sysmlpy import loads, as_interconnection_view
|
|
418
|
+
from sysmlpy.formatting import classtree
|
|
419
|
+
|
|
420
|
+
text = """package WaterSystem {
|
|
421
|
+
doc /* package doc: the coffee water loop */
|
|
422
|
+
|
|
423
|
+
part def WaterTank {
|
|
424
|
+
doc /* stores the water */
|
|
425
|
+
port waterOut;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
part def Brewer {
|
|
429
|
+
doc /* heats and brews */
|
|
430
|
+
port waterInlet;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
interface def WaterSupply {
|
|
434
|
+
doc /* the supply contract */
|
|
435
|
+
end supplierPort;
|
|
436
|
+
end consumerPort;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
part def CoffeeMachine {
|
|
440
|
+
doc /* makes coffee */
|
|
441
|
+
part waterTank : WaterTank;
|
|
442
|
+
part brewer : Brewer;
|
|
443
|
+
|
|
444
|
+
interface waterLine : WaterSupply {
|
|
445
|
+
doc /* internal plumbing */
|
|
446
|
+
end supplierPort ::> waterTank.waterOut;
|
|
447
|
+
end consumerPort ::> brewer.waterInlet;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
flow waterTank.waterOut to brewer.waterInlet;
|
|
451
|
+
}
|
|
452
|
+
}"""
|
|
453
|
+
|
|
454
|
+
model = loads(text)
|
|
455
|
+
package = model.children[0]
|
|
456
|
+
|
|
457
|
+
# doc text on every element
|
|
458
|
+
assert package.doc == "package doc: the coffee water loop"
|
|
459
|
+
tank = package.find("WaterTank")[0]
|
|
460
|
+
assert tank.doc == "stores the water"
|
|
461
|
+
|
|
462
|
+
# interface ends: names and ::> targets
|
|
463
|
+
machine = package.find("CoffeeMachine")[0]
|
|
464
|
+
water_line = next(c for c in machine.children if type(c).__name__ == "Interface")
|
|
465
|
+
assert [e[0] for e in water_line.ends] == ["supplierPort", "consumerPort"]
|
|
466
|
+
assert water_line.iface_connections == [
|
|
467
|
+
("supplierPort", "waterTank.waterOut"),
|
|
468
|
+
("consumerPort", "brewer.waterInlet"),
|
|
469
|
+
]
|
|
470
|
+
|
|
471
|
+
# flows show up in the Interconnection View
|
|
472
|
+
assert "flow" in as_interconnection_view(model)
|
|
473
|
+
|
|
474
|
+
# and everything survives the dump round-trip (docs included)
|
|
475
|
+
assert "stores the water" in classtree(model).dump()
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
See `examples/doc_ends_flows.py` for the full walk through the parse → grammar → API layers.
|
|
373
479
|
|
|
374
480
|
## Semantic Analysis
|
|
375
481
|
|
|
@@ -423,7 +529,8 @@ result = analyze(model, strict=True)
|
|
|
423
529
|
- **Undefined symbol detection** — catches references to non-existent types, features, and packages
|
|
424
530
|
- **Qualified name resolution** — `P::A` and `Outer::Inner::DeepPart` resolve through scope chains
|
|
425
531
|
- **Inheritance resolution** — subsetting/redefinition references resolve through supertype chains
|
|
426
|
-
- **
|
|
532
|
+
- **KerML parser** — OMG-KEBNF-generated ANTLR4 grammar for the Kernel Modeling Language (`sysmlpy.kerml`): `parse` / `parse_file` / `parse_to_dict`; all 130 `.kerml` corpus files (OMG examples + standard libraries) parse, and the library symbol index is backed by real parses (2,986 symbols)
|
|
533
|
+
- **Library symbol index** — scans 94 files (36 parsed `.kerml` + 58 `.sysml`) from the bundled standard library (~2,986 symbols)
|
|
427
534
|
|
|
428
535
|
### Import Resolution
|
|
429
536
|
|
|
@@ -8,7 +8,7 @@ Uses the ANTLR4 parser for full SysML v2 grammar support.
|
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
__all__ = [
|
|
11
|
-
"load", "loads", "parse", "load_grammar", "load_antlr", "load_grammar_antlr",
|
|
11
|
+
"load", "loads", "load_wrapped", "loads_wrapped", "parse", "load_grammar", "load_antlr", "load_grammar_antlr",
|
|
12
12
|
"load_files", "load_project", "load_with_dependencies",
|
|
13
13
|
"Searchable",
|
|
14
14
|
"Store", "InMemoryStore", "NetworkXStore", "KuzuStore", "CayleyStore", "create_store", "new_id",
|
|
@@ -35,7 +35,7 @@ __all__ = [
|
|
|
35
35
|
"render_state_transition_view_svg", "boxes_view",
|
|
36
36
|
]
|
|
37
37
|
__author__ = "Jon Fox"
|
|
38
|
-
__version__ = "0.
|
|
38
|
+
__version__ = "0.96.1"
|
|
39
39
|
|
|
40
40
|
from sysmlpy.usage import (
|
|
41
41
|
Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
|
|
@@ -311,6 +311,93 @@ def loads(s: str, library=None, rescue_language="English") -> Model:
|
|
|
311
311
|
rescue_language=rescue_language)
|
|
312
312
|
|
|
313
313
|
|
|
314
|
+
def _is_bare_top_level(s: str) -> bool:
|
|
315
|
+
"""True when *s* starts with a top-level definition/usage keyword
|
|
316
|
+
rather than a (library) package — the same textual probe
|
|
317
|
+
:meth:`sysmlpy.definition.Model.load` uses for its strict guard."""
|
|
318
|
+
s_stripped = s.strip() if isinstance(s, str) else s
|
|
319
|
+
if not isinstance(s_stripped, str) or not s_stripped.split():
|
|
320
|
+
return False
|
|
321
|
+
invalid_starts = ['item', 'part', 'port', 'attribute', 'action', 'state',
|
|
322
|
+
'connection', 'interface', 'requirement', 'case', 'use',
|
|
323
|
+
'calc', 'constraint', 'concern', 'ref', 'flow', 'allocation',
|
|
324
|
+
'view', 'viewpoint', 'rendering', 'metadata', 'individual']
|
|
325
|
+
return s_stripped.split(None, 1)[0] in invalid_starts
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def loads_wrapped(s: str, package_name="Snippets", library=None,
|
|
329
|
+
rescue_language="English") -> Model:
|
|
330
|
+
"""Load bare top-level SysML (no enclosing package) into a Model by
|
|
331
|
+
wrapping it in a synthetic package.
|
|
332
|
+
|
|
333
|
+
OMG example and training snippets frequently open directly with
|
|
334
|
+
``part def Camera { ... }`` or ``action def DecisionTest { ... }``.
|
|
335
|
+
:func:`loads` / ``Model.load`` deliberately reject that form ("Base
|
|
336
|
+
Model must be encapsulated by a package"). This loader accepts it:
|
|
337
|
+
the source is wrapped as ``package <package_name> { ... }`` and then
|
|
338
|
+
parsed exactly like :func:`loads`. Content already carrying a
|
|
339
|
+
top-level package (or ``standard library package``) passes through
|
|
340
|
+
untouched, so the function is safe to call unconditionally on file
|
|
341
|
+
text.
|
|
342
|
+
|
|
343
|
+
Parameters
|
|
344
|
+
----------
|
|
345
|
+
s : str
|
|
346
|
+
The SysML v2 source code to parse.
|
|
347
|
+
package_name : str, optional
|
|
348
|
+
Name of the synthetic package. Defaults to ``"Snippets"``.
|
|
349
|
+
library : str or Path, optional
|
|
350
|
+
Path to SysML v2 library files for resolving imports.
|
|
351
|
+
|
|
352
|
+
Returns
|
|
353
|
+
-------
|
|
354
|
+
Model
|
|
355
|
+
Model instance with one child: the synthetic package.
|
|
356
|
+
|
|
357
|
+
.. versionadded:: 0.96.1
|
|
358
|
+
"""
|
|
359
|
+
if _is_bare_top_level(s):
|
|
360
|
+
s = "package %s {\n%s\n}\n" % (package_name, s.rstrip("\n"))
|
|
361
|
+
return loads(s, library=library, rescue_language=rescue_language)
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def load_wrapped(fp, package_name="Snippets", library=None) -> Model:
|
|
365
|
+
"""File-pointer twin of :func:`loads_wrapped`.
|
|
366
|
+
|
|
367
|
+
Deserialize ``fp`` (a ``.read()``-supporting file-like object) —
|
|
368
|
+
wrapping bare top-level definitions in a synthetic package when
|
|
369
|
+
needed — to a Model object. Content with a top-level package passes
|
|
370
|
+
through untouched.
|
|
371
|
+
|
|
372
|
+
Parameters
|
|
373
|
+
----------
|
|
374
|
+
fp : _io.TextIOWrapper
|
|
375
|
+
File pointer to a SysML v2.0 document.
|
|
376
|
+
package_name : str, optional
|
|
377
|
+
Name of the synthetic package. Defaults to ``"Snippets"``.
|
|
378
|
+
library : str or Path, optional
|
|
379
|
+
Path to SysML v2 library files for resolving imports.
|
|
380
|
+
|
|
381
|
+
Returns
|
|
382
|
+
-------
|
|
383
|
+
Model
|
|
384
|
+
Model instance structured utilizing SysML v2.0 grammar.
|
|
385
|
+
|
|
386
|
+
Raises
|
|
387
|
+
------
|
|
388
|
+
TypeError
|
|
389
|
+
Input was not a ``.read()``-supporting file-like object.
|
|
390
|
+
|
|
391
|
+
.. versionadded:: 0.96.1
|
|
392
|
+
"""
|
|
393
|
+
if not hasattr(fp, "read"):
|
|
394
|
+
raise TypeError(
|
|
395
|
+
f"the SysML object must be a file-like object, "
|
|
396
|
+
f"not {fp.__class__.__name__}"
|
|
397
|
+
)
|
|
398
|
+
return loads_wrapped(fp.read(), package_name=package_name, library=library)
|
|
399
|
+
|
|
400
|
+
|
|
314
401
|
def parse(s: str, library=None):
|
|
315
402
|
"""Parse SysML source, returning (model, errors) rather than raising.
|
|
316
403
|
|
|
@@ -7321,6 +7321,20 @@ def _visit_multiplicity(mult_ctx):
|
|
|
7321
7321
|
if mult_ctx is None:
|
|
7322
7322
|
return result
|
|
7323
7323
|
|
|
7324
|
+
# OwnedCrossMultiplicityMember carries an OwnedCrossMultiplicity
|
|
7325
|
+
# wrapper (KerML OwnedCrossMultiplicity → OwnedMultiplicity); read
|
|
7326
|
+
# through it when present (interface ends: `connect [1] a to b`)
|
|
7327
|
+
if hasattr(mult_ctx, 'ownedCrossMultiplicity'):
|
|
7328
|
+
ocm = mult_ctx.ownedCrossMultiplicity()
|
|
7329
|
+
if ocm:
|
|
7330
|
+
om = ocm.ownedMultiplicity()
|
|
7331
|
+
if isinstance(om, list):
|
|
7332
|
+
om = om[0] if om else None
|
|
7333
|
+
if om:
|
|
7334
|
+
built = _extract_multiplicity_from_ctx(om)
|
|
7335
|
+
if built:
|
|
7336
|
+
return built
|
|
7337
|
+
|
|
7324
7338
|
if hasattr(mult_ctx, 'ownedRelatedElement') and mult_ctx.ownedRelatedElement():
|
|
7325
7339
|
related = mult_ctx.ownedRelatedElement()
|
|
7326
7340
|
if isinstance(related, list):
|
|
@@ -10208,6 +10222,19 @@ def _visit_definition_body_item_dict(item_ctx, is_interface=False):
|
|
|
10208
10222
|
inner_element = _visit_nested_non_occurrence_usage(non_occ)
|
|
10209
10223
|
wrapper = "NonOccurrenceUsageMember"
|
|
10210
10224
|
|
|
10225
|
+
# v0.96.1: a bare ``doc /* ... */`` member parses as
|
|
10226
|
+
# DefinitionMemberContext (MemberPrefix + DefinitionElement ->
|
|
10227
|
+
# AnnotatingElement -> Documentation) with NO
|
|
10228
|
+
# definitionBodyItemContent — handle it directly (previously the
|
|
10229
|
+
# doc member was dropped when it shared its body with siblings).
|
|
10230
|
+
if not inner_element and hasattr(item_ctx, 'definitionMember') and item_ctx.definitionMember():
|
|
10231
|
+
member_ctx = item_ctx.definitionMember()
|
|
10232
|
+
element_ctx = member_ctx.definitionElement()
|
|
10233
|
+
if element_ctx is not None:
|
|
10234
|
+
ann_dict = _visit_nested_definition_element(element_ctx)
|
|
10235
|
+
if ann_dict is not None and ann_dict.get("name") == "PackageMember":
|
|
10236
|
+
inner_element = ann_dict.get("ownedRelatedElement", {})
|
|
10237
|
+
wrapper = "DefinitionMember"
|
|
10211
10238
|
# Check for definitionBodyItemContent
|
|
10212
10239
|
if not inner_element and hasattr(item_ctx, 'definitionBodyItemContent') and item_ctx.definitionBodyItemContent():
|
|
10213
10240
|
content = item_ctx.definitionBodyItemContent()
|
|
@@ -26,6 +26,7 @@ from sysmlpy.usage import (
|
|
|
26
26
|
Allocation, Metadata, Rendering, Individual, FlowDef,
|
|
27
27
|
View, Viewpoint, Concern, Reference,
|
|
28
28
|
)
|
|
29
|
+
from sysmlpy.usage import _comment_body_to_text as _comment_body_to_text_package
|
|
29
30
|
|
|
30
31
|
ModelType = TypeVar("Model", bound="Model")
|
|
31
32
|
|
|
@@ -565,6 +566,8 @@ class Package(Searchable):
|
|
|
565
566
|
self.typedby = None
|
|
566
567
|
self.grammar = PackageGrammar()
|
|
567
568
|
self.parent = None
|
|
569
|
+
# v0.96.1: doc text from a package-level ``doc /* ... */`` comment.
|
|
570
|
+
self.doc = None
|
|
568
571
|
|
|
569
572
|
if name is not None:
|
|
570
573
|
self._set_name(name)
|
|
@@ -708,6 +711,33 @@ class Package(Searchable):
|
|
|
708
711
|
else:
|
|
709
712
|
child_defs.append(PackageMember(v).get_definition())
|
|
710
713
|
|
|
714
|
+
# v0.96.1: keep the package-level doc comment in the rebuilt
|
|
715
|
+
# body — captured as ``self.doc`` at load time (the doc member
|
|
716
|
+
# has no public-API child to re-serialize, so emit it directly).
|
|
717
|
+
if getattr(self, 'doc', None):
|
|
718
|
+
doc_dict = {
|
|
719
|
+
"name": "Documentation",
|
|
720
|
+
"body": "/* %s */" % self.doc,
|
|
721
|
+
"identification": None,
|
|
722
|
+
"ownedRelationship": [],
|
|
723
|
+
}
|
|
724
|
+
child_defs.append({
|
|
725
|
+
"name": "PackageMember",
|
|
726
|
+
"prefix": None,
|
|
727
|
+
"ownedRelatedElement": {
|
|
728
|
+
"name": "DefinitionElement",
|
|
729
|
+
"ownedRelatedElement": {
|
|
730
|
+
"name": "AnnotatingElement",
|
|
731
|
+
"ownedRelatedElement": {
|
|
732
|
+
"name": "Documentation",
|
|
733
|
+
"body": "/* %s */" % self.doc,
|
|
734
|
+
"identification": None,
|
|
735
|
+
"ownedRelationship": [],
|
|
736
|
+
},
|
|
737
|
+
},
|
|
738
|
+
},
|
|
739
|
+
})
|
|
740
|
+
|
|
711
741
|
body_children = getattr(
|
|
712
742
|
getattr(getattr(self, 'grammar', None), 'body', None), 'children', None
|
|
713
743
|
)
|
|
@@ -1311,6 +1341,15 @@ class Package(Searchable):
|
|
|
1311
1341
|
mf = getattr(inner_element, 'children', None)
|
|
1312
1342
|
if mf is not None and mf.__class__.__name__ == "MetadataFeature":
|
|
1313
1343
|
self._add_metadata_child(mf)
|
|
1344
|
+
elif mf is not None and mf.__class__.__name__ in (
|
|
1345
|
+
"Documentation", "CommentSysML"):
|
|
1346
|
+
# v0.96.1: package-level ``doc /* ... */`` — capture
|
|
1347
|
+
# the text as ``self.doc`` (previously silently
|
|
1348
|
+
# dropped).
|
|
1349
|
+
text = _comment_body_to_text_package(
|
|
1350
|
+
getattr(mf, 'body', ''))
|
|
1351
|
+
if text:
|
|
1352
|
+
self.doc = text
|
|
1314
1353
|
else:
|
|
1315
1354
|
print(f"[Package.load_from_grammar] Unknown class: {inner_class} - skipping") # pragma: no cover
|
|
1316
1355
|
elif inner_class == "NonOccurrenceUsageElement":
|
|
@@ -50,6 +50,7 @@ _state: Dict[str, Any] = {
|
|
|
50
50
|
"directory": None, # None = default (env/XDG/~/.cache/sysmlpy)
|
|
51
51
|
"load_attempted": False,
|
|
52
52
|
"loaded": False,
|
|
53
|
+
"file_states": 0, # DFA states in the cache file at load time
|
|
53
54
|
"save_attempted": False,
|
|
54
55
|
"saved": False,
|
|
55
56
|
"saved_states": 0,
|
|
@@ -290,9 +291,12 @@ def load_dfa_cache(path: Optional[str] = None) -> bool:
|
|
|
290
291
|
payload = pickle.load(f)
|
|
291
292
|
if not isinstance(payload, tuple) or len(payload) != 5:
|
|
292
293
|
raise ValueError("unexpected cache payload shape")
|
|
294
|
+
file_states = sum(len(dfa.states) for dfa in payload[1])
|
|
295
|
+
file_states += sum(len(dfa.states) for dfa in payload[4])
|
|
293
296
|
with _lock:
|
|
294
297
|
_install(payload)
|
|
295
298
|
_state["loaded"] = True
|
|
299
|
+
_state["file_states"] = file_states
|
|
296
300
|
return True
|
|
297
301
|
except Exception as exc:
|
|
298
302
|
warnings.warn(
|
|
@@ -315,10 +319,18 @@ def save_dfa_cache(path: Optional[str] = None) -> bool:
|
|
|
315
319
|
return False
|
|
316
320
|
path = path or cache_file()
|
|
317
321
|
try:
|
|
318
|
-
|
|
322
|
+
warm_states = sum(len(dfa.states) for dfa in _payload()[1])
|
|
323
|
+
warm_states += sum(len(dfa.states) for dfa in _payload()[4])
|
|
324
|
+
with _lock:
|
|
325
|
+
file_states = _state["file_states"]
|
|
326
|
+
if os.path.isfile(path) and warm_states <= file_states:
|
|
327
|
+
# Nothing learned beyond what the file already holds.
|
|
319
328
|
with _lock:
|
|
320
329
|
_state["saved"] = False
|
|
321
330
|
return False
|
|
331
|
+
# Fresh write, or a strictly warmer in-process cache: supersede
|
|
332
|
+
# the file so DFA states learned since its last write (e.g. new
|
|
333
|
+
# grammar paths like the short-name `<...>` forms) persist.
|
|
322
334
|
P, L = _classes()
|
|
323
335
|
payload = _payload()
|
|
324
336
|
blob = pickle.dumps(payload, protocol=_CACHE_PROTOCOL)
|
|
@@ -355,6 +367,7 @@ def reset_for_tests() -> None:
|
|
|
355
367
|
for key in ("load_attempted", "loaded", "save_attempted",
|
|
356
368
|
"saved", "saved_states"):
|
|
357
369
|
_state[key] = False if key != "saved_states" else 0
|
|
370
|
+
_state["file_states"] = 0
|
|
358
371
|
|
|
359
372
|
|
|
360
373
|
def stats() -> Dict[str, Any]:
|
|
@@ -4067,7 +4067,14 @@ class InterfaceDefinition:
|
|
|
4067
4067
|
if isinstance(def_dict, dict) and def_dict.get("body") is not None:
|
|
4068
4068
|
body_dict = def_dict["body"]
|
|
4069
4069
|
if isinstance(body_dict, dict) and body_dict.get("name") in ("DefinitionBody", "InterfaceBody"):
|
|
4070
|
-
|
|
4070
|
+
# v0.96.1: a rebuilt DefinitionBody dict carries
|
|
4071
|
+
# its items in "ownedRelatedElement" (the
|
|
4072
|
+
# standard relationship name); a native
|
|
4073
|
+
# InterfaceBody dict carries them in "item".
|
|
4074
|
+
items = body_dict.get("item",
|
|
4075
|
+
body_dict.get("ownedRelatedElement", []))
|
|
4076
|
+
self.body = InterfaceBody(
|
|
4077
|
+
{"name": "InterfaceBody", "item": items})
|
|
4071
4078
|
else:
|
|
4072
4079
|
self.body = InterfaceBody(body_dict)
|
|
4073
4080
|
else:
|
|
@@ -5105,6 +5112,13 @@ class DefinitionBodyItem:
|
|
|
5105
5112
|
self.children.append(NonOccurrenceUsageMember(item))
|
|
5106
5113
|
elif item["name"] == "DefinitionMember":
|
|
5107
5114
|
self.children.append(DefinitionMember(item))
|
|
5115
|
+
elif item["name"] == "InterfaceOccurrenceUsageMember":
|
|
5116
|
+
# v0.96.1: interface ends inside a rebuilt
|
|
5117
|
+
# definition body (the ends have no public-API
|
|
5118
|
+
# child to re-serialize).
|
|
5119
|
+
self.children.append(
|
|
5120
|
+
InterfaceOccurrenceUsageMember(item)
|
|
5121
|
+
)
|
|
5108
5122
|
elif item["name"] == "Import":
|
|
5109
5123
|
# Imports are legal in usage bodies too
|
|
5110
5124
|
# (``part p1 { private import Q::*; }``) —
|
|
@@ -7551,7 +7565,18 @@ class InterfaceUsageDeclaration:
|
|
|
7551
7565
|
if definition["part1"] is not None:
|
|
7552
7566
|
self.part = InterfacePart(definition["part1"])
|
|
7553
7567
|
# The connect usage was optional and it was used here.
|
|
7554
|
-
|
|
7568
|
+
# v0.96.1: only when the binary part actually carries the
|
|
7569
|
+
# CONNECT-form ends — the visitor also emits an EMPTY
|
|
7570
|
+
# part1 for plain ``interface x : T { ... }`` (body-form
|
|
7571
|
+
# ends), and marking those "connect" produced a
|
|
7572
|
+
# reparse-breaking ``interface x: T connect ...`` dump.
|
|
7573
|
+
binpart = getattr(self.part, 'children', None)
|
|
7574
|
+
has_end_members = False
|
|
7575
|
+
if binpart is not None and binpart.__class__.__name__ == "BinaryInterfacePart":
|
|
7576
|
+
has_end_members = bool(
|
|
7577
|
+
getattr(binpart, 'children', []) or [])
|
|
7578
|
+
if has_end_members:
|
|
7579
|
+
self.keyword = "connect\n"
|
|
7555
7580
|
elif definition["part2"] is not None:
|
|
7556
7581
|
self.part = InterfacePart(definition["part2"])
|
|
7557
7582
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* KerML v1.0 ANTLR4 grammar (lexer).
|
|
3
|
+
*
|
|
4
|
+
* Generated from the OMG KerML textual-notation KEBNF
|
|
5
|
+
* (Systems-Modeling/SysML-v2-Release, bnf/KerML-textual-bnf.kebnf,
|
|
6
|
+
* 2026-08 checkout / Release 2026-07 edition) using the daltskin
|
|
7
|
+
* sysml-v2-grammar generator in KerML-only mode. MIT license, same as
|
|
8
|
+
* the generator upstream.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
lexer grammar KerMLLexer;
|