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
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from typing_extensions import override
|
@@ -13,7 +13,8 @@ from .encodestate import EncodeState
|
|
13
13
|
from .environmentdata import EnvironmentData
|
14
14
|
from .exceptions import odxraise, odxrequire
|
15
15
|
from .nameditemlist import NamedItemList
|
16
|
-
from .
|
16
|
+
from .odxdoccontext import OdxDocContext
|
17
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
17
18
|
from .odxtypes import DataType, ParameterValue, ParameterValueDict
|
18
19
|
from .parameters.codedconstparameter import CodedConstParameter
|
19
20
|
from .parameters.parameter import Parameter
|
@@ -24,7 +25,7 @@ from .snrefcontext import SnRefContext
|
|
24
25
|
from .utils import dataclass_fields_asdict
|
25
26
|
|
26
27
|
|
27
|
-
@dataclass
|
28
|
+
@dataclass(kw_only=True)
|
28
29
|
class EnvironmentDataDescription(ComplexDop):
|
29
30
|
"""This class represents environment data descriptions
|
30
31
|
|
@@ -35,20 +36,20 @@ class EnvironmentDataDescription(ComplexDop):
|
|
35
36
|
|
36
37
|
"""
|
37
38
|
|
38
|
-
param_snref:
|
39
|
-
param_snpathref:
|
39
|
+
param_snref: str | None = None
|
40
|
+
param_snpathref: str | None = None
|
40
41
|
|
41
42
|
# in ODX 2.0.0, ENV-DATAS seems to be a mandatory
|
42
43
|
# sub-element of ENV-DATA-DESC, in ODX 2.2 it is not
|
43
44
|
# present
|
44
|
-
env_datas: NamedItemList[EnvironmentData]
|
45
|
-
env_data_refs:
|
45
|
+
env_datas: NamedItemList[EnvironmentData] = field(default_factory=NamedItemList)
|
46
|
+
env_data_refs: list[OdxLinkRef] = field(default_factory=list)
|
46
47
|
|
47
48
|
@staticmethod
|
48
49
|
def from_et(et_element: ElementTree.Element,
|
49
|
-
|
50
|
+
context: OdxDocContext) -> "EnvironmentDataDescription":
|
50
51
|
"""Reads Environment Data Description from Diag Layer."""
|
51
|
-
kwargs = dataclass_fields_asdict(ComplexDop.from_et(et_element,
|
52
|
+
kwargs = dataclass_fields_asdict(ComplexDop.from_et(et_element, context))
|
52
53
|
|
53
54
|
param_snref = None
|
54
55
|
if (param_snref_elem := et_element.find("PARAM-SNREF")) is not None:
|
@@ -63,11 +64,11 @@ class EnvironmentDataDescription(ComplexDop):
|
|
63
64
|
# empty and one non-empty list here. (Which is which depends
|
64
65
|
# on the version of the standard used by the file.)
|
65
66
|
env_datas = NamedItemList([
|
66
|
-
EnvironmentData.from_et(env_data_elem,
|
67
|
+
EnvironmentData.from_et(env_data_elem, context)
|
67
68
|
for env_data_elem in et_element.iterfind("ENV-DATAS/ENV-DATA")
|
68
69
|
])
|
69
70
|
env_data_refs = [
|
70
|
-
odxrequire(OdxLinkRef.from_et(env_data_ref,
|
71
|
+
odxrequire(OdxLinkRef.from_et(env_data_ref, context))
|
71
72
|
for env_data_ref in et_element.iterfind("ENV-DATA-REFS/ENV-DATA-REF")
|
72
73
|
]
|
73
74
|
|
@@ -78,7 +79,7 @@ class EnvironmentDataDescription(ComplexDop):
|
|
78
79
|
env_data_refs=env_data_refs,
|
79
80
|
**kwargs)
|
80
81
|
|
81
|
-
def _build_odxlinks(self) ->
|
82
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
82
83
|
odxlinks = {self.odx_id: self}
|
83
84
|
|
84
85
|
if not self.env_data_refs:
|
@@ -105,7 +106,7 @@ class EnvironmentDataDescription(ComplexDop):
|
|
105
106
|
ed._resolve_snrefs(context)
|
106
107
|
|
107
108
|
@override
|
108
|
-
def encode_into_pdu(self, physical_value:
|
109
|
+
def encode_into_pdu(self, physical_value: ParameterValue | None,
|
109
110
|
encode_state: EncodeState) -> None:
|
110
111
|
"""Convert a physical value into bytes and emplace them into a PDU.
|
111
112
|
"""
|
@@ -118,7 +119,7 @@ class EnvironmentDataDescription(ComplexDop):
|
|
118
119
|
"descriptions via SNPATHREF is not supported yet")
|
119
120
|
return None
|
120
121
|
|
121
|
-
numerical_dtc_value:
|
122
|
+
numerical_dtc_value: ParameterValue | None = None
|
122
123
|
for prev_param, prev_param_value in reversed(encode_state.journal):
|
123
124
|
if prev_param.short_name == self.param_snref:
|
124
125
|
numerical_dtc_value = self._get_numerical_dtc_from_parameter(
|
@@ -165,7 +166,7 @@ class EnvironmentDataDescription(ComplexDop):
|
|
165
166
|
"descriptions via SNPATHREF is not supported yet")
|
166
167
|
return None
|
167
168
|
|
168
|
-
numerical_dtc_value:
|
169
|
+
numerical_dtc_value: ParameterValue | None = None
|
169
170
|
for prev_param, prev_param_value in reversed(decode_state.journal):
|
170
171
|
if prev_param.short_name == self.param_snref:
|
171
172
|
numerical_dtc_value = self._get_numerical_dtc_from_parameter(
|
@@ -204,7 +205,7 @@ class EnvironmentDataDescription(ComplexDop):
|
|
204
205
|
return result
|
205
206
|
|
206
207
|
def _get_numerical_dtc_from_parameter(self, param: Parameter,
|
207
|
-
param_value:
|
208
|
+
param_value: ParameterValue | None) -> int:
|
208
209
|
if isinstance(param, ParameterWithDOP):
|
209
210
|
dop = param.dop
|
210
211
|
if not isinstance(dop, (DataObjectProperty, DtcDop)):
|
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,22 +1,20 @@
|
|
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
|
7
6
|
from .exceptions import odxrequire
|
8
|
-
from .
|
7
|
+
from .odxdoccontext import OdxDocContext
|
9
8
|
from .utils import dataclass_fields_asdict
|
10
9
|
|
11
10
|
|
12
|
-
@dataclass
|
11
|
+
@dataclass(kw_only=True)
|
13
12
|
class ExternalAccessMethod(IdentifiableElement):
|
14
13
|
method: str
|
15
14
|
|
16
15
|
@staticmethod
|
17
|
-
def from_et(et_element: ElementTree.Element,
|
18
|
-
|
19
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
16
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ExternalAccessMethod":
|
17
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
20
18
|
|
21
19
|
method = odxrequire(et_element.findtext("METHOD"))
|
22
20
|
|
odxtools/externaldoc.py
CHANGED
@@ -1,19 +1,19 @@
|
|
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
|
6
|
-
from .
|
6
|
+
from .odxdoccontext import OdxDocContext
|
7
7
|
|
8
8
|
|
9
|
-
@dataclass
|
9
|
+
@dataclass(kw_only=True)
|
10
10
|
class ExternalDoc:
|
11
|
-
description:
|
11
|
+
description: str | None = None
|
12
12
|
href: str
|
13
13
|
|
14
14
|
@staticmethod
|
15
|
-
def from_et(et_element:
|
16
|
-
|
15
|
+
def from_et(et_element: ElementTree.Element | None,
|
16
|
+
context: OdxDocContext) -> Optional["ExternalDoc"]:
|
17
17
|
if et_element is None:
|
18
18
|
return None
|
19
19
|
|
odxtools/field.py
CHANGED
@@ -1,25 +1,25 @@
|
|
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
|
7
6
|
from .complexdop import ComplexDop
|
8
7
|
from .environmentdatadescription import EnvironmentDataDescription
|
9
8
|
from .exceptions import odxassert, odxrequire
|
10
|
-
from .
|
9
|
+
from .odxdoccontext import OdxDocContext
|
10
|
+
from .odxlink import OdxLinkDatabase, OdxLinkRef, resolve_snref
|
11
11
|
from .odxtypes import odxstr_to_bool
|
12
12
|
from .snrefcontext import SnRefContext
|
13
13
|
from .utils import dataclass_fields_asdict
|
14
14
|
|
15
15
|
|
16
|
-
@dataclass
|
16
|
+
@dataclass(kw_only=True)
|
17
17
|
class Field(ComplexDop):
|
18
|
-
structure_ref:
|
19
|
-
structure_snref:
|
20
|
-
env_data_desc_ref:
|
21
|
-
env_data_desc_snref:
|
22
|
-
is_visible_raw:
|
18
|
+
structure_ref: OdxLinkRef | None = None
|
19
|
+
structure_snref: str | None = None
|
20
|
+
env_data_desc_ref: OdxLinkRef | None = None
|
21
|
+
env_data_desc_snref: str | None = None
|
22
|
+
is_visible_raw: bool | None = None
|
23
23
|
|
24
24
|
@property
|
25
25
|
def structure(self) -> BasicStructure:
|
@@ -31,15 +31,15 @@ class Field(ComplexDop):
|
|
31
31
|
return self.is_visible_raw in (None, True)
|
32
32
|
|
33
33
|
@staticmethod
|
34
|
-
def from_et(et_element: ElementTree.Element,
|
35
|
-
kwargs = dataclass_fields_asdict(ComplexDop.from_et(et_element,
|
34
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Field":
|
35
|
+
kwargs = dataclass_fields_asdict(ComplexDop.from_et(et_element, context))
|
36
36
|
|
37
|
-
structure_ref = OdxLinkRef.from_et(et_element.find("BASIC-STRUCTURE-REF"),
|
37
|
+
structure_ref = OdxLinkRef.from_et(et_element.find("BASIC-STRUCTURE-REF"), context)
|
38
38
|
structure_snref = None
|
39
39
|
if (edsnr_elem := et_element.find("BASIC-STRUCTURE-SNREF")) is not None:
|
40
40
|
structure_snref = edsnr_elem.get("SHORT-NAME")
|
41
41
|
|
42
|
-
env_data_desc_ref = OdxLinkRef.from_et(et_element.find("ENV-DATA-DESC-REF"),
|
42
|
+
env_data_desc_ref = OdxLinkRef.from_et(et_element.find("ENV-DATA-DESC-REF"), context)
|
43
43
|
env_data_desc_snref = None
|
44
44
|
if (edsnr_elem := et_element.find("ENV-DATA-DESC-SNREF")) is not None:
|
45
45
|
env_data_desc_snref = edsnr_elem.get("SHORT-NAME")
|
@@ -54,8 +54,8 @@ class Field(ComplexDop):
|
|
54
54
|
**kwargs)
|
55
55
|
|
56
56
|
def __post_init__(self) -> None:
|
57
|
-
self._structure:
|
58
|
-
self._env_data_desc:
|
57
|
+
self._structure: BasicStructure | None = None
|
58
|
+
self._env_data_desc: EnvironmentDataDescription | None = None
|
59
59
|
num_struct_refs = 0 if self.structure_ref is None else 1
|
60
60
|
num_struct_refs += 0 if self.structure_snref is None else 1
|
61
61
|
|
@@ -87,5 +87,5 @@ class Field(ComplexDop):
|
|
87
87
|
self._env_data_desc = resolve_snref(self.env_data_desc_snref, ddds.env_data_descs,
|
88
88
|
EnvironmentDataDescription)
|
89
89
|
|
90
|
-
def get_static_bit_length(self) ->
|
90
|
+
def get_static_bit_length(self) -> int | None:
|
91
91
|
return None
|
odxtools/functionalclass.py
CHANGED
@@ -1,34 +1,34 @@
|
|
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
|
7
7
|
from .element import IdentifiableElement
|
8
|
-
from .
|
8
|
+
from .odxdoccontext import OdxDocContext
|
9
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
9
10
|
from .snrefcontext import SnRefContext
|
10
11
|
from .utils import dataclass_fields_asdict
|
11
12
|
|
12
13
|
|
13
|
-
@dataclass
|
14
|
+
@dataclass(kw_only=True)
|
14
15
|
class FunctionalClass(IdentifiableElement):
|
15
16
|
"""
|
16
17
|
Corresponds to FUNCT-CLASS.
|
17
18
|
"""
|
18
19
|
|
19
|
-
admin_data:
|
20
|
+
admin_data: AdminData | None = None
|
20
21
|
|
21
22
|
@staticmethod
|
22
|
-
def from_et(et_element: ElementTree.Element,
|
23
|
-
doc_frags: List[OdxDocFragment]) -> "FunctionalClass":
|
23
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "FunctionalClass":
|
24
24
|
|
25
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
25
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
26
26
|
|
27
|
-
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"),
|
27
|
+
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), context)
|
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
|
@@ -8,17 +8,18 @@ from deprecation import deprecated
|
|
8
8
|
from .dopbase import DopBase
|
9
9
|
from .element import NamedElement
|
10
10
|
from .exceptions import odxrequire
|
11
|
-
from .
|
11
|
+
from .odxdoccontext import OdxDocContext
|
12
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
12
13
|
from .snrefcontext import SnRefContext
|
13
14
|
from .utils import dataclass_fields_asdict
|
14
15
|
|
15
16
|
|
16
|
-
@dataclass
|
17
|
+
@dataclass(kw_only=True)
|
17
18
|
class InputParam(NamedElement):
|
18
|
-
physical_default_value:
|
19
|
+
physical_default_value: str | None = None
|
19
20
|
dop_base_ref: OdxLinkRef
|
20
|
-
oid:
|
21
|
-
semantic:
|
21
|
+
oid: str | None = None
|
22
|
+
semantic: str | None = None
|
22
23
|
|
23
24
|
@property
|
24
25
|
def dop(self) -> DopBase:
|
@@ -30,11 +31,11 @@ class InputParam(NamedElement):
|
|
30
31
|
return self._dop
|
31
32
|
|
32
33
|
@staticmethod
|
33
|
-
def from_et(et_element: ElementTree.Element,
|
34
|
-
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element,
|
34
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "InputParam":
|
35
|
+
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context))
|
35
36
|
|
36
37
|
physical_default_value = et_element.findtext("PHYSICAL-DEFAULT-VALUE")
|
37
|
-
dop_base_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DOP-BASE-REF"),
|
38
|
+
dop_base_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DOP-BASE-REF"), context))
|
38
39
|
|
39
40
|
oid = et_element.get("OID")
|
40
41
|
semantic = et_element.get("SEMANTIC")
|
@@ -46,7 +47,7 @@ class InputParam(NamedElement):
|
|
46
47
|
semantic=semantic,
|
47
48
|
**kwargs)
|
48
49
|
|
49
|
-
def _build_odxlinks(self) ->
|
50
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
50
51
|
return {}
|
51
52
|
|
52
53
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/internalconstr.py
CHANGED
@@ -1,38 +1,37 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
3
|
-
from typing import List, Optional
|
2
|
+
from dataclasses import dataclass, field
|
4
3
|
from xml.etree import ElementTree
|
5
4
|
|
6
5
|
from .compumethods.limit import Limit
|
7
|
-
from .
|
6
|
+
from .odxdoccontext import OdxDocContext
|
8
7
|
from .odxtypes import DataType
|
9
8
|
from .scaleconstr import ScaleConstr
|
10
9
|
|
11
10
|
|
12
|
-
@dataclass
|
11
|
+
@dataclass(kw_only=True)
|
13
12
|
class InternalConstr:
|
14
13
|
"""This class represents INTERNAL-CONSTR objects.
|
15
14
|
"""
|
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 = None
|
19
|
+
upper_limit: Limit | None = None
|
20
|
+
scale_constrs: list[ScaleConstr] = field(default_factory=list)
|
22
21
|
|
23
22
|
value_type: DataType
|
24
23
|
|
25
24
|
@staticmethod
|
26
|
-
def constr_from_et(et_element: ElementTree.Element,
|
25
|
+
def constr_from_et(et_element: ElementTree.Element, context: OdxDocContext, *,
|
27
26
|
value_type: DataType) -> "InternalConstr":
|
28
27
|
|
29
28
|
lower_limit = Limit.limit_from_et(
|
30
|
-
et_element.find("LOWER-LIMIT"),
|
29
|
+
et_element.find("LOWER-LIMIT"), context, value_type=value_type)
|
31
30
|
upper_limit = Limit.limit_from_et(
|
32
|
-
et_element.find("UPPER-LIMIT"),
|
31
|
+
et_element.find("UPPER-LIMIT"), context, value_type=value_type)
|
33
32
|
|
34
33
|
scale_constrs = [
|
35
|
-
ScaleConstr.scale_constr_from_et(sc_el,
|
34
|
+
ScaleConstr.scale_constr_from_et(sc_el, context, value_type=value_type)
|
36
35
|
for sc_el in et_element.iterfind("SCALE-CONSTRS/SCALE-CONSTR")
|
37
36
|
]
|
38
37
|
|
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
|
@@ -9,12 +8,12 @@ from .decodestate import DecodeState
|
|
9
8
|
from .diagcodedtype import DctType, DiagCodedType
|
10
9
|
from .encodestate import EncodeState
|
11
10
|
from .exceptions import EncodeError, odxassert, odxraise, odxrequire
|
12
|
-
from .
|
11
|
+
from .odxdoccontext import OdxDocContext
|
13
12
|
from .odxtypes import AtomicOdxType, DataType
|
14
13
|
from .utils import dataclass_fields_asdict
|
15
14
|
|
16
15
|
|
17
|
-
@dataclass
|
16
|
+
@dataclass(kw_only=True)
|
18
17
|
class LeadingLengthInfoType(DiagCodedType):
|
19
18
|
#: bit length of the length specifier field
|
20
19
|
#:
|
@@ -29,9 +28,8 @@ class LeadingLengthInfoType(DiagCodedType):
|
|
29
28
|
|
30
29
|
@staticmethod
|
31
30
|
@override
|
32
|
-
def from_et(et_element: ElementTree.Element,
|
33
|
-
|
34
|
-
kwargs = dataclass_fields_asdict(DiagCodedType.from_et(et_element, doc_frags))
|
31
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "LeadingLengthInfoType":
|
32
|
+
kwargs = dataclass_fields_asdict(DiagCodedType.from_et(et_element, context))
|
35
33
|
|
36
34
|
bit_length = int(odxrequire(et_element.findtext("BIT-LENGTH")))
|
37
35
|
|
odxtools/library.py
CHANGED
@@ -1,16 +1,17 @@
|
|
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
|
7
7
|
from .exceptions import odxraise, odxrequire
|
8
|
-
from .
|
8
|
+
from .odxdoccontext import OdxDocContext
|
9
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
9
10
|
from .snrefcontext import SnRefContext
|
10
11
|
from .utils import dataclass_fields_asdict
|
11
12
|
|
12
13
|
|
13
|
-
@dataclass
|
14
|
+
@dataclass(kw_only=True)
|
14
15
|
class Library(IdentifiableElement):
|
15
16
|
"""
|
16
17
|
A library defines a shared library used for single ECU jobs etc.
|
@@ -19,19 +20,19 @@ class Library(IdentifiableElement):
|
|
19
20
|
"""
|
20
21
|
|
21
22
|
code_file: str
|
22
|
-
encryption:
|
23
|
+
encryption: str | None = None
|
23
24
|
syntax: str
|
24
25
|
revision: str
|
25
|
-
entrypoint:
|
26
|
+
entrypoint: str | None = None
|
26
27
|
|
27
28
|
@property
|
28
29
|
def code(self) -> bytes:
|
29
30
|
return self._code
|
30
31
|
|
31
32
|
@staticmethod
|
32
|
-
def from_et(et_element: ElementTree.Element,
|
33
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Library":
|
33
34
|
|
34
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
35
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
35
36
|
|
36
37
|
code_file = odxrequire(et_element.findtext("CODE-FILE"))
|
37
38
|
encryption = et_element.findtext("ENCRYPTION")
|
@@ -47,7 +48,7 @@ class Library(IdentifiableElement):
|
|
47
48
|
entrypoint=entrypoint,
|
48
49
|
**kwargs)
|
49
50
|
|
50
|
-
def _build_odxlinks(self) ->
|
51
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
51
52
|
return {self.odx_id: self}
|
52
53
|
|
53
54
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/linkeddtcdop.py
CHANGED
@@ -1,21 +1,22 @@
|
|
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 .diagnostictroublecode import DiagnosticTroubleCode
|
7
7
|
from .exceptions import odxrequire
|
8
8
|
from .nameditemlist import NamedItemList
|
9
|
-
from .
|
9
|
+
from .odxdoccontext import OdxDocContext
|
10
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
|
10
11
|
from .snrefcontext import SnRefContext
|
11
12
|
|
12
13
|
if TYPE_CHECKING:
|
13
14
|
from .dtcdop import DtcDop
|
14
15
|
|
15
16
|
|
16
|
-
@dataclass
|
17
|
+
@dataclass(kw_only=True)
|
17
18
|
class LinkedDtcDop:
|
18
|
-
not_inherited_dtc_snrefs:
|
19
|
+
not_inherited_dtc_snrefs: list[str] = field(default_factory=list)
|
19
20
|
dtc_dop_ref: OdxLinkRef
|
20
21
|
|
21
22
|
@property
|
@@ -31,19 +32,19 @@ class LinkedDtcDop:
|
|
31
32
|
return self._dtc_dop.short_name
|
32
33
|
|
33
34
|
@staticmethod
|
34
|
-
def from_et(et_element: ElementTree.Element,
|
35
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "LinkedDtcDop":
|
35
36
|
not_inherited_dtc_snrefs = [
|
36
37
|
odxrequire(el.get("SHORT-NAME"))
|
37
38
|
for el in et_element.iterfind("NOT-INHERITED-DTC-SNREFS/"
|
38
39
|
"NOT-INHERITED-DTC-SNREF")
|
39
40
|
]
|
40
41
|
|
41
|
-
dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"),
|
42
|
+
dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"), context))
|
42
43
|
|
43
44
|
return LinkedDtcDop(
|
44
45
|
not_inherited_dtc_snrefs=not_inherited_dtc_snrefs, dtc_dop_ref=dtc_dop_ref)
|
45
46
|
|
46
|
-
def _build_odxlinks(self) ->
|
47
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
47
48
|
return {}
|
48
49
|
|
49
50
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|