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/negoutputparam.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 .dopbase import DopBase
|
7
7
|
from .element import NamedElement
|
8
8
|
from .exceptions import odxrequire
|
9
|
-
from .
|
9
|
+
from .odxdoccontext import OdxDocContext
|
10
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
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 NegOutputParam(NamedElement):
|
16
17
|
dop_base_ref: OdxLinkRef
|
17
18
|
|
@@ -21,15 +22,14 @@ class NegOutputParam(NamedElement):
|
|
21
22
|
return self._dop
|
22
23
|
|
23
24
|
@staticmethod
|
24
|
-
def from_et(et_element: ElementTree.Element,
|
25
|
-
doc_frags: List[OdxDocFragment]) -> "NegOutputParam":
|
25
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "NegOutputParam":
|
26
26
|
|
27
|
-
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element,
|
28
|
-
dop_base_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DOP-BASE-REF"),
|
27
|
+
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context))
|
28
|
+
dop_base_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DOP-BASE-REF"), context))
|
29
29
|
|
30
30
|
return NegOutputParam(dop_base_ref=dop_base_ref, **kwargs)
|
31
31
|
|
32
|
-
def _build_odxlinks(self) ->
|
32
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
33
33
|
return {}
|
34
34
|
|
35
35
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/obd.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from enum import IntEnum
|
3
|
-
from typing import Optional
|
4
3
|
|
5
4
|
|
6
5
|
class SID(IntEnum):
|
@@ -47,7 +46,7 @@ _sid_to_name = {
|
|
47
46
|
}
|
48
47
|
|
49
48
|
|
50
|
-
def sid_to_name(sid: int) ->
|
49
|
+
def sid_to_name(sid: int) -> str | None:
|
51
50
|
if sid in _sid_to_name:
|
52
51
|
return _sid_to_name[sid]
|
53
52
|
|
odxtools/odxcategory.py
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
3
|
-
from typing import TYPE_CHECKING, Any
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from typing import TYPE_CHECKING, Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .admindata import AdminData
|
7
7
|
from .companydata import CompanyData
|
8
8
|
from .element import IdentifiableElement
|
9
|
-
from .exceptions import odxrequire
|
10
9
|
from .nameditemlist import NamedItemList
|
11
|
-
from .
|
10
|
+
from .odxdoccontext import OdxDocContext
|
11
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
12
12
|
from .snrefcontext import SnRefContext
|
13
13
|
from .specialdatagroup import SpecialDataGroup
|
14
14
|
from .utils import dataclass_fields_asdict
|
@@ -17,41 +17,29 @@ if TYPE_CHECKING:
|
|
17
17
|
from .database import Database
|
18
18
|
|
19
19
|
|
20
|
-
@dataclass
|
20
|
+
@dataclass(kw_only=True)
|
21
21
|
class OdxCategory(IdentifiableElement):
|
22
22
|
"""This is the base class for all top-level container classes in ODX"""
|
23
23
|
|
24
|
-
admin_data:
|
25
|
-
company_datas: NamedItemList[CompanyData]
|
26
|
-
sdgs:
|
24
|
+
admin_data: AdminData | None = None
|
25
|
+
company_datas: NamedItemList[CompanyData] = field(default_factory=NamedItemList)
|
26
|
+
sdgs: list[SpecialDataGroup] = field(default_factory=list)
|
27
27
|
|
28
28
|
@staticmethod
|
29
|
-
def from_et(et_element: ElementTree.Element,
|
30
|
-
raise Exception("Calling `._from_et()` is not allowed for OdxCategory. "
|
31
|
-
"Use `OdxCategory.category_from_et()`!")
|
29
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "OdxCategory":
|
32
30
|
|
33
|
-
|
34
|
-
def category_from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment], *,
|
35
|
-
doc_type: DocType) -> "OdxCategory":
|
36
|
-
|
37
|
-
short_name = odxrequire(et_element.findtext("SHORT-NAME"))
|
38
|
-
# create the current ODX "document fragment" (description of the
|
39
|
-
# current document for references and IDs)
|
40
|
-
doc_frags = [OdxDocFragment(short_name, doc_type)]
|
41
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
31
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
42
32
|
|
43
|
-
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"),
|
33
|
+
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), context)
|
44
34
|
company_datas = NamedItemList([
|
45
|
-
CompanyData.from_et(cde,
|
35
|
+
CompanyData.from_et(cde, context)
|
46
36
|
for cde in et_element.iterfind("COMPANY-DATAS/COMPANY-DATA")
|
47
37
|
])
|
48
|
-
sdgs = [
|
49
|
-
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
|
50
|
-
]
|
38
|
+
sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
|
51
39
|
|
52
40
|
return OdxCategory(admin_data=admin_data, company_datas=company_datas, sdgs=sdgs, **kwargs)
|
53
41
|
|
54
|
-
def _build_odxlinks(self) ->
|
42
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
55
43
|
result = {self.odx_id: self}
|
56
44
|
|
57
45
|
if self.admin_data is not None:
|
@@ -0,0 +1,16 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import TYPE_CHECKING
|
3
|
+
|
4
|
+
from packaging.version import Version
|
5
|
+
|
6
|
+
if TYPE_CHECKING:
|
7
|
+
from odxtools.odxlink import OdxDocFragment
|
8
|
+
|
9
|
+
|
10
|
+
@dataclass(slots=True, frozen=True)
|
11
|
+
class OdxDocContext:
|
12
|
+
version: Version
|
13
|
+
|
14
|
+
# the doc_fragments are either tuple(doc_frag(category),)
|
15
|
+
# or tuple(doc_frag(category), doc_frag(diag_layer))
|
16
|
+
doc_fragments: tuple["OdxDocFragment"] | tuple["OdxDocFragment", "OdxDocFragment"]
|
odxtools/odxlink.py
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import warnings
|
3
|
+
from collections.abc import Iterable
|
3
4
|
from dataclasses import dataclass
|
4
5
|
from enum import Enum
|
5
|
-
from typing import Any,
|
6
|
+
from typing import Any, Optional, TypeVar, overload
|
6
7
|
from xml.etree import ElementTree
|
7
8
|
|
8
9
|
from .exceptions import OdxWarning, odxassert, odxraise, odxrequire
|
9
10
|
from .nameditemlist import OdxNamed, TNamed
|
11
|
+
from .odxdoccontext import OdxDocContext
|
10
12
|
|
11
13
|
|
12
14
|
class DocType(Enum):
|
@@ -44,7 +46,7 @@ class OdxLinkId:
|
|
44
46
|
|
45
47
|
#: The name and type of the document fragment to which the
|
46
48
|
#: `local_id` is relative to
|
47
|
-
doc_fragments:
|
49
|
+
doc_fragments: tuple[OdxDocFragment] | tuple[OdxDocFragment, OdxDocFragment]
|
48
50
|
|
49
51
|
def __hash__(self) -> int:
|
50
52
|
# we do not hash about the document fragment here, because
|
@@ -67,8 +69,7 @@ class OdxLinkId:
|
|
67
69
|
return f"OdxLinkId('{self.local_id}')"
|
68
70
|
|
69
71
|
@staticmethod
|
70
|
-
def from_et(et: ElementTree.Element,
|
71
|
-
doc_fragments: List[OdxDocFragment]) -> Optional["OdxLinkId"]:
|
72
|
+
def from_et(et: ElementTree.Element, context: OdxDocContext) -> Optional["OdxLinkId"]:
|
72
73
|
"""Construct an OdxLinkId for a given XML node (ElementTree object).
|
73
74
|
|
74
75
|
Returns None if the given XML node does not exhibit an ID.
|
@@ -78,7 +79,7 @@ class OdxLinkId:
|
|
78
79
|
if local_id is None:
|
79
80
|
return None
|
80
81
|
|
81
|
-
return OdxLinkId(local_id, doc_fragments)
|
82
|
+
return OdxLinkId(local_id, context.doc_fragments)
|
82
83
|
|
83
84
|
|
84
85
|
@dataclass
|
@@ -94,7 +95,7 @@ class OdxLinkRef:
|
|
94
95
|
ref_id: str
|
95
96
|
|
96
97
|
#: The document fragments to which the `ref_id` refers to (in reverse order)
|
97
|
-
ref_docs:
|
98
|
+
ref_docs: tuple[OdxDocFragment, ...]
|
98
99
|
|
99
100
|
# TODO: this is difficult because OdxLinkRef is derived from and
|
100
101
|
# we do not want having to specify it mandatorily
|
@@ -102,17 +103,16 @@ class OdxLinkRef:
|
|
102
103
|
|
103
104
|
@overload
|
104
105
|
@staticmethod
|
105
|
-
def from_et(et: None,
|
106
|
+
def from_et(et: None, context: OdxDocContext) -> None:
|
106
107
|
...
|
107
108
|
|
108
109
|
@overload
|
109
110
|
@staticmethod
|
110
|
-
def from_et(et: ElementTree.Element,
|
111
|
+
def from_et(et: ElementTree.Element, context: OdxDocContext) -> "OdxLinkRef":
|
111
112
|
...
|
112
113
|
|
113
114
|
@staticmethod
|
114
|
-
def from_et(et:
|
115
|
-
source_doc_frags: List[OdxDocFragment]) -> Optional["OdxLinkRef"]:
|
115
|
+
def from_et(et: ElementTree.Element | None, context: OdxDocContext) -> Optional["OdxLinkRef"]:
|
116
116
|
"""Construct an OdxLinkRef for a given XML node (ElementTree object).
|
117
117
|
|
118
118
|
Returns None if the given XML node does not represent a reference.
|
@@ -143,10 +143,10 @@ class OdxLinkRef:
|
|
143
143
|
# if the target document fragment is specified by the
|
144
144
|
# reference, use it, else use the document fragment containing
|
145
145
|
# the reference.
|
146
|
-
if docref is
|
147
|
-
doc_frags =
|
146
|
+
if docref is None:
|
147
|
+
doc_frags = context.doc_fragments
|
148
148
|
else:
|
149
|
-
doc_frags =
|
149
|
+
doc_frags = (OdxDocFragment(docref, odxrequire(doctype)),)
|
150
150
|
|
151
151
|
return OdxLinkRef(id_ref, doc_frags)
|
152
152
|
|
@@ -170,17 +170,17 @@ class OdxLinkDatabase:
|
|
170
170
|
"""
|
171
171
|
|
172
172
|
def __init__(self) -> None:
|
173
|
-
self._db:
|
173
|
+
self._db: dict[OdxDocFragment, dict[str, Any]] = {}
|
174
174
|
|
175
175
|
@overload
|
176
176
|
def resolve(self, ref: OdxLinkRef, expected_type: None = None) -> Any:
|
177
177
|
...
|
178
178
|
|
179
179
|
@overload
|
180
|
-
def resolve(self, ref: OdxLinkRef, expected_type:
|
180
|
+
def resolve(self, ref: OdxLinkRef, expected_type: type[T]) -> T:
|
181
181
|
...
|
182
182
|
|
183
|
-
def resolve(self, ref: OdxLinkRef, expected_type:
|
183
|
+
def resolve(self, ref: OdxLinkRef, expected_type: Any | None = None) -> Any:
|
184
184
|
"""
|
185
185
|
Resolve a reference to an object
|
186
186
|
|
@@ -219,12 +219,10 @@ class OdxLinkDatabase:
|
|
219
219
|
...
|
220
220
|
|
221
221
|
@overload
|
222
|
-
def resolve_lenient(self, ref: OdxLinkRef, expected_type:
|
222
|
+
def resolve_lenient(self, ref: OdxLinkRef, expected_type: type[T]) -> T | None:
|
223
223
|
...
|
224
224
|
|
225
|
-
def resolve_lenient(self,
|
226
|
-
ref: OdxLinkRef,
|
227
|
-
expected_type: Optional[Any] = None) -> Optional[Any]:
|
225
|
+
def resolve_lenient(self, ref: OdxLinkRef, expected_type: Any | None = None) -> Any | None:
|
228
226
|
"""
|
229
227
|
Resolve a reference to an object
|
230
228
|
|
@@ -254,7 +252,7 @@ class OdxLinkDatabase:
|
|
254
252
|
|
255
253
|
return None
|
256
254
|
|
257
|
-
def update(self, new_entries:
|
255
|
+
def update(self, new_entries: dict[OdxLinkId, Any], *, overwrite: bool = True) -> None:
|
258
256
|
"""
|
259
257
|
Add a bunch of new objects to the ODXLINK database.
|
260
258
|
|
@@ -287,7 +285,7 @@ def resolve_snref(target_short_name: str,
|
|
287
285
|
@overload
|
288
286
|
def resolve_snref(target_short_name: str,
|
289
287
|
items: Iterable[OdxNamed],
|
290
|
-
expected_type:
|
288
|
+
expected_type: type[TNamed],
|
291
289
|
*,
|
292
290
|
lenient: None = None) -> TNamed:
|
293
291
|
...
|
@@ -296,16 +294,16 @@ def resolve_snref(target_short_name: str,
|
|
296
294
|
@overload
|
297
295
|
def resolve_snref(target_short_name: str,
|
298
296
|
items: Iterable[OdxNamed],
|
299
|
-
expected_type:
|
297
|
+
expected_type: type[TNamed],
|
300
298
|
*,
|
301
|
-
lenient: bool = True) ->
|
299
|
+
lenient: bool = True) -> TNamed | None:
|
302
300
|
...
|
303
301
|
|
304
302
|
|
305
303
|
def resolve_snref(target_short_name: str,
|
306
304
|
items: Iterable[OdxNamed],
|
307
305
|
expected_type: Any = None,
|
308
|
-
lenient:
|
306
|
+
lenient: bool | None = None) -> Any:
|
309
307
|
candidates = [x for x in items if x.short_name == target_short_name]
|
310
308
|
|
311
309
|
if not candidates:
|
odxtools/odxtypes.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
+
from collections.abc import Callable, Iterable
|
2
3
|
from enum import Enum
|
3
|
-
from typing import
|
4
|
-
Type, Union, overload)
|
4
|
+
from typing import TYPE_CHECKING, Any, SupportsBytes, Union, overload
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
7
|
from .exceptions import odxassert, odxraise, odxrequire
|
@@ -16,22 +16,22 @@ def bytefield_to_bytearray(bytefield: str) -> bytearray:
|
|
16
16
|
return bytearray([int(x, 16) for x in bytes_string])
|
17
17
|
|
18
18
|
|
19
|
-
BytesTypes =
|
20
|
-
AtomicOdxType =
|
19
|
+
BytesTypes = bytearray | bytes | SupportsBytes
|
20
|
+
AtomicOdxType = str | int | float | BytesTypes
|
21
21
|
|
22
22
|
# dictionary mapping short names to a Parameter that needs to be
|
23
23
|
# specified. Complex parameters (structures) may contain
|
24
24
|
# sub-parameters, so this is a recursive type...
|
25
|
-
ParameterDict =
|
25
|
+
ParameterDict = dict[str, Union["Parameter", "ParameterDict"]]
|
26
26
|
|
27
27
|
# Dictionary mapping short names of parameters to the value it
|
28
28
|
# exhibits. Complex parameters (structures) may contain
|
29
29
|
# sub-parameters, so this is a recursive type, and fields encompass
|
30
30
|
# multiple items, so this can be a list of objects.
|
31
|
-
TableStructParameterValue =
|
31
|
+
TableStructParameterValue = tuple[str, "ParameterValue"]
|
32
32
|
ParameterValue = Union[AtomicOdxType, "ParameterValueDict", TableStructParameterValue,
|
33
33
|
Iterable["ParameterValue"], "DiagnosticTroubleCode"]
|
34
|
-
ParameterValueDict =
|
34
|
+
ParameterValueDict = dict[str, ParameterValue]
|
35
35
|
|
36
36
|
|
37
37
|
@overload
|
@@ -44,7 +44,7 @@ def odxstr_to_bool(str_val: str) -> bool:
|
|
44
44
|
...
|
45
45
|
|
46
46
|
|
47
|
-
def odxstr_to_bool(str_val:
|
47
|
+
def odxstr_to_bool(str_val: str | None) -> bool | None:
|
48
48
|
if str_val is None:
|
49
49
|
return None
|
50
50
|
|
@@ -79,7 +79,7 @@ def parse_int(value: str) -> int:
|
|
79
79
|
|
80
80
|
#: conversion functions for strings from the XML to the types stored
|
81
81
|
#: by the internalized database
|
82
|
-
_PARSE_ODX_TYPE:
|
82
|
+
_PARSE_ODX_TYPE: dict[str, Callable[[str], AtomicOdxType]] = {
|
83
83
|
"A_INT32": parse_int,
|
84
84
|
"A_UINT32": parse_int,
|
85
85
|
"A_FLOAT32": float,
|
@@ -92,7 +92,7 @@ _PARSE_ODX_TYPE: Dict[str, Callable[[str], AtomicOdxType]] = {
|
|
92
92
|
|
93
93
|
#: mapping from type name strings specified by the XML to the types
|
94
94
|
#: used by the internalized database
|
95
|
-
_ODX_TYPE_TO_PYTHON_TYPE:
|
95
|
+
_ODX_TYPE_TO_PYTHON_TYPE: dict[str, type[int | float | str | bytearray]] = {
|
96
96
|
"A_INT32": int,
|
97
97
|
"A_UINT32": int,
|
98
98
|
"A_FLOAT32": float,
|
@@ -140,10 +140,13 @@ def compare_odx_values(a: AtomicOdxType, b: AtomicOdxType) -> int:
|
|
140
140
|
if not isinstance(b, BytesTypes):
|
141
141
|
odxraise()
|
142
142
|
|
143
|
-
|
143
|
+
a_bytes = bytes(a)
|
144
|
+
b_bytes = bytes(b)
|
144
145
|
|
145
|
-
|
146
|
-
|
146
|
+
obj_len = max(len(a_bytes), len(b_bytes))
|
147
|
+
|
148
|
+
tmp_a = a_bytes.ljust(obj_len, b'\x00')
|
149
|
+
tmp_b = b_bytes.ljust(obj_len, b'\x00')
|
147
150
|
|
148
151
|
if tmp_a > tmp_b:
|
149
152
|
return 1
|
@@ -193,7 +196,7 @@ class DataType(Enum):
|
|
193
196
|
A_UTF8STRING = "A_UTF8STRING"
|
194
197
|
|
195
198
|
@property
|
196
|
-
def python_type(self) ->
|
199
|
+
def python_type(self) -> type[int | float | str | bytearray]:
|
197
200
|
return _ODX_TYPE_TO_PYTHON_TYPE[self.value]
|
198
201
|
|
199
202
|
@property
|
@@ -211,7 +214,7 @@ class DataType(Enum):
|
|
211
214
|
def create_from_et(self, et_element: ElementTree.Element) -> AtomicOdxType:
|
212
215
|
...
|
213
216
|
|
214
|
-
def create_from_et(self, et_element:
|
217
|
+
def create_from_et(self, et_element: ElementTree.Element | None) -> AtomicOdxType | None:
|
215
218
|
"""
|
216
219
|
Parse a V/VT value union and return an AtomicOdxType from them that match current datatype
|
217
220
|
this includes, but not limited to COMPU-CONST, COMPU-DEFAULT-VALUE, COMPU-INVERSE-VALUE
|
odxtools/outputparam.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from deprecation import deprecated
|
@@ -8,15 +8,16 @@ from deprecation import deprecated
|
|
8
8
|
from .dopbase import DopBase
|
9
9
|
from .element import IdentifiableElement
|
10
10
|
from .exceptions import odxrequire
|
11
|
-
from .
|
11
|
+
from .odxdoccontext import OdxDocContext
|
12
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
12
13
|
from .snrefcontext import SnRefContext
|
13
14
|
from .utils import dataclass_fields_asdict
|
14
15
|
|
15
16
|
|
16
|
-
@dataclass
|
17
|
+
@dataclass(kw_only=True)
|
17
18
|
class OutputParam(IdentifiableElement):
|
18
19
|
dop_base_ref: OdxLinkRef
|
19
|
-
semantic:
|
20
|
+
semantic: str | None = None
|
20
21
|
|
21
22
|
@property
|
22
23
|
def dop(self) -> DopBase:
|
@@ -27,16 +28,16 @@ class OutputParam(IdentifiableElement):
|
|
27
28
|
return self._dop
|
28
29
|
|
29
30
|
@staticmethod
|
30
|
-
def from_et(et_element: ElementTree.Element,
|
31
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "OutputParam":
|
31
32
|
|
32
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
33
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
33
34
|
|
34
|
-
dop_base_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DOP-BASE-REF"),
|
35
|
+
dop_base_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DOP-BASE-REF"), context))
|
35
36
|
semantic = et_element.get("SEMANTIC")
|
36
37
|
|
37
38
|
return OutputParam(dop_base_ref=dop_base_ref, semantic=semantic, **kwargs)
|
38
39
|
|
39
|
-
def _build_odxlinks(self) ->
|
40
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
40
41
|
return {}
|
41
42
|
|
42
43
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/parameterinfo.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import textwrap
|
3
|
+
from collections.abc import Iterable
|
3
4
|
from io import StringIO
|
4
|
-
from typing import Iterable
|
5
5
|
|
6
6
|
from .compumethods.compucodecompumethod import CompuCodeCompuMethod
|
7
7
|
from .compumethods.identicalcompumethod import IdenticalCompuMethod
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import warnings
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import Any,
|
4
|
+
from typing import Any, cast
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
7
|
from typing_extensions import override
|
@@ -11,13 +11,14 @@ from ..decodestate import DecodeState
|
|
11
11
|
from ..diagcodedtype import DiagCodedType
|
12
12
|
from ..encodestate import EncodeState
|
13
13
|
from ..exceptions import DecodeError, EncodeError, odxraise, odxrequire
|
14
|
-
from ..
|
14
|
+
from ..odxdoccontext import OdxDocContext
|
15
|
+
from ..odxlink import OdxLinkId
|
15
16
|
from ..odxtypes import AtomicOdxType, DataType, ParameterValue
|
16
17
|
from ..utils import dataclass_fields_asdict
|
17
18
|
from .parameter import Parameter, ParameterType
|
18
19
|
|
19
20
|
|
20
|
-
@dataclass
|
21
|
+
@dataclass(kw_only=True)
|
21
22
|
class CodedConstParameter(Parameter):
|
22
23
|
|
23
24
|
coded_value_raw: str
|
@@ -44,14 +45,13 @@ class CodedConstParameter(Parameter):
|
|
44
45
|
|
45
46
|
@staticmethod
|
46
47
|
@override
|
47
|
-
def from_et(et_element: ElementTree.Element,
|
48
|
-
doc_frags: List[OdxDocFragment]) -> "CodedConstParameter":
|
48
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "CodedConstParameter":
|
49
49
|
|
50
|
-
kwargs = dataclass_fields_asdict(Parameter.from_et(et_element,
|
50
|
+
kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, context))
|
51
51
|
|
52
52
|
coded_value_raw = odxrequire(et_element.findtext("CODED-VALUE"))
|
53
53
|
dct_elem = odxrequire(et_element.find("DIAG-CODED-TYPE"))
|
54
|
-
diag_coded_type = create_any_diag_coded_type_from_et(dct_elem,
|
54
|
+
diag_coded_type = create_any_diag_coded_type_from_et(dct_elem, context)
|
55
55
|
|
56
56
|
return CodedConstParameter(
|
57
57
|
coded_value_raw=coded_value_raw, diag_coded_type=diag_coded_type, **kwargs)
|
@@ -61,7 +61,7 @@ class CodedConstParameter(Parameter):
|
|
61
61
|
AtomicOdxType, self.diag_coded_type.base_data_type.from_string(self.coded_value_raw))
|
62
62
|
|
63
63
|
@override
|
64
|
-
def _build_odxlinks(self) ->
|
64
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
65
65
|
result = super()._build_odxlinks()
|
66
66
|
|
67
67
|
result.update(self.diag_coded_type._build_odxlinks())
|
@@ -69,7 +69,7 @@ class CodedConstParameter(Parameter):
|
|
69
69
|
return result
|
70
70
|
|
71
71
|
@override
|
72
|
-
def get_static_bit_length(self) ->
|
72
|
+
def get_static_bit_length(self) -> int | None:
|
73
73
|
return self.diag_coded_type.get_static_bit_length()
|
74
74
|
|
75
75
|
@property
|
@@ -77,7 +77,7 @@ class CodedConstParameter(Parameter):
|
|
77
77
|
return self.diag_coded_type.base_data_type
|
78
78
|
|
79
79
|
@override
|
80
|
-
def _encode_positioned_into_pdu(self, physical_value:
|
80
|
+
def _encode_positioned_into_pdu(self, physical_value: ParameterValue | None,
|
81
81
|
encode_state: EncodeState) -> None:
|
82
82
|
if physical_value is not None and physical_value != self.coded_value:
|
83
83
|
odxraise(
|
@@ -1,10 +1,9 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from typing import List
|
3
2
|
from xml.etree import ElementTree
|
4
3
|
|
5
4
|
from ..exceptions import odxraise
|
6
5
|
from ..globals import xsi
|
7
|
-
from ..
|
6
|
+
from ..odxdoccontext import OdxDocContext
|
8
7
|
from .codedconstparameter import CodedConstParameter
|
9
8
|
from .dynamicparameter import DynamicParameter
|
10
9
|
from .lengthkeyparameter import LengthKeyParameter
|
@@ -21,35 +20,35 @@ from .valueparameter import ValueParameter
|
|
21
20
|
|
22
21
|
|
23
22
|
def create_any_parameter_from_et(et_element: ElementTree.Element,
|
24
|
-
|
23
|
+
context: OdxDocContext) \
|
25
24
|
-> Parameter:
|
26
25
|
parameter_type = et_element.get(f"{xsi}type")
|
27
26
|
|
28
27
|
# Which attributes are set depends on the type of the parameter.
|
29
28
|
if parameter_type == "VALUE":
|
30
|
-
return ValueParameter.from_et(et_element,
|
29
|
+
return ValueParameter.from_et(et_element, context)
|
31
30
|
elif parameter_type == "CODED-CONST":
|
32
|
-
return CodedConstParameter.from_et(et_element,
|
31
|
+
return CodedConstParameter.from_et(et_element, context)
|
33
32
|
elif parameter_type == "PHYS-CONST":
|
34
|
-
return PhysicalConstantParameter.from_et(et_element,
|
33
|
+
return PhysicalConstantParameter.from_et(et_element, context)
|
35
34
|
elif parameter_type == "SYSTEM":
|
36
|
-
return SystemParameter.from_et(et_element,
|
35
|
+
return SystemParameter.from_et(et_element, context)
|
37
36
|
elif parameter_type == "LENGTH-KEY":
|
38
|
-
return LengthKeyParameter.from_et(et_element,
|
37
|
+
return LengthKeyParameter.from_et(et_element, context)
|
39
38
|
elif parameter_type == "NRC-CONST":
|
40
|
-
return NrcConstParameter.from_et(et_element,
|
39
|
+
return NrcConstParameter.from_et(et_element, context)
|
41
40
|
elif parameter_type == "RESERVED":
|
42
|
-
return ReservedParameter.from_et(et_element,
|
41
|
+
return ReservedParameter.from_et(et_element, context)
|
43
42
|
elif parameter_type == "MATCHING-REQUEST-PARAM":
|
44
|
-
return MatchingRequestParameter.from_et(et_element,
|
43
|
+
return MatchingRequestParameter.from_et(et_element, context)
|
45
44
|
elif parameter_type == "DYNAMIC":
|
46
|
-
return DynamicParameter.from_et(et_element,
|
45
|
+
return DynamicParameter.from_et(et_element, context)
|
47
46
|
elif parameter_type == "TABLE-STRUCT":
|
48
|
-
return TableStructParameter.from_et(et_element,
|
47
|
+
return TableStructParameter.from_et(et_element, context)
|
49
48
|
elif parameter_type == "TABLE-KEY":
|
50
|
-
return TableKeyParameter.from_et(et_element,
|
49
|
+
return TableKeyParameter.from_et(et_element, context)
|
51
50
|
elif parameter_type == "TABLE-ENTRY":
|
52
|
-
return TableEntryParameter.from_et(et_element,
|
51
|
+
return TableEntryParameter.from_et(et_element, context)
|
53
52
|
|
54
53
|
odxraise(f"I don't know about parameters of type {parameter_type}", NotImplementedError)
|
55
|
-
return Parameter.from_et(et_element,
|
54
|
+
return Parameter.from_et(et_element, context)
|
@@ -1,19 +1,18 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import List, Optional
|
4
3
|
from xml.etree import ElementTree
|
5
4
|
|
6
5
|
from typing_extensions import override
|
7
6
|
|
8
7
|
from ..decodestate import DecodeState
|
9
8
|
from ..encodestate import EncodeState
|
10
|
-
from ..
|
9
|
+
from ..odxdoccontext import OdxDocContext
|
11
10
|
from ..odxtypes import ParameterValue
|
12
11
|
from ..utils import dataclass_fields_asdict
|
13
12
|
from .parameter import Parameter, ParameterType
|
14
13
|
|
15
14
|
|
16
|
-
@dataclass
|
15
|
+
@dataclass(kw_only=True)
|
17
16
|
class DynamicParameter(Parameter):
|
18
17
|
|
19
18
|
@property
|
@@ -33,15 +32,14 @@ class DynamicParameter(Parameter):
|
|
33
32
|
|
34
33
|
@staticmethod
|
35
34
|
@override
|
36
|
-
def from_et(et_element: ElementTree.Element,
|
37
|
-
doc_frags: List[OdxDocFragment]) -> "DynamicParameter":
|
35
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DynamicParameter":
|
38
36
|
|
39
|
-
kwargs = dataclass_fields_asdict(Parameter.from_et(et_element,
|
37
|
+
kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, context))
|
40
38
|
|
41
39
|
return DynamicParameter(**kwargs)
|
42
40
|
|
43
41
|
@override
|
44
|
-
def _encode_positioned_into_pdu(self, physical_value:
|
42
|
+
def _encode_positioned_into_pdu(self, physical_value: ParameterValue | None,
|
45
43
|
encode_state: EncodeState) -> None:
|
46
44
|
raise NotImplementedError("Encoding DynamicParameter is not implemented yet.")
|
47
45
|
|