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
@@ -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 typing_extensions import override
|
@@ -35,18 +35,18 @@ class EnvironmentDataDescription(ComplexDop):
|
|
35
35
|
|
36
36
|
"""
|
37
37
|
|
38
|
-
param_snref:
|
39
|
-
param_snpathref:
|
38
|
+
param_snref: str | None
|
39
|
+
param_snpathref: str | None
|
40
40
|
|
41
41
|
# in ODX 2.0.0, ENV-DATAS seems to be a mandatory
|
42
42
|
# sub-element of ENV-DATA-DESC, in ODX 2.2 it is not
|
43
43
|
# present
|
44
44
|
env_datas: NamedItemList[EnvironmentData]
|
45
|
-
env_data_refs:
|
45
|
+
env_data_refs: list[OdxLinkRef]
|
46
46
|
|
47
47
|
@staticmethod
|
48
48
|
def from_et(et_element: ElementTree.Element,
|
49
|
-
doc_frags:
|
49
|
+
doc_frags: list[OdxDocFragment]) -> "EnvironmentDataDescription":
|
50
50
|
"""Reads Environment Data Description from Diag Layer."""
|
51
51
|
kwargs = dataclass_fields_asdict(ComplexDop.from_et(et_element, doc_frags))
|
52
52
|
|
@@ -78,7 +78,7 @@ class EnvironmentDataDescription(ComplexDop):
|
|
78
78
|
env_data_refs=env_data_refs,
|
79
79
|
**kwargs)
|
80
80
|
|
81
|
-
def _build_odxlinks(self) ->
|
81
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
82
82
|
odxlinks = {self.odx_id: self}
|
83
83
|
|
84
84
|
if not self.env_data_refs:
|
@@ -105,7 +105,7 @@ class EnvironmentDataDescription(ComplexDop):
|
|
105
105
|
ed._resolve_snrefs(context)
|
106
106
|
|
107
107
|
@override
|
108
|
-
def encode_into_pdu(self, physical_value:
|
108
|
+
def encode_into_pdu(self, physical_value: ParameterValue | None,
|
109
109
|
encode_state: EncodeState) -> None:
|
110
110
|
"""Convert a physical value into bytes and emplace them into a PDU.
|
111
111
|
"""
|
@@ -118,7 +118,7 @@ class EnvironmentDataDescription(ComplexDop):
|
|
118
118
|
"descriptions via SNPATHREF is not supported yet")
|
119
119
|
return None
|
120
120
|
|
121
|
-
numerical_dtc_value:
|
121
|
+
numerical_dtc_value: ParameterValue | None = None
|
122
122
|
for prev_param, prev_param_value in reversed(encode_state.journal):
|
123
123
|
if prev_param.short_name == self.param_snref:
|
124
124
|
numerical_dtc_value = self._get_numerical_dtc_from_parameter(
|
@@ -165,7 +165,7 @@ class EnvironmentDataDescription(ComplexDop):
|
|
165
165
|
"descriptions via SNPATHREF is not supported yet")
|
166
166
|
return None
|
167
167
|
|
168
|
-
numerical_dtc_value:
|
168
|
+
numerical_dtc_value: ParameterValue | None = None
|
169
169
|
for prev_param, prev_param_value in reversed(decode_state.journal):
|
170
170
|
if prev_param.short_name == self.param_snref:
|
171
171
|
numerical_dtc_value = self._get_numerical_dtc_from_parameter(
|
@@ -204,10 +204,10 @@ class EnvironmentDataDescription(ComplexDop):
|
|
204
204
|
return result
|
205
205
|
|
206
206
|
def _get_numerical_dtc_from_parameter(self, param: Parameter,
|
207
|
-
param_value:
|
207
|
+
param_value: ParameterValue | None) -> int:
|
208
208
|
if isinstance(param, ParameterWithDOP):
|
209
209
|
dop = param.dop
|
210
|
-
if not isinstance(dop,
|
210
|
+
if not isinstance(dop, DataObjectProperty | DtcDop):
|
211
211
|
odxraise(f"The DOP of the parameter referenced by environment data descriptions "
|
212
212
|
f"must use either be DataObjectProperty or a DtcDop (encountered "
|
213
213
|
f"{type(param).__name__} for parameter '{param.short_name}' "
|
odxtools/exceptions.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from typing import TYPE_CHECKING, NoReturn,
|
2
|
+
from typing import TYPE_CHECKING, NoReturn, TypeVar
|
3
3
|
|
4
4
|
from .globals import logger
|
5
5
|
|
@@ -37,7 +37,7 @@ class OdxWarning(Warning):
|
|
37
37
|
strict_mode = True
|
38
38
|
|
39
39
|
|
40
|
-
def odxraise(message:
|
40
|
+
def odxraise(message: str | None = None, error_type: type[Exception] = OdxError) -> NoReturn:
|
41
41
|
"""
|
42
42
|
Raise an exception but only if in strict mode.
|
43
43
|
|
@@ -53,8 +53,8 @@ def odxraise(message: Optional[str] = None, error_type: Type[Exception] = OdxErr
|
|
53
53
|
|
54
54
|
|
55
55
|
def odxassert(condition: bool,
|
56
|
-
message:
|
57
|
-
error_type:
|
56
|
+
message: str | None = None,
|
57
|
+
error_type: type[Exception] = OdxError) -> None:
|
58
58
|
"""
|
59
59
|
This method works similar as the build-in `assert` statement
|
60
60
|
|
@@ -72,7 +72,7 @@ def odxassert(condition: bool,
|
|
72
72
|
T = TypeVar("T")
|
73
73
|
|
74
74
|
|
75
|
-
def odxrequire(obj:
|
75
|
+
def odxrequire(obj: T | None, message: str | None = None) -> T:
|
76
76
|
"""This function ensures that an object required by the ODX
|
77
77
|
specification is actually present.
|
78
78
|
|
odxtools/externalaccessmethod.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import List
|
4
3
|
from xml.etree import ElementTree
|
5
4
|
|
6
5
|
from .element import IdentifiableElement
|
@@ -15,7 +14,7 @@ class ExternalAccessMethod(IdentifiableElement):
|
|
15
14
|
|
16
15
|
@staticmethod
|
17
16
|
def from_et(et_element: ElementTree.Element,
|
18
|
-
doc_frags:
|
17
|
+
doc_frags: list[OdxDocFragment]) -> "ExternalAccessMethod":
|
19
18
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
20
19
|
|
21
20
|
method = odxrequire(et_element.findtext("METHOD"))
|
odxtools/externaldoc.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
|
-
from typing import
|
2
|
+
from typing import Optional
|
3
3
|
from xml.etree import ElementTree
|
4
4
|
|
5
5
|
from .exceptions import odxrequire
|
@@ -8,12 +8,12 @@ from .odxlink import OdxDocFragment
|
|
8
8
|
|
9
9
|
@dataclass
|
10
10
|
class ExternalDoc:
|
11
|
-
description:
|
11
|
+
description: str | None
|
12
12
|
href: str
|
13
13
|
|
14
14
|
@staticmethod
|
15
|
-
def from_et(et_element:
|
16
|
-
doc_frags:
|
15
|
+
def from_et(et_element: ElementTree.Element | None,
|
16
|
+
doc_frags: list[OdxDocFragment]) -> Optional["ExternalDoc"]:
|
17
17
|
if et_element is None:
|
18
18
|
return None
|
19
19
|
|
odxtools/field.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import List, Optional
|
4
3
|
from xml.etree import ElementTree
|
5
4
|
|
6
5
|
from .basicstructure import BasicStructure
|
@@ -15,11 +14,11 @@ from .utils import dataclass_fields_asdict
|
|
15
14
|
|
16
15
|
@dataclass
|
17
16
|
class Field(ComplexDop):
|
18
|
-
structure_ref:
|
19
|
-
structure_snref:
|
20
|
-
env_data_desc_ref:
|
21
|
-
env_data_desc_snref:
|
22
|
-
is_visible_raw:
|
17
|
+
structure_ref: OdxLinkRef | None
|
18
|
+
structure_snref: str | None
|
19
|
+
env_data_desc_ref: OdxLinkRef | None
|
20
|
+
env_data_desc_snref: str | None
|
21
|
+
is_visible_raw: bool | None
|
23
22
|
|
24
23
|
@property
|
25
24
|
def structure(self) -> BasicStructure:
|
@@ -31,7 +30,7 @@ class Field(ComplexDop):
|
|
31
30
|
return self.is_visible_raw in (None, True)
|
32
31
|
|
33
32
|
@staticmethod
|
34
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
33
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Field":
|
35
34
|
kwargs = dataclass_fields_asdict(ComplexDop.from_et(et_element, doc_frags))
|
36
35
|
|
37
36
|
structure_ref = OdxLinkRef.from_et(et_element.find("BASIC-STRUCTURE-REF"), doc_frags)
|
@@ -54,8 +53,8 @@ class Field(ComplexDop):
|
|
54
53
|
**kwargs)
|
55
54
|
|
56
55
|
def __post_init__(self) -> None:
|
57
|
-
self._structure:
|
58
|
-
self._env_data_desc:
|
56
|
+
self._structure: BasicStructure | None = None
|
57
|
+
self._env_data_desc: EnvironmentDataDescription | None = None
|
59
58
|
num_struct_refs = 0 if self.structure_ref is None else 1
|
60
59
|
num_struct_refs += 0 if self.structure_snref is None else 1
|
61
60
|
|
@@ -87,5 +86,5 @@ class Field(ComplexDop):
|
|
87
86
|
self._env_data_desc = resolve_snref(self.env_data_desc_snref, ddds.env_data_descs,
|
88
87
|
EnvironmentDataDescription)
|
89
88
|
|
90
|
-
def get_static_bit_length(self) ->
|
89
|
+
def get_static_bit_length(self) -> int | None:
|
91
90
|
return None
|
odxtools/functionalclass.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
|
@@ -16,11 +16,11 @@ class FunctionalClass(IdentifiableElement):
|
|
16
16
|
Corresponds to FUNCT-CLASS.
|
17
17
|
"""
|
18
18
|
|
19
|
-
admin_data:
|
19
|
+
admin_data: AdminData | None
|
20
20
|
|
21
21
|
@staticmethod
|
22
22
|
def from_et(et_element: ElementTree.Element,
|
23
|
-
doc_frags:
|
23
|
+
doc_frags: list[OdxDocFragment]) -> "FunctionalClass":
|
24
24
|
|
25
25
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
26
26
|
|
@@ -28,7 +28,7 @@ class FunctionalClass(IdentifiableElement):
|
|
28
28
|
|
29
29
|
return FunctionalClass(admin_data=admin_data, **kwargs)
|
30
30
|
|
31
|
-
def _build_odxlinks(self) ->
|
31
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
32
32
|
return {self.odx_id: self}
|
33
33
|
|
34
34
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/inputparam.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 deprecation import deprecated
|
@@ -15,10 +15,10 @@ from .utils import dataclass_fields_asdict
|
|
15
15
|
|
16
16
|
@dataclass
|
17
17
|
class InputParam(NamedElement):
|
18
|
-
physical_default_value:
|
18
|
+
physical_default_value: str | None
|
19
19
|
dop_base_ref: OdxLinkRef
|
20
|
-
oid:
|
21
|
-
semantic:
|
20
|
+
oid: str | None
|
21
|
+
semantic: str | None
|
22
22
|
|
23
23
|
@property
|
24
24
|
def dop(self) -> DopBase:
|
@@ -30,7 +30,7 @@ class InputParam(NamedElement):
|
|
30
30
|
return self._dop
|
31
31
|
|
32
32
|
@staticmethod
|
33
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
33
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "InputParam":
|
34
34
|
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
|
35
35
|
|
36
36
|
physical_default_value = et_element.findtext("PHYSICAL-DEFAULT-VALUE")
|
@@ -46,7 +46,7 @@ class InputParam(NamedElement):
|
|
46
46
|
semantic=semantic,
|
47
47
|
**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/internalconstr.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import List, Optional
|
4
3
|
from xml.etree import ElementTree
|
5
4
|
|
6
5
|
from .compumethods.limit import Limit
|
@@ -16,14 +15,14 @@ class InternalConstr:
|
|
16
15
|
|
17
16
|
# TODO: Enforce the internal and physical constraints.
|
18
17
|
|
19
|
-
lower_limit:
|
20
|
-
upper_limit:
|
21
|
-
scale_constrs:
|
18
|
+
lower_limit: Limit | None
|
19
|
+
upper_limit: Limit | None
|
20
|
+
scale_constrs: list[ScaleConstr]
|
22
21
|
|
23
22
|
value_type: DataType
|
24
23
|
|
25
24
|
@staticmethod
|
26
|
-
def constr_from_et(et_element: ElementTree.Element, doc_frags:
|
25
|
+
def constr_from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment], *,
|
27
26
|
value_type: DataType) -> "InternalConstr":
|
28
27
|
|
29
28
|
lower_limit = Limit.limit_from_et(
|
odxtools/isotp_state_machine.py
CHANGED
@@ -4,9 +4,10 @@
|
|
4
4
|
import asyncio
|
5
5
|
import re
|
6
6
|
import sys
|
7
|
+
from collections.abc import AsyncGenerator, Iterable
|
7
8
|
from enum import IntEnum
|
8
9
|
from io import TextIOBase
|
9
|
-
from typing import
|
10
|
+
from typing import TextIO
|
10
11
|
|
11
12
|
import bitstruct
|
12
13
|
import can
|
@@ -32,7 +33,7 @@ class IsoTpStateMachine:
|
|
32
33
|
can_fd_log_frame_re = re.compile(
|
33
34
|
"\\([0-9.]*\\) *([a-zA-Z0-9_-]*) ([0-9A-Fa-f]+)##[0-9A-Fa-f]([0-9A-Fa-f]+)")
|
34
35
|
|
35
|
-
def __init__(self, can_rx_ids:
|
36
|
+
def __init__(self, can_rx_ids: int | list[int]):
|
36
37
|
if isinstance(can_rx_ids, int):
|
37
38
|
can_rx_ids = [can_rx_ids]
|
38
39
|
|
@@ -40,10 +41,10 @@ class IsoTpStateMachine:
|
|
40
41
|
assert isinstance(self._can_rx_ids, list)
|
41
42
|
|
42
43
|
self._telegram_specified_len = [0] * len(can_rx_ids)
|
43
|
-
self._telegram_data:
|
44
|
+
self._telegram_data: list[bytearray | None] = [None] * len(can_rx_ids)
|
44
45
|
self._telegram_last_rx_fragment_idx = [0] * len(can_rx_ids)
|
45
46
|
|
46
|
-
def decode_rx_frame(self, rx_id: int, data: bytes) -> Iterable[
|
47
|
+
def decode_rx_frame(self, rx_id: int, data: bytes) -> Iterable[tuple[int, bytes]]:
|
47
48
|
"""Handle the ISO-TP state transitions caused by a CAN frame.
|
48
49
|
|
49
50
|
E.g., add some data to a telegram, etc. Returns a generator of
|
@@ -114,8 +115,8 @@ class IsoTpStateMachine:
|
|
114
115
|
else:
|
115
116
|
self.on_frame_type_error(telegram_idx, frame_type)
|
116
117
|
|
117
|
-
async def read_telegrams(self,
|
118
|
-
|
118
|
+
async def read_telegrams(self,
|
119
|
+
bus: can.BusABC | TextIO) -> AsyncGenerator[tuple[int, bytes], None]:
|
119
120
|
"""This is equivalent to the :py:meth:`file.readlines()` method, but
|
120
121
|
it yields ISO-TP telegrams instead of lines.
|
121
122
|
|
@@ -184,7 +185,7 @@ class IsoTpStateMachine:
|
|
184
185
|
"""
|
185
186
|
return self._can_rx_ids[telegram_idx]
|
186
187
|
|
187
|
-
def telegram_data(self, telegram_idx: int) ->
|
188
|
+
def telegram_data(self, telegram_idx: int) -> bytes | None:
|
188
189
|
"""Given a Telegram index, returns the data received for this telegram
|
189
190
|
so far.
|
190
191
|
|
@@ -233,8 +234,8 @@ class IsoTpActiveDecoder(IsoTpStateMachine):
|
|
233
234
|
|
234
235
|
def __init__(self,
|
235
236
|
can_bus: can.BusABC,
|
236
|
-
can_rx_ids:
|
237
|
-
can_tx_ids:
|
237
|
+
can_rx_ids: list[int],
|
238
|
+
can_tx_ids: list[int],
|
238
239
|
padding_size: int = 0,
|
239
240
|
padding_value: int = 0xAA):
|
240
241
|
self._can_bus = can_bus
|
@@ -251,8 +252,8 @@ class IsoTpActiveDecoder(IsoTpStateMachine):
|
|
251
252
|
assert len(self._can_rx_ids) == len(self._can_tx_ids)
|
252
253
|
assert set(self._can_rx_ids).isdisjoint(set(self._can_tx_ids)) # correct?
|
253
254
|
|
254
|
-
self._block_size:
|
255
|
-
self._frames_received:
|
255
|
+
self._block_size: list[int | None] = [None] * len(self._can_rx_ids)
|
256
|
+
self._frames_received: list[int | None] = [None] * len(self._can_rx_ids)
|
256
257
|
|
257
258
|
def can_tx_id(self, telegram_idx: int) -> int:
|
258
259
|
"""Given a Telegram index, returns the CAN ID for sending data.
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import List
|
4
3
|
from xml.etree import ElementTree
|
5
4
|
|
6
5
|
from typing_extensions import override
|
@@ -30,7 +29,7 @@ class LeadingLengthInfoType(DiagCodedType):
|
|
30
29
|
@staticmethod
|
31
30
|
@override
|
32
31
|
def from_et(et_element: ElementTree.Element,
|
33
|
-
doc_frags:
|
32
|
+
doc_frags: list[OdxDocFragment]) -> "LeadingLengthInfoType":
|
34
33
|
kwargs = dataclass_fields_asdict(DiagCodedType.from_et(et_element, doc_frags))
|
35
34
|
|
36
35
|
bit_length = int(odxrequire(et_element.findtext("BIT-LENGTH")))
|
@@ -53,7 +52,7 @@ class LeadingLengthInfoType(DiagCodedType):
|
|
53
52
|
@override
|
54
53
|
def encode_into_pdu(self, internal_value: AtomicOdxType, encode_state: EncodeState) -> None:
|
55
54
|
|
56
|
-
if not isinstance(internal_value,
|
55
|
+
if not isinstance(internal_value, str | bytes):
|
57
56
|
odxraise(
|
58
57
|
f"LEADING-LENGTH-INFO types can only be used for strings and byte fields, "
|
59
58
|
f"not {type(internal_value).__name__}", EncodeError)
|
odxtools/library.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 IdentifiableElement
|
@@ -19,17 +19,17 @@ class Library(IdentifiableElement):
|
|
19
19
|
"""
|
20
20
|
|
21
21
|
code_file: str
|
22
|
-
encryption:
|
22
|
+
encryption: str | None
|
23
23
|
syntax: str
|
24
24
|
revision: str
|
25
|
-
entrypoint:
|
25
|
+
entrypoint: str | None
|
26
26
|
|
27
27
|
@property
|
28
28
|
def code(self) -> bytes:
|
29
29
|
return self._code
|
30
30
|
|
31
31
|
@staticmethod
|
32
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
32
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Library":
|
33
33
|
|
34
34
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
35
35
|
|
@@ -47,7 +47,7 @@ class Library(IdentifiableElement):
|
|
47
47
|
entrypoint=entrypoint,
|
48
48
|
**kwargs)
|
49
49
|
|
50
|
-
def _build_odxlinks(self) ->
|
50
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
51
51
|
return {self.odx_id: self}
|
52
52
|
|
53
53
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/linkeddtcdop.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
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 .diagnostictroublecode import DiagnosticTroubleCode
|
@@ -15,7 +15,7 @@ if TYPE_CHECKING:
|
|
15
15
|
|
16
16
|
@dataclass
|
17
17
|
class LinkedDtcDop:
|
18
|
-
not_inherited_dtc_snrefs:
|
18
|
+
not_inherited_dtc_snrefs: list[str]
|
19
19
|
dtc_dop_ref: OdxLinkRef
|
20
20
|
|
21
21
|
@property
|
@@ -31,7 +31,7 @@ class LinkedDtcDop:
|
|
31
31
|
return self._dtc_dop.short_name
|
32
32
|
|
33
33
|
@staticmethod
|
34
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
34
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "LinkedDtcDop":
|
35
35
|
not_inherited_dtc_snrefs = [
|
36
36
|
odxrequire(el.get("SHORT-NAME"))
|
37
37
|
for el in et_element.iterfind("NOT-INHERITED-DTC-SNREFS/"
|
@@ -43,7 +43,7 @@ class LinkedDtcDop:
|
|
43
43
|
return LinkedDtcDop(
|
44
44
|
not_inherited_dtc_snrefs=not_inherited_dtc_snrefs, dtc_dop_ref=dtc_dop_ref)
|
45
45
|
|
46
|
-
def _build_odxlinks(self) ->
|
46
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
47
47
|
return {}
|
48
48
|
|
49
49
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/loadfile.py
CHANGED
@@ -1,19 +1,18 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import os
|
3
3
|
from pathlib import Path
|
4
|
-
from typing import Union
|
5
4
|
|
6
5
|
from .database import Database
|
7
6
|
|
8
7
|
|
9
|
-
def load_pdx_file(pdx_file:
|
8
|
+
def load_pdx_file(pdx_file: str | Path) -> Database:
|
10
9
|
db = Database()
|
11
10
|
db.add_pdx_file(str(pdx_file))
|
12
11
|
db.refresh()
|
13
12
|
return db
|
14
13
|
|
15
14
|
|
16
|
-
def load_odx_d_file(odx_d_file_name:
|
15
|
+
def load_odx_d_file(odx_d_file_name: str | Path) -> Database:
|
17
16
|
db = Database()
|
18
17
|
db.add_odx_file(str(odx_d_file_name))
|
19
18
|
db.refresh()
|
@@ -21,7 +20,7 @@ def load_odx_d_file(odx_d_file_name: Union[str, Path]) -> Database:
|
|
21
20
|
return db
|
22
21
|
|
23
22
|
|
24
|
-
def load_file(file_name:
|
23
|
+
def load_file(file_name: str | Path) -> Database:
|
25
24
|
if str(file_name).lower().endswith(".pdx"):
|
26
25
|
return load_pdx_file(str(file_name))
|
27
26
|
elif str(file_name).lower().endswith(".odx-d"):
|
@@ -30,7 +29,7 @@ def load_file(file_name: Union[str, Path]) -> Database:
|
|
30
29
|
raise RuntimeError(f"Could not guess the file format of file '{file_name}'!")
|
31
30
|
|
32
31
|
|
33
|
-
def load_files(*file_names:
|
32
|
+
def load_files(*file_names: str | Path) -> Database:
|
34
33
|
db = Database()
|
35
34
|
for file_name in file_names:
|
36
35
|
p = Path(file_name)
|
@@ -45,7 +44,7 @@ def load_files(*file_names: Union[str, Path]) -> Database:
|
|
45
44
|
return db
|
46
45
|
|
47
46
|
|
48
|
-
def load_directory(dir_name:
|
47
|
+
def load_directory(dir_name: str | Path) -> Database:
|
49
48
|
db = Database()
|
50
49
|
for file_name in os.listdir(str(dir_name)):
|
51
50
|
p = Path(dir_name) / file_name
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import List, Optional
|
4
3
|
from xml.etree import ElementTree
|
5
4
|
|
6
5
|
from .matchingparameter import MatchingParameter
|
@@ -18,7 +17,7 @@ class MatchingBaseVariantParameter(MatchingParameter):
|
|
18
17
|
additional subtag `USE-PHYSICAL-ADDRESSING`.
|
19
18
|
"""
|
20
19
|
|
21
|
-
use_physical_addressing_raw:
|
20
|
+
use_physical_addressing_raw: bool | None
|
22
21
|
|
23
22
|
@property
|
24
23
|
def use_physical_addressing(self) -> bool:
|
@@ -26,7 +25,7 @@ class MatchingBaseVariantParameter(MatchingParameter):
|
|
26
25
|
|
27
26
|
@staticmethod
|
28
27
|
def from_et(et_element: ElementTree.Element,
|
29
|
-
doc_frags:
|
28
|
+
doc_frags: list[OdxDocFragment]) -> "MatchingBaseVariantParameter":
|
30
29
|
|
31
30
|
kwargs = dataclass_fields_asdict(MatchingParameter.from_et(et_element, doc_frags))
|
32
31
|
|
odxtools/matchingparameter.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 .diaglayers.diaglayer import DiagLayer
|
@@ -34,12 +34,12 @@ class MatchingParameter:
|
|
34
34
|
# or negative response. What it probably actually wants to say is
|
35
35
|
# that any response that can possibly be received shall exhibit
|
36
36
|
# the referenced parameter.
|
37
|
-
out_param_if_snref:
|
38
|
-
out_param_if_snpathref:
|
37
|
+
out_param_if_snref: str | None
|
38
|
+
out_param_if_snpathref: str | None
|
39
39
|
|
40
40
|
@staticmethod
|
41
41
|
def from_et(et_element: ElementTree.Element,
|
42
|
-
doc_frags:
|
42
|
+
doc_frags: list[OdxDocFragment]) -> "MatchingParameter":
|
43
43
|
|
44
44
|
expected_value = odxrequire(et_element.findtext("EXPECTED-VALUE"))
|
45
45
|
diag_comm_snref = odxrequire(
|
@@ -61,7 +61,7 @@ class MatchingParameter:
|
|
61
61
|
out_param_if_snpathref=out_param_if_snpathref,
|
62
62
|
)
|
63
63
|
|
64
|
-
def _build_odxlinks(self) ->
|
64
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
65
65
|
return {}
|
66
66
|
|
67
67
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
@@ -93,7 +93,7 @@ class MatchingParameter:
|
|
93
93
|
|
94
94
|
return self.__matches(param_dict, snpath_chunks)
|
95
95
|
|
96
|
-
def __matches(self, param_dict: ParameterValue, snpath_chunks:
|
96
|
+
def __matches(self, param_dict: ParameterValue, snpath_chunks: list[str]) -> bool:
|
97
97
|
if len(snpath_chunks) == 0:
|
98
98
|
parameter_value = param_dict
|
99
99
|
if isinstance(parameter_value, dict):
|
@@ -105,7 +105,7 @@ class MatchingParameter:
|
|
105
105
|
# floating point
|
106
106
|
return abs(float(self.expected_value) - parameter_value) < 1e-8
|
107
107
|
elif isinstance(parameter_value, BytesTypes):
|
108
|
-
return parameter_value.hex().upper() == self.expected_value.upper()
|
108
|
+
return bytes(parameter_value).hex().upper() == self.expected_value.upper()
|
109
109
|
elif isinstance(parameter_value, DiagnosticTroubleCode):
|
110
110
|
# TODO: what happens if non-numerical DTCs like
|
111
111
|
# "U123456" are specified? Is specifying DTCs even
|
odxtools/minmaxlengthtype.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import
|
3
|
+
from typing import cast
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from typing_extensions import override
|
@@ -18,7 +18,7 @@ from .utils import dataclass_fields_asdict
|
|
18
18
|
|
19
19
|
@dataclass
|
20
20
|
class MinMaxLengthType(DiagCodedType):
|
21
|
-
max_length:
|
21
|
+
max_length: int | None
|
22
22
|
min_length: int
|
23
23
|
termination: Termination
|
24
24
|
|
@@ -29,7 +29,7 @@ class MinMaxLengthType(DiagCodedType):
|
|
29
29
|
@staticmethod
|
30
30
|
@override
|
31
31
|
def from_et(et_element: ElementTree.Element,
|
32
|
-
doc_frags:
|
32
|
+
doc_frags: list[OdxDocFragment]) -> "MinMaxLengthType":
|
33
33
|
kwargs = dataclass_fields_asdict(DiagCodedType.from_et(et_element, doc_frags))
|
34
34
|
|
35
35
|
max_length = None
|
@@ -77,7 +77,7 @@ class MinMaxLengthType(DiagCodedType):
|
|
77
77
|
@override
|
78
78
|
def encode_into_pdu(self, internal_value: AtomicOdxType, encode_state: EncodeState) -> None:
|
79
79
|
|
80
|
-
if not isinstance(internal_value,
|
80
|
+
if not isinstance(internal_value, str | BytesTypes):
|
81
81
|
odxraise("MinMaxLengthType is currently only implemented for strings and byte arrays",
|
82
82
|
EncodeError)
|
83
83
|
|
odxtools/modification.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 .exceptions import odxrequire
|
@@ -11,16 +11,16 @@ from .snrefcontext import SnRefContext
|
|
11
11
|
@dataclass
|
12
12
|
class Modification:
|
13
13
|
change: str
|
14
|
-
reason:
|
14
|
+
reason: str | None
|
15
15
|
|
16
16
|
@staticmethod
|
17
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
17
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Modification":
|
18
18
|
change = odxrequire(et_element.findtext("CHANGE"))
|
19
19
|
reason = et_element.findtext("REASON")
|
20
20
|
|
21
21
|
return Modification(change=change, reason=reason)
|
22
22
|
|
23
|
-
def _build_odxlinks(self) ->
|
23
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
24
24
|
return {}
|
25
25
|
|
26
26
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|