From 33872c1a2e9a309efd672c1a969bbced786e2b8d Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Tue, 11 Jun 2024 12:17:52 +0200 Subject: [PATCH 1/2] introduce short name reference resolution contexts this patch is quite large but also pretty simple: instead of passing the relevant containers directly to the `_resolve_snref()` methods, we put every object that is possibly required for short name resolution into a new `SnRefContext` object. Those parts of the context which are not available are simply `None` and the respective `_resolve_snref()` are responsible of ensuring that the parts of the context which they require are present... Signed-off-by: Andreas Lauser Signed-off-by: Christian Hackenbeck --- odxtools/additionalaudience.py | 8 ++--- odxtools/admindata.py | 12 +++---- odxtools/audience.py | 8 ++--- odxtools/basecomparam.py | 8 ++--- odxtools/basicstructure.py | 16 +++++---- odxtools/companydata.py | 12 +++---- odxtools/companydocinfo.py | 10 +++--- odxtools/companyrevisioninfo.py | 8 ++--- odxtools/companyspecificinfo.py | 12 +++---- odxtools/comparam.py | 10 +++--- odxtools/comparaminstance.py | 8 ++--- odxtools/comparamspec.py | 16 ++++----- odxtools/comparamsubset.py | 22 ++++++------ odxtools/complexcomparam.py | 12 +++---- odxtools/dataobjectproperty.py | 12 +++---- odxtools/determinenumberofitems.py | 9 +++-- odxtools/diagcodedtype.py | 8 ++--- odxtools/diagcomm.py | 11 +++--- odxtools/diagdatadictionaryspec.py | 36 +++++++++---------- odxtools/diaglayer.py | 6 +++- odxtools/diaglayerraw.py | 36 +++++++++---------- odxtools/diagnostictroublecode.py | 10 +++--- odxtools/diagservice.py | 16 +++++---- odxtools/docrevision.py | 12 +++---- odxtools/dopbase.py | 10 +++--- odxtools/dtcdop.py | 13 +++---- odxtools/dynamicendmarkerfield.py | 10 +++--- odxtools/dynamiclengthfield.py | 12 +++---- odxtools/environmentdatadescription.py | 10 +++--- odxtools/field.py | 18 +++++----- odxtools/functionalclass.py | 8 ++--- odxtools/inputparam.py | 8 ++--- odxtools/modification.py | 8 ++--- odxtools/multiplexer.py | 16 ++++----- odxtools/multiplexercase.py | 10 +++--- odxtools/multiplexerdefaultcase.py | 10 +++--- odxtools/multiplexerswitchkey.py | 9 +++-- odxtools/negoutputparam.py | 8 ++--- odxtools/outputparam.py | 8 ++--- odxtools/parameters/codedconstparameter.py | 16 ++------- odxtools/parameters/lengthkeyparameter.py | 18 ++-------- odxtools/parameters/nrcconstparameter.py | 16 ++------- odxtools/parameters/parameter.py | 16 +++------ odxtools/parameters/parameterwithdop.py | 14 ++++---- .../parameters/physicalconstantparameter.py | 13 +++---- odxtools/parameters/tablekeyparameter.py | 9 +++-- odxtools/parameters/tablestructparameter.py | 14 ++++---- odxtools/parameters/valueparameter.py | 13 +++---- odxtools/paramlengthinfotype.py | 6 ++-- odxtools/parentref.py | 3 +- odxtools/physicaldimension.py | 8 ++--- odxtools/progcode.py | 12 +++---- odxtools/protstack.py | 8 ++--- odxtools/relateddoc.py | 10 +++--- odxtools/request.py | 8 +++++ odxtools/response.py | 8 +++++ odxtools/singleecujob.py | 22 ++++++------ odxtools/snrefcontext.py | 29 +++++++++++++++ odxtools/specialdata.py | 8 ++--- odxtools/specialdatagroup.py | 12 +++---- odxtools/specialdatagroupcaption.py | 9 ++--- odxtools/state.py | 8 ++--- odxtools/statechart.py | 20 +++++------ odxtools/statetransition.py | 13 +++---- odxtools/staticfield.py | 10 +++--- odxtools/table.py | 10 +++--- odxtools/tablerow.py | 8 ++--- odxtools/teammember.py | 8 ++--- odxtools/unit.py | 8 ++--- odxtools/unitgroup.py | 8 ++--- odxtools/unitspec.py | 14 ++++---- odxtools/xdoc.py | 8 ++--- tests/test_decoding.py | 18 +++++----- tests/test_encoding.py | 12 ++++--- 74 files changed, 397 insertions(+), 496 deletions(-) create mode 100644 odxtools/snrefcontext.py diff --git a/odxtools/additionalaudience.py b/odxtools/additionalaudience.py index a62cdb66..4d855a9e 100644 --- a/odxtools/additionalaudience.py +++ b/odxtools/additionalaudience.py @@ -1,15 +1,13 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List +from typing import Any, Dict, List from xml.etree import ElementTree from .element import IdentifiableElement from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class AdditionalAudience(IdentifiableElement): @@ -30,5 +28,5 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: pass - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass diff --git a/odxtools/admindata.py b/odxtools/admindata.py index 350c78ba..e54dfee7 100644 --- a/odxtools/admindata.py +++ b/odxtools/admindata.py @@ -1,14 +1,12 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .companydocinfo import CompanyDocInfo from .docrevision import DocRevision from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId - -if TYPE_CHECKING: - from .diaglayer import DiagLayer +from .snrefcontext import SnRefContext @dataclass @@ -54,9 +52,9 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for dr in self.doc_revisions: dr._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: for cdi in self.company_doc_infos: - cdi._resolve_snrefs(diag_layer) + cdi._resolve_snrefs(context) for dr in self.doc_revisions: - dr._resolve_snrefs(diag_layer) + dr._resolve_snrefs(context) diff --git a/odxtools/audience.py b/odxtools/audience.py index e11d7f9a..93c6cfcb 100644 --- a/odxtools/audience.py +++ b/odxtools/audience.py @@ -1,14 +1,12 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .additionalaudience import AdditionalAudience from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef from .odxtypes import odxstr_to_bool - -if TYPE_CHECKING: - from .diaglayer import DiagLayer +from .snrefcontext import SnRefContext @dataclass @@ -94,5 +92,5 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: odxlinks.resolve(ref, AdditionalAudience) for ref in self.disabled_audience_refs ] - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass diff --git a/odxtools/basecomparam.py b/odxtools/basecomparam.py index 92988bce..f975c46e 100644 --- a/odxtools/basecomparam.py +++ b/odxtools/basecomparam.py @@ -1,17 +1,15 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass from enum import Enum -from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast +from typing import Any, Dict, List, Optional, cast from xml.etree import ElementTree from .element import IdentifiableElement from .exceptions import odxraise, odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - class StandardizationLevel(Enum): STANDARD = "STANDARD" @@ -74,5 +72,5 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: pass - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass diff --git a/odxtools/basicstructure.py b/odxtools/basicstructure.py index 12a30d82..7bc362a6 100644 --- a/odxtools/basicstructure.py +++ b/odxtools/basicstructure.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MIT import warnings from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast +from typing import Any, Dict, List, Optional, cast from xml.etree import ElementTree from typing_extensions import override @@ -23,11 +23,9 @@ from .parameters.parameterwithdop import ParameterWithDOP from .parameters.physicalconstantparameter import PhysicalConstantParameter from .parameters.tablekeyparameter import TableKeyParameter +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class BasicStructure(ComplexDop): @@ -292,9 +290,13 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for param in self.parameters: param._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: """Recursively resolve any references (odxlinks or sn-refs)""" - super()._resolve_snrefs(diag_layer) + context.parameters = self.parameters + + super()._resolve_snrefs(context) for param in self.parameters: - param._parameter_resolve_snrefs(diag_layer, param_list=self.parameters) + param._resolve_snrefs(context) + + context.parameters = None diff --git a/odxtools/companydata.py b/odxtools/companydata.py index 322599c1..27501912 100644 --- a/odxtools/companydata.py +++ b/odxtools/companydata.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .companyspecificinfo import CompanySpecificInfo @@ -8,12 +8,10 @@ from .exceptions import odxrequire from .nameditemlist import NamedItemList from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from .snrefcontext import SnRefContext from .teammember import TeamMember from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class CompanyData(IdentifiableElement): @@ -64,9 +62,9 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: if self.company_specific_info: self.company_specific_info._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: for tm in self.team_members: - tm._resolve_snrefs(diag_layer) + tm._resolve_snrefs(context) if self.company_specific_info: - self.company_specific_info._resolve_snrefs(diag_layer) + self.company_specific_info._resolve_snrefs(context) diff --git a/odxtools/companydocinfo.py b/odxtools/companydocinfo.py index e504ba82..f10979c0 100644 --- a/odxtools/companydocinfo.py +++ b/odxtools/companydocinfo.py @@ -1,17 +1,15 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .companydata import CompanyData from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef +from .snrefcontext import SnRefContext from .specialdatagroup import SpecialDataGroup from .teammember import TeamMember -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class CompanyDocInfo: @@ -65,6 +63,6 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for sdg in self.sdgs: sdg._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: for sdg in self.sdgs: - sdg._resolve_snrefs(diag_layer) + sdg._resolve_snrefs(context) diff --git a/odxtools/companyrevisioninfo.py b/odxtools/companyrevisioninfo.py index 883946ef..cbca674b 100644 --- a/odxtools/companyrevisioninfo.py +++ b/odxtools/companyrevisioninfo.py @@ -1,14 +1,12 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .companydata import CompanyData from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef - -if TYPE_CHECKING: - from .diaglayer import DiagLayer +from .snrefcontext import SnRefContext @dataclass @@ -39,5 +37,5 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._company_data = odxlinks.resolve(self.company_data_ref, CompanyData) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass diff --git a/odxtools/companyspecificinfo.py b/odxtools/companyspecificinfo.py index bbfdec6e..bfd80be8 100644 --- a/odxtools/companyspecificinfo.py +++ b/odxtools/companyspecificinfo.py @@ -1,15 +1,13 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List +from typing import Any, Dict, List from xml.etree import ElementTree from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from .relateddoc import RelatedDoc +from .snrefcontext import SnRefContext from .specialdatagroup import SpecialDataGroup -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class CompanySpecificInfo: @@ -45,9 +43,9 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for sdg in self.sdgs: sdg._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: for rd in self.related_docs: - rd._resolve_snrefs(diag_layer) + rd._resolve_snrefs(context) for sdg in self.sdgs: - sdg._resolve_snrefs(diag_layer) + sdg._resolve_snrefs(context) diff --git a/odxtools/comparam.py b/odxtools/comparam.py index 88fcb9d0..e98b7da0 100644 --- a/odxtools/comparam.py +++ b/odxtools/comparam.py @@ -1,17 +1,15 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List +from typing import Any, Dict, List from xml.etree import ElementTree from .basecomparam import BaseComparam from .dataobjectproperty import DataObjectProperty from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class Comparam(BaseComparam): @@ -41,5 +39,5 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._dop = odxlinks.resolve(self.dop_ref, DataObjectProperty) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: - super()._resolve_snrefs(diag_layer) + def _resolve_snrefs(self, context: SnRefContext) -> None: + super()._resolve_snrefs(context) diff --git a/odxtools/comparaminstance.py b/odxtools/comparaminstance.py index 58c215b5..922ee174 100644 --- a/odxtools/comparaminstance.py +++ b/odxtools/comparaminstance.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MIT import warnings from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Union from xml.etree import ElementTree from .basecomparam import BaseComparam @@ -10,9 +10,7 @@ from .description import Description from .exceptions import OdxWarning, odxraise, odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef - -if TYPE_CHECKING: - from .diaglayer import DiagLayer +from .snrefcontext import SnRefContext @dataclass @@ -68,7 +66,7 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._spec = odxlinks.resolve(self.spec_ref, BaseComparam) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass @property diff --git a/odxtools/comparamspec.py b/odxtools/comparamspec.py index 58606024..e8e03b15 100644 --- a/odxtools/comparamspec.py +++ b/odxtools/comparamspec.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .admindata import AdminData @@ -10,12 +10,10 @@ from .nameditemlist import NamedItemList from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from .protstack import ProtStack +from .snrefcontext import SnRefContext from .specialdatagroup import SpecialDataGroup from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class ComparamSpec(IdentifiableElement): @@ -83,15 +81,15 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for ps in self.prot_stacks: ps._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: if self.admin_data is not None: - self.admin_data._resolve_snrefs(diag_layer) + self.admin_data._resolve_snrefs(context) for cd in self.company_datas: - cd._resolve_snrefs(diag_layer) + cd._resolve_snrefs(context) for sdg in self.sdgs: - sdg._resolve_snrefs(diag_layer) + sdg._resolve_snrefs(context) for ps in self.prot_stacks: - ps._resolve_snrefs(diag_layer) + ps._resolve_snrefs(context) diff --git a/odxtools/comparamsubset.py b/odxtools/comparamsubset.py index 75cda154..5e6ecad8 100644 --- a/odxtools/comparamsubset.py +++ b/odxtools/comparamsubset.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .admindata import AdminData @@ -12,13 +12,11 @@ from .exceptions import odxrequire from .nameditemlist import NamedItemList from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from .snrefcontext import SnRefContext from .specialdatagroup import SpecialDataGroup from .unitspec import UnitSpec from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class ComparamSubset(IdentifiableElement): @@ -130,25 +128,25 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for sdg in self.sdgs: sdg._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: for dop in self.data_object_props: - dop._resolve_snrefs(diag_layer) + dop._resolve_snrefs(context) for comparam in self.comparams: - comparam._resolve_snrefs(diag_layer) + comparam._resolve_snrefs(context) for ccomparam in self.complex_comparams: - ccomparam._resolve_snrefs(diag_layer) + ccomparam._resolve_snrefs(context) if self.unit_spec: - self.unit_spec._resolve_snrefs(diag_layer) + self.unit_spec._resolve_snrefs(context) if self.admin_data is not None: - self.admin_data._resolve_snrefs(diag_layer) + self.admin_data._resolve_snrefs(context) if self.company_datas is not None: for cd in self.company_datas: - cd._resolve_snrefs(diag_layer) + cd._resolve_snrefs(context) for sdg in self.sdgs: - sdg._resolve_snrefs(diag_layer) + sdg._resolve_snrefs(context) diff --git a/odxtools/complexcomparam.py b/odxtools/complexcomparam.py index f8d6764f..2e88e7a1 100644 --- a/odxtools/complexcomparam.py +++ b/odxtools/complexcomparam.py @@ -1,17 +1,15 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Union from xml.etree import ElementTree from .basecomparam import BaseComparam from .nameditemlist import NamedItemList from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from .odxtypes import odxstr_to_bool +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - ComplexValue = List[Union[str, "ComplexValue"]] @@ -93,7 +91,7 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for subparam in self.subparams: subparam._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: - super()._resolve_snrefs(diag_layer) + def _resolve_snrefs(self, context: SnRefContext) -> None: + super()._resolve_snrefs(context) for subparam in self.subparams: - subparam._resolve_snrefs(diag_layer) + subparam._resolve_snrefs(context) diff --git a/odxtools/dataobjectproperty.py b/odxtools/dataobjectproperty.py index 3aa3b23e..9416b8d8 100644 --- a/odxtools/dataobjectproperty.py +++ b/odxtools/dataobjectproperty.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast +from typing import Any, Dict, List, Optional, cast from xml.etree import ElementTree from .compumethods.compumethod import CompuMethod @@ -15,12 +15,10 @@ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef from .odxtypes import AtomicOdxType, ParameterValue from .physicaltype import PhysicalType +from .snrefcontext import SnRefContext from .unit import Unit from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class DataObjectProperty(DopBase): @@ -98,10 +96,10 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: if self.unit_ref: self._unit = odxlinks.resolve(self.unit_ref, Unit) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: - super()._resolve_snrefs(diag_layer) + def _resolve_snrefs(self, context: SnRefContext) -> None: + super()._resolve_snrefs(context) - self.diag_coded_type._resolve_snrefs(diag_layer) + self.diag_coded_type._resolve_snrefs(context) @property def unit(self) -> Optional[Unit]: diff --git a/odxtools/determinenumberofitems.py b/odxtools/determinenumberofitems.py index 21fa343b..50d7cbca 100644 --- a/odxtools/determinenumberofitems.py +++ b/odxtools/determinenumberofitems.py @@ -1,13 +1,12 @@ +# SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .dataobjectproperty import DataObjectProperty from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef - -if TYPE_CHECKING: - from .diaglayer import DiagLayer +from .snrefcontext import SnRefContext @dataclass @@ -39,7 +38,7 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._dop = odxlinks.resolve(self.dop_ref, DataObjectProperty) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass @property diff --git a/odxtools/diagcodedtype.py b/odxtools/diagcodedtype.py index a0f6211f..ea8fa747 100644 --- a/odxtools/diagcodedtype.py +++ b/odxtools/diagcodedtype.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Union, cast +from typing import Any, Dict, List, Literal, Optional, Union, cast from xml.etree import ElementTree from .decodestate import DecodeState @@ -8,9 +8,7 @@ from .exceptions import odxassert, odxraise, odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from .odxtypes import AtomicOdxType, DataType, odxstr_to_bool - -if TYPE_CHECKING: - from .diaglayer import DiagLayer +from .snrefcontext import SnRefContext # Allowed diag-coded types DctType = Literal[ @@ -53,7 +51,7 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: # noqa: B027 """Recursively resolve any odxlinks references""" pass - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: # noqa: B027 + def _resolve_snrefs(self, context: SnRefContext) -> None: # noqa: B027 """Recursively resolve any short-name references""" pass diff --git a/odxtools/diagcomm.py b/odxtools/diagcomm.py index a032e852..e214dbcc 100644 --- a/odxtools/diagcomm.py +++ b/odxtools/diagcomm.py @@ -12,6 +12,7 @@ from .nameditemlist import NamedItemList from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref from .odxtypes import odxstr_to_bool +from .snrefcontext import SnRefContext from .specialdatagroup import SpecialDataGroup from .state import State from .statetransition import StateTransition @@ -202,22 +203,24 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._state_transitions = NamedItemList( [odxlinks.resolve(stt_ref, StateTransition) for stt_ref in self.state_transition_refs]) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: if self.admin_data: - self.admin_data._resolve_snrefs(diag_layer) + self.admin_data._resolve_snrefs(context) if self.audience: - self.audience._resolve_snrefs(diag_layer) + self.audience._resolve_snrefs(context) for sdg in self.sdgs: - sdg._resolve_snrefs(diag_layer) + sdg._resolve_snrefs(context) if TYPE_CHECKING: + diag_layer = odxrequire(context.diag_layer) self._protocols = NamedItemList([ resolve_snref(prot_snref, diag_layer.protocols, DiagLayer) for prot_snref in self.protocol_snrefs ]) else: + diag_layer = odxrequire(context.diag_layer) self._protocols = NamedItemList([ resolve_snref(prot_snref, diag_layer.protocols) for prot_snref in self.protocol_snrefs diff --git a/odxtools/diagdatadictionaryspec.py b/odxtools/diagdatadictionaryspec.py index b0a35b72..b384e280 100644 --- a/odxtools/diagdatadictionaryspec.py +++ b/odxtools/diagdatadictionaryspec.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass from itertools import chain -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .admindata import AdminData @@ -18,15 +18,13 @@ from .multiplexer import Multiplexer from .nameditemlist import NamedItemList from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from .snrefcontext import SnRefContext from .specialdatagroup import SpecialDataGroup from .staticfield import StaticField from .structure import Structure from .table import Table from .unitspec import UnitSpec -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class DiagDataDictionarySpec: @@ -220,35 +218,35 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for sdg in self.sdgs: sdg._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: if self.admin_data is not None: - self.admin_data._resolve_snrefs(diag_layer) + self.admin_data._resolve_snrefs(context) for dtc_dop in self.dtc_dops: - dtc_dop._resolve_snrefs(diag_layer) + dtc_dop._resolve_snrefs(context) for env_data_desc in self.env_data_descs: - env_data_desc._resolve_snrefs(diag_layer) + env_data_desc._resolve_snrefs(context) for data_object_prop in self.data_object_props: - data_object_prop._resolve_snrefs(diag_layer) + data_object_prop._resolve_snrefs(context) for structure in self.structures: - structure._resolve_snrefs(diag_layer) + structure._resolve_snrefs(context) for static_field in self.static_fields: - static_field._resolve_snrefs(diag_layer) + static_field._resolve_snrefs(context) for dynamic_length_field in self.dynamic_length_fields: - dynamic_length_field._resolve_snrefs(diag_layer) + dynamic_length_field._resolve_snrefs(context) for dynamic_endmarker_field in self.dynamic_endmarker_fields: - dynamic_endmarker_field._resolve_snrefs(diag_layer) + dynamic_endmarker_field._resolve_snrefs(context) for end_of_pdu_field in self.end_of_pdu_fields: - end_of_pdu_field._resolve_snrefs(diag_layer) + end_of_pdu_field._resolve_snrefs(context) for mux in self.muxs: - mux._resolve_snrefs(diag_layer) + mux._resolve_snrefs(context) for env_data in self.env_datas: - env_data._resolve_snrefs(diag_layer) + env_data._resolve_snrefs(context) if self.unit_spec is not None: - self.unit_spec._resolve_snrefs(diag_layer) + self.unit_spec._resolve_snrefs(context) for table in self.tables: - table._resolve_snrefs(diag_layer) + table._resolve_snrefs(context) for sdg in self.sdgs: - sdg._resolve_snrefs(diag_layer) + sdg._resolve_snrefs(context) @property def all_data_object_properties(self) -> NamedItemList[DopBase]: diff --git a/odxtools/diaglayer.py b/odxtools/diaglayer.py index d817a397..21c44d16 100644 --- a/odxtools/diaglayer.py +++ b/odxtools/diaglayer.py @@ -35,6 +35,7 @@ from .response import Response from .servicebinner import ServiceBinner from .singleecujob import SingleEcuJob +from .snrefcontext import SnRefContext from .specialdatagroup import SpecialDataGroup from .statechart import StateChart from .table import Table @@ -301,7 +302,10 @@ def _finalize_init(self, database: "Database", odxlinks: OdxLinkDatabase) -> Non # by the spec (So far, I haven't found any definitive # statement...) ##### - self.diag_layer_raw._resolve_snrefs(self) + context = SnRefContext(database=database) + context.diag_layer = self + self.diag_layer_raw._resolve_snrefs(context) + #context.diag_layer = None ##### # diff --git a/odxtools/diaglayerraw.py b/odxtools/diaglayerraw.py index d8644014..fca30f83 100644 --- a/odxtools/diaglayerraw.py +++ b/odxtools/diaglayerraw.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MIT from copy import copy from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union, cast +from typing import Any, Dict, List, Optional, Union, cast from xml.etree import ElementTree from .additionalaudience import AdditionalAudience @@ -25,13 +25,11 @@ from .request import Request from .response import Response from .singleecujob import SingleEcuJob +from .snrefcontext import SnRefContext from .specialdatagroup import SpecialDataGroup from .statechart import StateChart from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class DiagLayerRaw(IdentifiableElement): @@ -283,7 +281,7 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for comparam in self.comparams: comparam._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: self._prot_stack: Optional[ProtStack] = None if self.prot_stack_snref is not None: cp_spec = self.comparam_spec @@ -293,36 +291,36 @@ def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: # do short-name reference resolution if self.admin_data is not None: - self.admin_data._resolve_snrefs(diag_layer) + self.admin_data._resolve_snrefs(context) if self.diag_data_dictionary_spec is not None: - self.diag_data_dictionary_spec._resolve_snrefs(diag_layer) + self.diag_data_dictionary_spec._resolve_snrefs(context) for company_data in self.company_datas: - company_data._resolve_snrefs(diag_layer) + company_data._resolve_snrefs(context) for functional_class in self.functional_classes: - functional_class._resolve_snrefs(diag_layer) + functional_class._resolve_snrefs(context) for diag_comm in self.diag_comms: if isinstance(diag_comm, OdxLinkRef): continue - diag_comm._resolve_snrefs(diag_layer) + diag_comm._resolve_snrefs(context) for request in self.requests: - request._resolve_snrefs(diag_layer) + request._resolve_snrefs(context) for positive_response in self.positive_responses: - positive_response._resolve_snrefs(diag_layer) + positive_response._resolve_snrefs(context) for negative_response in self.negative_responses: - negative_response._resolve_snrefs(diag_layer) + negative_response._resolve_snrefs(context) for global_negative_response in self.global_negative_responses: - global_negative_response._resolve_snrefs(diag_layer) + global_negative_response._resolve_snrefs(context) for state_chart in self.state_charts: - state_chart._resolve_snrefs(diag_layer) + state_chart._resolve_snrefs(context) for additional_audience in self.additional_audiences: - additional_audience._resolve_snrefs(diag_layer) + additional_audience._resolve_snrefs(context) for sdg in self.sdgs: - sdg._resolve_snrefs(diag_layer) + sdg._resolve_snrefs(context) for parent_ref in self.parent_refs: - parent_ref._resolve_snrefs(diag_layer) + parent_ref._resolve_snrefs(context) for comparam in self.comparams: - comparam._resolve_snrefs(diag_layer) + comparam._resolve_snrefs(context) @property def comparam_spec(self) -> Optional[Union[ComparamSpec, ComparamSubset]]: diff --git a/odxtools/diagnostictroublecode.py b/odxtools/diagnostictroublecode.py index 73280b3a..cedb2898 100644 --- a/odxtools/diagnostictroublecode.py +++ b/odxtools/diagnostictroublecode.py @@ -1,18 +1,16 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Union from xml.etree import ElementTree from .element import IdentifiableElement from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from .odxtypes import odxstr_to_bool +from .snrefcontext import SnRefContext from .specialdatagroup import SpecialDataGroup from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class DiagnosticTroubleCode(IdentifiableElement): @@ -70,6 +68,6 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for sdg in self.sdgs: sdg._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: for sdg in self.sdgs: - sdg._resolve_snrefs(diag_layer) + sdg._resolve_snrefs(context) diff --git a/odxtools/diagservice.py b/odxtools/diagservice.py index 82480907..59bb491b 100644 --- a/odxtools/diagservice.py +++ b/odxtools/diagservice.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass from enum import Enum -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union, cast +from typing import Any, Dict, List, Optional, Union, cast from xml.etree import ElementTree from .comparaminstance import ComparamInstance @@ -14,11 +14,9 @@ from .parameters.parameter import Parameter from .request import Request from .response import Response +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - class Addressing(Enum): FUNCTIONAL = "FUNCTIONAL" @@ -175,16 +173,20 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._negative_responses = NamedItemList[Response]( [odxlinks.resolve(x, Response) for x in self.neg_response_refs]) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: - super()._resolve_snrefs(diag_layer) + def _resolve_snrefs(self, context: SnRefContext) -> None: + context.diag_service = self + + super()._resolve_snrefs(context) for cpr in self.comparam_refs: - cpr._resolve_snrefs(diag_layer) + cpr._resolve_snrefs(context) # comparams named list is lazy loaded # since ComparamInstance short_name is only valid after resolution self._comparams = NamedItemList(self.comparam_refs) + context.diag_service = None + def decode_message(self, raw_message: bytes) -> Message: request_prefix = b'' candidate_coding_objects: List[Union[Request, Response]] = [ diff --git a/odxtools/docrevision.py b/odxtools/docrevision.py index 35588da6..b7d48ae3 100644 --- a/odxtools/docrevision.py +++ b/odxtools/docrevision.py @@ -1,17 +1,15 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .companyrevisioninfo import CompanyRevisionInfo from .exceptions import odxrequire from .modification import Modification from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef +from .snrefcontext import SnRefContext from .teammember import TeamMember -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class DocRevision: @@ -75,9 +73,9 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for mod in self.modifications: mod._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: for cri in self.company_revision_infos: - cri._resolve_snrefs(diag_layer) + cri._resolve_snrefs(context) for mod in self.modifications: - mod._resolve_snrefs(diag_layer) + mod._resolve_snrefs(context) diff --git a/odxtools/dopbase.py b/odxtools/dopbase.py index 08e5bae8..6b0d4478 100644 --- a/odxtools/dopbase.py +++ b/odxtools/dopbase.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .admindata import AdminData @@ -9,12 +9,10 @@ from .encodestate import EncodeState from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from .odxtypes import ParameterValue +from .snrefcontext import SnRefContext from .specialdatagroup import SpecialDataGroup from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class DopBase(IdentifiableElement): @@ -54,9 +52,9 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for sdg in self.sdgs: sdg._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: for sdg in self.sdgs: - sdg._resolve_snrefs(diag_layer) + sdg._resolve_snrefs(context) def get_static_bit_length(self) -> Optional[int]: return None diff --git a/odxtools/dtcdop.py b/odxtools/dtcdop.py index 211bee63..02f7b8d9 100644 --- a/odxtools/dtcdop.py +++ b/odxtools/dtcdop.py @@ -1,7 +1,6 @@ # SPDX-License-Identifier: MIT -# from dataclasses import dataclass, field from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union, cast +from typing import Any, Dict, List, Optional, Union, cast from xml.etree import ElementTree from typing_extensions import override @@ -19,11 +18,9 @@ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef from .odxtypes import ParameterValue, odxstr_to_bool from .physicaltype import PhysicalType +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class DtcDop(DopBase): @@ -177,9 +174,9 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: linked_dtc_dops = [odxlinks.resolve(x, DtcDop) for x in self.linked_dtc_dop_refs] self._linked_dtc_dops = NamedItemList(linked_dtc_dops) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: - super()._resolve_snrefs(diag_layer) + def _resolve_snrefs(self, context: SnRefContext) -> None: + super()._resolve_snrefs(context) for dtc_proxy in self.dtcs_raw: if isinstance(dtc_proxy, DiagnosticTroubleCode): - dtc_proxy._resolve_snrefs(diag_layer) + dtc_proxy._resolve_snrefs(context) diff --git a/odxtools/dynamicendmarkerfield.py b/odxtools/dynamicendmarkerfield.py index 62055891..0e9b7903 100644 --- a/odxtools/dynamicendmarkerfield.py +++ b/odxtools/dynamicendmarkerfield.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Sequence +from typing import Any, Dict, List, Sequence from xml.etree import ElementTree from typing_extensions import override @@ -13,11 +13,9 @@ from .field import Field from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from .odxtypes import AtomicOdxType, ParameterValue +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class DynamicEndmarkerField(Field): @@ -49,8 +47,8 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._termination_value = tv_physical - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: - super()._resolve_snrefs(diag_layer) + def _resolve_snrefs(self, context: SnRefContext) -> None: + super()._resolve_snrefs(context) @property def dyn_end_dop(self) -> DataObjectProperty: diff --git a/odxtools/dynamiclengthfield.py b/odxtools/dynamiclengthfield.py index 79acedcb..0779c2c8 100644 --- a/odxtools/dynamiclengthfield.py +++ b/odxtools/dynamiclengthfield.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Sequence +from typing import Any, Dict, List, Sequence from xml.etree import ElementTree from typing_extensions import override @@ -12,11 +12,9 @@ from .field import Field from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from .odxtypes import ParameterValue +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class DynamicLengthField(Field): @@ -45,9 +43,9 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: super()._resolve_odxlinks(odxlinks) self.determine_number_of_items._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: - super()._resolve_snrefs(diag_layer) - self.determine_number_of_items._resolve_snrefs(diag_layer) + def _resolve_snrefs(self, context: SnRefContext) -> None: + super()._resolve_snrefs(context) + self.determine_number_of_items._resolve_snrefs(context) @override def encode_into_pdu(self, physical_value: ParameterValue, encode_state: EncodeState) -> None: diff --git a/odxtools/environmentdatadescription.py b/odxtools/environmentdatadescription.py index c3dd37d9..a4ef7b89 100644 --- a/odxtools/environmentdatadescription.py +++ b/odxtools/environmentdatadescription.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from typing_extensions import override @@ -12,11 +12,9 @@ from .exceptions import odxraise, odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef from .odxtypes import ParameterValue +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class EnvironmentDataDescription(ComplexDop): @@ -87,12 +85,12 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for ed in self.env_datas: ed._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: # ODX 2.0 specifies environment data objects here, ODX 2.2 # uses references if self.env_data_refs: for ed in self.env_datas: - ed._resolve_snrefs(diag_layer) + ed._resolve_snrefs(context) @override def encode_into_pdu(self, physical_value: Optional[ParameterValue], diff --git a/odxtools/field.py b/odxtools/field.py index 89ac409e..3998a30a 100644 --- a/odxtools/field.py +++ b/odxtools/field.py @@ -1,5 +1,6 @@ +# SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, List, Optional +from typing import List, Optional from xml.etree import ElementTree from .basicstructure import BasicStructure @@ -8,11 +9,9 @@ from .exceptions import odxassert, odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkRef, resolve_snref from .odxtypes import odxstr_to_bool +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class Field(ComplexDop): @@ -80,13 +79,14 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._env_data_desc = odxlinks.resolve(self.env_data_desc_ref, EnvironmentDataDescription) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: """Recursively resolve any short-name references""" + ddd_spec = odxrequire(context.diag_layer).diag_data_dictionary_spec + if self.structure_snref is not None: - structures = diag_layer.diag_data_dictionary_spec.structures - self._structure = resolve_snref(self.structure_snref, structures, BasicStructure) + self._structure = resolve_snref(self.structure_snref, ddd_spec.structures, + BasicStructure) if self.env_data_desc_snref is not None: - env_data_descs = diag_layer.diag_data_dictionary_spec.env_data_descs - self._env_data_desc = resolve_snref(self.env_data_desc_snref, env_data_descs, + self._env_data_desc = resolve_snref(self.env_data_desc_snref, ddd_spec.env_data_descs, EnvironmentDataDescription) diff --git a/odxtools/functionalclass.py b/odxtools/functionalclass.py index de613c93..2924e6bc 100644 --- a/odxtools/functionalclass.py +++ b/odxtools/functionalclass.py @@ -1,15 +1,13 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List +from typing import Any, Dict, List from xml.etree import ElementTree from .element import IdentifiableElement from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class FunctionalClass(IdentifiableElement): @@ -31,5 +29,5 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: pass - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass diff --git a/odxtools/inputparam.py b/odxtools/inputparam.py index e590ebe9..912b1678 100644 --- a/odxtools/inputparam.py +++ b/odxtools/inputparam.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from deprecation import deprecated @@ -9,11 +9,9 @@ from .element import NamedElement from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class InputParam(NamedElement): @@ -44,7 +42,7 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._dop_base = odxlinks.resolve(self.dop_base_ref, DopBase) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass @property diff --git a/odxtools/modification.py b/odxtools/modification.py index dc2a673d..8c96374e 100644 --- a/odxtools/modification.py +++ b/odxtools/modification.py @@ -1,12 +1,10 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId - -if TYPE_CHECKING: - from .diaglayer import DiagLayer +from .snrefcontext import SnRefContext @dataclass @@ -27,5 +25,5 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: pass - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass diff --git a/odxtools/multiplexer.py b/odxtools/multiplexer.py index 32e3a629..4c6d1eac 100644 --- a/odxtools/multiplexer.py +++ b/odxtools/multiplexer.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple +from typing import Any, Dict, List, Optional, Tuple from xml.etree import ElementTree from typing_extensions import override @@ -14,11 +14,9 @@ from .multiplexerswitchkey import MultiplexerSwitchKey from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from .odxtypes import AtomicOdxType, ParameterValue, odxstr_to_bool +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class Multiplexer(ComplexDop): @@ -186,12 +184,12 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: odxlinks, key_physical_type=self.switch_key.dop.physical_type.base_data_type) @override - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: - super()._resolve_snrefs(diag_layer) + def _resolve_snrefs(self, context: SnRefContext) -> None: + super()._resolve_snrefs(context) - self.switch_key._resolve_snrefs(diag_layer) + self.switch_key._resolve_snrefs(context) if self.default_case is not None: - self.default_case._resolve_snrefs(diag_layer) + self.default_case._resolve_snrefs(context) for mux_case in self.cases: - mux_case._resolve_snrefs(diag_layer) + mux_case._resolve_snrefs(context) diff --git a/odxtools/multiplexercase.py b/odxtools/multiplexercase.py index 2e8d0eeb..e2510af2 100644 --- a/odxtools/multiplexercase.py +++ b/odxtools/multiplexercase.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .basicstructure import BasicStructure @@ -9,11 +9,9 @@ from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref from .odxtypes import AtomicOdxType, DataType +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class MultiplexerCase(NamedElement): @@ -70,9 +68,9 @@ def _mux_case_resolve_odxlinks(self, odxlinks: OdxLinkDatabase, *, self.lower_limit.set_value_type(key_physical_type) self.upper_limit.set_value_type(key_physical_type) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: if self.structure_snref: - ddds = diag_layer.diag_data_dictionary_spec + ddds = odxrequire(context.diag_layer).diag_data_dictionary_spec self._structure = resolve_snref(self.structure_snref, ddds.structures, BasicStructure) def applies(self, value: AtomicOdxType) -> bool: diff --git a/odxtools/multiplexerdefaultcase.py b/odxtools/multiplexerdefaultcase.py index 45f289ce..9be805f8 100644 --- a/odxtools/multiplexerdefaultcase.py +++ b/odxtools/multiplexerdefaultcase.py @@ -1,17 +1,15 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .basicstructure import BasicStructure from .element import NamedElement from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class MultiplexerDefaultCase(NamedElement): @@ -43,9 +41,9 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: if self.structure_ref is not None: self._structure = odxlinks.resolve(self.structure_ref) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: if self.structure_snref: - ddds = diag_layer.diag_data_dictionary_spec + ddds = odxrequire(context.diag_layer).diag_data_dictionary_spec self._structure = resolve_snref(self.structure_snref, ddds.structures, BasicStructure) @property diff --git a/odxtools/multiplexerswitchkey.py b/odxtools/multiplexerswitchkey.py index 3afc85de..915f52a2 100644 --- a/odxtools/multiplexerswitchkey.py +++ b/odxtools/multiplexerswitchkey.py @@ -1,13 +1,12 @@ +# SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .dataobjectproperty import DataObjectProperty from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef - -if TYPE_CHECKING: - from .diaglayer import DiagLayer +from .snrefcontext import SnRefContext @dataclass @@ -39,7 +38,7 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._dop = odxlinks.resolve(self.dop_ref, DataObjectProperty) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass @property diff --git a/odxtools/negoutputparam.py b/odxtools/negoutputparam.py index ebdad797..df3d5daa 100644 --- a/odxtools/negoutputparam.py +++ b/odxtools/negoutputparam.py @@ -1,17 +1,15 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .dopbase import DopBase from .element import NamedElement from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class NegOutputParam(NamedElement): @@ -35,7 +33,7 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._dop = odxlinks.resolve(self.dop_base_ref) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass @property diff --git a/odxtools/outputparam.py b/odxtools/outputparam.py index e80d4ebc..21544311 100644 --- a/odxtools/outputparam.py +++ b/odxtools/outputparam.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from deprecation import deprecated @@ -9,11 +9,9 @@ from .element import IdentifiableElement from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class OutputParam(IdentifiableElement): @@ -37,7 +35,7 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._dop_base = odxlinks.resolve(self.dop_base_ref, DopBase) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass @property diff --git a/odxtools/parameters/codedconstparameter.py b/odxtools/parameters/codedconstparameter.py index e6f2c5d3..e9da635d 100644 --- a/odxtools/parameters/codedconstparameter.py +++ b/odxtools/parameters/codedconstparameter.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MIT import warnings from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from typing_extensions import override @@ -11,14 +11,11 @@ from ..diagcodedtype import DiagCodedType from ..encodestate import EncodeState from ..exceptions import DecodeError, EncodeError, odxraise, odxrequire -from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from ..odxlink import OdxDocFragment, OdxLinkId from ..odxtypes import AtomicOdxType, DataType, ParameterValue from ..utils import dataclass_fields_asdict from .parameter import Parameter, ParameterType -if TYPE_CHECKING: - from ..diaglayer import DiagLayer - @dataclass class CodedConstParameter(Parameter): @@ -54,15 +51,6 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: return result - @override - def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: - super()._resolve_odxlinks(odxlinks) - - @override - def _parameter_resolve_snrefs(self, diag_layer: "DiagLayer", *, - param_list: List[Parameter]) -> None: - super()._parameter_resolve_snrefs(diag_layer, param_list=param_list) - @override def get_static_bit_length(self) -> Optional[int]: return self.diag_coded_type.get_static_bit_length() diff --git a/odxtools/parameters/lengthkeyparameter.py b/odxtools/parameters/lengthkeyparameter.py index a3c99ef9..aa1af915 100644 --- a/odxtools/parameters/lengthkeyparameter.py +++ b/odxtools/parameters/lengthkeyparameter.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from typing_extensions import final, override @@ -8,15 +8,12 @@ from ..decodestate import DecodeState from ..encodestate import EncodeState from ..exceptions import EncodeError, odxraise, odxrequire -from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from ..odxlink import OdxDocFragment, OdxLinkId from ..odxtypes import ParameterValue from ..utils import dataclass_fields_asdict -from .parameter import Parameter, ParameterType +from .parameter import ParameterType from .parameterwithdop import ParameterWithDOP -if TYPE_CHECKING: - from ..diaglayer import DiagLayer - @dataclass class LengthKeyParameter(ParameterWithDOP): @@ -55,15 +52,6 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: return result - @override - def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: - super()._resolve_odxlinks(odxlinks) - - @override - def _parameter_resolve_snrefs(self, diag_layer: "DiagLayer", *, - param_list: List[Parameter]) -> None: - super()._parameter_resolve_snrefs(diag_layer, param_list=param_list) - @property @override def is_required(self) -> bool: diff --git a/odxtools/parameters/nrcconstparameter.py b/odxtools/parameters/nrcconstparameter.py index 6cbd1a5b..6e47614d 100644 --- a/odxtools/parameters/nrcconstparameter.py +++ b/odxtools/parameters/nrcconstparameter.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MIT import warnings from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast +from typing import Any, Dict, List, Optional, cast from xml.etree import ElementTree from typing_extensions import override @@ -11,14 +11,11 @@ from ..diagcodedtype import DiagCodedType from ..encodestate import EncodeState from ..exceptions import DecodeError, EncodeError, odxraise, odxrequire -from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from ..odxlink import OdxDocFragment, OdxLinkId from ..odxtypes import AtomicOdxType, DataType, ParameterValue from ..utils import dataclass_fields_asdict from .parameter import Parameter, ParameterType -if TYPE_CHECKING: - from ..diaglayer import DiagLayer - @dataclass class NrcConstParameter(Parameter): @@ -70,15 +67,6 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: return result - @override - def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: - super()._resolve_odxlinks(odxlinks) - - @override - def _parameter_resolve_snrefs(self, diag_layer: "DiagLayer", *, - param_list: List[Parameter]) -> None: - super()._parameter_resolve_snrefs(diag_layer, param_list=param_list) - @override def get_static_bit_length(self) -> Optional[int]: return self.diag_coded_type.get_static_bit_length() diff --git a/odxtools/parameters/parameter.py b/odxtools/parameters/parameter.py index 33c04e8d..d121022e 100644 --- a/odxtools/parameters/parameter.py +++ b/odxtools/parameters/parameter.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional +from typing import Any, Dict, List, Literal, Optional from xml.etree import ElementTree from typing_extensions import final, override @@ -10,12 +10,10 @@ from ..encodestate import EncodeState from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from ..odxtypes import ParameterValue +from ..snrefcontext import SnRefContext from ..specialdatagroup import SpecialDataGroup from ..utils import dataclass_fields_asdict -if TYPE_CHECKING: - from ..diaglayer import DiagLayer - ParameterType = Literal[ "CODED-CONST", "DYNAMIC", @@ -83,15 +81,9 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for sdg in self.sdgs: sdg._resolve_odxlinks(odxlinks) - @final - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: - raise RuntimeError("Calling _resolve_snrefs() is not allowed for parameters. " - "Use _parameter_resolve_snrefs() instead.") - - def _parameter_resolve_snrefs(self, diag_layer: "DiagLayer", *, - param_list: List["Parameter"]) -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: for sdg in self.sdgs: - sdg._resolve_snrefs(diag_layer) + sdg._resolve_snrefs(context) @property def parameter_type(self) -> ParameterType: diff --git a/odxtools/parameters/parameterwithdop.py b/odxtools/parameters/parameterwithdop.py index 7a08091e..6088e01a 100644 --- a/odxtools/parameters/parameterwithdop.py +++ b/odxtools/parameters/parameterwithdop.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast +from typing import Any, Dict, List, Optional, cast from xml.etree import ElementTree from typing_extensions import override @@ -14,12 +14,10 @@ from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref from ..odxtypes import AtomicOdxType, ParameterValue from ..physicaltype import PhysicalType +from ..snrefcontext import SnRefContext from ..utils import dataclass_fields_asdict from .parameter import Parameter -if TYPE_CHECKING: - from ..diaglayer import DiagLayer - @dataclass class ParameterWithDOP(Parameter): @@ -58,12 +56,12 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._dop = odxlinks.resolve(self.dop_ref) @override - def _parameter_resolve_snrefs(self, diag_layer: "DiagLayer", *, - param_list: List[Parameter]) -> None: - super()._parameter_resolve_snrefs(diag_layer, param_list=param_list) + def _resolve_snrefs(self, context: SnRefContext) -> None: + super()._resolve_snrefs(context) if self.dop_snref: - all_dops = diag_layer.diag_data_dictionary_spec.all_data_object_properties + all_dops = odxrequire( + context.diag_layer).diag_data_dictionary_spec.all_data_object_properties self._dop = resolve_snref(self.dop_snref, all_dops, DopBase) @property diff --git a/odxtools/parameters/physicalconstantparameter.py b/odxtools/parameters/physicalconstantparameter.py index f34dbf65..d7189e57 100644 --- a/odxtools/parameters/physicalconstantparameter.py +++ b/odxtools/parameters/physicalconstantparameter.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from typing_extensions import override @@ -11,13 +11,11 @@ from ..exceptions import DecodeError, EncodeError, odxraise, odxrequire from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from ..odxtypes import ParameterValue +from ..snrefcontext import SnRefContext from ..utils import dataclass_fields_asdict -from .parameter import Parameter, ParameterType +from .parameter import ParameterType from .parameterwithdop import ParameterWithDOP -if TYPE_CHECKING: - from ..diaglayer import DiagLayer - @dataclass class PhysicalConstantParameter(ParameterWithDOP): @@ -50,9 +48,8 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: super()._resolve_odxlinks(odxlinks) @override - def _parameter_resolve_snrefs(self, diag_layer: "DiagLayer", *, - param_list: List[Parameter]) -> None: - super()._parameter_resolve_snrefs(diag_layer, param_list=param_list) + def _resolve_snrefs(self, context: SnRefContext) -> None: + super()._resolve_snrefs(context) dop = odxrequire(self.dop) if not isinstance(dop, DataObjectProperty): diff --git a/odxtools/parameters/tablekeyparameter.py b/odxtools/parameters/tablekeyparameter.py index 37a30bf7..bddd34aa 100644 --- a/odxtools/parameters/tablekeyparameter.py +++ b/odxtools/parameters/tablekeyparameter.py @@ -10,11 +10,11 @@ from ..exceptions import DecodeError, EncodeError, odxraise, odxrequire from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref from ..odxtypes import ParameterValue +from ..snrefcontext import SnRefContext from ..utils import dataclass_fields_asdict from .parameter import Parameter, ParameterType if TYPE_CHECKING: - from ..diaglayer import DiagLayer from ..table import Table from ..tablerow import TableRow @@ -94,12 +94,11 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._table = self._table_row.table @override - def _parameter_resolve_snrefs(self, diag_layer: "DiagLayer", *, - param_list: List[Parameter]) -> None: - super()._parameter_resolve_snrefs(diag_layer, param_list=param_list) + def _resolve_snrefs(self, context: SnRefContext) -> None: + super()._resolve_snrefs(context) if self.table_snref is not None: - tables = diag_layer.diag_data_dictionary_spec.tables + tables = odxrequire(context.diag_layer).diag_data_dictionary_spec.tables self._table = resolve_snref(self.table_snref, tables, Table) if self.table_row_snref is not None: # make sure that we know the table to which the table row diff --git a/odxtools/parameters/tablestructparameter.py b/odxtools/parameters/tablestructparameter.py index 083da933..0703c887 100644 --- a/odxtools/parameters/tablestructparameter.py +++ b/odxtools/parameters/tablestructparameter.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast +from typing import Any, Dict, List, Optional, cast from xml.etree import ElementTree from typing_extensions import override @@ -10,13 +10,11 @@ from ..exceptions import DecodeError, EncodeError, odxraise, odxrequire from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref from ..odxtypes import ParameterValue +from ..snrefcontext import SnRefContext from ..utils import dataclass_fields_asdict from .parameter import Parameter, ParameterType from .tablekeyparameter import TableKeyParameter -if TYPE_CHECKING: - from ..diaglayer import DiagLayer - @dataclass class TableStructParameter(Parameter): @@ -60,12 +58,12 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._table_key = odxlinks.resolve(self.table_key_ref, TableKeyParameter) @override - def _parameter_resolve_snrefs(self, diag_layer: "DiagLayer", *, - param_list: List[Parameter]) -> None: - super()._parameter_resolve_snrefs(diag_layer, param_list=param_list) + def _resolve_snrefs(self, context: SnRefContext) -> None: + super()._resolve_snrefs(context) if self.table_key_snref is not None: - self._table_key = resolve_snref(self.table_key_snref, param_list, TableKeyParameter) + self._table_key = resolve_snref(self.table_key_snref, odxrequire(context.parameters), + TableKeyParameter) @property def table_key(self) -> TableKeyParameter: diff --git a/odxtools/parameters/valueparameter.py b/odxtools/parameters/valueparameter.py index 1ef22d60..38936bd4 100644 --- a/odxtools/parameters/valueparameter.py +++ b/odxtools/parameters/valueparameter.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from typing_extensions import override @@ -10,13 +10,11 @@ from ..exceptions import EncodeError, odxraise, odxrequire from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from ..odxtypes import AtomicOdxType, ParameterValue +from ..snrefcontext import SnRefContext from ..utils import dataclass_fields_asdict -from .parameter import Parameter, ParameterType +from .parameter import ParameterType from .parameterwithdop import ParameterWithDOP -if TYPE_CHECKING: - from ..diaglayer import DiagLayer - @dataclass class ValueParameter(ParameterWithDOP): @@ -50,9 +48,8 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: super()._resolve_odxlinks(odxlinks) @override - def _parameter_resolve_snrefs(self, diag_layer: "DiagLayer", *, - param_list: List[Parameter]) -> None: - super()._parameter_resolve_snrefs(diag_layer, param_list=param_list) + def _resolve_snrefs(self, context: SnRefContext) -> None: + super()._resolve_snrefs(context) if self.physical_default_value_raw is not None: dop = odxrequire(self.dop) diff --git a/odxtools/paramlengthinfotype.py b/odxtools/paramlengthinfotype.py index 19a10e86..d73f6b63 100644 --- a/odxtools/paramlengthinfotype.py +++ b/odxtools/paramlengthinfotype.py @@ -11,10 +11,10 @@ from .exceptions import EncodeError, odxraise, odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef from .odxtypes import AtomicOdxType, DataType +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict if TYPE_CHECKING: - from .diaglayer import DiagLayer from .parameters.lengthkeyparameter import LengthKeyParameter @@ -50,9 +50,9 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: else: self._length_key = odxlinks.resolve(self.length_key_ref) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: """Recursively resolve any short-name references""" - super()._resolve_snrefs(diag_layer) + super()._resolve_snrefs(context) @property def length_key(self) -> "LengthKeyParameter": diff --git a/odxtools/parentref.py b/odxtools/parentref.py index 51668be9..cf190df0 100644 --- a/odxtools/parentref.py +++ b/odxtools/parentref.py @@ -6,6 +6,7 @@ from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict if TYPE_CHECKING: @@ -78,7 +79,7 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: else: self._layer = odxlinks.resolve(self.layer_ref) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass def __deepcopy__(self, memo: Dict[int, Any]) -> Any: diff --git a/odxtools/physicaldimension.py b/odxtools/physicaldimension.py index 6832c517..7ddb1646 100644 --- a/odxtools/physicaldimension.py +++ b/odxtools/physicaldimension.py @@ -1,15 +1,13 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .element import IdentifiableElement from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class PhysicalDimension(IdentifiableElement): @@ -89,5 +87,5 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: pass - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass diff --git a/odxtools/progcode.py b/odxtools/progcode.py index 1c5ea69b..86ce5c96 100644 --- a/odxtools/progcode.py +++ b/odxtools/progcode.py @@ -1,13 +1,11 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast +from typing import Any, Dict, List, Optional, cast from xml.etree import ElementTree from .exceptions import odxraise, odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef - -if TYPE_CHECKING: - from .diaglayer import DiagLayer +from .snrefcontext import SnRefContext @dataclass @@ -55,10 +53,8 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: # Once they are internalized, resolve the `library_refs` references here. pass - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: - db = diag_layer._database - - aux_file = db.auxiliary_files.get(self.code_file) + def _resolve_snrefs(self, context: SnRefContext) -> None: + aux_file = odxrequire(context.database).auxiliary_files.get(self.code_file) if aux_file is None: odxraise(f"Reference to auxiliary file '{self.code_file}' " diff --git a/odxtools/protstack.py b/odxtools/protstack.py index 32cf2be3..15b4a6e4 100644 --- a/odxtools/protstack.py +++ b/odxtools/protstack.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List +from typing import Any, Dict, List from xml.etree import ElementTree from .comparamsubset import ComparamSubset @@ -8,11 +8,9 @@ from .exceptions import odxrequire from .nameditemlist import NamedItemList from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class ProtStack(IdentifiableElement): @@ -47,7 +45,7 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._comparam_subsets = NamedItemList[ComparamSubset]( [odxlinks.resolve(x, ComparamSubset) for x in self.comparam_subset_refs]) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass @property diff --git a/odxtools/relateddoc.py b/odxtools/relateddoc.py index cf8c7ae5..9967ead6 100644 --- a/odxtools/relateddoc.py +++ b/odxtools/relateddoc.py @@ -1,15 +1,13 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .description import Description from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from .snrefcontext import SnRefContext from .xdoc import XDoc -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class RelatedDoc: @@ -41,6 +39,6 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: if self.xdoc: self.xdoc._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: if self.xdoc: - self.xdoc._resolve_snrefs(diag_layer) + self.xdoc._resolve_snrefs(context) diff --git a/odxtools/request.py b/odxtools/request.py index d7f6a924..284cc767 100644 --- a/odxtools/request.py +++ b/odxtools/request.py @@ -7,6 +7,7 @@ from .encodestate import EncodeState from .odxlink import OdxDocFragment from .odxtypes import ParameterValue +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict @@ -29,3 +30,10 @@ def encode(self, **kwargs: ParameterValue) -> bytes: self.encode_into_pdu(physical_value=kwargs, encode_state=encode_state) return encode_state.coded_message + + def _resolve_snrefs(self, context: SnRefContext) -> None: + context.request = self + + super()._resolve_snrefs(context) + + context.request = None diff --git a/odxtools/response.py b/odxtools/response.py index a80e5519..da3dc289 100644 --- a/odxtools/response.py +++ b/odxtools/response.py @@ -9,6 +9,7 @@ from .exceptions import odxraise from .odxlink import OdxDocFragment from .odxtypes import ParameterValue +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict @@ -44,3 +45,10 @@ def encode(self, coded_request: Optional[bytes] = None, **kwargs: ParameterValue self.encode_into_pdu(physical_value=kwargs, encode_state=encode_state) return encode_state.coded_message + + def _resolve_snrefs(self, context: SnRefContext) -> None: + context.response = self + + super()._resolve_snrefs(context) + + context.response = None diff --git a/odxtools/singleecujob.py b/odxtools/singleecujob.py index 904f61f6..1399c6f8 100644 --- a/odxtools/singleecujob.py +++ b/odxtools/singleecujob.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List +from typing import Any, Dict, List from xml.etree import ElementTree from .diagcomm import DiagComm @@ -10,11 +10,9 @@ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from .outputparam import OutputParam from .progcode import ProgCode +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class SingleEcuJob(DiagComm): @@ -88,14 +86,18 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for neg_output_param in self.neg_output_params: neg_output_param._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: - super()._resolve_snrefs(diag_layer) + def _resolve_snrefs(self, context: SnRefContext) -> None: + context.single_ecu_job = self + + super()._resolve_snrefs(context) for prog_code in self.prog_codes: - prog_code._resolve_snrefs(diag_layer) + prog_code._resolve_snrefs(context) for input_param in self.input_params: - input_param._resolve_snrefs(diag_layer) + input_param._resolve_snrefs(context) for output_param in self.output_params: - output_param._resolve_snrefs(diag_layer) + output_param._resolve_snrefs(context) for neg_output_param in self.neg_output_params: - neg_output_param._resolve_snrefs(diag_layer) + neg_output_param._resolve_snrefs(context) + + context.single_ecu_job = None diff --git a/odxtools/snrefcontext.py b/odxtools/snrefcontext.py new file mode 100644 index 00000000..7eb82c73 --- /dev/null +++ b/odxtools/snrefcontext.py @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: MIT +from dataclasses import dataclass +from typing import TYPE_CHECKING, List, Optional + +if TYPE_CHECKING: + from .database import Database + from .diaglayer import DiagLayer + from .diagservice import DiagService + from .parameters.parameter import Parameter + from .request import Request + from .response import Response + from .singleecujob import SingleEcuJob + from .statechart import StateChart + + +@dataclass +class SnRefContext: + """Represents the context for which a short name reference ought + to be resolved + """ + + database: Optional["Database"] = None + diag_layer: Optional["DiagLayer"] = None + diag_service: Optional["DiagService"] = None + single_ecu_job: Optional["SingleEcuJob"] = None + request: Optional["Request"] = None + response: Optional["Response"] = None + parameters: Optional[List["Parameter"]] = None + state_chart: Optional["StateChart"] = None diff --git a/odxtools/specialdata.py b/odxtools/specialdata.py index fbad5edc..94a35710 100644 --- a/odxtools/specialdata.py +++ b/odxtools/specialdata.py @@ -1,12 +1,10 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId - -if TYPE_CHECKING: - from .diaglayer import DiagLayer +from .snrefcontext import SnRefContext @dataclass @@ -21,7 +19,7 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: pass - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass @staticmethod diff --git a/odxtools/specialdatagroup.py b/odxtools/specialdatagroup.py index e80b401c..e48667c0 100644 --- a/odxtools/specialdatagroup.py +++ b/odxtools/specialdatagroup.py @@ -1,15 +1,13 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Union from xml.etree import ElementTree from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef +from .snrefcontext import SnRefContext from .specialdata import SpecialData from .specialdatagroupcaption import SpecialDataGroupCaption -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class SpecialDataGroup: @@ -72,11 +70,11 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for val in self.values: val._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: # resolve the SNREFs of the caption, but only if the caption # was specified by value, not by reference if self.sdg_caption is not None and self.sdg_caption_ref is None: - self.sdg_caption._resolve_snrefs(diag_layer) + self.sdg_caption._resolve_snrefs(context) for val in self.values: - val._resolve_snrefs(diag_layer) + val._resolve_snrefs(context) diff --git a/odxtools/specialdatagroupcaption.py b/odxtools/specialdatagroupcaption.py index 62cc4244..19ac31cc 100644 --- a/odxtools/specialdatagroupcaption.py +++ b/odxtools/specialdatagroupcaption.py @@ -1,16 +1,13 @@ # SPDX-License-Identifier: MIT -# import warnings from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List +from typing import Any, Dict, List from xml.etree import ElementTree from .element import IdentifiableElement from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class SpecialDataGroupCaption(IdentifiableElement): @@ -32,5 +29,5 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: pass - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass diff --git a/odxtools/state.py b/odxtools/state.py index d737fdc3..8391ca05 100644 --- a/odxtools/state.py +++ b/odxtools/state.py @@ -1,15 +1,13 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List +from typing import Any, Dict, List from xml.etree import ElementTree from .element import IdentifiableElement from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class State(IdentifiableElement): @@ -29,5 +27,5 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: pass - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass diff --git a/odxtools/statechart.py b/odxtools/statechart.py index bd8bc9cd..8036a4e9 100644 --- a/odxtools/statechart.py +++ b/odxtools/statechart.py @@ -1,19 +1,17 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List +from typing import Any, Dict, List from xml.etree import ElementTree from .element import IdentifiableElement from .exceptions import odxrequire from .nameditemlist import NamedItemList from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, resolve_snref +from .snrefcontext import SnRefContext from .state import State from .statetransition import StateTransition from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class StateChart(IdentifiableElement): @@ -68,7 +66,9 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for st in self.states: st._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: + context.state_chart = self + # For now, we assume that the start state short name reference # points to a local state of the state chart. TODO: The XSD # allows to define state charts without any states, yet the @@ -78,11 +78,9 @@ def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: self._start_state = resolve_snref(self.start_state_snref, self.states, State) for st in self.states: - st._resolve_snrefs(diag_layer) + st._resolve_snrefs(context) for strans in self.state_transitions: - # note that the signature of the state transition's - # _resolve_snrefs() method is non-standard as the - # namespace of these SNREFs is the state chart, not the - # whole diag layer... - strans._resolve_snrefs(diag_layer, states=self.states) + strans._resolve_snrefs(context) + + context.state_chart = None diff --git a/odxtools/statetransition.py b/odxtools/statetransition.py index bcc6930f..6ea9469d 100644 --- a/odxtools/statetransition.py +++ b/odxtools/statetransition.py @@ -1,17 +1,15 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, Iterable, List +from typing import Any, Dict, List from xml.etree import ElementTree from .element import IdentifiableElement from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, resolve_snref +from .snrefcontext import SnRefContext from .state import State from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class StateTransition(IdentifiableElement): @@ -50,10 +48,7 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: pass - # note that the signature of this method is non-standard because - # the namespace of these SNREFs is the corresponding state - # chart. To mitigate this a bit, the non-standard parameters are - # keyword-only... - def _resolve_snrefs(self, diag_layer: "DiagLayer", *, states: Iterable[State]) -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: + states = odxrequire(context.state_chart).states self._source_state = resolve_snref(self.source_snref, states, State) self._target_state = resolve_snref(self.target_snref, states, State) diff --git a/odxtools/staticfield.py b/odxtools/staticfield.py index 492b8759..7ed25416 100644 --- a/odxtools/staticfield.py +++ b/odxtools/staticfield.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Sequence +from typing import Any, Dict, List, Sequence from xml.etree import ElementTree from typing_extensions import override @@ -11,11 +11,9 @@ from .field import Field from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from .odxtypes import ParameterValue +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class StaticField(Field): @@ -44,8 +42,8 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: super()._resolve_odxlinks(odxlinks) @override - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: - super()._resolve_snrefs(diag_layer) + def _resolve_snrefs(self, context: SnRefContext) -> None: + super()._resolve_snrefs(context) @override def encode_into_pdu(self, physical_value: ParameterValue, encode_state: EncodeState) -> None: diff --git a/odxtools/table.py b/odxtools/table.py index 1b4533de..d6b3ef75 100644 --- a/odxtools/table.py +++ b/odxtools/table.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Union from xml.etree import ElementTree from .admindata import AdminData @@ -9,13 +9,11 @@ from .exceptions import odxassert from .nameditemlist import NamedItemList from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef +from .snrefcontext import SnRefContext from .specialdatagroup import SpecialDataGroup from .tablerow import TableRow from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class Table(IdentifiableElement): @@ -100,7 +98,7 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._table_rows = NamedItemList(table_rows) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: for table_row_wrapper in self.table_rows_raw: if isinstance(table_row_wrapper, TableRow): - table_row_wrapper._resolve_snrefs(diag_layer) + table_row_wrapper._resolve_snrefs(context) diff --git a/odxtools/tablerow.py b/odxtools/tablerow.py index 475eeb8b..9e34c559 100644 --- a/odxtools/tablerow.py +++ b/odxtools/tablerow.py @@ -10,11 +10,11 @@ from .exceptions import odxassert, odxraise, odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref from .odxtypes import AtomicOdxType +from .snrefcontext import SnRefContext from .specialdatagroup import SpecialDataGroup from .utils import dataclass_fields_asdict if TYPE_CHECKING: - from .diaglayer import DiagLayer from .table import Table @@ -108,7 +108,7 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for sdg in self.sdgs: sdg._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: # convert the raw key into the proper internal # representation. note that we cannot do this earlier because # the table's ODXLINKs must be resolved and the order of @@ -126,7 +126,7 @@ def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: else: self._key = key_dop.physical_type.base_data_type.from_string(self.key_raw) - ddd_spec = diag_layer.diag_data_dictionary_spec + ddd_spec = odxrequire(context.diag_layer).diag_data_dictionary_spec if self.structure_snref is not None: self._structure = resolve_snref(self.structure_snref, ddd_spec.structures, @@ -136,7 +136,7 @@ def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: DataObjectProperty) for sdg in self.sdgs: - sdg._resolve_snrefs(diag_layer) + sdg._resolve_snrefs(context) @property def table(self) -> "Table": diff --git a/odxtools/teammember.py b/odxtools/teammember.py index 5677ce17..51cbad9d 100644 --- a/odxtools/teammember.py +++ b/odxtools/teammember.py @@ -1,16 +1,14 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .element import IdentifiableElement from .exceptions import odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class TeamMember(IdentifiableElement): @@ -55,5 +53,5 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: pass - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass diff --git a/odxtools/unit.py b/odxtools/unit.py index 38f058df..a5642451 100644 --- a/odxtools/unit.py +++ b/odxtools/unit.py @@ -1,17 +1,15 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .element import IdentifiableElement from .exceptions import odxassert, odxrequire from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef from .physicaldimension import PhysicalDimension +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class Unit(IdentifiableElement): @@ -104,5 +102,5 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: f"The physical_dimension_ref must be resolved to a PhysicalDimension." f" {self.physical_dimension_ref} referenced {self._physical_dimension}") - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass diff --git a/odxtools/unitgroup.py b/odxtools/unitgroup.py index 23c55a74..3d120985 100644 --- a/odxtools/unitgroup.py +++ b/odxtools/unitgroup.py @@ -1,19 +1,17 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass from enum import Enum -from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast +from typing import Any, Dict, List, Optional, cast from xml.etree import ElementTree from .element import NamedElement from .exceptions import odxraise, odxrequire from .nameditemlist import NamedItemList from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef +from .snrefcontext import SnRefContext from .unit import Unit from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - class UnitGroupCategory(Enum): COUNTRY = "COUNTRY" @@ -57,7 +55,7 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: self._units = NamedItemList[Unit]([odxlinks.resolve(ref) for ref in self.unit_refs]) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass @property diff --git a/odxtools/unitspec.py b/odxtools/unitspec.py index 5a7e47c6..cf41bc59 100644 --- a/odxtools/unitspec.py +++ b/odxtools/unitspec.py @@ -1,18 +1,16 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Union +from typing import Any, Dict, List, Union from xml.etree import ElementTree from .nameditemlist import NamedItemList from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId from .physicaldimension import PhysicalDimension +from .snrefcontext import SnRefContext from .specialdatagroup import SpecialDataGroup from .unit import Unit from .unitgroup import UnitGroup -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class UnitSpec: @@ -77,10 +75,10 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: for sdg in self.sdgs: sdg._resolve_odxlinks(odxlinks) - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: for unit in self.units: - unit._resolve_snrefs(diag_layer) + unit._resolve_snrefs(context) for group in self.unit_groups: - group._resolve_snrefs(diag_layer) + group._resolve_snrefs(context) for sdg in self.sdgs: - sdg._resolve_snrefs(diag_layer) + sdg._resolve_snrefs(context) diff --git a/odxtools/xdoc.py b/odxtools/xdoc.py index 32cb7acb..1625218c 100644 --- a/odxtools/xdoc.py +++ b/odxtools/xdoc.py @@ -1,15 +1,13 @@ # SPDX-License-Identifier: MIT from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import Any, Dict, List, Optional from xml.etree import ElementTree from .element import NamedElement from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId +from .snrefcontext import SnRefContext from .utils import dataclass_fields_asdict -if TYPE_CHECKING: - from .diaglayer import DiagLayer - @dataclass class XDoc(NamedElement): @@ -45,5 +43,5 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: pass - def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None: + def _resolve_snrefs(self, context: SnRefContext) -> None: pass diff --git a/tests/test_decoding.py b/tests/test_decoding.py index 4e021e27..126e25d4 100644 --- a/tests/test_decoding.py +++ b/tests/test_decoding.py @@ -1,6 +1,5 @@ # SPDX-License-Identifier: MIT import unittest -from typing import cast from odxtools.compumethods.compuinternaltophys import CompuInternalToPhys from odxtools.compumethods.compumethod import CompuCategory @@ -36,6 +35,7 @@ from odxtools.physicaltype import PhysicalType from odxtools.request import Request from odxtools.response import Response, ResponseType +from odxtools.snrefcontext import SnRefContext from odxtools.standardlengthtype import StandardLengthType from odxtools.staticfield import StaticField from odxtools.structure import Structure @@ -2307,9 +2307,9 @@ def setUp(self) -> None: self.parameter_termination_end_of_pdu._resolve_odxlinks(odxlinks) self.parameter_sid._resolve_odxlinks(odxlinks) - self.parameter_termination_end_of_pdu._parameter_resolve_snrefs( - cast(DiagLayer, None), param_list=[]) - self.parameter_sid._parameter_resolve_snrefs(cast(DiagLayer, None), param_list=[]) + snref_ctx = SnRefContext() + self.parameter_termination_end_of_pdu._resolve_snrefs(snref_ctx) + self.parameter_sid._resolve_snrefs(snref_ctx) def test_min_max_length_type_end_of_pdu(self) -> None: req_param1 = self.parameter_sid @@ -2377,8 +2377,9 @@ def test_min_max_length_type_end_of_pdu_in_structure(self) -> None: req_param1._resolve_odxlinks(odxlinks) req_param2._resolve_odxlinks(odxlinks) - req_param1._parameter_resolve_snrefs(cast(DiagLayer, None), param_list=[]) - req_param2._parameter_resolve_snrefs(cast(DiagLayer, None), param_list=[]) + snref_ctx = SnRefContext() + req_param1._resolve_snrefs(snref_ctx) + req_param2._resolve_snrefs(snref_ctx) expected_coded_message = bytes([0x12, 0x34]) expected_param_dict = { @@ -2480,8 +2481,9 @@ def test_physical_constant_parameter(self) -> None: req_param1._resolve_odxlinks(odxlinks) req_param2._resolve_odxlinks(odxlinks) - req_param1._parameter_resolve_snrefs(cast(DiagLayer, None), param_list=[]) - req_param2._parameter_resolve_snrefs(cast(DiagLayer, None), param_list=[]) + snref_ctx = SnRefContext() + req_param1._resolve_snrefs(snref_ctx) + req_param2._resolve_snrefs(snref_ctx) expected_coded_message = bytes([0x12, 0x0]) expected_param_dict = {"SID": 0x12, "physical_constant_parameter": offset} diff --git a/tests/test_encoding.py b/tests/test_encoding.py index 390870d6..b5916993 100644 --- a/tests/test_encoding.py +++ b/tests/test_encoding.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT import unittest -from typing import List, cast +from typing import List from odxtools.compumethods.compuinternaltophys import CompuInternalToPhys from odxtools.compumethods.compumethod import CompuCategory @@ -9,7 +9,6 @@ from odxtools.compumethods.identicalcompumethod import IdenticalCompuMethod from odxtools.compumethods.linearcompumethod import LinearCompuMethod from odxtools.dataobjectproperty import DataObjectProperty -from odxtools.diaglayer import DiagLayer from odxtools.exceptions import EncodeError from odxtools.nameditemlist import NamedItemList from odxtools.odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef @@ -21,6 +20,7 @@ from odxtools.physicaltype import PhysicalType from odxtools.request import Request from odxtools.response import Response, ResponseType +from odxtools.snrefcontext import SnRefContext from odxtools.standardlengthtype import StandardLengthType doc_frags = [OdxDocFragment("UnitTest", "WinneThePoh")] @@ -186,8 +186,9 @@ def test_encode_linear(self) -> None: byte_size=None, ) + snref_ctx = SnRefContext(parameters=req.parameters) param1._resolve_odxlinks(odxlinks) - param1._parameter_resolve_snrefs(cast(DiagLayer, None), param_list=req.parameters) + param1._resolve_snrefs(snref_ctx) # Missing mandatory parameter. with self.assertRaises(EncodeError): @@ -426,8 +427,9 @@ def test_bit_mask(self) -> None: semantic=None, sdgs=[], physical_default_value_raw=None) + snref_ctx = SnRefContext(parameters=[]) inner_param._resolve_odxlinks(odxlinks) - inner_param._parameter_resolve_snrefs(cast(DiagLayer, None), param_list=[]) + inner_param._resolve_snrefs(snref_ctx) # Outer outer_param = ValueParameter( @@ -442,7 +444,7 @@ def test_bit_mask(self) -> None: sdgs=[], physical_default_value_raw=None) outer_param._resolve_odxlinks(odxlinks) - outer_param._parameter_resolve_snrefs(cast(DiagLayer, None), param_list=[]) + outer_param._resolve_snrefs(snref_ctx) req = self._create_request([inner_param, outer_param]) From 72a3af15277c5e5c5f3adefbae8b4a84666ccf15 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Tue, 11 Jun 2024 16:09:41 +0200 Subject: [PATCH 2/2] do not keep commented out code in the repository the reason why this was commented out is that the object goes out of scope immediately afterward, so it is unnecessary to change it back to `None`. the reason why the line was kept in the first place is that it is conceptually what is supposed happen. Anyway, since this is in no way performance critical, let's just add the line back. thanks to [at]kayoub5 for the catch. Signed-off-by: Andreas Lauser Signed-off-by: Christian Hackenbeck --- odxtools/diaglayer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/odxtools/diaglayer.py b/odxtools/diaglayer.py index 21c44d16..0af64948 100644 --- a/odxtools/diaglayer.py +++ b/odxtools/diaglayer.py @@ -305,7 +305,7 @@ def _finalize_init(self, database: "Database", odxlinks: OdxLinkDatabase) -> Non context = SnRefContext(database=database) context.diag_layer = self self.diag_layer_raw._resolve_snrefs(context) - #context.diag_layer = None + context.diag_layer = None ##### #