odxtools 10.0.0__py3-none-any.whl → 10.1.1__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 +5 -5
- odxtools/admindata.py +10 -9
- odxtools/audience.py +15 -15
- odxtools/basecomparam.py +7 -6
- odxtools/basevariantpattern.py +7 -7
- odxtools/basicstructure.py +9 -9
- odxtools/cli/_print_utils.py +1 -1
- odxtools/cli/browse.py +1 -1
- odxtools/cli/compare.py +143 -170
- odxtools/cli/list.py +1 -1
- odxtools/commrelation.py +14 -13
- odxtools/companydata.py +11 -11
- odxtools/companydocinfo.py +11 -13
- odxtools/companyrevisioninfo.py +7 -7
- odxtools/companyspecificinfo.py +9 -11
- odxtools/comparam.py +6 -5
- odxtools/comparaminstance.py +10 -10
- odxtools/comparamspec.py +8 -9
- odxtools/comparamsubset.py +14 -22
- odxtools/complexcomparam.py +10 -10
- odxtools/complexdop.py +1 -1
- odxtools/compositecodec.py +3 -3
- odxtools/compumethods/compucodecompumethod.py +4 -4
- odxtools/compumethods/compuconst.py +3 -3
- odxtools/compumethods/compudefaultvalue.py +2 -2
- odxtools/compumethods/compuinternaltophys.py +11 -10
- odxtools/compumethods/compumethod.py +8 -7
- odxtools/compumethods/compuphystointernal.py +11 -10
- odxtools/compumethods/compurationalcoeffs.py +6 -6
- odxtools/compumethods/compuscale.py +14 -14
- odxtools/compumethods/createanycompumethod.py +12 -12
- odxtools/compumethods/identicalcompumethod.py +4 -4
- odxtools/compumethods/limit.py +8 -8
- odxtools/compumethods/linearcompumethod.py +4 -4
- odxtools/compumethods/linearsegment.py +8 -8
- odxtools/compumethods/ratfunccompumethod.py +4 -4
- odxtools/compumethods/ratfuncsegment.py +8 -8
- odxtools/compumethods/scalelinearcompumethod.py +5 -5
- odxtools/compumethods/scaleratfunccompumethod.py +4 -4
- odxtools/compumethods/tabintpcompumethod.py +12 -12
- odxtools/compumethods/texttablecompumethod.py +4 -4
- odxtools/createanycomparam.py +4 -4
- odxtools/createanydiagcodedtype.py +7 -7
- odxtools/database.py +28 -26
- odxtools/dataobjectproperty.py +15 -16
- odxtools/description.py +7 -7
- odxtools/determinenumberofitems.py +6 -5
- odxtools/diagcodedtype.py +6 -6
- odxtools/diagcomm.py +26 -27
- odxtools/diagdatadictionaryspec.py +34 -34
- odxtools/diaglayercontainer.py +32 -31
- odxtools/diaglayers/basevariant.py +5 -4
- odxtools/diaglayers/basevariantraw.py +18 -19
- odxtools/diaglayers/diaglayer.py +5 -4
- odxtools/diaglayers/diaglayerraw.py +39 -48
- odxtools/diaglayers/ecushareddata.py +6 -6
- odxtools/diaglayers/ecushareddataraw.py +11 -12
- odxtools/diaglayers/ecuvariant.py +5 -4
- odxtools/diaglayers/ecuvariantraw.py +17 -18
- odxtools/diaglayers/functionalgroup.py +5 -5
- odxtools/diaglayers/functionalgroupraw.py +13 -14
- odxtools/diaglayers/hierarchyelement.py +9 -9
- odxtools/diaglayers/hierarchyelementraw.py +8 -9
- odxtools/diaglayers/protocol.py +4 -4
- odxtools/diaglayers/protocolraw.py +10 -11
- odxtools/diagnostictroublecode.py +12 -14
- odxtools/diagservice.py +19 -18
- odxtools/diagvariable.py +19 -20
- odxtools/docrevision.py +14 -13
- odxtools/dopbase.py +10 -11
- odxtools/dtcconnector.py +6 -5
- odxtools/dtcdop.py +15 -15
- odxtools/dynamicendmarkerfield.py +6 -6
- odxtools/dynamiclengthfield.py +6 -6
- odxtools/dyndefinedspec.py +7 -7
- odxtools/dynenddopref.py +7 -7
- odxtools/dyniddefmodeinfo.py +17 -17
- odxtools/ecuvariantpattern.py +6 -7
- odxtools/element.py +12 -12
- odxtools/endofpdufield.py +6 -7
- odxtools/envdataconnector.py +6 -6
- odxtools/environmentdata.py +7 -8
- odxtools/environmentdatadescription.py +13 -12
- odxtools/externalaccessmethod.py +4 -5
- odxtools/externaldoc.py +4 -4
- odxtools/field.py +12 -11
- odxtools/functionalclass.py +7 -7
- odxtools/inputparam.py +9 -8
- odxtools/internalconstr.py +10 -10
- odxtools/leadinglengthinfotype.py +5 -6
- odxtools/library.py +7 -6
- odxtools/linkeddtcdop.py +7 -6
- odxtools/matchingbasevariantparameter.py +5 -5
- odxtools/matchingparameter.py +6 -6
- odxtools/message.py +1 -1
- odxtools/minmaxlengthtype.py +6 -7
- odxtools/modification.py +5 -4
- odxtools/multiplexer.py +48 -12
- odxtools/multiplexercase.py +10 -10
- odxtools/multiplexerdefaultcase.py +8 -7
- odxtools/multiplexerswitchkey.py +6 -6
- odxtools/nameditemlist.py +1 -1
- odxtools/negoutputparam.py +6 -6
- odxtools/odxcategory.py +12 -24
- odxtools/odxdoccontext.py +16 -0
- odxtools/odxlink.py +11 -12
- odxtools/odxtypes.py +3 -3
- odxtools/outputparam.py +7 -6
- odxtools/parameters/codedconstparameter.py +6 -6
- odxtools/parameters/createanyparameter.py +15 -15
- odxtools/parameters/dynamicparameter.py +4 -5
- odxtools/parameters/lengthkeyparameter.py +6 -6
- odxtools/parameters/matchingrequestparameter.py +4 -4
- odxtools/parameters/nrcconstparameter.py +8 -8
- odxtools/parameters/parameter.py +12 -13
- odxtools/parameters/parameterwithdop.py +9 -9
- odxtools/parameters/physicalconstantparameter.py +5 -4
- odxtools/parameters/reservedparameter.py +4 -5
- odxtools/parameters/systemparameter.py +4 -5
- odxtools/parameters/tableentryparameter.py +6 -6
- odxtools/parameters/tablekeyparameter.py +12 -12
- odxtools/parameters/tablestructparameter.py +9 -9
- odxtools/parameters/valueparameter.py +6 -6
- odxtools/paramlengthinfotype.py +6 -7
- odxtools/parentref.py +12 -10
- odxtools/physicaldimension.py +12 -12
- odxtools/physicaltype.py +5 -5
- odxtools/posresponsesuppressible.py +11 -11
- odxtools/preconditionstateref.py +8 -8
- odxtools/progcode.py +9 -8
- odxtools/protstack.py +8 -7
- odxtools/relateddiagcommref.py +5 -5
- odxtools/relateddoc.py +8 -7
- odxtools/request.py +12 -13
- odxtools/response.py +12 -13
- odxtools/scaleconstr.py +8 -8
- odxtools/singleecujob.py +14 -13
- odxtools/snrefcontext.py +1 -1
- odxtools/specialdata.py +6 -5
- odxtools/specialdatagroup.py +13 -13
- odxtools/specialdatagroupcaption.py +5 -4
- odxtools/standardlengthtype.py +5 -13
- odxtools/state.py +5 -4
- odxtools/statechart.py +10 -9
- odxtools/statemachine.py +2 -2
- odxtools/statetransition.py +7 -7
- odxtools/statetransitionref.py +11 -11
- odxtools/staticfield.py +5 -4
- odxtools/structure.py +5 -5
- odxtools/subcomponent.py +18 -16
- odxtools/subcomponentparamconnector.py +8 -7
- odxtools/subcomponentpattern.py +7 -7
- odxtools/swvariable.py +6 -6
- odxtools/table.py +20 -21
- odxtools/tablediagcommconnector.py +7 -6
- odxtools/tablerow.py +57 -36
- odxtools/tablerowconnector.py +6 -6
- odxtools/teammember.py +14 -13
- odxtools/templates/macros/printParentRef.xml.jinja2 +3 -1
- odxtools/text.py +4 -4
- odxtools/unit.py +9 -8
- odxtools/unitgroup.py +9 -8
- odxtools/unitspec.py +15 -16
- odxtools/variablegroup.py +4 -5
- odxtools/variantpattern.py +3 -4
- odxtools/version.py +2 -2
- odxtools/writepdxfile.py +0 -19
- odxtools/xdoc.py +11 -10
- {odxtools-10.0.0.dist-info → odxtools-10.1.1.dist-info}/METADATA +1 -1
- odxtools-10.1.1.dist-info/RECORD +265 -0
- {odxtools-10.0.0.dist-info → odxtools-10.1.1.dist-info}/WHEEL +1 -1
- odxtools-10.0.0.dist-info/RECORD +0 -264
- {odxtools-10.0.0.dist-info → odxtools-10.1.1.dist-info}/entry_points.txt +0 -0
- {odxtools-10.0.0.dist-info → odxtools-10.1.1.dist-info}/licenses/LICENSE +0 -0
- {odxtools-10.0.0.dist-info → odxtools-10.1.1.dist-info}/top_level.txt +0 -0
odxtools/response.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
2
|
+
from dataclasses import dataclass, field
|
3
3
|
from enum import Enum
|
4
4
|
from typing import Any, cast
|
5
5
|
from xml.etree import ElementTree
|
@@ -15,7 +15,8 @@ from .element import IdentifiableElement
|
|
15
15
|
from .encodestate import EncodeState
|
16
16
|
from .exceptions import odxraise
|
17
17
|
from .nameditemlist import NamedItemList
|
18
|
-
from .
|
18
|
+
from .odxdoccontext import OdxDocContext
|
19
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
19
20
|
from .odxtypes import ParameterValue, ParameterValueDict
|
20
21
|
from .parameters.createanyparameter import create_any_parameter_from_et
|
21
22
|
from .parameters.parameter import Parameter
|
@@ -30,7 +31,7 @@ class ResponseType(Enum):
|
|
30
31
|
GLOBAL_NEGATIVE = "GLOBAL-NEG-RESPONSE"
|
31
32
|
|
32
33
|
|
33
|
-
@dataclass
|
34
|
+
@dataclass(kw_only=True)
|
34
35
|
class Response(IdentifiableElement):
|
35
36
|
"""Represents all information related to an UDS response
|
36
37
|
|
@@ -39,14 +40,14 @@ class Response(IdentifiableElement):
|
|
39
40
|
|
40
41
|
response_type: ResponseType
|
41
42
|
|
42
|
-
admin_data: AdminData | None
|
43
|
-
parameters: NamedItemList[Parameter]
|
44
|
-
sdgs: list[SpecialDataGroup]
|
43
|
+
admin_data: AdminData | None = None
|
44
|
+
parameters: NamedItemList[Parameter] = field(default_factory=NamedItemList)
|
45
|
+
sdgs: list[SpecialDataGroup] = field(default_factory=list)
|
45
46
|
|
46
47
|
@staticmethod
|
47
|
-
def from_et(et_element: ElementTree.Element,
|
48
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Response":
|
48
49
|
"""Reads a response."""
|
49
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
50
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
50
51
|
|
51
52
|
try:
|
52
53
|
response_type = ResponseType(et_element.tag)
|
@@ -54,14 +55,12 @@ class Response(IdentifiableElement):
|
|
54
55
|
response_type = cast(ResponseType, None)
|
55
56
|
odxraise(f"Encountered unknown response type '{et_element.tag}'")
|
56
57
|
|
57
|
-
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"),
|
58
|
+
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), context)
|
58
59
|
parameters = NamedItemList([
|
59
|
-
create_any_parameter_from_et(et_parameter,
|
60
|
+
create_any_parameter_from_et(et_parameter, context)
|
60
61
|
for et_parameter in et_element.iterfind("PARAMS/PARAM")
|
61
62
|
])
|
62
|
-
sdgs = [
|
63
|
-
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
|
64
|
-
]
|
63
|
+
sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
|
65
64
|
|
66
65
|
return Response(
|
67
66
|
response_type=response_type,
|
odxtools/scaleconstr.py
CHANGED
@@ -5,32 +5,32 @@ from xml.etree import ElementTree
|
|
5
5
|
from .compumethods.limit import Limit
|
6
6
|
from .description import Description
|
7
7
|
from .exceptions import odxraise, odxrequire
|
8
|
-
from .
|
8
|
+
from .odxdoccontext import OdxDocContext
|
9
9
|
from .odxtypes import DataType
|
10
10
|
from .validtype import ValidType
|
11
11
|
|
12
12
|
|
13
|
-
@dataclass
|
13
|
+
@dataclass(kw_only=True)
|
14
14
|
class ScaleConstr:
|
15
15
|
"""This class represents a SCALE-CONSTR.
|
16
16
|
"""
|
17
17
|
|
18
|
-
short_label: str | None
|
19
|
-
description: Description | None
|
18
|
+
short_label: str | None = None
|
19
|
+
description: Description | None = None
|
20
20
|
lower_limit: Limit
|
21
21
|
upper_limit: Limit
|
22
22
|
validity: ValidType
|
23
23
|
value_type: DataType
|
24
24
|
|
25
25
|
@staticmethod
|
26
|
-
def scale_constr_from_et(et_element: ElementTree.Element,
|
26
|
+
def scale_constr_from_et(et_element: ElementTree.Element, context: OdxDocContext, *,
|
27
27
|
value_type: DataType) -> "ScaleConstr":
|
28
28
|
short_label = et_element.findtext("SHORT-LABEL")
|
29
|
-
description = Description.from_et(et_element.find("DESC"),
|
29
|
+
description = Description.from_et(et_element.find("DESC"), context)
|
30
30
|
lower_limit = Limit.limit_from_et(
|
31
|
-
odxrequire(et_element.find("LOWER-LIMIT")),
|
31
|
+
odxrequire(et_element.find("LOWER-LIMIT")), context, value_type=value_type)
|
32
32
|
upper_limit = Limit.limit_from_et(
|
33
|
-
odxrequire(et_element.find("UPPER-LIMIT")),
|
33
|
+
odxrequire(et_element.find("UPPER-LIMIT")), context, value_type=value_type)
|
34
34
|
|
35
35
|
validity_str = odxrequire(et_element.get("VALIDITY"))
|
36
36
|
try:
|
odxtools/singleecujob.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
2
|
+
from dataclasses import dataclass, field
|
3
3
|
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
@@ -7,14 +7,15 @@ from .diagcomm import DiagComm
|
|
7
7
|
from .inputparam import InputParam
|
8
8
|
from .nameditemlist import NamedItemList
|
9
9
|
from .negoutputparam import NegOutputParam
|
10
|
-
from .
|
10
|
+
from .odxdoccontext import OdxDocContext
|
11
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
11
12
|
from .outputparam import OutputParam
|
12
13
|
from .progcode import ProgCode
|
13
14
|
from .snrefcontext import SnRefContext
|
14
15
|
from .utils import dataclass_fields_asdict
|
15
16
|
|
16
17
|
|
17
|
-
@dataclass
|
18
|
+
@dataclass(kw_only=True)
|
18
19
|
class SingleEcuJob(DiagComm):
|
19
20
|
"""A single ECU job is a diagnostic communication primitive.
|
20
21
|
|
@@ -30,30 +31,30 @@ class SingleEcuJob(DiagComm):
|
|
30
31
|
standard.
|
31
32
|
"""
|
32
33
|
|
33
|
-
prog_codes: list[ProgCode]
|
34
|
-
input_params: NamedItemList[InputParam]
|
35
|
-
output_params: NamedItemList[OutputParam]
|
36
|
-
neg_output_params: NamedItemList[NegOutputParam]
|
34
|
+
prog_codes: list[ProgCode] = field(default_factory=list)
|
35
|
+
input_params: NamedItemList[InputParam] = field(default_factory=NamedItemList)
|
36
|
+
output_params: NamedItemList[OutputParam] = field(default_factory=NamedItemList)
|
37
|
+
neg_output_params: NamedItemList[NegOutputParam] = field(default_factory=NamedItemList)
|
37
38
|
|
38
39
|
@staticmethod
|
39
|
-
def from_et(et_element: ElementTree.Element,
|
40
|
-
kwargs = dataclass_fields_asdict(DiagComm.from_et(et_element,
|
40
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "SingleEcuJob":
|
41
|
+
kwargs = dataclass_fields_asdict(DiagComm.from_et(et_element, context))
|
41
42
|
|
42
43
|
prog_codes = [
|
43
|
-
ProgCode.from_et(pc_elem,
|
44
|
+
ProgCode.from_et(pc_elem, context)
|
44
45
|
for pc_elem in et_element.iterfind("PROG-CODES/PROG-CODE")
|
45
46
|
]
|
46
47
|
|
47
48
|
input_params = NamedItemList([
|
48
|
-
InputParam.from_et(el,
|
49
|
+
InputParam.from_et(el, context)
|
49
50
|
for el in et_element.iterfind("INPUT-PARAMS/INPUT-PARAM")
|
50
51
|
])
|
51
52
|
output_params = NamedItemList([
|
52
|
-
OutputParam.from_et(el,
|
53
|
+
OutputParam.from_et(el, context)
|
53
54
|
for el in et_element.iterfind("OUTPUT-PARAMS/OUTPUT-PARAM")
|
54
55
|
])
|
55
56
|
neg_output_params = NamedItemList([
|
56
|
-
NegOutputParam.from_et(el,
|
57
|
+
NegOutputParam.from_et(el, context)
|
57
58
|
for el in et_element.iterfind("NEG-OUTPUT-PARAMS/NEG-OUTPUT-PARAM")
|
58
59
|
])
|
59
60
|
|
odxtools/snrefcontext.py
CHANGED
odxtools/specialdata.py
CHANGED
@@ -3,19 +3,20 @@ from dataclasses import dataclass
|
|
3
3
|
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
|
-
from .
|
6
|
+
from .odxdoccontext import OdxDocContext
|
7
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
7
8
|
from .snrefcontext import SnRefContext
|
8
9
|
|
9
10
|
|
10
|
-
@dataclass
|
11
|
+
@dataclass(kw_only=True)
|
11
12
|
class SpecialData:
|
12
13
|
"""This corresponds to the SD XML tag"""
|
13
|
-
semantic_info: str | None # the "SI" attribute
|
14
|
-
text_identifier: str | None # the "TI" attribute, specifies the language used
|
14
|
+
semantic_info: str | None = None # the "SI" attribute
|
15
|
+
text_identifier: str | None = None # the "TI" attribute, specifies the language used
|
15
16
|
value: str
|
16
17
|
|
17
18
|
@staticmethod
|
18
|
-
def from_et(et_element: ElementTree.Element,
|
19
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "SpecialData":
|
19
20
|
semantic_info = et_element.get("SI")
|
20
21
|
text_identifier = et_element.get("TI")
|
21
22
|
value = et_element.text or ""
|
odxtools/specialdatagroup.py
CHANGED
@@ -1,33 +1,33 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
2
|
+
from dataclasses import dataclass, field
|
3
3
|
from typing import Any, Union
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
|
-
from .
|
6
|
+
from .odxdoccontext import OdxDocContext
|
7
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
7
8
|
from .snrefcontext import SnRefContext
|
8
9
|
from .specialdata import SpecialData
|
9
10
|
from .specialdatagroupcaption import SpecialDataGroupCaption
|
10
11
|
|
11
12
|
|
12
|
-
@dataclass
|
13
|
+
@dataclass(kw_only=True)
|
13
14
|
class SpecialDataGroup:
|
14
15
|
"""This corresponds to the SDG XML tag"""
|
15
|
-
sdg_caption: SpecialDataGroupCaption | None
|
16
|
-
sdg_caption_ref: OdxLinkRef | None
|
17
|
-
values: list[Union["SpecialDataGroup", SpecialData]]
|
18
|
-
semantic_info: str | None # the "SI" attribute
|
16
|
+
sdg_caption: SpecialDataGroupCaption | None = None
|
17
|
+
sdg_caption_ref: OdxLinkRef | None = None
|
18
|
+
values: list[Union["SpecialDataGroup", SpecialData]] = field(default_factory=list)
|
19
|
+
semantic_info: str | None = None # the "SI" attribute
|
19
20
|
|
20
21
|
@staticmethod
|
21
|
-
def from_et(et_element: ElementTree.Element,
|
22
|
-
doc_frags: list[OdxDocFragment]) -> "SpecialDataGroup":
|
22
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "SpecialDataGroup":
|
23
23
|
|
24
24
|
sdg_caption = None
|
25
25
|
if caption_elem := et_element.find("SDG-CAPTION"):
|
26
|
-
sdg_caption = SpecialDataGroupCaption.from_et(caption_elem,
|
26
|
+
sdg_caption = SpecialDataGroupCaption.from_et(caption_elem, context)
|
27
27
|
|
28
28
|
sdg_caption_ref = None
|
29
29
|
if (caption_ref_elem := et_element.find("SDG-CAPTION-REF")) is not None:
|
30
|
-
sdg_caption_ref = OdxLinkRef.from_et(caption_ref_elem,
|
30
|
+
sdg_caption_ref = OdxLinkRef.from_et(caption_ref_elem, context)
|
31
31
|
|
32
32
|
semantic_info = et_element.get("SI")
|
33
33
|
|
@@ -35,9 +35,9 @@ class SpecialDataGroup:
|
|
35
35
|
for value_elem in et_element:
|
36
36
|
next_entry: SpecialData | SpecialDataGroup | None = None
|
37
37
|
if value_elem.tag == "SDG":
|
38
|
-
next_entry = SpecialDataGroup.from_et(value_elem,
|
38
|
+
next_entry = SpecialDataGroup.from_et(value_elem, context)
|
39
39
|
elif value_elem.tag == "SD":
|
40
|
-
next_entry = SpecialData.from_et(value_elem,
|
40
|
+
next_entry = SpecialData.from_et(value_elem, context)
|
41
41
|
|
42
42
|
if next_entry is not None:
|
43
43
|
values.append(next_entry)
|
@@ -4,18 +4,19 @@ from typing import Any
|
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import IdentifiableElement
|
7
|
-
from .
|
7
|
+
from .odxdoccontext import OdxDocContext
|
8
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
8
9
|
from .snrefcontext import SnRefContext
|
9
10
|
from .utils import dataclass_fields_asdict
|
10
11
|
|
11
12
|
|
12
|
-
@dataclass
|
13
|
+
@dataclass(kw_only=True)
|
13
14
|
class SpecialDataGroupCaption(IdentifiableElement):
|
14
15
|
|
15
16
|
@staticmethod
|
16
17
|
def from_et(et_element: ElementTree.Element,
|
17
|
-
|
18
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
18
|
+
context: OdxDocContext) -> "SpecialDataGroupCaption":
|
19
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
19
20
|
|
20
21
|
return SpecialDataGroupCaption(**kwargs)
|
21
22
|
|
odxtools/standardlengthtype.py
CHANGED
@@ -9,7 +9,7 @@ from .decodestate import DecodeState
|
|
9
9
|
from .diagcodedtype import DctType, DiagCodedType
|
10
10
|
from .encodestate import EncodeState
|
11
11
|
from .exceptions import odxassert, odxraise, odxrequire
|
12
|
-
from .
|
12
|
+
from .odxdoccontext import OdxDocContext
|
13
13
|
from .odxtypes import AtomicOdxType, BytesTypes, DataType, odxstr_to_bool
|
14
14
|
from .utils import dataclass_fields_asdict, read_hex_binary
|
15
15
|
|
@@ -31,9 +31,8 @@ class StandardLengthType(DiagCodedType):
|
|
31
31
|
|
32
32
|
@staticmethod
|
33
33
|
@override
|
34
|
-
def from_et(et_element: ElementTree.Element,
|
35
|
-
|
36
|
-
kwargs = dataclass_fields_asdict(DiagCodedType.from_et(et_element, doc_frags))
|
34
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "StandardLengthType":
|
35
|
+
kwargs = dataclass_fields_asdict(DiagCodedType.from_et(et_element, context))
|
37
36
|
|
38
37
|
bit_length = int(odxrequire(et_element.findtext("BIT-LENGTH")))
|
39
38
|
bit_mask = read_hex_binary(et_element.find("BIT-MASK"))
|
@@ -72,11 +71,7 @@ class StandardLengthType(DiagCodedType):
|
|
72
71
|
if self.is_condensed:
|
73
72
|
# if a condensed bitmask is specified, the number of bits
|
74
73
|
# set to one in the bit mask are used in the PDU
|
75
|
-
|
76
|
-
# TODO: this is pretty slow. replace it by
|
77
|
-
# `self.bit_mask.bit_count()` once we require python >=
|
78
|
-
# 3.10.
|
79
|
-
bit_sz = bin(self.bit_mask).count("1")
|
74
|
+
bit_sz = self.bit_mask.bit_count()
|
80
75
|
used_mask = (1 << bit_sz) - 1
|
81
76
|
|
82
77
|
return used_mask.to_bytes((bit_sz + 7) // 8, endianness)
|
@@ -171,10 +166,7 @@ class StandardLengthType(DiagCodedType):
|
|
171
166
|
|
172
167
|
def get_static_bit_length(self) -> int | None:
|
173
168
|
if self.bit_mask is not None and self.is_condensed:
|
174
|
-
|
175
|
-
# `self.bit_mask.bit_count()` once we require python >=
|
176
|
-
# 3.10.
|
177
|
-
return bin(self.bit_mask).count("1")
|
169
|
+
return self.bit_mask.bit_count()
|
178
170
|
|
179
171
|
return self.bit_length
|
180
172
|
|
odxtools/state.py
CHANGED
@@ -4,20 +4,21 @@ from typing import Any
|
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import IdentifiableElement
|
7
|
-
from .
|
7
|
+
from .odxdoccontext import OdxDocContext
|
8
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
8
9
|
from .snrefcontext import SnRefContext
|
9
10
|
from .utils import dataclass_fields_asdict
|
10
11
|
|
11
12
|
|
12
|
-
@dataclass
|
13
|
+
@dataclass(kw_only=True)
|
13
14
|
class State(IdentifiableElement):
|
14
15
|
"""
|
15
16
|
Corresponds to STATE.
|
16
17
|
"""
|
17
18
|
|
18
19
|
@staticmethod
|
19
|
-
def from_et(et_element: ElementTree.Element,
|
20
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
20
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "State":
|
21
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
21
22
|
|
22
23
|
return State(**kwargs)
|
23
24
|
|
odxtools/statechart.py
CHANGED
@@ -1,40 +1,41 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
2
|
+
from dataclasses import dataclass, field
|
3
3
|
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import IdentifiableElement
|
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, resolve_snref
|
10
11
|
from .snrefcontext import SnRefContext
|
11
12
|
from .state import State
|
12
13
|
from .statetransition import StateTransition
|
13
14
|
from .utils import dataclass_fields_asdict
|
14
15
|
|
15
16
|
|
16
|
-
@dataclass
|
17
|
+
@dataclass(kw_only=True)
|
17
18
|
class StateChart(IdentifiableElement):
|
18
19
|
"""
|
19
20
|
Corresponds to STATE-CHART.
|
20
21
|
"""
|
21
22
|
semantic: str
|
22
|
-
state_transitions: list[StateTransition]
|
23
|
+
state_transitions: list[StateTransition] = field(default_factory=list)
|
23
24
|
start_state_snref: str
|
24
|
-
states: NamedItemList[State]
|
25
|
+
states: NamedItemList[State] = field(default_factory=NamedItemList)
|
25
26
|
|
26
27
|
@property
|
27
28
|
def start_state(self) -> State:
|
28
29
|
return self._start_state
|
29
30
|
|
30
31
|
@staticmethod
|
31
|
-
def from_et(et_element: ElementTree.Element,
|
32
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
32
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "StateChart":
|
33
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
33
34
|
|
34
35
|
semantic: str = odxrequire(et_element.findtext("SEMANTIC"))
|
35
36
|
|
36
37
|
state_transitions = [
|
37
|
-
StateTransition.from_et(st_elem,
|
38
|
+
StateTransition.from_et(st_elem, context)
|
38
39
|
for st_elem in et_element.iterfind("STATE-TRANSITIONS/STATE-TRANSITION")
|
39
40
|
]
|
40
41
|
|
@@ -42,7 +43,7 @@ class StateChart(IdentifiableElement):
|
|
42
43
|
start_state_snref = start_state_snref_elem.attrib["SHORT-NAME"]
|
43
44
|
|
44
45
|
states = [
|
45
|
-
State.from_et(st_elem,
|
46
|
+
State.from_et(st_elem, context) for st_elem in et_element.iterfind("STATES/STATE")
|
46
47
|
]
|
47
48
|
|
48
49
|
return StateChart(
|
odxtools/statemachine.py
CHANGED
@@ -13,7 +13,7 @@ if TYPE_CHECKING:
|
|
13
13
|
from .diagservice import DiagService
|
14
14
|
|
15
15
|
|
16
|
-
@dataclass
|
16
|
+
@dataclass(kw_only=True)
|
17
17
|
class StateMachine:
|
18
18
|
"""Objects of this class represent the runtime state of a state chart
|
19
19
|
|
@@ -160,7 +160,7 @@ class StateMachine:
|
|
160
160
|
|
161
161
|
if raw_resp is None:
|
162
162
|
raise RuntimeError("The calling code must send back a reply")
|
163
|
-
elif isinstance(raw_resp, bytes
|
163
|
+
elif isinstance(raw_resp, (bytes, bytearray)):
|
164
164
|
for decoded_resp_msg in self.diag_layer.decode_response(raw_resp, raw_req):
|
165
165
|
for stransref in service.state_transition_refs:
|
166
166
|
# we only execute the first applicable state
|
odxtools/statetransition.py
CHANGED
@@ -6,20 +6,21 @@ from xml.etree import ElementTree
|
|
6
6
|
from .element import IdentifiableElement
|
7
7
|
from .exceptions import odxrequire
|
8
8
|
from .externalaccessmethod import ExternalAccessMethod
|
9
|
-
from .
|
9
|
+
from .odxdoccontext import OdxDocContext
|
10
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, resolve_snref
|
10
11
|
from .snrefcontext import SnRefContext
|
11
12
|
from .state import State
|
12
13
|
from .utils import dataclass_fields_asdict
|
13
14
|
|
14
15
|
|
15
|
-
@dataclass
|
16
|
+
@dataclass(kw_only=True)
|
16
17
|
class StateTransition(IdentifiableElement):
|
17
18
|
"""
|
18
19
|
Corresponds to STATE-TRANSITION.
|
19
20
|
"""
|
20
21
|
source_snref: str
|
21
22
|
target_snref: str
|
22
|
-
external_access_method: ExternalAccessMethod | None
|
23
|
+
external_access_method: ExternalAccessMethod | None = None
|
23
24
|
|
24
25
|
@property
|
25
26
|
def source_state(self) -> State:
|
@@ -30,10 +31,9 @@ class StateTransition(IdentifiableElement):
|
|
30
31
|
return self._target_state
|
31
32
|
|
32
33
|
@staticmethod
|
33
|
-
def from_et(et_element: ElementTree.Element,
|
34
|
-
doc_frags: list[OdxDocFragment]) -> "StateTransition":
|
34
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "StateTransition":
|
35
35
|
|
36
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
36
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
37
37
|
|
38
38
|
source_snref_elem = odxrequire(et_element.find("SOURCE-SNREF"))
|
39
39
|
source_snref = odxrequire(source_snref_elem.attrib["SHORT-NAME"])
|
@@ -43,7 +43,7 @@ class StateTransition(IdentifiableElement):
|
|
43
43
|
|
44
44
|
external_access_method = None
|
45
45
|
if (eam_elem := et_element.find("EXTERNAL-ACCESS-METHOD")) is not None:
|
46
|
-
external_access_method = ExternalAccessMethod.from_et(eam_elem,
|
46
|
+
external_access_method = ExternalAccessMethod.from_et(eam_elem, context)
|
47
47
|
return StateTransition(
|
48
48
|
source_snref=source_snref,
|
49
49
|
target_snref=target_snref,
|
odxtools/statetransitionref.py
CHANGED
@@ -6,7 +6,8 @@ from xml.etree import ElementTree
|
|
6
6
|
from .basicstructure import BasicStructure
|
7
7
|
from .dataobjectproperty import DataObjectProperty
|
8
8
|
from .exceptions import odxassert, odxraise, odxrequire
|
9
|
-
from .
|
9
|
+
from .odxdoccontext import OdxDocContext
|
10
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
|
10
11
|
from .odxtypes import ParameterValue, ParameterValueDict
|
11
12
|
from .parameters.codedconstparameter import CodedConstParameter
|
12
13
|
from .parameters.parameter import Parameter
|
@@ -108,13 +109,13 @@ def _check_applies(ref: Union["StateTransitionRef",
|
|
108
109
|
return False
|
109
110
|
elif not isinstance(
|
110
111
|
param,
|
111
|
-
|
112
|
+
(CodedConstParameter, PhysicalConstantParameter, TableKeyParameter, ValueParameter)):
|
112
113
|
# see checker rule 194 in section B.2 of the spec
|
113
114
|
odxraise(f"Parameter referenced by state transition ref is of "
|
114
115
|
f"invalid type {type(param).__name__}")
|
115
116
|
return False
|
116
|
-
elif isinstance(param, CodedConstParameter
|
117
|
-
|
117
|
+
elif isinstance(param, (CodedConstParameter, PhysicalConstantParameter,
|
118
|
+
TableKeyParameter)) and ref.value is not None:
|
118
119
|
# see checker rule 193 in section B.2 of the spec. Why can
|
119
120
|
# no values for constant parameters be specified? (This
|
120
121
|
# seems to be rather inconvenient...)
|
@@ -146,7 +147,7 @@ def _check_applies(ref: Union["StateTransitionRef",
|
|
146
147
|
return True
|
147
148
|
|
148
149
|
|
149
|
-
@dataclass
|
150
|
+
@dataclass(kw_only=True)
|
150
151
|
class StateTransitionRef(OdxLinkRef):
|
151
152
|
"""Describes a state transition that is to be potentially taken if
|
152
153
|
a diagnostic communication is executed
|
@@ -155,10 +156,10 @@ class StateTransitionRef(OdxLinkRef):
|
|
155
156
|
may also be conditional on the observed response of the ECU.
|
156
157
|
|
157
158
|
"""
|
158
|
-
value: str | None
|
159
|
+
value: str | None = None
|
159
160
|
|
160
|
-
in_param_if_snref: str | None
|
161
|
-
in_param_if_snpathref: str | None
|
161
|
+
in_param_if_snref: str | None = None
|
162
|
+
in_param_if_snpathref: str | None = None
|
162
163
|
|
163
164
|
@property
|
164
165
|
def state_transition(self) -> StateTransition:
|
@@ -170,9 +171,8 @@ class StateTransitionRef(OdxLinkRef):
|
|
170
171
|
|
171
172
|
@staticmethod
|
172
173
|
def from_et( # type: ignore[override]
|
173
|
-
et_element: ElementTree.Element,
|
174
|
-
|
175
|
-
kwargs = dataclass_fields_asdict(OdxLinkRef.from_et(et_element, doc_frags))
|
174
|
+
et_element: ElementTree.Element, context: OdxDocContext) -> "StateTransitionRef":
|
175
|
+
kwargs = dataclass_fields_asdict(OdxLinkRef.from_et(et_element, context))
|
176
176
|
|
177
177
|
value = et_element.findtext("VALUE")
|
178
178
|
|
odxtools/staticfield.py
CHANGED
@@ -10,13 +10,14 @@ from .decodestate import DecodeState
|
|
10
10
|
from .encodestate import EncodeState
|
11
11
|
from .exceptions import odxassert, odxraise, odxrequire
|
12
12
|
from .field import Field
|
13
|
-
from .
|
13
|
+
from .odxdoccontext import OdxDocContext
|
14
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
14
15
|
from .odxtypes import ParameterValue
|
15
16
|
from .snrefcontext import SnRefContext
|
16
17
|
from .utils import dataclass_fields_asdict
|
17
18
|
|
18
19
|
|
19
|
-
@dataclass
|
20
|
+
@dataclass(kw_only=True)
|
20
21
|
class StaticField(Field):
|
21
22
|
"""Array of a fixed number of structure objects"""
|
22
23
|
fixed_number_of_items: int
|
@@ -24,8 +25,8 @@ class StaticField(Field):
|
|
24
25
|
|
25
26
|
@staticmethod
|
26
27
|
@override
|
27
|
-
def from_et(et_element: ElementTree.Element,
|
28
|
-
kwargs = dataclass_fields_asdict(Field.from_et(et_element,
|
28
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "StaticField":
|
29
|
+
kwargs = dataclass_fields_asdict(Field.from_et(et_element, context))
|
29
30
|
|
30
31
|
fixed_number_of_items = int(odxrequire(et_element.findtext('FIXED-NUMBER-OF-ITEMS')))
|
31
32
|
item_byte_size = int(odxrequire(et_element.findtext('ITEM-BYTE-SIZE')))
|
odxtools/structure.py
CHANGED
@@ -3,23 +3,23 @@ from dataclasses import dataclass
|
|
3
3
|
from xml.etree import ElementTree
|
4
4
|
|
5
5
|
from .basicstructure import BasicStructure
|
6
|
-
from .
|
6
|
+
from .odxdoccontext import OdxDocContext
|
7
7
|
from .odxtypes import odxstr_to_bool
|
8
8
|
from .utils import dataclass_fields_asdict
|
9
9
|
|
10
10
|
|
11
|
-
@dataclass
|
11
|
+
@dataclass(kw_only=True)
|
12
12
|
class Structure(BasicStructure):
|
13
|
-
is_visible_raw: bool | None
|
13
|
+
is_visible_raw: bool | None = None
|
14
14
|
|
15
15
|
@property
|
16
16
|
def is_visible(self) -> bool:
|
17
17
|
return self.is_visible_raw in (True, None)
|
18
18
|
|
19
19
|
@staticmethod
|
20
|
-
def from_et(et_element: ElementTree.Element,
|
20
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Structure":
|
21
21
|
"""Read a STRUCTURE element from XML."""
|
22
|
-
kwargs = dataclass_fields_asdict(BasicStructure.from_et(et_element,
|
22
|
+
kwargs = dataclass_fields_asdict(BasicStructure.from_et(et_element, context))
|
23
23
|
|
24
24
|
is_visible_raw = odxstr_to_bool(et_element.get("IS-VISIBLE"))
|
25
25
|
|