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/inputparam.py
CHANGED
@@ -8,17 +8,18 @@ from deprecation import deprecated
|
|
8
8
|
from .dopbase import DopBase
|
9
9
|
from .element import NamedElement
|
10
10
|
from .exceptions import odxrequire
|
11
|
-
from .
|
11
|
+
from .odxdoccontext import OdxDocContext
|
12
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
12
13
|
from .snrefcontext import SnRefContext
|
13
14
|
from .utils import dataclass_fields_asdict
|
14
15
|
|
15
16
|
|
16
|
-
@dataclass
|
17
|
+
@dataclass(kw_only=True)
|
17
18
|
class InputParam(NamedElement):
|
18
|
-
physical_default_value: str | None
|
19
|
+
physical_default_value: str | None = None
|
19
20
|
dop_base_ref: OdxLinkRef
|
20
|
-
oid: str | None
|
21
|
-
semantic: str | None
|
21
|
+
oid: str | None = None
|
22
|
+
semantic: str | None = None
|
22
23
|
|
23
24
|
@property
|
24
25
|
def dop(self) -> DopBase:
|
@@ -30,11 +31,11 @@ class InputParam(NamedElement):
|
|
30
31
|
return self._dop
|
31
32
|
|
32
33
|
@staticmethod
|
33
|
-
def from_et(et_element: ElementTree.Element,
|
34
|
-
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element,
|
34
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "InputParam":
|
35
|
+
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context))
|
35
36
|
|
36
37
|
physical_default_value = et_element.findtext("PHYSICAL-DEFAULT-VALUE")
|
37
|
-
dop_base_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DOP-BASE-REF"),
|
38
|
+
dop_base_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DOP-BASE-REF"), context))
|
38
39
|
|
39
40
|
oid = et_element.get("OID")
|
40
41
|
semantic = et_element.get("SEMANTIC")
|
odxtools/internalconstr.py
CHANGED
@@ -1,37 +1,37 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
2
|
+
from dataclasses import dataclass, field
|
3
3
|
from xml.etree import ElementTree
|
4
4
|
|
5
5
|
from .compumethods.limit import Limit
|
6
|
-
from .
|
6
|
+
from .odxdoccontext import OdxDocContext
|
7
7
|
from .odxtypes import DataType
|
8
8
|
from .scaleconstr import ScaleConstr
|
9
9
|
|
10
10
|
|
11
|
-
@dataclass
|
11
|
+
@dataclass(kw_only=True)
|
12
12
|
class InternalConstr:
|
13
13
|
"""This class represents INTERNAL-CONSTR objects.
|
14
14
|
"""
|
15
15
|
|
16
16
|
# TODO: Enforce the internal and physical constraints.
|
17
17
|
|
18
|
-
lower_limit: Limit | None
|
19
|
-
upper_limit: Limit | None
|
20
|
-
scale_constrs: list[ScaleConstr]
|
18
|
+
lower_limit: Limit | None = None
|
19
|
+
upper_limit: Limit | None = None
|
20
|
+
scale_constrs: list[ScaleConstr] = field(default_factory=list)
|
21
21
|
|
22
22
|
value_type: DataType
|
23
23
|
|
24
24
|
@staticmethod
|
25
|
-
def constr_from_et(et_element: ElementTree.Element,
|
25
|
+
def constr_from_et(et_element: ElementTree.Element, context: OdxDocContext, *,
|
26
26
|
value_type: DataType) -> "InternalConstr":
|
27
27
|
|
28
28
|
lower_limit = Limit.limit_from_et(
|
29
|
-
et_element.find("LOWER-LIMIT"),
|
29
|
+
et_element.find("LOWER-LIMIT"), context, value_type=value_type)
|
30
30
|
upper_limit = Limit.limit_from_et(
|
31
|
-
et_element.find("UPPER-LIMIT"),
|
31
|
+
et_element.find("UPPER-LIMIT"), context, value_type=value_type)
|
32
32
|
|
33
33
|
scale_constrs = [
|
34
|
-
ScaleConstr.scale_constr_from_et(sc_el,
|
34
|
+
ScaleConstr.scale_constr_from_et(sc_el, context, value_type=value_type)
|
35
35
|
for sc_el in et_element.iterfind("SCALE-CONSTRS/SCALE-CONSTR")
|
36
36
|
]
|
37
37
|
|
@@ -8,12 +8,12 @@ from .decodestate import DecodeState
|
|
8
8
|
from .diagcodedtype import DctType, DiagCodedType
|
9
9
|
from .encodestate import EncodeState
|
10
10
|
from .exceptions import EncodeError, odxassert, odxraise, odxrequire
|
11
|
-
from .
|
11
|
+
from .odxdoccontext import OdxDocContext
|
12
12
|
from .odxtypes import AtomicOdxType, DataType
|
13
13
|
from .utils import dataclass_fields_asdict
|
14
14
|
|
15
15
|
|
16
|
-
@dataclass
|
16
|
+
@dataclass(kw_only=True)
|
17
17
|
class LeadingLengthInfoType(DiagCodedType):
|
18
18
|
#: bit length of the length specifier field
|
19
19
|
#:
|
@@ -28,9 +28,8 @@ class LeadingLengthInfoType(DiagCodedType):
|
|
28
28
|
|
29
29
|
@staticmethod
|
30
30
|
@override
|
31
|
-
def from_et(et_element: ElementTree.Element,
|
32
|
-
|
33
|
-
kwargs = dataclass_fields_asdict(DiagCodedType.from_et(et_element, doc_frags))
|
31
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "LeadingLengthInfoType":
|
32
|
+
kwargs = dataclass_fields_asdict(DiagCodedType.from_et(et_element, context))
|
34
33
|
|
35
34
|
bit_length = int(odxrequire(et_element.findtext("BIT-LENGTH")))
|
36
35
|
|
@@ -52,7 +51,7 @@ class LeadingLengthInfoType(DiagCodedType):
|
|
52
51
|
@override
|
53
52
|
def encode_into_pdu(self, internal_value: AtomicOdxType, encode_state: EncodeState) -> None:
|
54
53
|
|
55
|
-
if not isinstance(internal_value, str
|
54
|
+
if not isinstance(internal_value, (str, bytes)):
|
56
55
|
odxraise(
|
57
56
|
f"LEADING-LENGTH-INFO types can only be used for strings and byte fields, "
|
58
57
|
f"not {type(internal_value).__name__}", EncodeError)
|
odxtools/library.py
CHANGED
@@ -5,12 +5,13 @@ from xml.etree import ElementTree
|
|
5
5
|
|
6
6
|
from .element import IdentifiableElement
|
7
7
|
from .exceptions import odxraise, odxrequire
|
8
|
-
from .
|
8
|
+
from .odxdoccontext import OdxDocContext
|
9
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
9
10
|
from .snrefcontext import SnRefContext
|
10
11
|
from .utils import dataclass_fields_asdict
|
11
12
|
|
12
13
|
|
13
|
-
@dataclass
|
14
|
+
@dataclass(kw_only=True)
|
14
15
|
class Library(IdentifiableElement):
|
15
16
|
"""
|
16
17
|
A library defines a shared library used for single ECU jobs etc.
|
@@ -19,19 +20,19 @@ class Library(IdentifiableElement):
|
|
19
20
|
"""
|
20
21
|
|
21
22
|
code_file: str
|
22
|
-
encryption: str | None
|
23
|
+
encryption: str | None = None
|
23
24
|
syntax: str
|
24
25
|
revision: str
|
25
|
-
entrypoint: str | None
|
26
|
+
entrypoint: str | None = None
|
26
27
|
|
27
28
|
@property
|
28
29
|
def code(self) -> bytes:
|
29
30
|
return self._code
|
30
31
|
|
31
32
|
@staticmethod
|
32
|
-
def from_et(et_element: ElementTree.Element,
|
33
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Library":
|
33
34
|
|
34
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
35
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
35
36
|
|
36
37
|
code_file = odxrequire(et_element.findtext("CODE-FILE"))
|
37
38
|
encryption = et_element.findtext("ENCRYPTION")
|
odxtools/linkeddtcdop.py
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
2
|
+
from dataclasses import dataclass, field
|
3
3
|
from typing import TYPE_CHECKING, Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .diagnostictroublecode import DiagnosticTroubleCode
|
7
7
|
from .exceptions import odxrequire
|
8
8
|
from .nameditemlist import NamedItemList
|
9
|
-
from .
|
9
|
+
from .odxdoccontext import OdxDocContext
|
10
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
|
10
11
|
from .snrefcontext import SnRefContext
|
11
12
|
|
12
13
|
if TYPE_CHECKING:
|
13
14
|
from .dtcdop import DtcDop
|
14
15
|
|
15
16
|
|
16
|
-
@dataclass
|
17
|
+
@dataclass(kw_only=True)
|
17
18
|
class LinkedDtcDop:
|
18
|
-
not_inherited_dtc_snrefs: list[str]
|
19
|
+
not_inherited_dtc_snrefs: list[str] = field(default_factory=list)
|
19
20
|
dtc_dop_ref: OdxLinkRef
|
20
21
|
|
21
22
|
@property
|
@@ -31,14 +32,14 @@ class LinkedDtcDop:
|
|
31
32
|
return self._dtc_dop.short_name
|
32
33
|
|
33
34
|
@staticmethod
|
34
|
-
def from_et(et_element: ElementTree.Element,
|
35
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "LinkedDtcDop":
|
35
36
|
not_inherited_dtc_snrefs = [
|
36
37
|
odxrequire(el.get("SHORT-NAME"))
|
37
38
|
for el in et_element.iterfind("NOT-INHERITED-DTC-SNREFS/"
|
38
39
|
"NOT-INHERITED-DTC-SNREF")
|
39
40
|
]
|
40
41
|
|
41
|
-
dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"),
|
42
|
+
dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"), context))
|
42
43
|
|
43
44
|
return LinkedDtcDop(
|
44
45
|
not_inherited_dtc_snrefs=not_inherited_dtc_snrefs, dtc_dop_ref=dtc_dop_ref)
|
@@ -3,12 +3,12 @@ from dataclasses import dataclass
|
|
3
3
|
from xml.etree import ElementTree
|
4
4
|
|
5
5
|
from .matchingparameter import MatchingParameter
|
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 MatchingBaseVariantParameter(MatchingParameter):
|
13
13
|
"""A description of a parameter used for base variant matching.
|
14
14
|
|
@@ -17,7 +17,7 @@ class MatchingBaseVariantParameter(MatchingParameter):
|
|
17
17
|
additional subtag `USE-PHYSICAL-ADDRESSING`.
|
18
18
|
"""
|
19
19
|
|
20
|
-
use_physical_addressing_raw: bool | None
|
20
|
+
use_physical_addressing_raw: bool | None = None
|
21
21
|
|
22
22
|
@property
|
23
23
|
def use_physical_addressing(self) -> bool:
|
@@ -25,9 +25,9 @@ class MatchingBaseVariantParameter(MatchingParameter):
|
|
25
25
|
|
26
26
|
@staticmethod
|
27
27
|
def from_et(et_element: ElementTree.Element,
|
28
|
-
|
28
|
+
context: OdxDocContext) -> "MatchingBaseVariantParameter":
|
29
29
|
|
30
|
-
kwargs = dataclass_fields_asdict(MatchingParameter.from_et(et_element,
|
30
|
+
kwargs = dataclass_fields_asdict(MatchingParameter.from_et(et_element, context))
|
31
31
|
|
32
32
|
use_physical_addressing_raw = odxstr_to_bool(et_element.findtext("USE-PHYSICAL-ADDRESSING"))
|
33
33
|
|
odxtools/matchingparameter.py
CHANGED
@@ -7,12 +7,13 @@ from .diaglayers.diaglayer import DiagLayer
|
|
7
7
|
from .diagnostictroublecode import DiagnosticTroubleCode
|
8
8
|
from .diagservice import DiagService
|
9
9
|
from .exceptions import odxraise, odxrequire
|
10
|
-
from .
|
10
|
+
from .odxdoccontext import OdxDocContext
|
11
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, resolve_snref
|
11
12
|
from .odxtypes import BytesTypes, ParameterValue, ParameterValueDict
|
12
13
|
from .snrefcontext import SnRefContext
|
13
14
|
|
14
15
|
|
15
|
-
@dataclass
|
16
|
+
@dataclass(kw_only=True)
|
16
17
|
class MatchingParameter:
|
17
18
|
"""According to ISO 22901, a MatchingParameter contains a string
|
18
19
|
value identifying the active ECU or base variant. Moreover, it
|
@@ -34,12 +35,11 @@ class MatchingParameter:
|
|
34
35
|
# or negative response. What it probably actually wants to say is
|
35
36
|
# that any response that can possibly be received shall exhibit
|
36
37
|
# the referenced parameter.
|
37
|
-
out_param_if_snref: str | None
|
38
|
-
out_param_if_snpathref: str | None
|
38
|
+
out_param_if_snref: str | None = None
|
39
|
+
out_param_if_snpathref: str | None = None
|
39
40
|
|
40
41
|
@staticmethod
|
41
|
-
def from_et(et_element: ElementTree.Element,
|
42
|
-
doc_frags: list[OdxDocFragment]) -> "MatchingParameter":
|
42
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "MatchingParameter":
|
43
43
|
|
44
44
|
expected_value = odxrequire(et_element.findtext("EXPECTED-VALUE"))
|
45
45
|
diag_comm_snref = odxrequire(
|
odxtools/message.py
CHANGED
odxtools/minmaxlengthtype.py
CHANGED
@@ -10,15 +10,15 @@ from .diagcodedtype import DctType, DiagCodedType
|
|
10
10
|
from .encodestate import EncodeState
|
11
11
|
from .encoding import get_string_encoding
|
12
12
|
from .exceptions import DecodeError, EncodeError, odxassert, odxraise, odxrequire
|
13
|
-
from .
|
13
|
+
from .odxdoccontext import OdxDocContext
|
14
14
|
from .odxtypes import AtomicOdxType, BytesTypes, DataType
|
15
15
|
from .termination import Termination
|
16
16
|
from .utils import dataclass_fields_asdict
|
17
17
|
|
18
18
|
|
19
|
-
@dataclass
|
19
|
+
@dataclass(kw_only=True)
|
20
20
|
class MinMaxLengthType(DiagCodedType):
|
21
|
-
max_length: int | None
|
21
|
+
max_length: int | None = None
|
22
22
|
min_length: int
|
23
23
|
termination: Termination
|
24
24
|
|
@@ -28,9 +28,8 @@ class MinMaxLengthType(DiagCodedType):
|
|
28
28
|
|
29
29
|
@staticmethod
|
30
30
|
@override
|
31
|
-
def from_et(et_element: ElementTree.Element,
|
32
|
-
|
33
|
-
kwargs = dataclass_fields_asdict(DiagCodedType.from_et(et_element, doc_frags))
|
31
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "MinMaxLengthType":
|
32
|
+
kwargs = dataclass_fields_asdict(DiagCodedType.from_et(et_element, context))
|
34
33
|
|
35
34
|
max_length = None
|
36
35
|
if et_element.find("MAX-LENGTH") is not None:
|
@@ -77,7 +76,7 @@ class MinMaxLengthType(DiagCodedType):
|
|
77
76
|
@override
|
78
77
|
def encode_into_pdu(self, internal_value: AtomicOdxType, encode_state: EncodeState) -> None:
|
79
78
|
|
80
|
-
if not isinstance(internal_value, str
|
79
|
+
if not isinstance(internal_value, (str, BytesTypes)):
|
81
80
|
odxraise("MinMaxLengthType is currently only implemented for strings and byte arrays",
|
82
81
|
EncodeError)
|
83
82
|
|
odxtools/modification.py
CHANGED
@@ -4,17 +4,18 @@ from typing import Any
|
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .exceptions import odxrequire
|
7
|
-
from .
|
7
|
+
from .odxdoccontext import OdxDocContext
|
8
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
8
9
|
from .snrefcontext import SnRefContext
|
9
10
|
|
10
11
|
|
11
|
-
@dataclass
|
12
|
+
@dataclass(kw_only=True)
|
12
13
|
class Modification:
|
13
14
|
change: str
|
14
|
-
reason: str | None
|
15
|
+
reason: str | None = None
|
15
16
|
|
16
17
|
@staticmethod
|
17
|
-
def from_et(et_element: ElementTree.Element,
|
18
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Modification":
|
18
19
|
change = odxrequire(et_element.findtext("CHANGE"))
|
19
20
|
reason = et_element.findtext("REASON")
|
20
21
|
|
odxtools/multiplexer.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, cast
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
@@ -13,13 +13,14 @@ from .multiplexercase import MultiplexerCase
|
|
13
13
|
from .multiplexerdefaultcase import MultiplexerDefaultCase
|
14
14
|
from .multiplexerswitchkey import MultiplexerSwitchKey
|
15
15
|
from .nameditemlist import NamedItemList
|
16
|
-
from .
|
16
|
+
from .odxdoccontext import OdxDocContext
|
17
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
17
18
|
from .odxtypes import AtomicOdxType, ParameterValue, odxstr_to_bool
|
18
19
|
from .snrefcontext import SnRefContext
|
19
20
|
from .utils import dataclass_fields_asdict
|
20
21
|
|
21
22
|
|
22
|
-
@dataclass
|
23
|
+
@dataclass(kw_only=True)
|
23
24
|
class Multiplexer(ComplexDop):
|
24
25
|
"""This class represents a Multiplexer (MUX)
|
25
26
|
|
@@ -30,9 +31,9 @@ class Multiplexer(ComplexDop):
|
|
30
31
|
|
31
32
|
byte_position: int
|
32
33
|
switch_key: MultiplexerSwitchKey
|
33
|
-
default_case: MultiplexerDefaultCase | None
|
34
|
-
cases: NamedItemList[MultiplexerCase]
|
35
|
-
is_visible_raw: bool | None
|
34
|
+
default_case: MultiplexerDefaultCase | None = None
|
35
|
+
cases: NamedItemList[MultiplexerCase] = field(default_factory=NamedItemList)
|
36
|
+
is_visible_raw: bool | None = None
|
36
37
|
|
37
38
|
@property
|
38
39
|
def is_visible(self) -> bool:
|
@@ -40,20 +41,20 @@ class Multiplexer(ComplexDop):
|
|
40
41
|
|
41
42
|
@staticmethod
|
42
43
|
@override
|
43
|
-
def from_et(et_element: ElementTree.Element,
|
44
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Multiplexer":
|
44
45
|
"""Reads a Multiplexer from Diag Layer."""
|
45
|
-
kwargs = dataclass_fields_asdict(ComplexDop.from_et(et_element,
|
46
|
+
kwargs = dataclass_fields_asdict(ComplexDop.from_et(et_element, context))
|
46
47
|
|
47
48
|
byte_position = int(et_element.findtext("BYTE-POSITION", "0"))
|
48
49
|
switch_key = MultiplexerSwitchKey.from_et(
|
49
|
-
odxrequire(et_element.find("SWITCH-KEY")),
|
50
|
+
odxrequire(et_element.find("SWITCH-KEY")), context)
|
50
51
|
|
51
52
|
default_case = None
|
52
53
|
if (dc_elem := et_element.find("DEFAULT-CASE")) is not None:
|
53
|
-
default_case = MultiplexerDefaultCase.from_et(dc_elem,
|
54
|
+
default_case = MultiplexerDefaultCase.from_et(dc_elem, context)
|
54
55
|
|
55
56
|
cases = NamedItemList(
|
56
|
-
[MultiplexerCase.from_et(el,
|
57
|
+
[MultiplexerCase.from_et(el, context) for el in et_element.iterfind("CASES/CASE")])
|
57
58
|
|
58
59
|
is_visible_raw = odxstr_to_bool(et_element.get("IS-VISIBLE"))
|
59
60
|
|
@@ -118,7 +119,7 @@ class Multiplexer(ComplexDop):
|
|
118
119
|
orig_origin = encode_state.origin_byte_position
|
119
120
|
encode_state.origin_byte_position = encode_state.cursor_byte_position
|
120
121
|
|
121
|
-
if isinstance(physical_value, list
|
122
|
+
if isinstance(physical_value, (list, tuple)) and len(physical_value) == 2:
|
122
123
|
case_spec, case_value = physical_value
|
123
124
|
elif isinstance(physical_value, dict) and len(physical_value) == 1:
|
124
125
|
case_spec, case_value = next(iter(physical_value.items()))
|
@@ -235,3 +236,38 @@ class Multiplexer(ComplexDop):
|
|
235
236
|
decode_state.origin_byte_position = orig_origin
|
236
237
|
|
237
238
|
return result
|
239
|
+
|
240
|
+
@override
|
241
|
+
def get_static_bit_length(self) -> int | None:
|
242
|
+
"""
|
243
|
+
Returns the static bit length of the multiplexer structure, if determinable.
|
244
|
+
|
245
|
+
If all cases (including the default, if present) have the same static bit length,
|
246
|
+
the codec length is considered static and is returned.
|
247
|
+
Otherwise, returns None to indicate that the size is dynamic.
|
248
|
+
"""
|
249
|
+
reference_case = self.default_case if self.default_case else self.cases[0]
|
250
|
+
|
251
|
+
case_bit_length: int | None
|
252
|
+
if reference_case.structure is None:
|
253
|
+
case_bit_length = 0
|
254
|
+
else:
|
255
|
+
case_bit_length = reference_case.structure.get_static_bit_length()
|
256
|
+
if case_bit_length is None:
|
257
|
+
return None
|
258
|
+
case_size: int | None
|
259
|
+
for mux_case in self.cases:
|
260
|
+
if mux_case.structure is None:
|
261
|
+
case_size = 0
|
262
|
+
else:
|
263
|
+
case_size = mux_case.structure.get_static_bit_length()
|
264
|
+
if case_size != case_bit_length:
|
265
|
+
return None # Found a case with a different or unknown size
|
266
|
+
|
267
|
+
switch_key_size = self.switch_key.dop.get_static_bit_length()
|
268
|
+
if switch_key_size is None:
|
269
|
+
return None
|
270
|
+
|
271
|
+
return max(
|
272
|
+
switch_key_size + self.switch_key.byte_position * 8 +
|
273
|
+
(self.switch_key.bit_position or 0), case_bit_length + self.byte_position * 8)
|
odxtools/multiplexercase.py
CHANGED
@@ -6,19 +6,20 @@ from xml.etree import ElementTree
|
|
6
6
|
from .compumethods.limit import Limit
|
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, resolve_snref
|
10
11
|
from .odxtypes import AtomicOdxType, DataType
|
11
12
|
from .snrefcontext import SnRefContext
|
12
13
|
from .structure import Structure
|
13
14
|
from .utils import dataclass_fields_asdict
|
14
15
|
|
15
16
|
|
16
|
-
@dataclass
|
17
|
+
@dataclass(kw_only=True)
|
17
18
|
class MultiplexerCase(NamedElement):
|
18
19
|
"""This class represents a case which represents a range of keys of a multiplexer."""
|
19
20
|
|
20
|
-
structure_ref: OdxLinkRef | None
|
21
|
-
structure_snref: str | None
|
21
|
+
structure_ref: OdxLinkRef | None = None
|
22
|
+
structure_snref: str | None = None
|
22
23
|
lower_limit: Limit
|
23
24
|
upper_limit: Limit
|
24
25
|
|
@@ -27,23 +28,22 @@ class MultiplexerCase(NamedElement):
|
|
27
28
|
return self._structure
|
28
29
|
|
29
30
|
@staticmethod
|
30
|
-
def from_et(et_element: ElementTree.Element,
|
31
|
-
doc_frags: list[OdxDocFragment]) -> "MultiplexerCase":
|
31
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "MultiplexerCase":
|
32
32
|
"""Reads a case for a Multiplexer."""
|
33
|
-
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element,
|
34
|
-
structure_ref = OdxLinkRef.from_et(et_element.find("STRUCTURE-REF"),
|
33
|
+
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context))
|
34
|
+
structure_ref = OdxLinkRef.from_et(et_element.find("STRUCTURE-REF"), context)
|
35
35
|
structure_snref = None
|
36
36
|
if (structure_snref_elem := et_element.find("STRUCTURE-SNREF")) is not None:
|
37
37
|
structure_snref = odxrequire(structure_snref_elem.get("SHORT-NAME"))
|
38
38
|
|
39
39
|
lower_limit = Limit.limit_from_et(
|
40
40
|
odxrequire(et_element.find("LOWER-LIMIT")),
|
41
|
-
|
41
|
+
context,
|
42
42
|
value_type=None,
|
43
43
|
)
|
44
44
|
upper_limit = Limit.limit_from_et(
|
45
45
|
odxrequire(et_element.find("UPPER-LIMIT")),
|
46
|
-
|
46
|
+
context,
|
47
47
|
value_type=None,
|
48
48
|
)
|
49
49
|
|
@@ -5,17 +5,18 @@ 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 .structure import Structure
|
11
12
|
from .utils import dataclass_fields_asdict
|
12
13
|
|
13
14
|
|
14
|
-
@dataclass
|
15
|
+
@dataclass(kw_only=True)
|
15
16
|
class MultiplexerDefaultCase(NamedElement):
|
16
17
|
"""This class represents a Default Case, which is selected when there are no cases defined in the Multiplexer."""
|
17
|
-
structure_ref: OdxLinkRef | None
|
18
|
-
structure_snref: str | None
|
18
|
+
structure_ref: OdxLinkRef | None = None
|
19
|
+
structure_snref: str | None = None
|
19
20
|
|
20
21
|
@property
|
21
22
|
def structure(self) -> Structure | None:
|
@@ -23,11 +24,11 @@ class MultiplexerDefaultCase(NamedElement):
|
|
23
24
|
|
24
25
|
@staticmethod
|
25
26
|
def from_et(et_element: ElementTree.Element,
|
26
|
-
|
27
|
+
context: OdxDocContext) -> "MultiplexerDefaultCase":
|
27
28
|
"""Reads a default case for a multiplexer."""
|
28
|
-
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element,
|
29
|
+
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context))
|
29
30
|
|
30
|
-
structure_ref = OdxLinkRef.from_et(et_element.find("STRUCTURE-REF"),
|
31
|
+
structure_ref = OdxLinkRef.from_et(et_element.find("STRUCTURE-REF"), context)
|
31
32
|
structure_snref = None
|
32
33
|
if (structure_snref_elem := et_element.find("STRUCTURE-SNREF")) is not None:
|
33
34
|
structure_snref = odxrequire(structure_snref_elem.get("SHORT-NAME"))
|
odxtools/multiplexerswitchkey.py
CHANGED
@@ -5,17 +5,18 @@ from xml.etree import ElementTree
|
|
5
5
|
|
6
6
|
from .dataobjectproperty import DataObjectProperty
|
7
7
|
from .exceptions import odxrequire
|
8
|
-
from .
|
8
|
+
from .odxdoccontext import OdxDocContext
|
9
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
9
10
|
from .snrefcontext import SnRefContext
|
10
11
|
|
11
12
|
|
12
|
-
@dataclass
|
13
|
+
@dataclass(kw_only=True)
|
13
14
|
class MultiplexerSwitchKey:
|
14
15
|
"""
|
15
16
|
The object that determines the case to be used by a multiplexer
|
16
17
|
"""
|
17
18
|
byte_position: int
|
18
|
-
bit_position: int | None
|
19
|
+
bit_position: int | None = None
|
19
20
|
dop_ref: OdxLinkRef
|
20
21
|
|
21
22
|
@property
|
@@ -23,12 +24,11 @@ class MultiplexerSwitchKey:
|
|
23
24
|
return self._dop
|
24
25
|
|
25
26
|
@staticmethod
|
26
|
-
def from_et(et_element: ElementTree.Element,
|
27
|
-
doc_frags: list[OdxDocFragment]) -> "MultiplexerSwitchKey":
|
27
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "MultiplexerSwitchKey":
|
28
28
|
byte_position = int(odxrequire(et_element.findtext("BYTE-POSITION")))
|
29
29
|
bit_position_str = et_element.findtext("BIT-POSITION")
|
30
30
|
bit_position = int(bit_position_str) if bit_position_str is not None else None
|
31
|
-
dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DATA-OBJECT-PROP-REF"),
|
31
|
+
dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DATA-OBJECT-PROP-REF"), context))
|
32
32
|
|
33
33
|
return MultiplexerSwitchKey(
|
34
34
|
byte_position=byte_position,
|
odxtools/nameditemlist.py
CHANGED
@@ -142,7 +142,7 @@ class ItemAttributeList(list[T]):
|
|
142
142
|
...
|
143
143
|
|
144
144
|
def __getitem__(self, key: SupportsIndex | str | slice) -> T | list[T]:
|
145
|
-
if isinstance(key, SupportsIndex
|
145
|
+
if isinstance(key, (SupportsIndex, slice)):
|
146
146
|
return super().__getitem__(key)
|
147
147
|
else:
|
148
148
|
return self._item_dict[key]
|
odxtools/negoutputparam.py
CHANGED
@@ -6,12 +6,13 @@ from xml.etree import ElementTree
|
|
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,11 +22,10 @@ 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
|
|