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
odxtools/table.py
CHANGED
@@ -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 .admindata import AdminData
|
@@ -8,7 +8,8 @@ from .dataobjectproperty import DataObjectProperty
|
|
8
8
|
from .element import IdentifiableElement
|
9
9
|
from .exceptions import odxassert
|
10
10
|
from .nameditemlist import NamedItemList
|
11
|
-
from .
|
11
|
+
from .odxdoccontext import OdxDocContext
|
12
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
12
13
|
from .snrefcontext import SnRefContext
|
13
14
|
from .specialdatagroup import SpecialDataGroup
|
14
15
|
from .tablediagcommconnector import TableDiagCommConnector
|
@@ -16,20 +17,20 @@ from .tablerow import TableRow
|
|
16
17
|
from .utils import dataclass_fields_asdict
|
17
18
|
|
18
19
|
|
19
|
-
@dataclass
|
20
|
+
@dataclass(kw_only=True)
|
20
21
|
class Table(IdentifiableElement):
|
21
22
|
"""This class represents a TABLE."""
|
22
|
-
key_label:
|
23
|
-
struct_label:
|
24
|
-
admin_data:
|
25
|
-
key_dop_ref:
|
26
|
-
table_rows_raw:
|
27
|
-
table_diag_comm_connectors:
|
28
|
-
sdgs:
|
29
|
-
semantic:
|
23
|
+
key_label: str | None = None
|
24
|
+
struct_label: str | None = None
|
25
|
+
admin_data: AdminData | None = None
|
26
|
+
key_dop_ref: OdxLinkRef | None = None
|
27
|
+
table_rows_raw: list[TableRow | OdxLinkRef] = field(default_factory=list)
|
28
|
+
table_diag_comm_connectors: list[TableDiagCommConnector] = field(default_factory=list)
|
29
|
+
sdgs: list[SpecialDataGroup] = field(default_factory=list)
|
30
|
+
semantic: str | None = None
|
30
31
|
|
31
32
|
@property
|
32
|
-
def key_dop(self) ->
|
33
|
+
def key_dop(self) -> DataObjectProperty | None:
|
33
34
|
"""The key data object property associated with this table."""
|
34
35
|
return self._key_dop
|
35
36
|
|
@@ -39,31 +40,29 @@ class Table(IdentifiableElement):
|
|
39
40
|
return self._table_rows
|
40
41
|
|
41
42
|
@staticmethod
|
42
|
-
def from_et(et_element: ElementTree.Element,
|
43
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Table":
|
43
44
|
"""Reads a TABLE."""
|
44
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
45
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
45
46
|
odx_id = kwargs["odx_id"]
|
46
47
|
key_label = et_element.findtext("KEY-LABEL")
|
47
48
|
struct_label = et_element.findtext("STRUCT-LABEL")
|
48
|
-
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"),
|
49
|
-
key_dop_ref = OdxLinkRef.from_et(et_element.find("KEY-DOP-REF"),
|
49
|
+
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), context)
|
50
|
+
key_dop_ref = OdxLinkRef.from_et(et_element.find("KEY-DOP-REF"), context)
|
50
51
|
|
51
|
-
table_rows_raw:
|
52
|
+
table_rows_raw: list[OdxLinkRef | TableRow] = []
|
52
53
|
for sub_elem in et_element:
|
53
54
|
if sub_elem.tag == "TABLE-ROW":
|
54
55
|
table_rows_raw.append(
|
55
56
|
TableRow.tablerow_from_et(
|
56
|
-
sub_elem,
|
57
|
+
sub_elem, context, table_ref=OdxLinkRef.from_id(odx_id)))
|
57
58
|
elif sub_elem.tag == "TABLE-ROW-REF":
|
58
|
-
table_rows_raw.append(OdxLinkRef.from_et(sub_elem,
|
59
|
+
table_rows_raw.append(OdxLinkRef.from_et(sub_elem, context))
|
59
60
|
|
60
61
|
table_diag_comm_connectors = [
|
61
|
-
TableDiagCommConnector.from_et(dcc_elem,
|
62
|
+
TableDiagCommConnector.from_et(dcc_elem, context) for dcc_elem in et_element.iterfind(
|
62
63
|
"TABLE-DIAG-COMM-CONNECTORS/TABLE-DIAG-COMM-CONNECTOR")
|
63
64
|
]
|
64
|
-
sdgs = [
|
65
|
-
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
|
66
|
-
]
|
65
|
+
sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
|
67
66
|
semantic = et_element.get("SEMANTIC")
|
68
67
|
|
69
68
|
return Table(
|
@@ -77,7 +76,7 @@ class Table(IdentifiableElement):
|
|
77
76
|
semantic=semantic,
|
78
77
|
**kwargs)
|
79
78
|
|
80
|
-
def _build_odxlinks(self) ->
|
79
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
81
80
|
result = {self.odx_id: self}
|
82
81
|
|
83
82
|
for table_row_wrapper in self.table_rows_raw:
|
@@ -93,7 +92,7 @@ class Table(IdentifiableElement):
|
|
93
92
|
return result
|
94
93
|
|
95
94
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
96
|
-
self._key_dop:
|
95
|
+
self._key_dop: DataObjectProperty | None = None
|
97
96
|
if self.key_dop_ref is not None:
|
98
97
|
self._key_dop = odxlinks.resolve(self.key_dop_ref, DataObjectProperty)
|
99
98
|
|
@@ -1,20 +1,21 @@
|
|
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 .diagcomm import DiagComm
|
7
7
|
from .exceptions import odxrequire
|
8
|
-
from .
|
8
|
+
from .odxdoccontext import OdxDocContext
|
9
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
|
9
10
|
from .snrefcontext import SnRefContext
|
10
11
|
|
11
12
|
|
12
|
-
@dataclass
|
13
|
+
@dataclass(kw_only=True)
|
13
14
|
class TableDiagCommConnector:
|
14
15
|
semantic: str
|
15
16
|
|
16
|
-
diag_comm_ref:
|
17
|
-
diag_comm_snref:
|
17
|
+
diag_comm_ref: OdxLinkRef | None = None
|
18
|
+
diag_comm_snref: str | None = None
|
18
19
|
|
19
20
|
@property
|
20
21
|
def diag_comm(self) -> DiagComm:
|
@@ -22,11 +23,11 @@ class TableDiagCommConnector:
|
|
22
23
|
|
23
24
|
@staticmethod
|
24
25
|
def from_et(et_element: ElementTree.Element,
|
25
|
-
|
26
|
+
context: OdxDocContext) -> "TableDiagCommConnector":
|
26
27
|
|
27
28
|
semantic = odxrequire(et_element.findtext("SEMANTIC"))
|
28
29
|
|
29
|
-
diag_comm_ref = OdxLinkRef.from_et(et_element.find("DIAG-COMM-REF"),
|
30
|
+
diag_comm_ref = OdxLinkRef.from_et(et_element.find("DIAG-COMM-REF"), context)
|
30
31
|
diag_comm_snref = None
|
31
32
|
if (dc_snref_elem := et_element.find("DIAG-COMM-SNREF")) is not None:
|
32
33
|
diag_comm_snref = odxrequire(dc_snref_elem.get("SHORT-NAME"))
|
@@ -34,7 +35,7 @@ class TableDiagCommConnector:
|
|
34
35
|
return TableDiagCommConnector(
|
35
36
|
semantic=semantic, diag_comm_ref=diag_comm_ref, diag_comm_snref=diag_comm_snref)
|
36
37
|
|
37
|
-
def _build_odxlinks(self) ->
|
38
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
38
39
|
return {}
|
39
40
|
|
40
41
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/tablerow.py
CHANGED
@@ -1,6 +1,6 @@
|
|
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, cast
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .admindata import AdminData
|
@@ -11,7 +11,8 @@ from .element import IdentifiableElement
|
|
11
11
|
from .exceptions import odxassert, odxraise, odxrequire
|
12
12
|
from .functionalclass import FunctionalClass
|
13
13
|
from .nameditemlist import NamedItemList
|
14
|
-
from .
|
14
|
+
from .odxdoccontext import OdxDocContext
|
15
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
|
15
16
|
from .odxtypes import AtomicOdxType, odxstr_to_bool
|
16
17
|
from .preconditionstateref import PreConditionStateRef
|
17
18
|
from .snrefcontext import SnRefContext
|
@@ -24,7 +25,7 @@ if TYPE_CHECKING:
|
|
24
25
|
from .table import Table
|
25
26
|
|
26
27
|
|
27
|
-
@dataclass
|
28
|
+
@dataclass(kw_only=True)
|
28
29
|
class TableRow(IdentifiableElement):
|
29
30
|
"""This class represents a TABLE-ROW."""
|
30
31
|
table_ref: OdxLinkRef
|
@@ -33,22 +34,22 @@ class TableRow(IdentifiableElement):
|
|
33
34
|
# The spec mandates that either a structure or a non-complex DOP
|
34
35
|
# must be referenced here, i.e., exactly one of the four
|
35
36
|
# attributes below is not None
|
36
|
-
dop_ref:
|
37
|
-
dop_snref:
|
38
|
-
structure_ref:
|
39
|
-
structure_snref:
|
40
|
-
|
41
|
-
sdgs:
|
42
|
-
audience:
|
43
|
-
functional_class_refs:
|
44
|
-
state_transition_refs:
|
45
|
-
pre_condition_state_refs:
|
46
|
-
admin_data:
|
47
|
-
|
48
|
-
is_executable_raw:
|
49
|
-
semantic:
|
50
|
-
is_mandatory_raw:
|
51
|
-
is_final_raw:
|
37
|
+
dop_ref: OdxLinkRef | None = None
|
38
|
+
dop_snref: str | None = None
|
39
|
+
structure_ref: OdxLinkRef | None = None
|
40
|
+
structure_snref: str | None = None
|
41
|
+
|
42
|
+
sdgs: list[SpecialDataGroup] = field(default_factory=list)
|
43
|
+
audience: Audience | None = None
|
44
|
+
functional_class_refs: list[OdxLinkRef] = field(default_factory=list)
|
45
|
+
state_transition_refs: list[StateTransitionRef] = field(default_factory=list)
|
46
|
+
pre_condition_state_refs: list[PreConditionStateRef] = field(default_factory=list)
|
47
|
+
admin_data: AdminData | None = None
|
48
|
+
|
49
|
+
is_executable_raw: bool | None = None
|
50
|
+
semantic: str | None = None
|
51
|
+
is_mandatory_raw: bool | None = None
|
52
|
+
is_final_raw: bool | None = None
|
52
53
|
|
53
54
|
@property
|
54
55
|
def table(self) -> "Table":
|
@@ -57,16 +58,16 @@ class TableRow(IdentifiableElement):
|
|
57
58
|
# the value of the key expressed in the type represented by the
|
58
59
|
# referenced DOP
|
59
60
|
@property
|
60
|
-
def key(self) ->
|
61
|
+
def key(self) -> AtomicOdxType | None:
|
61
62
|
return self._key
|
62
63
|
|
63
64
|
@property
|
64
|
-
def dop(self) ->
|
65
|
+
def dop(self) -> DataObjectProperty | None:
|
65
66
|
"""The data object property object resolved by dop_ref."""
|
66
67
|
return self._dop
|
67
68
|
|
68
69
|
@property
|
69
|
-
def structure(self) ->
|
70
|
+
def structure(self) -> Structure | None:
|
70
71
|
"""The structure associated with this table row."""
|
71
72
|
return self._structure
|
72
73
|
|
@@ -87,52 +88,50 @@ class TableRow(IdentifiableElement):
|
|
87
88
|
return self.is_final_raw is True
|
88
89
|
|
89
90
|
@staticmethod
|
90
|
-
def from_et(et_element: ElementTree.Element,
|
91
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> Any:
|
91
92
|
raise RuntimeError(
|
92
93
|
"Calling TableRow.from_et() is not allowed. Use TableRow.tablerow_from_et().")
|
93
94
|
|
94
95
|
@staticmethod
|
95
|
-
def tablerow_from_et(et_element: ElementTree.Element,
|
96
|
+
def tablerow_from_et(et_element: ElementTree.Element, context: OdxDocContext, *,
|
96
97
|
table_ref: OdxLinkRef) -> "TableRow":
|
97
98
|
"""Reads a TABLE-ROW."""
|
98
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
99
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
99
100
|
|
100
101
|
key_raw = odxrequire(et_element.findtext("KEY"))
|
101
102
|
|
102
|
-
dop_ref = OdxLinkRef.from_et(et_element.find("DATA-OBJECT-PROP-REF"),
|
103
|
-
dop_snref:
|
103
|
+
dop_ref = OdxLinkRef.from_et(et_element.find("DATA-OBJECT-PROP-REF"), context)
|
104
|
+
dop_snref: str | None = None
|
104
105
|
if (dop_snref_elem := et_element.find("DATA-OBJECT-PROP-SNREF")) is not None:
|
105
106
|
dop_snref = dop_snref_elem.attrib["SHORT-NAME"]
|
106
107
|
|
107
|
-
structure_ref = OdxLinkRef.from_et(et_element.find("STRUCTURE-REF"),
|
108
|
-
structure_snref:
|
108
|
+
structure_ref = OdxLinkRef.from_et(et_element.find("STRUCTURE-REF"), context)
|
109
|
+
structure_snref: str | None = None
|
109
110
|
if (structure_snref_elem := et_element.find("STRUCTURE-SNREF")) is not None:
|
110
111
|
structure_snref = structure_snref_elem.attrib["SHORT-NAME"]
|
111
112
|
|
112
|
-
sdgs = [
|
113
|
-
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
|
114
|
-
]
|
113
|
+
sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
|
115
114
|
|
116
115
|
audience = None
|
117
116
|
if (audience_elem := et_element.find("AUDIENCE")) is not None:
|
118
|
-
audience = Audience.from_et(audience_elem,
|
117
|
+
audience = Audience.from_et(audience_elem, context)
|
119
118
|
|
120
119
|
functional_class_refs = [
|
121
|
-
odxrequire(OdxLinkRef.from_et(el,
|
120
|
+
odxrequire(OdxLinkRef.from_et(el, context))
|
122
121
|
for el in et_element.iterfind("FUNCT-CLASS-REFS/FUNCT-CLASS-REF")
|
123
122
|
]
|
124
123
|
|
125
124
|
state_transition_refs = [
|
126
|
-
StateTransitionRef.from_et(el,
|
125
|
+
StateTransitionRef.from_et(el, context)
|
127
126
|
for el in et_element.iterfind("STATE-TRANSITION-REFS/STATE-TRANSITION-REF")
|
128
127
|
]
|
129
128
|
|
130
129
|
pre_condition_state_refs = [
|
131
|
-
PreConditionStateRef.from_et(el,
|
130
|
+
PreConditionStateRef.from_et(el, context)
|
132
131
|
for el in et_element.iterfind("PRE-CONDITION-STATE-REFS/PRE-CONDITION-STATE-REF")
|
133
132
|
]
|
134
133
|
|
135
|
-
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"),
|
134
|
+
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), context)
|
136
135
|
|
137
136
|
is_executable_raw = odxstr_to_bool(et_element.attrib.get("IS-EXECUTABLE"))
|
138
137
|
semantic = et_element.attrib.get("SEMANTIC")
|
@@ -159,8 +158,8 @@ class TableRow(IdentifiableElement):
|
|
159
158
|
**kwargs)
|
160
159
|
|
161
160
|
def __post_init__(self) -> None:
|
162
|
-
self._dop:
|
163
|
-
self._structure:
|
161
|
+
self._dop: DataObjectProperty | None = None
|
162
|
+
self._structure: Structure | None = None
|
164
163
|
|
165
164
|
n = sum([0 if x is None else 1 for x in (self.dop_ref, self.dop_snref)])
|
166
165
|
odxassert(
|
@@ -174,7 +173,7 @@ class TableRow(IdentifiableElement):
|
|
174
173
|
f"Table row {self.short_name}: The structure can either be defined using ODXLINK or SNREF but not both."
|
175
174
|
)
|
176
175
|
|
177
|
-
def _build_odxlinks(self) ->
|
176
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
178
177
|
result = {self.odx_id: self}
|
179
178
|
|
180
179
|
for sdg in self.sdgs:
|
@@ -258,7 +257,29 @@ class TableRow(IdentifiableElement):
|
|
258
257
|
for pc_ref in self.pre_condition_state_refs:
|
259
258
|
pc_ref._resolve_snrefs(context)
|
260
259
|
|
261
|
-
def __reduce__(self) ->
|
260
|
+
def __reduce__(self) -> tuple[Any, ...]:
|
262
261
|
"""This ensures that the object can be correctly reconstructed during unpickling."""
|
263
262
|
state = self.__dict__.copy()
|
264
|
-
return
|
263
|
+
return _reconstruct_tablerow, (self.__class__, state)
|
264
|
+
|
265
|
+
def __setstate__(self, state: dict[str, Any]) -> None:
|
266
|
+
"""
|
267
|
+
Restore the object's internal state.
|
268
|
+
|
269
|
+
This method is called during the unpickling, it updates
|
270
|
+
the instance's __dict__ with the saved state.
|
271
|
+
"""
|
272
|
+
self.__dict__.update(state)
|
273
|
+
|
274
|
+
|
275
|
+
def _reconstruct_tablerow(cls: Any, state: dict[str, Any]) -> TableRow:
|
276
|
+
"""
|
277
|
+
Reconstruct a TableRow instance from pickled state.
|
278
|
+
|
279
|
+
This function is used during unpickling to bypass the `__init__`
|
280
|
+
constructor, which would normally enforce `kw_only=True` arguments.
|
281
|
+
Instead, it creates an uninitialized object and restores its state.
|
282
|
+
"""
|
283
|
+
obj = cls.__new__(cls)
|
284
|
+
obj.__setstate__(state)
|
285
|
+
return cast(TableRow, obj)
|
odxtools/tablerowconnector.py
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import NamedElement
|
7
7
|
from .exceptions import odxrequire
|
8
|
-
from .
|
8
|
+
from .odxdoccontext import OdxDocContext
|
9
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
|
9
10
|
from .snrefcontext import SnRefContext
|
10
11
|
from .table import Table
|
11
12
|
from .tablerow import TableRow
|
12
13
|
from .utils import dataclass_fields_asdict
|
13
14
|
|
14
15
|
|
15
|
-
@dataclass
|
16
|
+
@dataclass(kw_only=True)
|
16
17
|
class TableRowConnector(NamedElement):
|
17
18
|
table_ref: OdxLinkRef
|
18
19
|
table_row_snref: str
|
@@ -26,17 +27,16 @@ class TableRowConnector(NamedElement):
|
|
26
27
|
return self._table_row
|
27
28
|
|
28
29
|
@staticmethod
|
29
|
-
def from_et(et_element: ElementTree.Element,
|
30
|
-
|
31
|
-
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
|
30
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "TableRowConnector":
|
31
|
+
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context))
|
32
32
|
|
33
|
-
table_ref = odxrequire(OdxLinkRef.from_et(et_element.find("TABLE-REF"),
|
33
|
+
table_ref = odxrequire(OdxLinkRef.from_et(et_element.find("TABLE-REF"), context))
|
34
34
|
table_row_snref_el = odxrequire(et_element.find("TABLE-ROW-SNREF"))
|
35
35
|
table_row_snref = odxrequire(table_row_snref_el.get("SHORT-NAME"))
|
36
36
|
|
37
37
|
return TableRowConnector(table_ref=table_ref, table_row_snref=table_row_snref, **kwargs)
|
38
38
|
|
39
|
-
def _build_odxlinks(self) ->
|
39
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
40
40
|
return {}
|
41
41
|
|
42
42
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/teammember.py
CHANGED
@@ -1,29 +1,30 @@
|
|
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 .element import IdentifiableElement
|
7
7
|
from .exceptions import 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 TeamMember(IdentifiableElement):
|
15
|
-
roles:
|
16
|
-
department:
|
17
|
-
address:
|
18
|
-
zipcode:
|
19
|
-
city:
|
20
|
-
phone:
|
21
|
-
fax:
|
22
|
-
email:
|
16
|
+
roles: list[str] = field(default_factory=list)
|
17
|
+
department: str | None = None
|
18
|
+
address: str | None = None
|
19
|
+
zipcode: str | None = None # the tag for this is "ZIP", but `zip` is a keyword in python
|
20
|
+
city: str | None = None
|
21
|
+
phone: str | None = None
|
22
|
+
fax: str | None = None
|
23
|
+
email: str | None = None
|
23
24
|
|
24
25
|
@staticmethod
|
25
|
-
def from_et(et_element: ElementTree.Element,
|
26
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
26
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "TeamMember":
|
27
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
27
28
|
|
28
29
|
roles = [odxrequire(role_elem.text) for role_elem in et_element.iterfind("ROLES/ROLE")]
|
29
30
|
department = et_element.findtext("DEPARTMENT")
|
@@ -45,7 +46,7 @@ class TeamMember(IdentifiableElement):
|
|
45
46
|
email=email,
|
46
47
|
**kwargs)
|
47
48
|
|
48
|
-
def _build_odxlinks(self) ->
|
49
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
49
50
|
result = {self.odx_id: self}
|
50
51
|
|
51
52
|
return result
|
@@ -5,8 +5,10 @@
|
|
5
5
|
|
6
6
|
{%- macro printParentRef(par) -%}
|
7
7
|
<PARENT-REF ID-REF="{{par.layer.odx_id.local_id}}"
|
8
|
-
|
8
|
+
{%- if par.layer_ref.ref_docs|length == 1 %}
|
9
|
+
DOCREF="{{par.layer_ref.ref_docs[0].doc_name}}"
|
9
10
|
DOCTYPE="CONTAINER"
|
11
|
+
{%- endif %}
|
10
12
|
xsi:type="{{par.layer.variant_type.value}}-REF">
|
11
13
|
{%- if par.not_inherited_diag_comms %}
|
12
14
|
<NOT-INHERITED-DIAG-COMMS>
|
odxtools/text.py
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
|
-
from typing import List, Optional
|
3
2
|
from xml.etree import ElementTree
|
4
3
|
|
5
|
-
from .
|
4
|
+
from .odxdoccontext import OdxDocContext
|
6
5
|
|
7
6
|
|
8
|
-
@dataclass
|
7
|
+
@dataclass(kw_only=True)
|
9
8
|
class Text:
|
10
9
|
text: str
|
11
|
-
text_identifier:
|
10
|
+
text_identifier: str | None = None
|
12
11
|
|
13
12
|
@staticmethod
|
14
|
-
def from_et(et_element: ElementTree.Element,
|
13
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Text":
|
15
14
|
# Extract the contents of the tag as a string.
|
16
15
|
raw_string = et_element.text or ""
|
17
16
|
for e in et_element:
|
odxtools/uds.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from enum import IntEnum
|
3
3
|
from itertools import chain
|
4
|
-
from typing import Optional
|
5
4
|
|
6
5
|
import odxtools.obd as obd
|
7
6
|
|
@@ -82,7 +81,7 @@ _sid_to_name = {
|
|
82
81
|
SID = IntEnum("UdsSID", ((i.name, i.value) for i in chain(obd.SID, UDSSID))) # type: ignore[misc]
|
83
82
|
|
84
83
|
|
85
|
-
def sid_to_name(sid: int) ->
|
84
|
+
def sid_to_name(sid: int) -> str | None:
|
86
85
|
if sid in _sid_to_name:
|
87
86
|
return _sid_to_name[sid]
|
88
87
|
elif 0x81 <= sid and sid <= 0x82:
|
@@ -142,7 +141,7 @@ def negative_response_id(service_id: int) -> int:
|
|
142
141
|
return NegativeResponseId
|
143
142
|
|
144
143
|
|
145
|
-
def is_response_pending(telegram_payload: bytes, request_sid:
|
144
|
+
def is_response_pending(telegram_payload: bytes, request_sid: int | None = None) -> bool:
|
146
145
|
# "response pending" responses exhibit at least three bytes
|
147
146
|
if len(telegram_payload) < 3:
|
148
147
|
return False
|
odxtools/unit.py
CHANGED
@@ -1,17 +1,18 @@
|
|
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
|
7
7
|
from .exceptions import odxrequire
|
8
|
-
from .
|
8
|
+
from .odxdoccontext import OdxDocContext
|
9
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
9
10
|
from .physicaldimension import PhysicalDimension
|
10
11
|
from .snrefcontext import SnRefContext
|
11
12
|
from .utils import dataclass_fields_asdict
|
12
13
|
|
13
14
|
|
14
|
-
@dataclass
|
15
|
+
@dataclass(kw_only=True)
|
15
16
|
class Unit(IdentifiableElement):
|
16
17
|
"""
|
17
18
|
A unit consists of an ID, short name and a display name.
|
@@ -53,21 +54,21 @@ class Unit(IdentifiableElement):
|
|
53
54
|
```
|
54
55
|
"""
|
55
56
|
display_name: str
|
56
|
-
factor_si_to_unit:
|
57
|
-
offset_si_to_unit:
|
58
|
-
physical_dimension_ref:
|
57
|
+
factor_si_to_unit: float | None = None
|
58
|
+
offset_si_to_unit: float | None = None
|
59
|
+
physical_dimension_ref: OdxLinkRef | None = None
|
59
60
|
|
60
61
|
@property
|
61
|
-
def physical_dimension(self) ->
|
62
|
+
def physical_dimension(self) -> PhysicalDimension | None:
|
62
63
|
return self._physical_dimension
|
63
64
|
|
64
65
|
@staticmethod
|
65
|
-
def from_et(et_element: ElementTree.Element,
|
66
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
66
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Unit":
|
67
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
67
68
|
|
68
69
|
display_name = odxrequire(et_element.findtext("DISPLAY-NAME"))
|
69
70
|
|
70
|
-
def read_optional_float(element: ElementTree.Element, name: str) ->
|
71
|
+
def read_optional_float(element: ElementTree.Element, name: str) -> float | None:
|
71
72
|
if (elem_str := element.findtext(name)) is not None:
|
72
73
|
return float(elem_str)
|
73
74
|
else:
|
@@ -76,7 +77,7 @@ class Unit(IdentifiableElement):
|
|
76
77
|
factor_si_to_unit = read_optional_float(et_element, "FACTOR-SI-TO-UNIT")
|
77
78
|
offset_si_to_unit = read_optional_float(et_element, "OFFSET-SI-TO-UNIT")
|
78
79
|
physical_dimension_ref = OdxLinkRef.from_et(
|
79
|
-
et_element.find("PHYSICAL-DIMENSION-REF"),
|
80
|
+
et_element.find("PHYSICAL-DIMENSION-REF"), context)
|
80
81
|
|
81
82
|
return Unit(
|
82
83
|
display_name=display_name,
|
@@ -85,11 +86,11 @@ class Unit(IdentifiableElement):
|
|
85
86
|
physical_dimension_ref=physical_dimension_ref,
|
86
87
|
**kwargs)
|
87
88
|
|
88
|
-
def _build_odxlinks(self) ->
|
89
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
89
90
|
return {self.odx_id: self}
|
90
91
|
|
91
92
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
92
|
-
self._physical_dimension:
|
93
|
+
self._physical_dimension: PhysicalDimension | None = None
|
93
94
|
if self.physical_dimension_ref:
|
94
95
|
self._physical_dimension = odxlinks.resolve(self.physical_dimension_ref,
|
95
96
|
PhysicalDimension)
|
odxtools/unitgroup.py
CHANGED
@@ -1,35 +1,36 @@
|
|
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, cast
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import NamedElement
|
7
7
|
from .exceptions import odxraise, odxrequire
|
8
8
|
from .nameditemlist import NamedItemList
|
9
|
-
from .
|
9
|
+
from .odxdoccontext import OdxDocContext
|
10
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
10
11
|
from .snrefcontext import SnRefContext
|
11
12
|
from .unit import Unit
|
12
13
|
from .unitgroupcategory import UnitGroupCategory
|
13
14
|
from .utils import dataclass_fields_asdict
|
14
15
|
|
15
16
|
|
16
|
-
@dataclass
|
17
|
+
@dataclass(kw_only=True)
|
17
18
|
class UnitGroup(NamedElement):
|
18
19
|
"""A group of units.
|
19
20
|
|
20
21
|
There are two categories of groups: COUNTRY and EQUIV-UNITS.
|
21
22
|
"""
|
22
23
|
category: UnitGroupCategory
|
23
|
-
unit_refs:
|
24
|
-
oid:
|
24
|
+
unit_refs: list[OdxLinkRef] = field(default_factory=list)
|
25
|
+
oid: str | None = None
|
25
26
|
|
26
27
|
@property
|
27
28
|
def units(self) -> NamedItemList[Unit]:
|
28
29
|
return self._units
|
29
30
|
|
30
31
|
@staticmethod
|
31
|
-
def from_et(et_element: ElementTree.Element,
|
32
|
-
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element,
|
32
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "UnitGroup":
|
33
|
+
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context))
|
33
34
|
|
34
35
|
category_str = odxrequire(et_element.findtext("CATEGORY"))
|
35
36
|
try:
|
@@ -39,14 +40,14 @@ class UnitGroup(NamedElement):
|
|
39
40
|
odxraise(f"Encountered unknown unit group category '{category_str}'")
|
40
41
|
|
41
42
|
unit_refs = [
|
42
|
-
odxrequire(OdxLinkRef.from_et(el,
|
43
|
+
odxrequire(OdxLinkRef.from_et(el, context))
|
43
44
|
for el in et_element.iterfind("UNIT-REFS/UNIT-REF")
|
44
45
|
]
|
45
46
|
oid = et_element.get("OID")
|
46
47
|
|
47
48
|
return UnitGroup(category=category, unit_refs=unit_refs, oid=oid, **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:
|