odxtools 9.7.0__py3-none-any.whl → 10.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odxtools/additionalaudience.py +7 -7
- odxtools/admindata.py +14 -13
- odxtools/audience.py +17 -17
- odxtools/basecomparam.py +9 -8
- odxtools/basevariantpattern.py +9 -10
- odxtools/basicstructure.py +15 -15
- odxtools/cli/_print_utils.py +34 -22
- odxtools/cli/browse.py +8 -8
- odxtools/cli/compare.py +24 -24
- odxtools/cli/decode.py +3 -4
- odxtools/cli/find.py +4 -5
- odxtools/cli/list.py +6 -6
- odxtools/cli/main.py +2 -2
- odxtools/cli/snoop.py +3 -3
- odxtools/codec.py +3 -3
- odxtools/commrelation.py +18 -17
- odxtools/companydata.py +13 -13
- odxtools/companydocinfo.py +15 -17
- odxtools/companyrevisioninfo.py +9 -9
- odxtools/companyspecificinfo.py +11 -13
- odxtools/comparam.py +8 -7
- odxtools/comparaminstance.py +14 -14
- odxtools/comparamspec.py +10 -11
- odxtools/comparamsubset.py +17 -25
- odxtools/complexcomparam.py +14 -14
- odxtools/complexdop.py +1 -1
- odxtools/compositecodec.py +8 -8
- odxtools/compumethods/compucodecompumethod.py +7 -7
- odxtools/compumethods/compuconst.py +5 -6
- odxtools/compumethods/compudefaultvalue.py +2 -3
- odxtools/compumethods/compuinternaltophys.py +13 -12
- odxtools/compumethods/compumethod.py +10 -9
- odxtools/compumethods/compuphystointernal.py +13 -12
- odxtools/compumethods/compurationalcoeffs.py +7 -7
- odxtools/compumethods/compuscale.py +15 -16
- odxtools/compumethods/createanycompumethod.py +12 -13
- odxtools/compumethods/identicalcompumethod.py +4 -5
- odxtools/compumethods/limit.py +14 -14
- odxtools/compumethods/linearcompumethod.py +5 -5
- odxtools/compumethods/linearsegment.py +10 -11
- odxtools/compumethods/ratfunccompumethod.py +6 -6
- odxtools/compumethods/ratfuncsegment.py +7 -8
- odxtools/compumethods/scalelinearcompumethod.py +9 -9
- odxtools/compumethods/scaleratfunccompumethod.py +7 -7
- odxtools/compumethods/tabintpcompumethod.py +10 -13
- odxtools/compumethods/texttablecompumethod.py +6 -6
- odxtools/createanycomparam.py +5 -7
- odxtools/createanydiagcodedtype.py +7 -8
- odxtools/database.py +34 -31
- odxtools/dataobjectproperty.py +19 -20
- odxtools/decodestate.py +5 -5
- odxtools/description.py +9 -9
- odxtools/determinenumberofitems.py +8 -7
- odxtools/diagcodedtype.py +10 -10
- odxtools/diagcomm.py +29 -30
- odxtools/diagdatadictionaryspec.py +36 -36
- odxtools/diaglayercontainer.py +35 -34
- odxtools/diaglayers/basevariant.py +14 -12
- odxtools/diaglayers/basevariantraw.py +22 -23
- odxtools/diaglayers/diaglayer.py +24 -22
- odxtools/diaglayers/diaglayerraw.py +43 -52
- odxtools/diaglayers/diaglayertype.py +1 -2
- odxtools/diaglayers/ecushareddata.py +9 -9
- odxtools/diaglayers/ecushareddataraw.py +15 -16
- odxtools/diaglayers/ecuvariant.py +15 -13
- odxtools/diaglayers/ecuvariantraw.py +21 -22
- odxtools/diaglayers/functionalgroup.py +12 -11
- odxtools/diaglayers/functionalgroupraw.py +17 -18
- odxtools/diaglayers/hierarchyelement.py +48 -54
- odxtools/diaglayers/hierarchyelementraw.py +10 -11
- odxtools/diaglayers/protocol.py +7 -7
- odxtools/diaglayers/protocolraw.py +13 -14
- odxtools/diagnostictroublecode.py +15 -17
- odxtools/diagservice.py +28 -27
- odxtools/diagvariable.py +24 -25
- odxtools/docrevision.py +18 -17
- odxtools/dopbase.py +13 -14
- odxtools/dtcconnector.py +8 -7
- odxtools/dtcdop.py +24 -20
- odxtools/dynamicendmarkerfield.py +10 -9
- odxtools/dynamiclengthfield.py +10 -9
- odxtools/dyndefinedspec.py +10 -10
- odxtools/dynenddopref.py +9 -9
- odxtools/dyniddefmodeinfo.py +21 -21
- odxtools/ecuvariantpattern.py +8 -10
- odxtools/element.py +12 -13
- odxtools/encodestate.py +11 -11
- odxtools/encoding.py +2 -3
- odxtools/endofpdufield.py +9 -10
- odxtools/envdataconnector.py +8 -8
- odxtools/environmentdata.py +7 -9
- odxtools/environmentdatadescription.py +18 -17
- odxtools/exceptions.py +5 -5
- odxtools/externalaccessmethod.py +4 -6
- odxtools/externaldoc.py +6 -6
- odxtools/field.py +15 -15
- odxtools/functionalclass.py +9 -9
- odxtools/inputparam.py +11 -10
- odxtools/internalconstr.py +10 -11
- odxtools/isotp_state_machine.py +12 -11
- odxtools/leadinglengthinfotype.py +4 -6
- odxtools/library.py +9 -8
- odxtools/linkeddtcdop.py +9 -8
- odxtools/loadfile.py +5 -6
- odxtools/matchingbasevariantparameter.py +5 -6
- odxtools/matchingparameter.py +10 -10
- odxtools/message.py +1 -1
- odxtools/minmaxlengthtype.py +6 -7
- odxtools/modification.py +7 -6
- odxtools/multiplexer.py +54 -18
- odxtools/multiplexercase.py +13 -13
- odxtools/multiplexerdefaultcase.py +11 -10
- odxtools/multiplexerswitchkey.py +8 -8
- odxtools/nameditemlist.py +13 -13
- odxtools/negoutputparam.py +8 -8
- odxtools/obd.py +1 -2
- odxtools/odxcategory.py +14 -26
- odxtools/odxdoccontext.py +16 -0
- odxtools/odxlink.py +23 -25
- odxtools/odxtypes.py +18 -15
- odxtools/outputparam.py +9 -8
- odxtools/parameterinfo.py +1 -1
- odxtools/parameters/codedconstparameter.py +10 -10
- odxtools/parameters/createanyparameter.py +15 -16
- odxtools/parameters/dynamicparameter.py +5 -7
- odxtools/parameters/lengthkeyparameter.py +10 -10
- odxtools/parameters/matchingrequestparameter.py +6 -7
- odxtools/parameters/nrcconstparameter.py +13 -13
- odxtools/parameters/parameter.py +17 -18
- odxtools/parameters/parameterwithdop.py +13 -13
- odxtools/parameters/physicalconstantparameter.py +8 -7
- odxtools/parameters/reservedparameter.py +6 -8
- odxtools/parameters/systemparameter.py +5 -7
- odxtools/parameters/tableentryparameter.py +8 -8
- odxtools/parameters/tablekeyparameter.py +17 -17
- odxtools/parameters/tablestructparameter.py +11 -11
- odxtools/parameters/valueparameter.py +11 -11
- odxtools/paramlengthinfotype.py +10 -9
- odxtools/parentref.py +15 -13
- odxtools/physicaldimension.py +15 -15
- odxtools/physicaltype.py +5 -6
- odxtools/posresponsesuppressible.py +11 -12
- odxtools/preconditionstateref.py +11 -11
- odxtools/progcode.py +11 -10
- odxtools/protstack.py +10 -9
- odxtools/relateddiagcommref.py +5 -6
- odxtools/relateddoc.py +11 -10
- odxtools/request.py +18 -19
- odxtools/response.py +19 -20
- odxtools/scaleconstr.py +8 -9
- odxtools/servicebinner.py +5 -5
- odxtools/singleecujob.py +16 -15
- odxtools/snrefcontext.py +3 -3
- odxtools/specialdata.py +8 -7
- odxtools/specialdatagroup.py +17 -17
- odxtools/specialdatagroupcaption.py +7 -6
- odxtools/standardlengthtype.py +14 -22
- odxtools/state.py +7 -6
- odxtools/statechart.py +12 -11
- odxtools/statemachine.py +4 -3
- odxtools/statetransition.py +9 -9
- odxtools/statetransitionref.py +19 -19
- odxtools/staticfield.py +9 -7
- odxtools/structure.py +5 -6
- odxtools/subcomponent.py +20 -18
- odxtools/subcomponentparamconnector.py +10 -9
- odxtools/subcomponentpattern.py +9 -9
- odxtools/swvariable.py +6 -7
- odxtools/table.py +25 -26
- odxtools/tablediagcommconnector.py +9 -8
- odxtools/tablerow.py +64 -43
- odxtools/tablerowconnector.py +8 -8
- odxtools/teammember.py +16 -15
- odxtools/templates/macros/printParentRef.xml.jinja2 +3 -1
- odxtools/text.py +4 -5
- odxtools/uds.py +2 -3
- odxtools/unit.py +14 -13
- odxtools/unitgroup.py +11 -10
- odxtools/unitspec.py +18 -19
- odxtools/utils.py +3 -3
- odxtools/variablegroup.py +5 -6
- odxtools/variantmatcher.py +10 -10
- odxtools/variantpattern.py +5 -6
- odxtools/version.py +2 -2
- odxtools/writepdxfile.py +5 -24
- odxtools/xdoc.py +13 -12
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/METADATA +4 -5
- odxtools-10.1.0.dist-info/RECORD +265 -0
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/WHEEL +1 -1
- odxtools-9.7.0.dist-info/RECORD +0 -264
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/entry_points.txt +0 -0
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/licenses/LICENSE +0 -0
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/top_level.txt +0 -0
odxtools/database.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
+
from collections import OrderedDict
|
2
3
|
from itertools import chain
|
3
4
|
from os import PathLike
|
4
5
|
from pathlib import Path
|
5
|
-
from typing import IO, Any,
|
6
|
+
from typing import IO, Any, Union
|
6
7
|
from xml.etree import ElementTree
|
7
8
|
from zipfile import ZipFile
|
8
9
|
|
@@ -19,7 +20,8 @@ from .diaglayers.functionalgroup import FunctionalGroup
|
|
19
20
|
from .diaglayers.protocol import Protocol
|
20
21
|
from .exceptions import odxraise, odxrequire
|
21
22
|
from .nameditemlist import NamedItemList
|
22
|
-
from .
|
23
|
+
from .odxdoccontext import OdxDocContext
|
24
|
+
from .odxlink import DocType, OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
23
25
|
from .snrefcontext import SnRefContext
|
24
26
|
|
25
27
|
|
@@ -30,7 +32,7 @@ class Database:
|
|
30
32
|
"""
|
31
33
|
|
32
34
|
def __init__(self) -> None:
|
33
|
-
self.model_version:
|
35
|
+
self.model_version: Version | None = None
|
34
36
|
self.auxiliary_files: OrderedDict[str, IO[bytes]] = OrderedDict()
|
35
37
|
|
36
38
|
# create an empty database object
|
@@ -68,17 +70,13 @@ class Database:
|
|
68
70
|
|
69
71
|
def add_auxiliary_file(self,
|
70
72
|
aux_file_name: Union[str, "PathLike[Any]"],
|
71
|
-
aux_file_obj:
|
73
|
+
aux_file_obj: IO[bytes] | None = None) -> None:
|
72
74
|
if aux_file_obj is None:
|
73
75
|
aux_file_obj = open(aux_file_name, "rb")
|
74
76
|
|
75
77
|
self.auxiliary_files[str(aux_file_name)] = aux_file_obj
|
76
78
|
|
77
79
|
def _process_xml_tree(self, root: ElementTree.Element) -> None:
|
78
|
-
dlcs: List[DiagLayerContainer] = []
|
79
|
-
comparam_subsets: List[ComparamSubset] = []
|
80
|
-
comparam_specs: List[ComparamSpec] = []
|
81
|
-
|
82
80
|
# ODX spec version
|
83
81
|
model_version = Version(root.attrib.get("MODEL-VERSION", "2.0"))
|
84
82
|
if self.model_version is not None and self.model_version != model_version:
|
@@ -87,28 +85,33 @@ class Database:
|
|
87
85
|
|
88
86
|
self.model_version = model_version
|
89
87
|
|
90
|
-
|
91
|
-
if
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
88
|
+
child_elements = list(root)
|
89
|
+
if len(child_elements) != 1:
|
90
|
+
odxraise("Each ODX document must contain exactly one category.")
|
91
|
+
|
92
|
+
category_et = child_elements[0]
|
93
|
+
category_sn = odxrequire(category_et.findtext("SHORT-NAME"))
|
94
|
+
category_tag = category_et.tag
|
95
|
+
|
96
|
+
if category_tag == "DIAG-LAYER-CONTAINER":
|
97
|
+
context = OdxDocContext(model_version,
|
98
|
+
(OdxDocFragment(category_sn, DocType.CONTAINER),))
|
99
|
+
self._diag_layer_containers.append(DiagLayerContainer.from_et(category_et, context))
|
100
|
+
elif category_tag == "COMPARAM-SUBSET":
|
101
|
+
context = OdxDocContext(model_version,
|
102
|
+
(OdxDocFragment(category_sn, DocType.COMPARAM_SUBSET),))
|
103
|
+
self._comparam_subsets.append(ComparamSubset.from_et(category_et, context))
|
104
|
+
elif category_tag == "COMPARAM-SPEC":
|
105
|
+
# In ODX 2.0 there was only COMPARAM-SPEC. In ODX 2.2 the
|
106
|
+
# content of COMPARAM-SPEC was moved to COMPARAM-SUBSET
|
107
|
+
# and COMPARAM-SPEC became a container for PROT-STACKS and
|
108
|
+
# a PROT-STACK references a list of COMPARAM-SUBSET
|
109
|
+
context = OdxDocContext(model_version,
|
110
|
+
(OdxDocFragment(category_sn, DocType.COMPARAM_SPEC),))
|
104
111
|
if model_version < Version("2.2"):
|
105
|
-
|
106
|
-
else:
|
107
|
-
|
108
|
-
|
109
|
-
self._diag_layer_containers.extend(dlcs)
|
110
|
-
self._comparam_subsets.extend(comparam_subsets)
|
111
|
-
self._comparam_specs.extend(comparam_specs)
|
112
|
+
self._comparam_subsets.append(ComparamSubset.from_et(category_et, context))
|
113
|
+
else:
|
114
|
+
self._comparam_specs.append(ComparamSpec.from_et(category_et, context))
|
112
115
|
|
113
116
|
def refresh(self) -> None:
|
114
117
|
# Create wrapper objects
|
@@ -160,8 +163,8 @@ class Database:
|
|
160
163
|
for dlc in self.diag_layer_containers:
|
161
164
|
dlc._resolve_snrefs(context)
|
162
165
|
|
163
|
-
def _build_odxlinks(self) ->
|
164
|
-
result:
|
166
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
167
|
+
result: dict[OdxLinkId, Any] = {}
|
165
168
|
|
166
169
|
for subset in self.comparam_subsets:
|
167
170
|
result.update(subset._build_odxlinks())
|
odxtools/dataobjectproperty.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any,
|
3
|
+
from typing import Any, cast
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .compumethods.compumethod import CompuMethod
|
@@ -12,7 +12,8 @@ from .dopbase import DopBase
|
|
12
12
|
from .encodestate import EncodeState
|
13
13
|
from .exceptions import EncodeError, odxraise, odxrequire
|
14
14
|
from .internalconstr import InternalConstr
|
15
|
-
from .
|
15
|
+
from .odxdoccontext import OdxDocContext
|
16
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
16
17
|
from .odxtypes import AtomicOdxType, BytesTypes, ParameterValue
|
17
18
|
from .physicaltype import PhysicalType
|
18
19
|
from .snrefcontext import SnRefContext
|
@@ -20,7 +21,7 @@ from .unit import Unit
|
|
20
21
|
from .utils import dataclass_fields_asdict
|
21
22
|
|
22
23
|
|
23
|
-
@dataclass
|
24
|
+
@dataclass(kw_only=True)
|
24
25
|
class DataObjectProperty(DopBase):
|
25
26
|
"""This class represents a DATA-OBJECT-PROP.
|
26
27
|
|
@@ -37,42 +38,40 @@ class DataObjectProperty(DopBase):
|
|
37
38
|
#: The type of the value in the physical world
|
38
39
|
physical_type: PhysicalType
|
39
40
|
|
40
|
-
internal_constr:
|
41
|
+
internal_constr: InternalConstr | None = None
|
41
42
|
|
42
43
|
#: The unit associated with physical values (e.g. 'm/s^2')
|
43
|
-
unit_ref:
|
44
|
+
unit_ref: OdxLinkRef | None = None
|
44
45
|
|
45
|
-
physical_constr:
|
46
|
+
physical_constr: InternalConstr | None = None
|
46
47
|
|
47
48
|
@property
|
48
|
-
def unit(self) ->
|
49
|
+
def unit(self) -> Unit | None:
|
49
50
|
return self._unit
|
50
51
|
|
51
52
|
@staticmethod
|
52
|
-
def from_et(et_element: ElementTree.Element,
|
53
|
-
doc_frags: List[OdxDocFragment]) -> "DataObjectProperty":
|
53
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DataObjectProperty":
|
54
54
|
"""Reads a DATA-OBJECT-PROP."""
|
55
|
-
kwargs = dataclass_fields_asdict(DopBase.from_et(et_element,
|
55
|
+
kwargs = dataclass_fields_asdict(DopBase.from_et(et_element, context))
|
56
56
|
|
57
57
|
diag_coded_type = create_any_diag_coded_type_from_et(
|
58
|
-
odxrequire(et_element.find("DIAG-CODED-TYPE")),
|
59
|
-
physical_type = PhysicalType.from_et(
|
60
|
-
odxrequire(et_element.find("PHYSICAL-TYPE")), doc_frags)
|
58
|
+
odxrequire(et_element.find("DIAG-CODED-TYPE")), context)
|
59
|
+
physical_type = PhysicalType.from_et(odxrequire(et_element.find("PHYSICAL-TYPE")), context)
|
61
60
|
compu_method = create_any_compu_method_from_et(
|
62
61
|
odxrequire(et_element.find("COMPU-METHOD")),
|
63
|
-
|
62
|
+
context,
|
64
63
|
internal_type=diag_coded_type.base_data_type,
|
65
64
|
physical_type=physical_type.base_data_type,
|
66
65
|
)
|
67
66
|
internal_constr = None
|
68
67
|
if (internal_constr_elem := et_element.find("INTERNAL-CONSTR")) is not None:
|
69
68
|
internal_constr = InternalConstr.constr_from_et(
|
70
|
-
internal_constr_elem,
|
71
|
-
unit_ref = OdxLinkRef.from_et(et_element.find("UNIT-REF"),
|
69
|
+
internal_constr_elem, context, value_type=diag_coded_type.base_data_type)
|
70
|
+
unit_ref = OdxLinkRef.from_et(et_element.find("UNIT-REF"), context)
|
72
71
|
physical_constr = None
|
73
72
|
if (physical_constr_elem := et_element.find("PHYS-CONSTR")) is not None:
|
74
73
|
physical_constr = InternalConstr.constr_from_et(
|
75
|
-
physical_constr_elem,
|
74
|
+
physical_constr_elem, context, value_type=physical_type.base_data_type)
|
76
75
|
|
77
76
|
return DataObjectProperty(
|
78
77
|
compu_method=compu_method,
|
@@ -83,7 +82,7 @@ class DataObjectProperty(DopBase):
|
|
83
82
|
physical_constr=physical_constr,
|
84
83
|
**kwargs)
|
85
84
|
|
86
|
-
def _build_odxlinks(self) ->
|
85
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
87
86
|
result = super()._build_odxlinks()
|
88
87
|
result.update(self.compu_method._build_odxlinks())
|
89
88
|
result.update(self.diag_coded_type._build_odxlinks())
|
@@ -96,7 +95,7 @@ class DataObjectProperty(DopBase):
|
|
96
95
|
self.compu_method._resolve_odxlinks(odxlinks)
|
97
96
|
self.diag_coded_type._resolve_odxlinks(odxlinks)
|
98
97
|
|
99
|
-
self._unit:
|
98
|
+
self._unit: Unit | None = None
|
100
99
|
if self.unit_ref:
|
101
100
|
self._unit = odxlinks.resolve(self.unit_ref, Unit)
|
102
101
|
|
@@ -106,7 +105,7 @@ class DataObjectProperty(DopBase):
|
|
106
105
|
self.compu_method._resolve_snrefs(context)
|
107
106
|
self.diag_coded_type._resolve_snrefs(context)
|
108
107
|
|
109
|
-
def get_static_bit_length(self) ->
|
108
|
+
def get_static_bit_length(self) -> int | None:
|
110
109
|
return self.diag_coded_type.get_static_bit_length()
|
111
110
|
|
112
111
|
def encode_into_pdu(self, physical_value: ParameterValue, encode_state: EncodeState) -> None:
|
odxtools/decodestate.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass, field
|
3
|
-
from typing import TYPE_CHECKING
|
3
|
+
from typing import TYPE_CHECKING
|
4
4
|
|
5
5
|
from .encoding import Encoding, get_string_encoding
|
6
6
|
from .exceptions import DecodeError, odxassert, odxraise, strict_mode
|
@@ -41,22 +41,22 @@ class DecodeState:
|
|
41
41
|
cursor_bit_position: int = 0
|
42
42
|
|
43
43
|
#: values of the length key parameters decoded so far
|
44
|
-
length_keys:
|
44
|
+
length_keys: dict[str, int] = field(default_factory=dict)
|
45
45
|
|
46
46
|
#: values of the table key parameters decoded so far
|
47
|
-
table_keys:
|
47
|
+
table_keys: dict[str, "TableRow"] = field(default_factory=dict)
|
48
48
|
|
49
49
|
#: List of parameters that have been decoded so far. The journal
|
50
50
|
#: is used by some types of parameters which depend on the values of
|
51
51
|
#: other parameters; i.e., environment data description parameters
|
52
|
-
journal:
|
52
|
+
journal: list[tuple["Parameter", ParameterValue | None]] = field(default_factory=list)
|
53
53
|
|
54
54
|
def extract_atomic_value(
|
55
55
|
self,
|
56
56
|
*,
|
57
57
|
bit_length: int,
|
58
58
|
base_data_type: DataType,
|
59
|
-
base_type_encoding:
|
59
|
+
base_type_encoding: Encoding | None,
|
60
60
|
is_highlow_byte_order: bool,
|
61
61
|
) -> AtomicOdxType:
|
62
62
|
"""Extract an internal value from a blob of raw bytes.
|
odxtools/description.py
CHANGED
@@ -1,22 +1,22 @@
|
|
1
|
-
from dataclasses import dataclass
|
2
|
-
from typing import
|
1
|
+
from dataclasses import dataclass, field
|
2
|
+
from typing import Optional
|
3
3
|
from xml.etree import ElementTree
|
4
4
|
|
5
5
|
from .exceptions import odxrequire
|
6
6
|
from .externaldoc import ExternalDoc
|
7
|
-
from .
|
7
|
+
from .odxdoccontext import OdxDocContext
|
8
8
|
|
9
9
|
|
10
|
-
@dataclass
|
10
|
+
@dataclass(kw_only=True)
|
11
11
|
class Description:
|
12
12
|
text: str
|
13
|
-
external_docs:
|
13
|
+
external_docs: list[ExternalDoc] = field(default_factory=list)
|
14
14
|
|
15
|
-
text_identifier:
|
15
|
+
text_identifier: str | None = None
|
16
16
|
|
17
17
|
@staticmethod
|
18
|
-
def from_et(et_element:
|
19
|
-
|
18
|
+
def from_et(et_element: ElementTree.Element | None,
|
19
|
+
context: OdxDocContext) -> Optional["Description"]:
|
20
20
|
if et_element is None:
|
21
21
|
return None
|
22
22
|
|
@@ -35,7 +35,7 @@ class Description:
|
|
35
35
|
|
36
36
|
external_docs = \
|
37
37
|
[
|
38
|
-
odxrequire(ExternalDoc.from_et(ed,
|
38
|
+
odxrequire(ExternalDoc.from_et(ed, context)) for ed in et_element.iterfind("EXTERNAL-DOCS/EXTERNAL-DOC")
|
39
39
|
]
|
40
40
|
|
41
41
|
text_identifier = et_element.attrib.get("TI")
|
@@ -1,21 +1,22 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .dataobjectproperty import DataObjectProperty
|
7
7
|
from .exceptions import odxrequire
|
8
|
-
from .
|
8
|
+
from .odxdoccontext import OdxDocContext
|
9
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
9
10
|
from .snrefcontext import SnRefContext
|
10
11
|
|
11
12
|
|
12
|
-
@dataclass
|
13
|
+
@dataclass(kw_only=True)
|
13
14
|
class DetermineNumberOfItems:
|
14
15
|
"""
|
15
16
|
The object that determines the number of items of dynamic fields
|
16
17
|
"""
|
17
18
|
byte_position: int
|
18
|
-
bit_position:
|
19
|
+
bit_position: int | None = None
|
19
20
|
dop_ref: OdxLinkRef
|
20
21
|
|
21
22
|
@property
|
@@ -24,11 +25,11 @@ class DetermineNumberOfItems:
|
|
24
25
|
|
25
26
|
@staticmethod
|
26
27
|
def from_et(et_element: ElementTree.Element,
|
27
|
-
|
28
|
+
context: OdxDocContext) -> "DetermineNumberOfItems":
|
28
29
|
byte_position = int(odxrequire(et_element.findtext("BYTE-POSITION")))
|
29
30
|
bit_position_str = et_element.findtext("BIT-POSITION")
|
30
31
|
bit_position = int(bit_position_str) if bit_position_str is not None else None
|
31
|
-
dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DATA-OBJECT-PROP-REF"),
|
32
|
+
dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DATA-OBJECT-PROP-REF"), context))
|
32
33
|
|
33
34
|
return DetermineNumberOfItems(
|
34
35
|
byte_position=byte_position,
|
@@ -36,7 +37,7 @@ class DetermineNumberOfItems:
|
|
36
37
|
dop_ref=dop_ref,
|
37
38
|
)
|
38
39
|
|
39
|
-
def _build_odxlinks(self) ->
|
40
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
40
41
|
return {}
|
41
42
|
|
42
43
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/diagcodedtype.py
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any,
|
3
|
+
from typing import Any, Literal, cast
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .decodestate import DecodeState
|
7
7
|
from .encodestate import EncodeState
|
8
8
|
from .encoding import Encoding
|
9
9
|
from .exceptions import odxassert, odxraise, odxrequire
|
10
|
-
from .
|
10
|
+
from .odxdoccontext import OdxDocContext
|
11
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
11
12
|
from .odxtypes import AtomicOdxType, DataType, odxstr_to_bool
|
12
13
|
from .snrefcontext import SnRefContext
|
13
14
|
|
@@ -20,12 +21,12 @@ DctType = Literal[
|
|
20
21
|
]
|
21
22
|
|
22
23
|
|
23
|
-
@dataclass
|
24
|
+
@dataclass(kw_only=True)
|
24
25
|
class DiagCodedType:
|
25
|
-
base_type_encoding:
|
26
|
+
base_type_encoding: Encoding | None = None
|
26
27
|
base_data_type: DataType
|
27
28
|
|
28
|
-
is_highlow_byte_order_raw:
|
29
|
+
is_highlow_byte_order_raw: bool | None = None
|
29
30
|
|
30
31
|
@property
|
31
32
|
def dct_type(self) -> DctType:
|
@@ -38,8 +39,7 @@ class DiagCodedType:
|
|
38
39
|
return self.is_highlow_byte_order_raw in [None, True]
|
39
40
|
|
40
41
|
@staticmethod
|
41
|
-
def from_et(et_element: ElementTree.Element,
|
42
|
-
doc_frags: List[OdxDocFragment]) -> "DiagCodedType":
|
42
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DiagCodedType":
|
43
43
|
base_type_encoding = None
|
44
44
|
if (base_type_encoding_str := et_element.get("BASE-TYPE-ENCODING")) is not None:
|
45
45
|
try:
|
@@ -61,7 +61,7 @@ class DiagCodedType:
|
|
61
61
|
base_data_type=base_data_type,
|
62
62
|
is_highlow_byte_order_raw=is_highlow_byte_order_raw)
|
63
63
|
|
64
|
-
def _build_odxlinks(self) ->
|
64
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]: # noqa: B027
|
65
65
|
return {}
|
66
66
|
|
67
67
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: # noqa: B027
|
@@ -72,10 +72,10 @@ class DiagCodedType:
|
|
72
72
|
"""Recursively resolve any short-name references"""
|
73
73
|
pass
|
74
74
|
|
75
|
-
def get_static_bit_length(self) ->
|
75
|
+
def get_static_bit_length(self) -> int | None:
|
76
76
|
return None
|
77
77
|
|
78
|
-
def _minimal_byte_length_of(self, internal_value:
|
78
|
+
def _minimal_byte_length_of(self, internal_value: bytes | str) -> int:
|
79
79
|
"""Helper method to get the minimal byte length.
|
80
80
|
(needed for LeadingLength- and MinMaxLengthType)
|
81
81
|
"""
|
odxtools/diagcomm.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
3
|
-
from typing import TYPE_CHECKING, Any
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from typing import TYPE_CHECKING, Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .admindata import AdminData
|
@@ -10,7 +10,8 @@ from .element import IdentifiableElement
|
|
10
10
|
from .exceptions import odxraise, odxrequire
|
11
11
|
from .functionalclass import FunctionalClass
|
12
12
|
from .nameditemlist import NamedItemList
|
13
|
-
from .
|
13
|
+
from .odxdoccontext import OdxDocContext
|
14
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
|
14
15
|
from .odxtypes import odxstr_to_bool
|
15
16
|
from .preconditionstateref import PreConditionStateRef
|
16
17
|
from .relateddiagcommref import RelatedDiagCommRef
|
@@ -25,7 +26,7 @@ if TYPE_CHECKING:
|
|
25
26
|
from .diaglayers.protocol import Protocol
|
26
27
|
|
27
28
|
|
28
|
-
@dataclass
|
29
|
+
@dataclass(kw_only=True)
|
29
30
|
class DiagComm(IdentifiableElement):
|
30
31
|
"""Representation of a diagnostic communication object.
|
31
32
|
|
@@ -34,21 +35,21 @@ class DiagComm(IdentifiableElement):
|
|
34
35
|
|
35
36
|
"""
|
36
37
|
|
37
|
-
admin_data:
|
38
|
-
sdgs:
|
39
|
-
functional_class_refs:
|
40
|
-
audience:
|
41
|
-
protocol_snrefs:
|
42
|
-
related_diag_comm_refs:
|
43
|
-
pre_condition_state_refs:
|
44
|
-
state_transition_refs:
|
38
|
+
admin_data: AdminData | None = None
|
39
|
+
sdgs: list[SpecialDataGroup] = field(default_factory=list)
|
40
|
+
functional_class_refs: list[OdxLinkRef] = field(default_factory=list)
|
41
|
+
audience: Audience | None = None
|
42
|
+
protocol_snrefs: list[str] = field(default_factory=list)
|
43
|
+
related_diag_comm_refs: list[RelatedDiagCommRef] = field(default_factory=list)
|
44
|
+
pre_condition_state_refs: list[PreConditionStateRef] = field(default_factory=list)
|
45
|
+
state_transition_refs: list[StateTransitionRef] = field(default_factory=list)
|
45
46
|
|
46
47
|
# attributes
|
47
|
-
semantic:
|
48
|
-
diagnostic_class:
|
49
|
-
is_mandatory_raw:
|
50
|
-
is_executable_raw:
|
51
|
-
is_final_raw:
|
48
|
+
semantic: str | None = None
|
49
|
+
diagnostic_class: DiagClassType | None = None
|
50
|
+
is_mandatory_raw: bool | None = None
|
51
|
+
is_executable_raw: bool | None = None
|
52
|
+
is_final_raw: bool | None = None
|
52
53
|
|
53
54
|
@property
|
54
55
|
def functional_classes(self) -> NamedItemList[FunctionalClass]:
|
@@ -83,22 +84,20 @@ class DiagComm(IdentifiableElement):
|
|
83
84
|
return self.is_final_raw is True
|
84
85
|
|
85
86
|
@staticmethod
|
86
|
-
def from_et(et_element: ElementTree.Element,
|
87
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
87
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DiagComm":
|
88
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
88
89
|
|
89
|
-
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"),
|
90
|
-
sdgs = [
|
91
|
-
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
|
92
|
-
]
|
90
|
+
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), context)
|
91
|
+
sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
|
93
92
|
|
94
93
|
functional_class_refs = [
|
95
|
-
odxrequire(OdxLinkRef.from_et(el,
|
94
|
+
odxrequire(OdxLinkRef.from_et(el, context))
|
96
95
|
for el in et_element.iterfind("FUNCT-CLASS-REFS/FUNCT-CLASS-REF")
|
97
96
|
]
|
98
97
|
|
99
98
|
audience = None
|
100
99
|
if (audience_elem := et_element.find("AUDIENCE")) is not None:
|
101
|
-
audience = Audience.from_et(audience_elem,
|
100
|
+
audience = Audience.from_et(audience_elem, context)
|
102
101
|
|
103
102
|
protocol_snrefs = [
|
104
103
|
odxrequire(el.get("SHORT-NAME"))
|
@@ -106,23 +105,23 @@ class DiagComm(IdentifiableElement):
|
|
106
105
|
]
|
107
106
|
|
108
107
|
related_diag_comm_refs = [
|
109
|
-
RelatedDiagCommRef.from_et(el,
|
108
|
+
RelatedDiagCommRef.from_et(el, context)
|
110
109
|
for el in et_element.iterfind("RELATED-DIAG-COMM-REFS/RELATED-DIAG-COMM-REF")
|
111
110
|
]
|
112
111
|
|
113
112
|
pre_condition_state_refs = [
|
114
|
-
PreConditionStateRef.from_et(el,
|
113
|
+
PreConditionStateRef.from_et(el, context)
|
115
114
|
for el in et_element.iterfind("PRE-CONDITION-STATE-REFS/PRE-CONDITION-STATE-REF")
|
116
115
|
]
|
117
116
|
|
118
117
|
state_transition_refs = [
|
119
|
-
StateTransitionRef.from_et(el,
|
118
|
+
StateTransitionRef.from_et(el, context)
|
120
119
|
for el in et_element.iterfind("STATE-TRANSITION-REFS/STATE-TRANSITION-REF")
|
121
120
|
]
|
122
121
|
|
123
122
|
semantic = et_element.attrib.get("SEMANTIC")
|
124
123
|
|
125
|
-
diagnostic_class:
|
124
|
+
diagnostic_class: DiagClassType | None = None
|
126
125
|
if (diagnostic_class_str := et_element.attrib.get("DIAGNOSTIC-CLASS")) is not None:
|
127
126
|
try:
|
128
127
|
diagnostic_class = DiagClassType(diagnostic_class_str)
|
@@ -149,7 +148,7 @@ class DiagComm(IdentifiableElement):
|
|
149
148
|
is_final_raw=is_final_raw,
|
150
149
|
**kwargs)
|
151
150
|
|
152
|
-
def _build_odxlinks(self) ->
|
151
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
153
152
|
result = {self.odx_id: self}
|
154
153
|
|
155
154
|
if self.admin_data is not None:
|