odxtools 9.6.1__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/addressing.py +8 -0
- odxtools/admindata.py +8 -8
- odxtools/audience.py +10 -10
- odxtools/basecomparam.py +7 -20
- odxtools/basevariantpattern.py +4 -5
- odxtools/basicstructure.py +12 -11
- 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 -186
- odxtools/commrelation.py +12 -19
- odxtools/commrelationvaluetype.py +9 -0
- 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 +191 -0
- odxtools/compumethods/compucategory.py +13 -0
- odxtools/compumethods/compucodecompumethod.py +6 -5
- odxtools/compumethods/compuconst.py +4 -5
- odxtools/compumethods/compudefaultvalue.py +1 -2
- odxtools/compumethods/compuinternaltophys.py +6 -6
- odxtools/compumethods/compumethod.py +6 -17
- 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/intervaltype.py +8 -0
- odxtools/compumethods/limit.py +13 -19
- odxtools/compumethods/linearcompumethod.py +4 -3
- odxtools/compumethods/linearsegment.py +14 -15
- odxtools/compumethods/ratfunccompumethod.py +5 -4
- odxtools/compumethods/ratfuncsegment.py +7 -8
- odxtools/compumethods/scalelinearcompumethod.py +10 -9
- odxtools/compumethods/scaleratfunccompumethod.py +6 -5
- odxtools/compumethods/tabintpcompumethod.py +19 -20
- odxtools/compumethods/texttablecompumethod.py +5 -4
- 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 +6 -22
- odxtools/determinenumberofitems.py +4 -4
- odxtools/diagclasstype.py +11 -0
- odxtools/diagcodedtype.py +7 -7
- odxtools/diagcomm.py +19 -42
- 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 +21 -97
- odxtools/diagvariable.py +14 -14
- odxtools/docrevision.py +11 -11
- odxtools/dopbase.py +6 -6
- odxtools/dtcconnector.py +45 -0
- odxtools/dtcdop.py +15 -56
- odxtools/dynamicendmarkerfield.py +5 -4
- odxtools/dynamiclengthfield.py +5 -4
- odxtools/dyndefinedspec.py +7 -159
- odxtools/dynenddopref.py +5 -5
- odxtools/dyniddefmodeinfo.py +161 -0
- 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 +49 -0
- odxtools/environmentdata.py +3 -4
- odxtools/environmentdatadescription.py +11 -11
- odxtools/exceptions.py +5 -5
- odxtools/externalaccessmethod.py +22 -0
- odxtools/externaldoc.py +23 -0
- 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 +62 -0
- odxtools/loadfile.py +5 -6
- odxtools/matchingbasevariantparameter.py +2 -3
- odxtools/matchingparameter.py +7 -7
- odxtools/minmaxlengthtype.py +5 -11
- 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 +2 -2
- 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/rowfragment.py +7 -0
- odxtools/parameters/systemparameter.py +2 -3
- odxtools/parameters/tableentryparameter.py +4 -9
- 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 +4 -12
- odxtools/posresponsesuppressible.py +72 -0
- odxtools/preconditionstateref.py +7 -7
- odxtools/progcode.py +6 -6
- odxtools/protstack.py +4 -4
- odxtools/radix.py +9 -0
- odxtools/relateddiagcommref.py +22 -0
- odxtools/relateddoc.py +6 -6
- odxtools/request.py +14 -12
- odxtools/response.py +15 -13
- odxtools/scaleconstr.py +4 -12
- 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/standardizationlevel.py +9 -0
- odxtools/standardlengthtype.py +12 -21
- odxtools/state.py +3 -3
- odxtools/statechart.py +4 -4
- odxtools/statemachine.py +4 -3
- odxtools/statetransition.py +5 -18
- odxtools/statetransitionref.py +18 -18
- odxtools/staticfield.py +5 -4
- odxtools/structure.py +2 -3
- odxtools/subcomponent.py +12 -245
- odxtools/subcomponentparamconnector.py +103 -0
- odxtools/subcomponentpattern.py +42 -0
- odxtools/swvariable.py +3 -4
- odxtools/table.py +17 -55
- odxtools/tablediagcommconnector.py +47 -0
- odxtools/tablerow.py +30 -30
- odxtools/tablerowconnector.py +46 -0
- odxtools/teammember.py +11 -11
- odxtools/templates/macros/printService.xml.jinja2 +2 -1
- odxtools/termination.py +8 -0
- odxtools/text.py +2 -3
- odxtools/transmode.py +9 -0
- odxtools/uds.py +2 -3
- odxtools/unit.py +9 -9
- odxtools/unitgroup.py +6 -11
- odxtools/unitgroupcategory.py +7 -0
- odxtools/unitspec.py +6 -6
- odxtools/usage.py +9 -0
- odxtools/utils.py +31 -2
- odxtools/validtype.py +9 -0
- 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.6.1.dist-info → odxtools-10.0.0.dist-info}/METADATA +4 -5
- odxtools-10.0.0.dist-info/RECORD +264 -0
- odxtools-9.6.1.dist-info/RECORD +0 -238
- {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/WHEEL +0 -0
- {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/entry_points.txt +0 -0
- {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/licenses/LICENSE +0 -0
- {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/top_level.txt +0 -0
odxtools/additionalaudience.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
|
@@ -17,12 +17,12 @@ class AdditionalAudience(IdentifiableElement):
|
|
17
17
|
|
18
18
|
@staticmethod
|
19
19
|
def from_et(et_element: ElementTree.Element,
|
20
|
-
doc_frags:
|
20
|
+
doc_frags: list[OdxDocFragment]) -> "AdditionalAudience":
|
21
21
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
22
22
|
|
23
23
|
return AdditionalAudience(**kwargs)
|
24
24
|
|
25
|
-
def _build_odxlinks(self) ->
|
25
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
26
26
|
return {self.odx_id: self}
|
27
27
|
|
28
28
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/addressing.py
ADDED
odxtools/admindata.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, Optional
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .companydocinfo import CompanyDocInfo
|
@@ -11,13 +11,13 @@ from .snrefcontext import SnRefContext
|
|
11
11
|
|
12
12
|
@dataclass
|
13
13
|
class AdminData:
|
14
|
-
language:
|
15
|
-
company_doc_infos:
|
16
|
-
doc_revisions:
|
14
|
+
language: str | None
|
15
|
+
company_doc_infos: list[CompanyDocInfo]
|
16
|
+
doc_revisions: list[DocRevision]
|
17
17
|
|
18
18
|
@staticmethod
|
19
|
-
def from_et(et_element:
|
20
|
-
doc_frags:
|
19
|
+
def from_et(et_element: ElementTree.Element | None,
|
20
|
+
doc_frags: list[OdxDocFragment]) -> Optional["AdminData"]:
|
21
21
|
|
22
22
|
if et_element is None:
|
23
23
|
return None
|
@@ -37,8 +37,8 @@ class AdminData:
|
|
37
37
|
return AdminData(
|
38
38
|
language=language, company_doc_infos=company_doc_infos, doc_revisions=doc_revisions)
|
39
39
|
|
40
|
-
def _build_odxlinks(self) ->
|
41
|
-
result:
|
40
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
41
|
+
result: dict[OdxLinkId, Any] = {}
|
42
42
|
|
43
43
|
for cdi in self.company_doc_infos:
|
44
44
|
result.update(cdi._build_odxlinks())
|
odxtools/audience.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 .additionalaudience import AdditionalAudience
|
@@ -12,14 +12,14 @@ from .snrefcontext import SnRefContext
|
|
12
12
|
|
13
13
|
@dataclass
|
14
14
|
class Audience:
|
15
|
-
enabled_audience_refs:
|
16
|
-
disabled_audience_refs:
|
15
|
+
enabled_audience_refs: list[OdxLinkRef]
|
16
|
+
disabled_audience_refs: list[OdxLinkRef]
|
17
17
|
|
18
|
-
is_supplier_raw:
|
19
|
-
is_development_raw:
|
20
|
-
is_manufacturing_raw:
|
21
|
-
is_aftersales_raw:
|
22
|
-
is_aftermarket_raw:
|
18
|
+
is_supplier_raw: bool | None
|
19
|
+
is_development_raw: bool | None
|
20
|
+
is_manufacturing_raw: bool | None
|
21
|
+
is_aftersales_raw: bool | None
|
22
|
+
is_aftermarket_raw: bool | None
|
23
23
|
|
24
24
|
@property
|
25
25
|
def is_supplier(self) -> bool:
|
@@ -50,7 +50,7 @@ class Audience:
|
|
50
50
|
return self._disabled_audiences
|
51
51
|
|
52
52
|
@staticmethod
|
53
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
53
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Audience":
|
54
54
|
|
55
55
|
enabled_audience_refs = [
|
56
56
|
OdxLinkRef.from_et(ref, doc_frags)
|
@@ -78,7 +78,7 @@ class Audience:
|
|
78
78
|
is_aftermarket_raw=is_aftermarket_raw,
|
79
79
|
)
|
80
80
|
|
81
|
-
def _build_odxlinks(self) ->
|
81
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
82
82
|
return {}
|
83
83
|
|
84
84
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/basecomparam.py
CHANGED
@@ -1,39 +1,26 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from
|
4
|
-
from typing import Any, Dict, List, Optional, cast
|
3
|
+
from typing import Any, cast
|
5
4
|
from xml.etree import ElementTree
|
6
5
|
|
7
6
|
from .element import IdentifiableElement
|
8
7
|
from .exceptions import odxraise, odxrequire
|
9
8
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
10
9
|
from .snrefcontext import SnRefContext
|
10
|
+
from .standardizationlevel import StandardizationLevel
|
11
|
+
from .usage import Usage
|
11
12
|
from .utils import dataclass_fields_asdict
|
12
13
|
|
13
14
|
|
14
|
-
class StandardizationLevel(Enum):
|
15
|
-
STANDARD = "STANDARD"
|
16
|
-
OEM_SPECIFIC = "OEM-SPECIFIC"
|
17
|
-
OPTIONAL = "OPTIONAL"
|
18
|
-
OEM_OPTIONAL = "OEM-OPTIONAL"
|
19
|
-
|
20
|
-
|
21
|
-
class Usage(Enum):
|
22
|
-
ECU_SOFTWARE = "ECU-SOFTWARE"
|
23
|
-
ECU_COMM = "ECU-COMM"
|
24
|
-
APPLICATION = "APPLICATION"
|
25
|
-
TESTER = "TESTER"
|
26
|
-
|
27
|
-
|
28
15
|
@dataclass
|
29
16
|
class BaseComparam(IdentifiableElement):
|
30
17
|
param_class: str
|
31
18
|
cptype: StandardizationLevel
|
32
|
-
display_level:
|
33
|
-
cpusage:
|
19
|
+
display_level: int | None
|
20
|
+
cpusage: Usage | None # Required in ODX 2.2, missing in ODX 2.0
|
34
21
|
|
35
22
|
@staticmethod
|
36
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
23
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "BaseComparam":
|
37
24
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
38
25
|
|
39
26
|
param_class = odxrequire(et_element.attrib.get("PARAM-CLASS"))
|
@@ -65,7 +52,7 @@ class BaseComparam(IdentifiableElement):
|
|
65
52
|
cpusage=cpusage,
|
66
53
|
**kwargs)
|
67
54
|
|
68
|
-
def _build_odxlinks(self) ->
|
55
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
69
56
|
return {self.odx_id: self}
|
70
57
|
|
71
58
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/basevariantpattern.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import List, Union
|
4
3
|
from xml.etree import ElementTree
|
5
4
|
|
6
5
|
from typing_extensions import override
|
@@ -17,11 +16,11 @@ class BaseVariantPattern(VariantPattern):
|
|
17
16
|
"""Base variant patterns are variant patterns used to identify the
|
18
17
|
base variant of an ECU.
|
19
18
|
"""
|
20
|
-
matching_base_variant_parameters:
|
19
|
+
matching_base_variant_parameters: list[MatchingBaseVariantParameter]
|
21
20
|
|
22
21
|
@staticmethod
|
23
22
|
def from_et(et_element: ElementTree.Element,
|
24
|
-
doc_frags:
|
23
|
+
doc_frags: list[OdxDocFragment]) -> "BaseVariantPattern":
|
25
24
|
|
26
25
|
matching_base_variant_parameters = [
|
27
26
|
MatchingBaseVariantParameter.from_et(mbvp_el, doc_frags)
|
@@ -33,6 +32,6 @@ class BaseVariantPattern(VariantPattern):
|
|
33
32
|
return BaseVariantPattern(matching_base_variant_parameters=matching_base_variant_parameters)
|
34
33
|
|
35
34
|
@override
|
36
|
-
def get_matching_parameters(
|
37
|
-
|
35
|
+
def get_matching_parameters(self
|
36
|
+
) -> list[MatchingParameter] | list[MatchingBaseVariantParameter]:
|
38
37
|
return self.matching_base_variant_parameters
|
odxtools/basicstructure.py
CHANGED
@@ -1,14 +1,15 @@
|
|
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
|
7
7
|
|
8
|
-
from .codec import (composite_codec_decode_from_pdu, composite_codec_encode_into_pdu,
|
9
|
-
composite_codec_get_free_parameters, composite_codec_get_required_parameters,
|
10
|
-
composite_codec_get_static_bit_length)
|
11
8
|
from .complexdop import ComplexDop
|
9
|
+
from .compositecodec import (composite_codec_decode_from_pdu, composite_codec_encode_into_pdu,
|
10
|
+
composite_codec_get_free_parameters,
|
11
|
+
composite_codec_get_required_parameters,
|
12
|
+
composite_codec_get_static_bit_length)
|
12
13
|
from .decodestate import DecodeState
|
13
14
|
from .encodestate import EncodeState
|
14
15
|
from .exceptions import DecodeError, odxraise
|
@@ -29,20 +30,20 @@ class BasicStructure(ComplexDop):
|
|
29
30
|
data objects. All structure-like objects adhere to the
|
30
31
|
`CompositeCodec` type protocol.
|
31
32
|
"""
|
32
|
-
byte_size:
|
33
|
+
byte_size: int | None
|
33
34
|
parameters: NamedItemList[Parameter]
|
34
35
|
|
35
36
|
@property
|
36
|
-
def required_parameters(self) ->
|
37
|
+
def required_parameters(self) -> list[Parameter]:
|
37
38
|
return composite_codec_get_required_parameters(self)
|
38
39
|
|
39
40
|
@property
|
40
|
-
def free_parameters(self) ->
|
41
|
+
def free_parameters(self) -> list[Parameter]:
|
41
42
|
return composite_codec_get_free_parameters(self)
|
42
43
|
|
43
44
|
@staticmethod
|
44
45
|
def from_et(et_element: ElementTree.Element,
|
45
|
-
doc_frags:
|
46
|
+
doc_frags: list[OdxDocFragment]) -> "BasicStructure":
|
46
47
|
"""Read a BASIC-STRUCTURE."""
|
47
48
|
kwargs = dataclass_fields_asdict(ComplexDop.from_et(et_element, doc_frags))
|
48
49
|
|
@@ -55,7 +56,7 @@ class BasicStructure(ComplexDop):
|
|
55
56
|
|
56
57
|
return BasicStructure(byte_size=byte_size, parameters=parameters, **kwargs)
|
57
58
|
|
58
|
-
def _build_odxlinks(self) ->
|
59
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
59
60
|
result = super()._build_odxlinks()
|
60
61
|
|
61
62
|
for param in self.parameters:
|
@@ -78,7 +79,7 @@ class BasicStructure(ComplexDop):
|
|
78
79
|
|
79
80
|
context.parameters = None
|
80
81
|
|
81
|
-
def get_static_bit_length(self) ->
|
82
|
+
def get_static_bit_length(self) -> int | None:
|
82
83
|
# Explicit size was specified, so we do not need to look at
|
83
84
|
# the list of parameters
|
84
85
|
if self.byte_size is not None:
|
@@ -95,7 +96,7 @@ class BasicStructure(ComplexDop):
|
|
95
96
|
print(parameter_info(self.free_parameters), end="")
|
96
97
|
|
97
98
|
@override
|
98
|
-
def encode_into_pdu(self, physical_value:
|
99
|
+
def encode_into_pdu(self, physical_value: ParameterValue | None,
|
99
100
|
encode_state: EncodeState) -> None:
|
100
101
|
orig_pos = encode_state.cursor_byte_position
|
101
102
|
|
odxtools/cli/_print_utils.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import re
|
3
3
|
import textwrap
|
4
|
-
from typing import List, Optional, Tuple, Union
|
5
4
|
|
6
5
|
import markdownify
|
7
6
|
from rich import print as rich_print
|
@@ -113,9 +112,9 @@ def print_service_parameters(service: DiagService,
|
|
113
112
|
rich_print("\n")
|
114
113
|
|
115
114
|
|
116
|
-
def extract_service_tabulation_data(services:
|
115
|
+
def extract_service_tabulation_data(services: list[DiagService],
|
117
116
|
*,
|
118
|
-
additional_columns:
|
117
|
+
additional_columns: list[tuple[str, list[str]]] | None = None
|
119
118
|
) -> RichTable:
|
120
119
|
"""Extracts data of diagnostic services into Dictionary which can
|
121
120
|
be printed by tabulate module
|
@@ -125,9 +124,9 @@ def extract_service_tabulation_data(services: List[DiagService],
|
|
125
124
|
table = RichTable(
|
126
125
|
title="", show_header=True, header_style="bold cyan", border_style="blue", show_lines=True)
|
127
126
|
|
128
|
-
name_column:
|
129
|
-
semantic_column:
|
130
|
-
request_column:
|
127
|
+
name_column: list[str] = []
|
128
|
+
semantic_column: list[str] = []
|
129
|
+
request_column: list[str] = []
|
131
130
|
|
132
131
|
for service in services:
|
133
132
|
name_column.append(service.short_name)
|
@@ -147,15 +146,19 @@ def extract_service_tabulation_data(services: List[DiagService],
|
|
147
146
|
for ac_title, _ in additional_columns:
|
148
147
|
table.add_column(ac_title, justify="left", style="white")
|
149
148
|
|
150
|
-
rows = zip(
|
151
|
-
|
149
|
+
rows = zip(
|
150
|
+
name_column,
|
151
|
+
semantic_column,
|
152
|
+
request_column,
|
153
|
+
*[ac[1] for ac in additional_columns],
|
154
|
+
strict=False)
|
152
155
|
for row in rows:
|
153
156
|
table.add_row(*map(str, row))
|
154
157
|
|
155
158
|
return table
|
156
159
|
|
157
160
|
|
158
|
-
def extract_parameter_tabulation_data(parameters:
|
161
|
+
def extract_parameter_tabulation_data(parameters: list[Parameter]) -> RichTable:
|
159
162
|
# extracts data of parameters of diagnostic services into
|
160
163
|
# a RichTable object that can be printed
|
161
164
|
|
@@ -174,15 +177,15 @@ def extract_parameter_tabulation_data(parameters: List[Parameter]) -> RichTable:
|
|
174
177
|
table.add_column("Value Type", justify="left", style="white")
|
175
178
|
table.add_column("Linked DOP", justify="left", style="white")
|
176
179
|
|
177
|
-
name_column:
|
178
|
-
byte_column:
|
179
|
-
bit_length_column:
|
180
|
-
semantic_column:
|
181
|
-
param_type_column:
|
182
|
-
value_column:
|
183
|
-
value_type_column:
|
184
|
-
data_type_column:
|
185
|
-
dop_column:
|
180
|
+
name_column: list[str] = []
|
181
|
+
byte_column: list[str] = []
|
182
|
+
bit_length_column: list[str] = []
|
183
|
+
semantic_column: list[str] = []
|
184
|
+
param_type_column: list[str] = []
|
185
|
+
value_column: list[str] = []
|
186
|
+
value_type_column: list[str] = []
|
187
|
+
data_type_column: list[str] = []
|
188
|
+
dop_column: list[str] = []
|
186
189
|
|
187
190
|
for param in parameters:
|
188
191
|
name_column.append(param.short_name)
|
@@ -211,7 +214,7 @@ def extract_parameter_tabulation_data(parameters: List[Parameter]) -> RichTable:
|
|
211
214
|
value_column.append(str(param.coded_values))
|
212
215
|
value_type_column.append('coded values')
|
213
216
|
dop_column.append("")
|
214
|
-
elif isinstance(param,
|
217
|
+
elif isinstance(param, PhysicalConstantParameter | SystemParameter | ValueParameter):
|
215
218
|
# this is a hack to make this routine work for parameters
|
216
219
|
# which reference DOPs of a type that a is not yet
|
217
220
|
# internalized. (all parameter objects of the tested types
|
@@ -250,15 +253,24 @@ def extract_parameter_tabulation_data(parameters: List[Parameter]) -> RichTable:
|
|
250
253
|
dop_column.append("")
|
251
254
|
|
252
255
|
# Add all rows at once by zipping dictionary values
|
253
|
-
rows = zip(
|
254
|
-
|
256
|
+
rows = zip(
|
257
|
+
name_column,
|
258
|
+
byte_column,
|
259
|
+
bit_length_column,
|
260
|
+
semantic_column,
|
261
|
+
param_type_column,
|
262
|
+
data_type_column,
|
263
|
+
value_column,
|
264
|
+
value_type_column,
|
265
|
+
dop_column,
|
266
|
+
strict=False)
|
255
267
|
for row in rows:
|
256
268
|
table.add_row(*map(str, row))
|
257
269
|
|
258
270
|
return table
|
259
271
|
|
260
272
|
|
261
|
-
def print_dl_metrics(variants:
|
273
|
+
def print_dl_metrics(variants: list[DiagLayer]) -> None:
|
262
274
|
"""
|
263
275
|
Print diagnostic layer metrics using Rich tables.
|
264
276
|
Args:
|
@@ -278,7 +290,7 @@ def print_dl_metrics(variants: List[DiagLayer]) -> None:
|
|
278
290
|
# Process each variant
|
279
291
|
for variant in variants:
|
280
292
|
assert isinstance(variant, DiagLayer)
|
281
|
-
all_services:
|
293
|
+
all_services: list[DiagService | SingleEcuJob] = sorted(
|
282
294
|
variant.services, key=lambda x: x.short_name)
|
283
295
|
ddds = variant.diag_data_dictionary_spec
|
284
296
|
|
odxtools/cli/browse.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
import argparse
|
3
3
|
import logging
|
4
4
|
import sys
|
5
|
-
from typing import
|
5
|
+
from typing import cast
|
6
6
|
|
7
7
|
import InquirerPy.prompt as IP_prompt
|
8
8
|
|
@@ -66,7 +66,7 @@ def _validate_string_value(input: str, parameter: Parameter) -> bool:
|
|
66
66
|
return input != ""
|
67
67
|
|
68
68
|
|
69
|
-
def prompt_single_parameter_value(parameter: Parameter) ->
|
69
|
+
def prompt_single_parameter_value(parameter: Parameter) -> AtomicOdxType | None:
|
70
70
|
if not isinstance(parameter, ValueParameter):
|
71
71
|
odxraise("Only the value of ValueParameters can be queried")
|
72
72
|
if parameter.physical_type is None:
|
@@ -113,7 +113,7 @@ def prompt_single_parameter_value(parameter: Parameter) -> Optional[AtomicOdxTyp
|
|
113
113
|
return cast(str, answer.get(parameter.short_name))
|
114
114
|
|
115
115
|
|
116
|
-
def encode_message_interactively(codec:
|
116
|
+
def encode_message_interactively(codec: Request | Response,
|
117
117
|
ask_user_confirmation: bool = False) -> None:
|
118
118
|
if sys.__stdin__ is None or sys.__stdout__ is None or not sys.__stdin__.isatty(
|
119
119
|
) or not sys.__stdout__.isatty():
|
@@ -168,7 +168,7 @@ def encode_message_interactively(codec: Union[Request, Response],
|
|
168
168
|
if (inner_params := getattr(dop := getattr(param, "dop", None), "parameters",
|
169
169
|
None)) is not None:
|
170
170
|
assert isinstance(dop, DopBase)
|
171
|
-
inner_params = cast(
|
171
|
+
inner_params = cast(list[Parameter], inner_params)
|
172
172
|
# param refers to a complex DOP, i.e., the required
|
173
173
|
# value is a key-value dict
|
174
174
|
print(
|
@@ -201,8 +201,8 @@ def encode_message_interactively(codec: Union[Request, Response],
|
|
201
201
|
|
202
202
|
|
203
203
|
def encode_message_from_string_values(
|
204
|
-
sub_service:
|
205
|
-
parameter_values:
|
204
|
+
sub_service: Request | Response,
|
205
|
+
parameter_values: ParameterValueDict | None = None,
|
206
206
|
) -> None:
|
207
207
|
if parameter_values is None:
|
208
208
|
parameter_values = {}
|
@@ -243,7 +243,7 @@ def encode_message_from_string_values(
|
|
243
243
|
inner_params = getattr(dop, "parameters", None)
|
244
244
|
assert isinstance(dop, ComplexDop)
|
245
245
|
assert isinstance(inner_params, list)
|
246
|
-
inner_params = cast(
|
246
|
+
inner_params = cast(list[Parameter], inner_params)
|
247
247
|
|
248
248
|
typed_dict = parameter_value.copy()
|
249
249
|
for inner_param_sn, inner_param_value in parameter_value.items():
|
@@ -316,7 +316,7 @@ def browse(odxdb: Database) -> None:
|
|
316
316
|
)
|
317
317
|
|
318
318
|
while True:
|
319
|
-
services:
|
319
|
+
services: list[DiagService] = [
|
320
320
|
s for s in variant.services if isinstance(s, DiagService)
|
321
321
|
]
|
322
322
|
# Select a service of the ECU
|
@@ -370,7 +370,7 @@ def browse(odxdb: Database) -> None:
|
|
370
370
|
|
371
371
|
codec = answer.get("message_type")
|
372
372
|
if codec is not None:
|
373
|
-
assert isinstance(codec,
|
373
|
+
assert isinstance(codec, Request | Response)
|
374
374
|
table = extract_parameter_tabulation_data(codec.parameters)
|
375
375
|
print(table)
|
376
376
|
|
odxtools/cli/compare.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
import argparse
|
5
5
|
import os
|
6
|
-
from typing import Any,
|
6
|
+
from typing import Any, cast
|
7
7
|
|
8
8
|
from rich import print as rich_print
|
9
9
|
from rich.padding import Padding as RichPadding
|
@@ -29,18 +29,18 @@ _odxtools_tool_name_ = "compare"
|
|
29
29
|
|
30
30
|
VariantName = str
|
31
31
|
VariantType = str
|
32
|
-
NewServices =
|
33
|
-
DeletedServices =
|
34
|
-
RenamedServices =
|
35
|
-
ServicesWithParamChanges =
|
32
|
+
NewServices = list[DiagService]
|
33
|
+
DeletedServices = list[DiagService]
|
34
|
+
RenamedServices = list[list[str | DiagService]]
|
35
|
+
ServicesWithParamChanges = list[list[str | DiagService]]
|
36
36
|
|
37
|
-
SpecsServiceDict =
|
38
|
-
|
37
|
+
SpecsServiceDict = dict[str, VariantName | VariantType | NewServices | DeletedServices
|
38
|
+
| RenamedServices | ServicesWithParamChanges]
|
39
39
|
|
40
|
-
NewVariants =
|
41
|
-
DeletedVariants =
|
40
|
+
NewVariants = list[DiagLayer]
|
41
|
+
DeletedVariants = list[DiagLayer]
|
42
42
|
|
43
|
-
SpecsChangesVariants =
|
43
|
+
SpecsChangesVariants = dict[str, NewVariants | DeletedVariants | SpecsServiceDict]
|
44
44
|
|
45
45
|
|
46
46
|
class Display:
|
@@ -71,13 +71,13 @@ class Display:
|
|
71
71
|
f"Changed diagnostic services for diagnostic layer '{service_dict['diag_layer']}' ({service_dict['diag_layer_type']}):"
|
72
72
|
)
|
73
73
|
if service_dict["new_services"]:
|
74
|
-
assert isinstance(service_dict["new_services"],
|
74
|
+
assert isinstance(service_dict["new_services"], list)
|
75
75
|
rich_print()
|
76
76
|
rich_print(" [blue]New services[/blue]")
|
77
77
|
rich_print(extract_service_tabulation_data(
|
78
78
|
service_dict["new_services"])) # type: ignore[arg-type]
|
79
79
|
if service_dict["deleted_services"]:
|
80
|
-
assert isinstance(service_dict["deleted_services"],
|
80
|
+
assert isinstance(service_dict["deleted_services"], list)
|
81
81
|
rich_print()
|
82
82
|
rich_print(" [blue]Deleted services[/blue]")
|
83
83
|
rich_print(extract_service_tabulation_data(
|
@@ -123,7 +123,7 @@ class Display:
|
|
123
123
|
show_lines=True)
|
124
124
|
for header in detailed_info:
|
125
125
|
table.add_column(header)
|
126
|
-
rows = zip(*detailed_info.values())
|
126
|
+
rows = zip(*detailed_info.values(), strict=False)
|
127
127
|
for row in rows:
|
128
128
|
table.add_row(*map(str, row))
|
129
129
|
|
@@ -159,9 +159,9 @@ class Display:
|
|
159
159
|
|
160
160
|
|
161
161
|
class Comparison(Display):
|
162
|
-
databases:
|
163
|
-
diagnostic_layers:
|
164
|
-
diagnostic_layer_names:
|
162
|
+
databases: list[Database] = [] # storage of database objects
|
163
|
+
diagnostic_layers: list[DiagLayer] = [] # storage of DiagLayer objects
|
164
|
+
diagnostic_layer_names: set[str] = set() # storage of diagnostic layer names
|
165
165
|
|
166
166
|
db_indicator_1: int
|
167
167
|
db_indicator_2: int
|
@@ -169,7 +169,7 @@ class Comparison(Display):
|
|
169
169
|
def __init__(self) -> None:
|
170
170
|
pass
|
171
171
|
|
172
|
-
def compare_parameters(self, param1: Parameter, param2: Parameter) ->
|
172
|
+
def compare_parameters(self, param1: Parameter, param2: Parameter) -> dict[str, Any]:
|
173
173
|
# checks whether properties of param1 and param2 differ
|
174
174
|
# checked properties: Name, Byte Position, Bit Length, Semantic, Parameter Type, Value (Coded, Constant, Default etc.), Data Type, Data Object Property (Name, Physical Data Type, Unit)
|
175
175
|
|
@@ -177,8 +177,8 @@ class Comparison(Display):
|
|
177
177
|
old = []
|
178
178
|
new = []
|
179
179
|
|
180
|
-
def append_list(property_name: str, new_property_value:
|
181
|
-
old_property_value:
|
180
|
+
def append_list(property_name: str, new_property_value: AtomicOdxType | None,
|
181
|
+
old_property_value: AtomicOdxType | None) -> None:
|
182
182
|
property.append(property_name)
|
183
183
|
old.append(old_property_value)
|
184
184
|
new.append(new_property_value)
|
@@ -277,10 +277,10 @@ class Comparison(Display):
|
|
277
277
|
return {"Property": property, "Old Value": old, "New Value": new}
|
278
278
|
|
279
279
|
def compare_services(self, service1: DiagService,
|
280
|
-
service2: DiagService) ->
|
280
|
+
service2: DiagService) -> list[SpecsServiceDict]:
|
281
281
|
# compares request, positive response and negative response parameters of two diagnostic services
|
282
282
|
|
283
|
-
information:
|
283
|
+
information: list[str | dict[str, Any]] = [
|
284
284
|
] # information = [infotext1, table1, infotext2, table2, ...]
|
285
285
|
changed_params = ""
|
286
286
|
|
@@ -438,10 +438,10 @@ class Comparison(Display):
|
|
438
438
|
|
439
439
|
# extract the constant prefixes for the requests of all
|
440
440
|
# services (used for duck-typed rename detection)
|
441
|
-
dl1_request_prefixes:
|
441
|
+
dl1_request_prefixes: list[bytes | None] = [
|
442
442
|
None if s.request is None else s.request.coded_const_prefix() for s in dl1.services
|
443
443
|
]
|
444
|
-
dl2_request_prefixes:
|
444
|
+
dl2_request_prefixes: list[bytes | None] = [
|
445
445
|
None if s.request is None else s.request.coded_const_prefix() for s in dl2.services
|
446
446
|
]
|
447
447
|
|
@@ -449,7 +449,7 @@ class Comparison(Display):
|
|
449
449
|
for service1 in dl1.services:
|
450
450
|
|
451
451
|
# check for added diagnostic services
|
452
|
-
rq_prefix:
|
452
|
+
rq_prefix: bytes | None = None
|
453
453
|
if service1.request is not None:
|
454
454
|
rq_prefix = service1.request.coded_const_prefix()
|
455
455
|
|
odxtools/cli/decode.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import argparse
|
3
3
|
import re
|
4
|
-
from typing import Dict, List, Optional
|
5
4
|
|
6
5
|
from ..database import Database
|
7
6
|
from ..diagservice import DiagService
|
@@ -26,13 +25,13 @@ def get_display_value(v: ParameterValue) -> str:
|
|
26
25
|
|
27
26
|
def print_summary(
|
28
27
|
odxdb: Database,
|
29
|
-
ecu_variants:
|
28
|
+
ecu_variants: list[str] | None = None,
|
30
29
|
data: bytes = b'',
|
31
30
|
decode: bool = False,
|
32
31
|
) -> None:
|
33
32
|
ecu_names = ecu_variants if ecu_variants else [ecu.short_name for ecu in odxdb.ecus]
|
34
|
-
service_db:
|
35
|
-
service_ecus:
|
33
|
+
service_db: dict[str, DiagService] = {}
|
34
|
+
service_ecus: dict[str, list[str]] = {}
|
36
35
|
for ecu_name in ecu_names:
|
37
36
|
ecu = odxdb.ecus[ecu_name]
|
38
37
|
if not ecu:
|
odxtools/cli/find.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import argparse
|
3
|
-
from typing import Dict, List, Optional
|
4
3
|
|
5
4
|
from ..database import Database
|
6
5
|
from ..diagservice import DiagService
|
@@ -24,13 +23,13 @@ def get_display_value(v: ParameterValue) -> str:
|
|
24
23
|
|
25
24
|
|
26
25
|
def print_summary(odxdb: Database,
|
27
|
-
service_names:
|
28
|
-
ecu_variants:
|
26
|
+
service_names: list[str],
|
27
|
+
ecu_variants: list[str] | None = None,
|
29
28
|
allow_unknown_bit_lengths: bool = False,
|
30
29
|
print_params: bool = False) -> None:
|
31
30
|
ecu_names = ecu_variants if ecu_variants else [ecu.short_name for ecu in odxdb.ecus]
|
32
|
-
service_db:
|
33
|
-
service_ecus:
|
31
|
+
service_db: dict[str, DiagService] = {}
|
32
|
+
service_ecus: dict[str, list[str]] = {}
|
34
33
|
for ecu_name in ecu_names:
|
35
34
|
ecu = odxdb.ecus[ecu_name]
|
36
35
|
if not ecu:
|