odxtools 9.7.0__py3-none-any.whl → 10.0.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 +3 -3
- odxtools/admindata.py +8 -8
- odxtools/audience.py +10 -10
- odxtools/basecomparam.py +5 -5
- odxtools/basevariantpattern.py +4 -5
- odxtools/basicstructure.py +8 -8
- odxtools/cli/_print_utils.py +35 -23
- odxtools/cli/browse.py +9 -9
- odxtools/cli/compare.py +24 -24
- odxtools/cli/decode.py +3 -4
- odxtools/cli/find.py +4 -5
- odxtools/cli/list.py +7 -7
- odxtools/cli/main.py +2 -2
- odxtools/cli/snoop.py +3 -3
- odxtools/codec.py +3 -3
- odxtools/commrelation.py +11 -11
- odxtools/companydata.py +5 -5
- odxtools/companydocinfo.py +8 -8
- odxtools/companyrevisioninfo.py +5 -5
- odxtools/companyspecificinfo.py +5 -5
- odxtools/comparam.py +3 -3
- odxtools/comparaminstance.py +10 -10
- odxtools/comparamspec.py +3 -3
- odxtools/comparamsubset.py +5 -5
- odxtools/complexcomparam.py +7 -7
- odxtools/compositecodec.py +11 -11
- odxtools/compumethods/compucodecompumethod.py +4 -4
- odxtools/compumethods/compuconst.py +4 -5
- odxtools/compumethods/compudefaultvalue.py +1 -2
- odxtools/compumethods/compuinternaltophys.py +6 -6
- odxtools/compumethods/compumethod.py +5 -5
- odxtools/compumethods/compuphystointernal.py +6 -6
- odxtools/compumethods/compurationalcoeffs.py +4 -4
- odxtools/compumethods/compuscale.py +9 -10
- odxtools/compumethods/createanycompumethod.py +1 -2
- odxtools/compumethods/identicalcompumethod.py +1 -2
- odxtools/compumethods/limit.py +12 -12
- odxtools/compumethods/linearcompumethod.py +2 -2
- odxtools/compumethods/linearsegment.py +14 -15
- odxtools/compumethods/ratfunccompumethod.py +3 -3
- odxtools/compumethods/ratfuncsegment.py +7 -8
- odxtools/compumethods/scalelinearcompumethod.py +7 -7
- odxtools/compumethods/scaleratfunccompumethod.py +4 -4
- odxtools/compumethods/tabintpcompumethod.py +15 -18
- odxtools/compumethods/texttablecompumethod.py +3 -3
- odxtools/createanycomparam.py +2 -4
- odxtools/createanydiagcodedtype.py +1 -2
- odxtools/database.py +9 -8
- odxtools/dataobjectproperty.py +10 -10
- odxtools/decodestate.py +5 -5
- odxtools/description.py +5 -5
- odxtools/determinenumberofitems.py +4 -4
- odxtools/diagcodedtype.py +7 -7
- odxtools/diagcomm.py +17 -17
- odxtools/diagdatadictionaryspec.py +6 -6
- odxtools/diaglayercontainer.py +4 -4
- odxtools/diaglayers/basevariant.py +10 -9
- odxtools/diaglayers/basevariantraw.py +9 -9
- odxtools/diaglayers/diaglayer.py +20 -19
- odxtools/diaglayers/diaglayerraw.py +10 -10
- odxtools/diaglayers/diaglayertype.py +1 -2
- odxtools/diaglayers/ecushareddata.py +4 -4
- odxtools/diaglayers/ecushareddataraw.py +6 -6
- odxtools/diaglayers/ecuvariant.py +11 -10
- odxtools/diaglayers/ecuvariantraw.py +9 -9
- odxtools/diaglayers/functionalgroup.py +8 -7
- odxtools/diaglayers/functionalgroupraw.py +7 -7
- odxtools/diaglayers/hierarchyelement.py +43 -49
- odxtools/diaglayers/hierarchyelementraw.py +4 -4
- odxtools/diaglayers/protocol.py +4 -4
- odxtools/diaglayers/protocolraw.py +6 -6
- odxtools/diagnostictroublecode.py +8 -8
- odxtools/diagservice.py +18 -18
- odxtools/diagvariable.py +14 -14
- odxtools/docrevision.py +11 -11
- odxtools/dopbase.py +6 -6
- odxtools/dtcconnector.py +3 -3
- odxtools/dtcdop.py +13 -9
- odxtools/dynamicendmarkerfield.py +5 -4
- odxtools/dynamiclengthfield.py +5 -4
- odxtools/dyndefinedspec.py +5 -5
- odxtools/dynenddopref.py +5 -5
- odxtools/dyniddefmodeinfo.py +13 -13
- odxtools/ecuvariantpattern.py +4 -5
- odxtools/element.py +5 -6
- odxtools/encodestate.py +11 -11
- odxtools/encoding.py +2 -3
- odxtools/endofpdufield.py +6 -6
- odxtools/envdataconnector.py +3 -3
- odxtools/environmentdata.py +3 -4
- odxtools/environmentdatadescription.py +11 -11
- odxtools/exceptions.py +5 -5
- odxtools/externalaccessmethod.py +1 -2
- odxtools/externaldoc.py +4 -4
- odxtools/field.py +9 -10
- odxtools/functionalclass.py +4 -4
- odxtools/inputparam.py +6 -6
- odxtools/internalconstr.py +4 -5
- odxtools/isotp_state_machine.py +12 -11
- odxtools/leadinglengthinfotype.py +2 -3
- odxtools/library.py +5 -5
- odxtools/linkeddtcdop.py +4 -4
- odxtools/loadfile.py +5 -6
- odxtools/matchingbasevariantparameter.py +2 -3
- odxtools/matchingparameter.py +7 -7
- odxtools/minmaxlengthtype.py +4 -4
- odxtools/modification.py +4 -4
- odxtools/multiplexer.py +11 -11
- odxtools/multiplexercase.py +6 -6
- odxtools/multiplexerdefaultcase.py +6 -6
- odxtools/multiplexerswitchkey.py +4 -4
- odxtools/nameditemlist.py +14 -14
- odxtools/negoutputparam.py +3 -3
- odxtools/obd.py +1 -2
- odxtools/odxcategory.py +6 -6
- odxtools/odxlink.py +19 -20
- odxtools/odxtypes.py +21 -18
- odxtools/outputparam.py +4 -4
- odxtools/parameterinfo.py +1 -1
- odxtools/parameters/codedconstparameter.py +5 -5
- odxtools/parameters/createanyparameter.py +1 -2
- odxtools/parameters/dynamicparameter.py +2 -3
- odxtools/parameters/lengthkeyparameter.py +5 -5
- odxtools/parameters/matchingrequestparameter.py +3 -4
- odxtools/parameters/nrcconstparameter.py +7 -7
- odxtools/parameters/parameter.py +11 -11
- odxtools/parameters/parameterwithdop.py +9 -9
- odxtools/parameters/physicalconstantparameter.py +4 -4
- odxtools/parameters/reservedparameter.py +3 -4
- odxtools/parameters/systemparameter.py +2 -3
- odxtools/parameters/tableentryparameter.py +3 -3
- odxtools/parameters/tablekeyparameter.py +10 -10
- odxtools/parameters/tablestructparameter.py +7 -7
- odxtools/parameters/valueparameter.py +7 -7
- odxtools/paramlengthinfotype.py +5 -3
- odxtools/parentref.py +9 -9
- odxtools/physicaldimension.py +11 -11
- odxtools/physicaltype.py +3 -4
- odxtools/posresponsesuppressible.py +9 -10
- odxtools/preconditionstateref.py +7 -7
- odxtools/progcode.py +6 -6
- odxtools/protstack.py +4 -4
- odxtools/relateddiagcommref.py +1 -2
- odxtools/relateddoc.py +6 -6
- odxtools/request.py +9 -9
- odxtools/response.py +10 -10
- odxtools/scaleconstr.py +3 -4
- odxtools/servicebinner.py +5 -5
- odxtools/singleecujob.py +4 -4
- odxtools/snrefcontext.py +2 -2
- odxtools/specialdata.py +5 -5
- odxtools/specialdatagroup.py +9 -9
- odxtools/specialdatagroupcaption.py +3 -3
- odxtools/standardlengthtype.py +10 -10
- odxtools/state.py +3 -3
- odxtools/statechart.py +4 -4
- odxtools/statemachine.py +4 -3
- odxtools/statetransition.py +4 -4
- odxtools/statetransitionref.py +18 -18
- odxtools/staticfield.py +5 -4
- odxtools/structure.py +2 -3
- odxtools/subcomponent.py +5 -5
- odxtools/subcomponentparamconnector.py +5 -5
- odxtools/subcomponentpattern.py +4 -4
- odxtools/swvariable.py +3 -4
- odxtools/table.py +14 -14
- odxtools/tablediagcommconnector.py +5 -5
- odxtools/tablerow.py +30 -30
- odxtools/tablerowconnector.py +3 -3
- odxtools/teammember.py +11 -11
- odxtools/text.py +2 -3
- odxtools/uds.py +2 -3
- odxtools/unit.py +9 -9
- odxtools/unitgroup.py +5 -5
- odxtools/unitspec.py +6 -6
- odxtools/utils.py +3 -3
- odxtools/variablegroup.py +2 -2
- odxtools/variantmatcher.py +10 -10
- odxtools/variantpattern.py +3 -3
- odxtools/version.py +2 -2
- odxtools/writepdxfile.py +5 -5
- odxtools/xdoc.py +9 -9
- {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/METADATA +4 -5
- odxtools-10.0.0.dist-info/RECORD +264 -0
- odxtools-9.7.0.dist-info/RECORD +0 -264
- {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/WHEEL +0 -0
- {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/entry_points.txt +0 -0
- {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/licenses/LICENSE +0 -0
- {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/top_level.txt +0 -0
odxtools/tablerow.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass, fields
|
3
|
-
from typing import TYPE_CHECKING, Any
|
3
|
+
from typing import TYPE_CHECKING, Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .admindata import AdminData
|
@@ -33,22 +33,22 @@ class TableRow(IdentifiableElement):
|
|
33
33
|
# The spec mandates that either a structure or a non-complex DOP
|
34
34
|
# must be referenced here, i.e., exactly one of the four
|
35
35
|
# attributes below is not None
|
36
|
-
dop_ref:
|
37
|
-
dop_snref:
|
38
|
-
structure_ref:
|
39
|
-
structure_snref:
|
40
|
-
|
41
|
-
sdgs:
|
42
|
-
audience:
|
43
|
-
functional_class_refs:
|
44
|
-
state_transition_refs:
|
45
|
-
pre_condition_state_refs:
|
46
|
-
admin_data:
|
47
|
-
|
48
|
-
is_executable_raw:
|
49
|
-
semantic:
|
50
|
-
is_mandatory_raw:
|
51
|
-
is_final_raw:
|
36
|
+
dop_ref: OdxLinkRef | None
|
37
|
+
dop_snref: str | None
|
38
|
+
structure_ref: OdxLinkRef | None
|
39
|
+
structure_snref: str | None
|
40
|
+
|
41
|
+
sdgs: list[SpecialDataGroup]
|
42
|
+
audience: Audience | None
|
43
|
+
functional_class_refs: list[OdxLinkRef]
|
44
|
+
state_transition_refs: list[StateTransitionRef]
|
45
|
+
pre_condition_state_refs: list[PreConditionStateRef]
|
46
|
+
admin_data: AdminData | None
|
47
|
+
|
48
|
+
is_executable_raw: bool | None
|
49
|
+
semantic: str | None
|
50
|
+
is_mandatory_raw: bool | None
|
51
|
+
is_final_raw: bool | None
|
52
52
|
|
53
53
|
@property
|
54
54
|
def table(self) -> "Table":
|
@@ -57,16 +57,16 @@ class TableRow(IdentifiableElement):
|
|
57
57
|
# the value of the key expressed in the type represented by the
|
58
58
|
# referenced DOP
|
59
59
|
@property
|
60
|
-
def key(self) ->
|
60
|
+
def key(self) -> AtomicOdxType | None:
|
61
61
|
return self._key
|
62
62
|
|
63
63
|
@property
|
64
|
-
def dop(self) ->
|
64
|
+
def dop(self) -> DataObjectProperty | None:
|
65
65
|
"""The data object property object resolved by dop_ref."""
|
66
66
|
return self._dop
|
67
67
|
|
68
68
|
@property
|
69
|
-
def structure(self) ->
|
69
|
+
def structure(self) -> Structure | None:
|
70
70
|
"""The structure associated with this table row."""
|
71
71
|
return self._structure
|
72
72
|
|
@@ -87,12 +87,12 @@ class TableRow(IdentifiableElement):
|
|
87
87
|
return self.is_final_raw is True
|
88
88
|
|
89
89
|
@staticmethod
|
90
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
90
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> Any:
|
91
91
|
raise RuntimeError(
|
92
92
|
"Calling TableRow.from_et() is not allowed. Use TableRow.tablerow_from_et().")
|
93
93
|
|
94
94
|
@staticmethod
|
95
|
-
def tablerow_from_et(et_element: ElementTree.Element, doc_frags:
|
95
|
+
def tablerow_from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment], *,
|
96
96
|
table_ref: OdxLinkRef) -> "TableRow":
|
97
97
|
"""Reads a TABLE-ROW."""
|
98
98
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
@@ -100,12 +100,12 @@ class TableRow(IdentifiableElement):
|
|
100
100
|
key_raw = odxrequire(et_element.findtext("KEY"))
|
101
101
|
|
102
102
|
dop_ref = OdxLinkRef.from_et(et_element.find("DATA-OBJECT-PROP-REF"), doc_frags)
|
103
|
-
dop_snref:
|
103
|
+
dop_snref: str | None = None
|
104
104
|
if (dop_snref_elem := et_element.find("DATA-OBJECT-PROP-SNREF")) is not None:
|
105
105
|
dop_snref = dop_snref_elem.attrib["SHORT-NAME"]
|
106
106
|
|
107
107
|
structure_ref = OdxLinkRef.from_et(et_element.find("STRUCTURE-REF"), doc_frags)
|
108
|
-
structure_snref:
|
108
|
+
structure_snref: str | None = None
|
109
109
|
if (structure_snref_elem := et_element.find("STRUCTURE-SNREF")) is not None:
|
110
110
|
structure_snref = structure_snref_elem.attrib["SHORT-NAME"]
|
111
111
|
|
@@ -159,8 +159,8 @@ class TableRow(IdentifiableElement):
|
|
159
159
|
**kwargs)
|
160
160
|
|
161
161
|
def __post_init__(self) -> None:
|
162
|
-
self._dop:
|
163
|
-
self._structure:
|
162
|
+
self._dop: DataObjectProperty | None = None
|
163
|
+
self._structure: Structure | None = None
|
164
164
|
|
165
165
|
n = sum([0 if x is None else 1 for x in (self.dop_ref, self.dop_snref)])
|
166
166
|
odxassert(
|
@@ -174,7 +174,7 @@ class TableRow(IdentifiableElement):
|
|
174
174
|
f"Table row {self.short_name}: The structure can either be defined using ODXLINK or SNREF but not both."
|
175
175
|
)
|
176
176
|
|
177
|
-
def _build_odxlinks(self) ->
|
177
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
178
178
|
result = {self.odx_id: self}
|
179
179
|
|
180
180
|
for sdg in self.sdgs:
|
@@ -199,7 +199,7 @@ class TableRow(IdentifiableElement):
|
|
199
199
|
|
200
200
|
if self.dop_ref is not None:
|
201
201
|
self._dop = odxlinks.resolve(self.dop_ref)
|
202
|
-
if not isinstance(self._dop,
|
202
|
+
if not isinstance(self._dop, DataObjectProperty | DtcDop):
|
203
203
|
odxraise("The DOP-REF of TABLE-ROWs must reference a simple DOP!")
|
204
204
|
if self.structure_ref is not None:
|
205
205
|
self._structure = odxlinks.resolve(self.structure_ref, Structure)
|
@@ -243,7 +243,7 @@ class TableRow(IdentifiableElement):
|
|
243
243
|
self._structure = resolve_snref(self.structure_snref, ddd_spec.structures, Structure)
|
244
244
|
if self.dop_snref is not None:
|
245
245
|
self._dop = resolve_snref(self.dop_snref, ddd_spec.data_object_props)
|
246
|
-
if not isinstance(self._dop,
|
246
|
+
if not isinstance(self._dop, DataObjectProperty | DtcDop):
|
247
247
|
odxraise("The DOP-SNREF of TABLE-ROWs must reference a simple DOP!")
|
248
248
|
|
249
249
|
if self.audience is not None:
|
@@ -258,7 +258,7 @@ class TableRow(IdentifiableElement):
|
|
258
258
|
for pc_ref in self.pre_condition_state_refs:
|
259
259
|
pc_ref._resolve_snrefs(context)
|
260
260
|
|
261
|
-
def __reduce__(self) ->
|
261
|
+
def __reduce__(self) -> tuple[Any, ...]:
|
262
262
|
"""This ensures that the object can be correctly reconstructed during unpickling."""
|
263
263
|
state = self.__dict__.copy()
|
264
264
|
return self.__class__, tuple([getattr(self, x.name) for x in fields(self)]), state
|
odxtools/tablerowconnector.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
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import NamedElement
|
@@ -27,7 +27,7 @@ class TableRowConnector(NamedElement):
|
|
27
27
|
|
28
28
|
@staticmethod
|
29
29
|
def from_et(et_element: ElementTree.Element,
|
30
|
-
doc_frags:
|
30
|
+
doc_frags: list[OdxDocFragment]) -> "TableRowConnector":
|
31
31
|
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
|
32
32
|
|
33
33
|
table_ref = odxrequire(OdxLinkRef.from_et(et_element.find("TABLE-REF"), doc_frags))
|
@@ -36,7 +36,7 @@ class TableRowConnector(NamedElement):
|
|
36
36
|
|
37
37
|
return TableRowConnector(table_ref=table_ref, table_row_snref=table_row_snref, **kwargs)
|
38
38
|
|
39
|
-
def _build_odxlinks(self) ->
|
39
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
40
40
|
return {}
|
41
41
|
|
42
42
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/teammember.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
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import IdentifiableElement
|
@@ -12,17 +12,17 @@ from .utils import dataclass_fields_asdict
|
|
12
12
|
|
13
13
|
@dataclass
|
14
14
|
class TeamMember(IdentifiableElement):
|
15
|
-
roles:
|
16
|
-
department:
|
17
|
-
address:
|
18
|
-
zipcode:
|
19
|
-
city:
|
20
|
-
phone:
|
21
|
-
fax:
|
22
|
-
email:
|
15
|
+
roles: list[str]
|
16
|
+
department: str | None
|
17
|
+
address: str | None
|
18
|
+
zipcode: str | None # the tag for this is "ZIP", but `zip` is a keyword in python
|
19
|
+
city: str | None
|
20
|
+
phone: str | None
|
21
|
+
fax: str | None
|
22
|
+
email: str | None
|
23
23
|
|
24
24
|
@staticmethod
|
25
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
25
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "TeamMember":
|
26
26
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
27
27
|
|
28
28
|
roles = [odxrequire(role_elem.text) for role_elem in et_element.iterfind("ROLES/ROLE")]
|
@@ -45,7 +45,7 @@ class TeamMember(IdentifiableElement):
|
|
45
45
|
email=email,
|
46
46
|
**kwargs)
|
47
47
|
|
48
|
-
def _build_odxlinks(self) ->
|
48
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
49
49
|
result = {self.odx_id: self}
|
50
50
|
|
51
51
|
return result
|
odxtools/text.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
|
-
from typing import List, Optional
|
3
2
|
from xml.etree import ElementTree
|
4
3
|
|
5
4
|
from .odxlink import OdxDocFragment
|
@@ -8,10 +7,10 @@ from .odxlink import OdxDocFragment
|
|
8
7
|
@dataclass
|
9
8
|
class Text:
|
10
9
|
text: str
|
11
|
-
text_identifier:
|
10
|
+
text_identifier: str | None
|
12
11
|
|
13
12
|
@staticmethod
|
14
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
13
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Text":
|
15
14
|
# Extract the contents of the tag as a string.
|
16
15
|
raw_string = et_element.text or ""
|
17
16
|
for e in et_element:
|
odxtools/uds.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from enum import IntEnum
|
3
3
|
from itertools import chain
|
4
|
-
from typing import Optional
|
5
4
|
|
6
5
|
import odxtools.obd as obd
|
7
6
|
|
@@ -82,7 +81,7 @@ _sid_to_name = {
|
|
82
81
|
SID = IntEnum("UdsSID", ((i.name, i.value) for i in chain(obd.SID, UDSSID))) # type: ignore[misc]
|
83
82
|
|
84
83
|
|
85
|
-
def sid_to_name(sid: int) ->
|
84
|
+
def sid_to_name(sid: int) -> str | None:
|
86
85
|
if sid in _sid_to_name:
|
87
86
|
return _sid_to_name[sid]
|
88
87
|
elif 0x81 <= sid and sid <= 0x82:
|
@@ -142,7 +141,7 @@ def negative_response_id(service_id: int) -> int:
|
|
142
141
|
return NegativeResponseId
|
143
142
|
|
144
143
|
|
145
|
-
def is_response_pending(telegram_payload: bytes, request_sid:
|
144
|
+
def is_response_pending(telegram_payload: bytes, request_sid: int | None = None) -> bool:
|
146
145
|
# "response pending" responses exhibit at least three bytes
|
147
146
|
if len(telegram_payload) < 3:
|
148
147
|
return False
|
odxtools/unit.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
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import IdentifiableElement
|
@@ -53,21 +53,21 @@ class Unit(IdentifiableElement):
|
|
53
53
|
```
|
54
54
|
"""
|
55
55
|
display_name: str
|
56
|
-
factor_si_to_unit:
|
57
|
-
offset_si_to_unit:
|
58
|
-
physical_dimension_ref:
|
56
|
+
factor_si_to_unit: float | None
|
57
|
+
offset_si_to_unit: float | None
|
58
|
+
physical_dimension_ref: OdxLinkRef | None
|
59
59
|
|
60
60
|
@property
|
61
|
-
def physical_dimension(self) ->
|
61
|
+
def physical_dimension(self) -> PhysicalDimension | None:
|
62
62
|
return self._physical_dimension
|
63
63
|
|
64
64
|
@staticmethod
|
65
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
65
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Unit":
|
66
66
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
67
67
|
|
68
68
|
display_name = odxrequire(et_element.findtext("DISPLAY-NAME"))
|
69
69
|
|
70
|
-
def read_optional_float(element: ElementTree.Element, name: str) ->
|
70
|
+
def read_optional_float(element: ElementTree.Element, name: str) -> float | None:
|
71
71
|
if (elem_str := element.findtext(name)) is not None:
|
72
72
|
return float(elem_str)
|
73
73
|
else:
|
@@ -85,11 +85,11 @@ class Unit(IdentifiableElement):
|
|
85
85
|
physical_dimension_ref=physical_dimension_ref,
|
86
86
|
**kwargs)
|
87
87
|
|
88
|
-
def _build_odxlinks(self) ->
|
88
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
89
89
|
return {self.odx_id: self}
|
90
90
|
|
91
91
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
92
|
-
self._physical_dimension:
|
92
|
+
self._physical_dimension: PhysicalDimension | None = None
|
93
93
|
if self.physical_dimension_ref:
|
94
94
|
self._physical_dimension = odxlinks.resolve(self.physical_dimension_ref,
|
95
95
|
PhysicalDimension)
|
odxtools/unitgroup.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 .element import NamedElement
|
@@ -20,15 +20,15 @@ class UnitGroup(NamedElement):
|
|
20
20
|
There are two categories of groups: COUNTRY and EQUIV-UNITS.
|
21
21
|
"""
|
22
22
|
category: UnitGroupCategory
|
23
|
-
unit_refs:
|
24
|
-
oid:
|
23
|
+
unit_refs: list[OdxLinkRef]
|
24
|
+
oid: str | None
|
25
25
|
|
26
26
|
@property
|
27
27
|
def units(self) -> NamedItemList[Unit]:
|
28
28
|
return self._units
|
29
29
|
|
30
30
|
@staticmethod
|
31
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
31
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "UnitGroup":
|
32
32
|
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
|
33
33
|
|
34
34
|
category_str = odxrequire(et_element.findtext("CATEGORY"))
|
@@ -46,7 +46,7 @@ class UnitGroup(NamedElement):
|
|
46
46
|
|
47
47
|
return UnitGroup(category=category, unit_refs=unit_refs, oid=oid, **kwargs)
|
48
48
|
|
49
|
-
def _build_odxlinks(self) ->
|
49
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
50
50
|
return {}
|
51
51
|
|
52
52
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/unitspec.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
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .admindata import AdminData
|
@@ -25,11 +25,11 @@ class UnitSpec:
|
|
25
25
|
The following odx elements are not internalized: ADMIN-DATA, SDGS
|
26
26
|
"""
|
27
27
|
|
28
|
-
admin_data:
|
28
|
+
admin_data: AdminData | None
|
29
29
|
unit_groups: NamedItemList[UnitGroup]
|
30
30
|
units: NamedItemList[Unit]
|
31
31
|
physical_dimensions: NamedItemList[PhysicalDimension]
|
32
|
-
sdgs:
|
32
|
+
sdgs: list[SpecialDataGroup]
|
33
33
|
|
34
34
|
def __post_init__(self) -> None:
|
35
35
|
self.unit_groups = NamedItemList(self.unit_groups)
|
@@ -37,7 +37,7 @@ class UnitSpec:
|
|
37
37
|
self.physical_dimensions = NamedItemList(self.physical_dimensions)
|
38
38
|
|
39
39
|
@staticmethod
|
40
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
40
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "UnitSpec":
|
41
41
|
|
42
42
|
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
|
43
43
|
unit_groups = NamedItemList([
|
@@ -60,8 +60,8 @@ class UnitSpec:
|
|
60
60
|
physical_dimensions=physical_dimensions,
|
61
61
|
sdgs=sdgs)
|
62
62
|
|
63
|
-
def _build_odxlinks(self) ->
|
64
|
-
odxlinks:
|
63
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
64
|
+
odxlinks: dict[OdxLinkId, Any] = {}
|
65
65
|
for unit in self.units:
|
66
66
|
odxlinks.update(unit._build_odxlinks())
|
67
67
|
for dim in self.physical_dimensions:
|
odxtools/utils.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import dataclasses
|
3
3
|
import re
|
4
|
-
from typing import TYPE_CHECKING, Any,
|
4
|
+
from typing import TYPE_CHECKING, Any, Optional
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
7
|
from .exceptions import odxraise
|
@@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
|
12
12
|
from .snrefcontext import SnRefContext
|
13
13
|
|
14
14
|
|
15
|
-
def read_hex_binary(et_element:
|
15
|
+
def read_hex_binary(et_element: ElementTree.Element | None) -> int | None:
|
16
16
|
"""Convert the contents of an xsd:hexBinary to an integer
|
17
17
|
"""
|
18
18
|
if et_element is None:
|
@@ -76,7 +76,7 @@ def retarget_snrefs(database: "Database",
|
|
76
76
|
retarget_snrefs(database, pr.layer, context)
|
77
77
|
|
78
78
|
|
79
|
-
def dataclass_fields_asdict(obj: Any) ->
|
79
|
+
def dataclass_fields_asdict(obj: Any) -> dict[str, Any]:
|
80
80
|
"""Extract all attributes from a dataclass object that are fields.
|
81
81
|
|
82
82
|
This is a non-recursive version of `dataclasses.asdict()`. Its
|
odxtools/variablegroup.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import typing
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import TYPE_CHECKING,
|
4
|
+
from typing import TYPE_CHECKING, runtime_checkable
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
7
|
from .element import IdentifiableElement, NamedElement
|
@@ -26,7 +26,7 @@ class VariableGroup(IdentifiableElement):
|
|
26
26
|
|
27
27
|
@staticmethod
|
28
28
|
def from_et(et_element: ElementTree.Element,
|
29
|
-
doc_frags:
|
29
|
+
doc_frags: list[OdxDocFragment]) -> "VariableGroup":
|
30
30
|
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
|
31
31
|
|
32
32
|
return VariableGroup(**kwargs)
|
odxtools/variantmatcher.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
+
from collections.abc import Generator
|
2
3
|
from copy import copy
|
3
4
|
from enum import Enum
|
4
|
-
from typing import Dict, Generator, List, Optional, Tuple, Union
|
5
5
|
|
6
6
|
from .diaglayers.basevariant import BaseVariant
|
7
7
|
from .diaglayers.ecuvariant import EcuVariant
|
@@ -56,18 +56,18 @@ class VariantMatcher:
|
|
56
56
|
MATCH = 2
|
57
57
|
|
58
58
|
def __init__(self,
|
59
|
-
variant_candidates:
|
59
|
+
variant_candidates: list[EcuVariant] | list[BaseVariant],
|
60
60
|
use_cache: bool = True):
|
61
61
|
|
62
62
|
self.variant_candidates = variant_candidates
|
63
63
|
self.use_cache = use_cache
|
64
|
-
self.req_resp_cache:
|
65
|
-
self._recent_ident_response:
|
64
|
+
self.req_resp_cache: dict[bytes, bytes] = {}
|
65
|
+
self._recent_ident_response: bytes | None = None
|
66
66
|
|
67
67
|
self._state = VariantMatcher.State.PENDING
|
68
|
-
self._matching_variant:
|
68
|
+
self._matching_variant: EcuVariant | BaseVariant | None = None
|
69
69
|
|
70
|
-
def request_loop(self) -> Generator[
|
70
|
+
def request_loop(self) -> Generator[tuple[bool, bytes], None, None]:
|
71
71
|
"""The request loop yielding tuples of byte sequences of
|
72
72
|
requests and the whether physical addressing ought to be used
|
73
73
|
to send them
|
@@ -86,7 +86,7 @@ class VariantMatcher:
|
|
86
86
|
|
87
87
|
self._matching_variant = None
|
88
88
|
for variant in self.variant_candidates:
|
89
|
-
variant_patterns:
|
89
|
+
variant_patterns: list[EcuVariantPattern] | list[BaseVariantPattern]
|
90
90
|
if isinstance(variant, EcuVariant):
|
91
91
|
variant_patterns = variant.ecu_variant_patterns
|
92
92
|
elif isinstance(variant, BaseVariant):
|
@@ -158,13 +158,13 @@ class VariantMatcher:
|
|
158
158
|
return self._state == VariantMatcher.State.MATCH
|
159
159
|
|
160
160
|
@property
|
161
|
-
def matching_variant(self) ->
|
161
|
+
def matching_variant(self) -> EcuVariant | BaseVariant | None:
|
162
162
|
"""Returns the matched, i.e., active ecu variant if such a variant has been found."""
|
163
163
|
return self._matching_variant
|
164
164
|
|
165
165
|
def _ident_response_matches(
|
166
166
|
self,
|
167
|
-
variant:
|
167
|
+
variant: EcuVariant | BaseVariant,
|
168
168
|
matching_param: MatchingParameter,
|
169
169
|
response_bytes: bytes,
|
170
170
|
) -> bool:
|
@@ -175,7 +175,7 @@ class VariantMatcher:
|
|
175
175
|
|
176
176
|
# ISO 22901 requires that snref or snpathref is resolvable in
|
177
177
|
# at least one POS-RESPONSE or NEG-RESPONSE
|
178
|
-
all_responses:
|
178
|
+
all_responses: list[Response] = []
|
179
179
|
all_responses.extend(service.positive_responses)
|
180
180
|
all_responses.extend(service.negative_responses)
|
181
181
|
all_responses.extend(variant.global_negative_responses)
|
odxtools/variantpattern.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import TYPE_CHECKING
|
3
|
+
from typing import TYPE_CHECKING
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .exceptions import odxraise
|
@@ -26,7 +26,7 @@ class VariantPattern:
|
|
26
26
|
"""
|
27
27
|
|
28
28
|
def get_matching_parameters(
|
29
|
-
self) ->
|
29
|
+
self) -> list["MatchingParameter"] | list["MatchingBaseVariantParameter"]:
|
30
30
|
odxraise(
|
31
31
|
f"VariantPattern subclass `{type(self).__name__}` does not "
|
32
32
|
f"implement `.get_match_parameters()`", RuntimeError)
|
@@ -34,5 +34,5 @@ class VariantPattern:
|
|
34
34
|
|
35
35
|
@staticmethod
|
36
36
|
def from_et(et_element: ElementTree.Element,
|
37
|
-
doc_frags:
|
37
|
+
doc_frags: list[OdxDocFragment]) -> "VariantPattern":
|
38
38
|
return VariantPattern()
|
odxtools/version.py
CHANGED
odxtools/writepdxfile.py
CHANGED
@@ -5,7 +5,7 @@ import mimetypes
|
|
5
5
|
import os
|
6
6
|
import time
|
7
7
|
import zipfile
|
8
|
-
from typing import Any
|
8
|
+
from typing import Any
|
9
9
|
|
10
10
|
import jinja2
|
11
11
|
|
@@ -14,7 +14,7 @@ import odxtools
|
|
14
14
|
from .database import Database
|
15
15
|
from .odxtypes import bool_to_odxstr
|
16
16
|
|
17
|
-
odxdatabase:
|
17
|
+
odxdatabase: Database | None = None
|
18
18
|
|
19
19
|
|
20
20
|
def jinja2_odxraise_helper(msg: str) -> None:
|
@@ -39,14 +39,14 @@ def get_parent_container_name(dl_short_name: str) -> str:
|
|
39
39
|
f"container for diagnostic layer '{dl_short_name}'.")
|
40
40
|
|
41
41
|
|
42
|
-
def make_xml_attrib(attrib_name: str, attrib_val:
|
42
|
+
def make_xml_attrib(attrib_name: str, attrib_val: Any | None) -> str:
|
43
43
|
if attrib_val is None:
|
44
44
|
return ""
|
45
45
|
|
46
46
|
return f' {attrib_name}="{attrib_val}"'
|
47
47
|
|
48
48
|
|
49
|
-
def make_bool_xml_attrib(attrib_name: str, attrib_val:
|
49
|
+
def make_bool_xml_attrib(attrib_name: str, attrib_val: bool | None) -> str:
|
50
50
|
if attrib_val is None:
|
51
51
|
return ""
|
52
52
|
|
@@ -147,7 +147,7 @@ def write_pdx_file(
|
|
147
147
|
jinja_env.globals["make_bool_xml_attrib"] = make_bool_xml_attrib
|
148
148
|
jinja_env.globals["get_parent_container_name"] = get_parent_container_name
|
149
149
|
|
150
|
-
vars:
|
150
|
+
vars: dict[str, Any] = {}
|
151
151
|
vars["odxtools_version"] = odxtools.__version__
|
152
152
|
vars["database"] = database
|
153
153
|
|
odxtools/xdoc.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
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import NamedElement
|
@@ -11,15 +11,15 @@ from .utils import dataclass_fields_asdict
|
|
11
11
|
|
12
12
|
@dataclass
|
13
13
|
class XDoc(NamedElement):
|
14
|
-
number:
|
15
|
-
state:
|
16
|
-
date:
|
17
|
-
publisher:
|
18
|
-
url:
|
19
|
-
position:
|
14
|
+
number: str | None
|
15
|
+
state: str | None
|
16
|
+
date: str | None
|
17
|
+
publisher: str | None
|
18
|
+
url: str | None
|
19
|
+
position: str | None
|
20
20
|
|
21
21
|
@staticmethod
|
22
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
22
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "XDoc":
|
23
23
|
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
|
24
24
|
number = et_element.findtext("NUMBER")
|
25
25
|
state = et_element.findtext("STATE")
|
@@ -37,7 +37,7 @@ class XDoc(NamedElement):
|
|
37
37
|
position=position,
|
38
38
|
**kwargs)
|
39
39
|
|
40
|
-
def _build_odxlinks(self) ->
|
40
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
41
41
|
return {}
|
42
42
|
|
43
43
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: odxtools
|
3
|
-
Version:
|
3
|
+
Version: 10.0.0
|
4
4
|
Summary: Utilities to work with the ODX standard for automotive diagnostics
|
5
5
|
Author-email: Katrin Bauer <katrin.bauer@mbition.io>, Andreas Lauser <andreas.lauser@mbition.io>, Ayoub Kaanich <kayoub5@live.com>
|
6
6
|
Maintainer-email: Andreas Lauser <andreas.lauser@mbition.io>, Ayoub Kaanich <kayoub5@live.com>
|
@@ -10,16 +10,16 @@ Project-URL: Bug Tracker, https://github.com/mercedes-benz/odxtools/issues
|
|
10
10
|
Project-URL: Repository, https://github.com/mercedes-benz/odxtools
|
11
11
|
Keywords: can,can bus,DoIP,odx,pdx,obd,uds,automotive,diagnostics
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
13
|
-
Classifier: Programming Language :: Python :: 3.8
|
14
|
-
Classifier: Programming Language :: Python :: 3.9
|
15
13
|
Classifier: Programming Language :: Python :: 3.10
|
16
14
|
Classifier: Programming Language :: Python :: 3.11
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
17
17
|
Classifier: Development Status :: 5 - Production/Stable
|
18
18
|
Classifier: Environment :: Console
|
19
19
|
Classifier: Intended Audience :: Developers
|
20
20
|
Classifier: License :: OSI Approved :: MIT License
|
21
21
|
Classifier: Operating System :: OS Independent
|
22
|
-
Requires-Python: >=3.
|
22
|
+
Requires-Python: >=3.10
|
23
23
|
Description-Content-Type: text/markdown
|
24
24
|
License-File: LICENSE
|
25
25
|
Requires-Dist: bitstruct>=8.17
|
@@ -35,7 +35,6 @@ Provides-Extra: browse-tool
|
|
35
35
|
Requires-Dist: InquirerPy>=0.3.4; extra == "browse-tool"
|
36
36
|
Provides-Extra: test
|
37
37
|
Requires-Dist: mypy>=1.5; extra == "test"
|
38
|
-
Requires-Dist: types-tabulate>=0.9.0.3; extra == "test"
|
39
38
|
Requires-Dist: ruff>=0.0.290; extra == "test"
|
40
39
|
Requires-Dist: pytest>=7.4; extra == "test"
|
41
40
|
Requires-Dist: coverage>=7.3; extra == "test"
|