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.
Files changed (193) hide show
  1. odxtools/additionalaudience.py +7 -7
  2. odxtools/admindata.py +14 -13
  3. odxtools/audience.py +17 -17
  4. odxtools/basecomparam.py +9 -8
  5. odxtools/basevariantpattern.py +9 -10
  6. odxtools/basicstructure.py +15 -15
  7. odxtools/cli/_print_utils.py +34 -22
  8. odxtools/cli/browse.py +8 -8
  9. odxtools/cli/compare.py +24 -24
  10. odxtools/cli/decode.py +3 -4
  11. odxtools/cli/find.py +4 -5
  12. odxtools/cli/list.py +6 -6
  13. odxtools/cli/main.py +2 -2
  14. odxtools/cli/snoop.py +3 -3
  15. odxtools/codec.py +3 -3
  16. odxtools/commrelation.py +18 -17
  17. odxtools/companydata.py +13 -13
  18. odxtools/companydocinfo.py +15 -17
  19. odxtools/companyrevisioninfo.py +9 -9
  20. odxtools/companyspecificinfo.py +11 -13
  21. odxtools/comparam.py +8 -7
  22. odxtools/comparaminstance.py +14 -14
  23. odxtools/comparamspec.py +10 -11
  24. odxtools/comparamsubset.py +17 -25
  25. odxtools/complexcomparam.py +14 -14
  26. odxtools/complexdop.py +1 -1
  27. odxtools/compositecodec.py +8 -8
  28. odxtools/compumethods/compucodecompumethod.py +7 -7
  29. odxtools/compumethods/compuconst.py +5 -6
  30. odxtools/compumethods/compudefaultvalue.py +2 -3
  31. odxtools/compumethods/compuinternaltophys.py +13 -12
  32. odxtools/compumethods/compumethod.py +10 -9
  33. odxtools/compumethods/compuphystointernal.py +13 -12
  34. odxtools/compumethods/compurationalcoeffs.py +7 -7
  35. odxtools/compumethods/compuscale.py +15 -16
  36. odxtools/compumethods/createanycompumethod.py +12 -13
  37. odxtools/compumethods/identicalcompumethod.py +4 -5
  38. odxtools/compumethods/limit.py +14 -14
  39. odxtools/compumethods/linearcompumethod.py +5 -5
  40. odxtools/compumethods/linearsegment.py +10 -11
  41. odxtools/compumethods/ratfunccompumethod.py +6 -6
  42. odxtools/compumethods/ratfuncsegment.py +7 -8
  43. odxtools/compumethods/scalelinearcompumethod.py +9 -9
  44. odxtools/compumethods/scaleratfunccompumethod.py +7 -7
  45. odxtools/compumethods/tabintpcompumethod.py +10 -13
  46. odxtools/compumethods/texttablecompumethod.py +6 -6
  47. odxtools/createanycomparam.py +5 -7
  48. odxtools/createanydiagcodedtype.py +7 -8
  49. odxtools/database.py +34 -31
  50. odxtools/dataobjectproperty.py +19 -20
  51. odxtools/decodestate.py +5 -5
  52. odxtools/description.py +9 -9
  53. odxtools/determinenumberofitems.py +8 -7
  54. odxtools/diagcodedtype.py +10 -10
  55. odxtools/diagcomm.py +29 -30
  56. odxtools/diagdatadictionaryspec.py +36 -36
  57. odxtools/diaglayercontainer.py +35 -34
  58. odxtools/diaglayers/basevariant.py +14 -12
  59. odxtools/diaglayers/basevariantraw.py +22 -23
  60. odxtools/diaglayers/diaglayer.py +24 -22
  61. odxtools/diaglayers/diaglayerraw.py +43 -52
  62. odxtools/diaglayers/diaglayertype.py +1 -2
  63. odxtools/diaglayers/ecushareddata.py +9 -9
  64. odxtools/diaglayers/ecushareddataraw.py +15 -16
  65. odxtools/diaglayers/ecuvariant.py +15 -13
  66. odxtools/diaglayers/ecuvariantraw.py +21 -22
  67. odxtools/diaglayers/functionalgroup.py +12 -11
  68. odxtools/diaglayers/functionalgroupraw.py +17 -18
  69. odxtools/diaglayers/hierarchyelement.py +48 -54
  70. odxtools/diaglayers/hierarchyelementraw.py +10 -11
  71. odxtools/diaglayers/protocol.py +7 -7
  72. odxtools/diaglayers/protocolraw.py +13 -14
  73. odxtools/diagnostictroublecode.py +15 -17
  74. odxtools/diagservice.py +28 -27
  75. odxtools/diagvariable.py +24 -25
  76. odxtools/docrevision.py +18 -17
  77. odxtools/dopbase.py +13 -14
  78. odxtools/dtcconnector.py +8 -7
  79. odxtools/dtcdop.py +24 -20
  80. odxtools/dynamicendmarkerfield.py +10 -9
  81. odxtools/dynamiclengthfield.py +10 -9
  82. odxtools/dyndefinedspec.py +10 -10
  83. odxtools/dynenddopref.py +9 -9
  84. odxtools/dyniddefmodeinfo.py +21 -21
  85. odxtools/ecuvariantpattern.py +8 -10
  86. odxtools/element.py +12 -13
  87. odxtools/encodestate.py +11 -11
  88. odxtools/encoding.py +2 -3
  89. odxtools/endofpdufield.py +9 -10
  90. odxtools/envdataconnector.py +8 -8
  91. odxtools/environmentdata.py +7 -9
  92. odxtools/environmentdatadescription.py +18 -17
  93. odxtools/exceptions.py +5 -5
  94. odxtools/externalaccessmethod.py +4 -6
  95. odxtools/externaldoc.py +6 -6
  96. odxtools/field.py +15 -15
  97. odxtools/functionalclass.py +9 -9
  98. odxtools/inputparam.py +11 -10
  99. odxtools/internalconstr.py +10 -11
  100. odxtools/isotp_state_machine.py +12 -11
  101. odxtools/leadinglengthinfotype.py +4 -6
  102. odxtools/library.py +9 -8
  103. odxtools/linkeddtcdop.py +9 -8
  104. odxtools/loadfile.py +5 -6
  105. odxtools/matchingbasevariantparameter.py +5 -6
  106. odxtools/matchingparameter.py +10 -10
  107. odxtools/message.py +1 -1
  108. odxtools/minmaxlengthtype.py +6 -7
  109. odxtools/modification.py +7 -6
  110. odxtools/multiplexer.py +54 -18
  111. odxtools/multiplexercase.py +13 -13
  112. odxtools/multiplexerdefaultcase.py +11 -10
  113. odxtools/multiplexerswitchkey.py +8 -8
  114. odxtools/nameditemlist.py +13 -13
  115. odxtools/negoutputparam.py +8 -8
  116. odxtools/obd.py +1 -2
  117. odxtools/odxcategory.py +14 -26
  118. odxtools/odxdoccontext.py +16 -0
  119. odxtools/odxlink.py +23 -25
  120. odxtools/odxtypes.py +18 -15
  121. odxtools/outputparam.py +9 -8
  122. odxtools/parameterinfo.py +1 -1
  123. odxtools/parameters/codedconstparameter.py +10 -10
  124. odxtools/parameters/createanyparameter.py +15 -16
  125. odxtools/parameters/dynamicparameter.py +5 -7
  126. odxtools/parameters/lengthkeyparameter.py +10 -10
  127. odxtools/parameters/matchingrequestparameter.py +6 -7
  128. odxtools/parameters/nrcconstparameter.py +13 -13
  129. odxtools/parameters/parameter.py +17 -18
  130. odxtools/parameters/parameterwithdop.py +13 -13
  131. odxtools/parameters/physicalconstantparameter.py +8 -7
  132. odxtools/parameters/reservedparameter.py +6 -8
  133. odxtools/parameters/systemparameter.py +5 -7
  134. odxtools/parameters/tableentryparameter.py +8 -8
  135. odxtools/parameters/tablekeyparameter.py +17 -17
  136. odxtools/parameters/tablestructparameter.py +11 -11
  137. odxtools/parameters/valueparameter.py +11 -11
  138. odxtools/paramlengthinfotype.py +10 -9
  139. odxtools/parentref.py +15 -13
  140. odxtools/physicaldimension.py +15 -15
  141. odxtools/physicaltype.py +5 -6
  142. odxtools/posresponsesuppressible.py +11 -12
  143. odxtools/preconditionstateref.py +11 -11
  144. odxtools/progcode.py +11 -10
  145. odxtools/protstack.py +10 -9
  146. odxtools/relateddiagcommref.py +5 -6
  147. odxtools/relateddoc.py +11 -10
  148. odxtools/request.py +18 -19
  149. odxtools/response.py +19 -20
  150. odxtools/scaleconstr.py +8 -9
  151. odxtools/servicebinner.py +5 -5
  152. odxtools/singleecujob.py +16 -15
  153. odxtools/snrefcontext.py +3 -3
  154. odxtools/specialdata.py +8 -7
  155. odxtools/specialdatagroup.py +17 -17
  156. odxtools/specialdatagroupcaption.py +7 -6
  157. odxtools/standardlengthtype.py +14 -22
  158. odxtools/state.py +7 -6
  159. odxtools/statechart.py +12 -11
  160. odxtools/statemachine.py +4 -3
  161. odxtools/statetransition.py +9 -9
  162. odxtools/statetransitionref.py +19 -19
  163. odxtools/staticfield.py +9 -7
  164. odxtools/structure.py +5 -6
  165. odxtools/subcomponent.py +20 -18
  166. odxtools/subcomponentparamconnector.py +10 -9
  167. odxtools/subcomponentpattern.py +9 -9
  168. odxtools/swvariable.py +6 -7
  169. odxtools/table.py +25 -26
  170. odxtools/tablediagcommconnector.py +9 -8
  171. odxtools/tablerow.py +64 -43
  172. odxtools/tablerowconnector.py +8 -8
  173. odxtools/teammember.py +16 -15
  174. odxtools/templates/macros/printParentRef.xml.jinja2 +3 -1
  175. odxtools/text.py +4 -5
  176. odxtools/uds.py +2 -3
  177. odxtools/unit.py +14 -13
  178. odxtools/unitgroup.py +11 -10
  179. odxtools/unitspec.py +18 -19
  180. odxtools/utils.py +3 -3
  181. odxtools/variablegroup.py +5 -6
  182. odxtools/variantmatcher.py +10 -10
  183. odxtools/variantpattern.py +5 -6
  184. odxtools/version.py +2 -2
  185. odxtools/writepdxfile.py +5 -24
  186. odxtools/xdoc.py +13 -12
  187. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/METADATA +4 -5
  188. odxtools-10.1.0.dist-info/RECORD +265 -0
  189. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/WHEEL +1 -1
  190. odxtools-9.7.0.dist-info/RECORD +0 -264
  191. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/entry_points.txt +0 -0
  192. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/licenses/LICENSE +0 -0
  193. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast
3
+ from typing import TYPE_CHECKING, Any, cast
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from typing_extensions import override
@@ -8,7 +8,8 @@ from typing_extensions import override
8
8
  from ..decodestate import DecodeState
9
9
  from ..encodestate import EncodeState
10
10
  from ..exceptions import DecodeError, EncodeError, odxraise, odxrequire
11
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
11
+ from ..odxdoccontext import OdxDocContext
12
+ from ..odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
12
13
  from ..odxtypes import ParameterValue
13
14
  from ..snrefcontext import SnRefContext
14
15
  from ..utils import dataclass_fields_asdict
@@ -19,10 +20,10 @@ if TYPE_CHECKING:
19
20
  from ..table import Table
20
21
 
21
22
 
22
- @dataclass
23
+ @dataclass(kw_only=True)
23
24
  class TableStructParameter(Parameter):
24
- table_key_ref: Optional[OdxLinkRef]
25
- table_key_snref: Optional[str]
25
+ table_key_ref: OdxLinkRef | None = None
26
+ table_key_snref: str | None = None
26
27
 
27
28
  @property
28
29
  @override
@@ -49,12 +50,11 @@ class TableStructParameter(Parameter):
49
50
 
50
51
  @staticmethod
51
52
  @override
52
- def from_et(et_element: ElementTree.Element,
53
- doc_frags: List[OdxDocFragment]) -> "TableStructParameter":
53
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "TableStructParameter":
54
54
 
55
- kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
55
+ kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, context))
56
56
 
57
- table_key_ref = OdxLinkRef.from_et(et_element.find("TABLE-KEY-REF"), doc_frags)
57
+ table_key_ref = OdxLinkRef.from_et(et_element.find("TABLE-KEY-REF"), context)
58
58
  table_key_snref = None
59
59
  if (table_key_snref_elem := et_element.find("TABLE-KEY-SNREF")) is not None:
60
60
  table_key_snref = odxrequire(table_key_snref_elem.get("SHORT-NAME"))
@@ -67,7 +67,7 @@ class TableStructParameter(Parameter):
67
67
  odxraise("Either table_key_ref or table_key_snref must be defined.")
68
68
 
69
69
  @override
70
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
70
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
71
71
  return super()._build_odxlinks()
72
72
 
73
73
  @override
@@ -86,7 +86,7 @@ class TableStructParameter(Parameter):
86
86
  TableKeyParameter)
87
87
 
88
88
  @override
89
- def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
89
+ def _encode_positioned_into_pdu(self, physical_value: ParameterValue | None,
90
90
  encode_state: EncodeState) -> None:
91
91
 
92
92
  if not isinstance(physical_value, (tuple, list)) or \
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List, Optional
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from typing_extensions import override
@@ -8,7 +8,8 @@ from typing_extensions import override
8
8
  from ..dataobjectproperty import DataObjectProperty
9
9
  from ..encodestate import EncodeState
10
10
  from ..exceptions import EncodeError, odxraise, odxrequire
11
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
11
+ from ..odxdoccontext import OdxDocContext
12
+ from ..odxlink import OdxLinkDatabase, OdxLinkId
12
13
  from ..odxtypes import AtomicOdxType, ParameterValue
13
14
  from ..snrefcontext import SnRefContext
14
15
  from ..utils import dataclass_fields_asdict
@@ -16,9 +17,9 @@ from .parameter import ParameterType
16
17
  from .parameterwithdop import ParameterWithDOP
17
18
 
18
19
 
19
- @dataclass
20
+ @dataclass(kw_only=True)
20
21
  class ValueParameter(ParameterWithDOP):
21
- physical_default_value_raw: Optional[str]
22
+ physical_default_value_raw: str | None = None
22
23
 
23
24
  @property
24
25
  @override
@@ -26,7 +27,7 @@ class ValueParameter(ParameterWithDOP):
26
27
  return "VALUE"
27
28
 
28
29
  @property
29
- def physical_default_value(self) -> Optional[AtomicOdxType]:
30
+ def physical_default_value(self) -> AtomicOdxType | None:
30
31
  return self._physical_default_value
31
32
 
32
33
  @property
@@ -41,20 +42,19 @@ class ValueParameter(ParameterWithDOP):
41
42
 
42
43
  @staticmethod
43
44
  @override
44
- def from_et(et_element: ElementTree.Element,
45
- doc_frags: List[OdxDocFragment]) -> "ValueParameter":
45
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ValueParameter":
46
46
 
47
- kwargs = dataclass_fields_asdict(ParameterWithDOP.from_et(et_element, doc_frags))
47
+ kwargs = dataclass_fields_asdict(ParameterWithDOP.from_et(et_element, context))
48
48
 
49
49
  physical_default_value_raw = et_element.findtext("PHYSICAL-DEFAULT-VALUE")
50
50
 
51
51
  return ValueParameter(physical_default_value_raw=physical_default_value_raw, **kwargs)
52
52
 
53
53
  def __post_init__(self) -> None:
54
- self._physical_default_value: Optional[AtomicOdxType] = None
54
+ self._physical_default_value: AtomicOdxType | None = None
55
55
 
56
56
  @override
57
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
57
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
58
58
  return super()._build_odxlinks()
59
59
 
60
60
  @override
@@ -75,7 +75,7 @@ class ValueParameter(ParameterWithDOP):
75
75
  self.physical_default_value_raw)
76
76
 
77
77
  @override
78
- def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
78
+ def _encode_positioned_into_pdu(self, physical_value: ParameterValue | None,
79
79
  encode_state: EncodeState) -> None:
80
80
 
81
81
  if physical_value is None:
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, Any, Dict, List, cast
3
+ from typing import TYPE_CHECKING, Any, cast
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from typing_extensions import override
@@ -9,7 +9,8 @@ from .decodestate import DecodeState
9
9
  from .diagcodedtype import DctType, DiagCodedType
10
10
  from .encodestate import EncodeState
11
11
  from .exceptions import EncodeError, odxraise, odxrequire
12
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
12
+ from .odxdoccontext import OdxDocContext
13
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
13
14
  from .odxtypes import AtomicOdxType, DataType
14
15
  from .snrefcontext import SnRefContext
15
16
  from .utils import dataclass_fields_asdict
@@ -18,7 +19,7 @@ if TYPE_CHECKING:
18
19
  from .parameters.lengthkeyparameter import LengthKeyParameter
19
20
 
20
21
 
21
- @dataclass
22
+ @dataclass(kw_only=True)
22
23
  class ParamLengthInfoType(DiagCodedType):
23
24
  length_key_ref: OdxLinkRef
24
25
 
@@ -32,16 +33,14 @@ class ParamLengthInfoType(DiagCodedType):
32
33
 
33
34
  @staticmethod
34
35
  @override
35
- def from_et(et_element: ElementTree.Element,
36
- doc_frags: List[OdxDocFragment]) -> "ParamLengthInfoType":
37
- kwargs = dataclass_fields_asdict(DiagCodedType.from_et(et_element, doc_frags))
36
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ParamLengthInfoType":
37
+ kwargs = dataclass_fields_asdict(DiagCodedType.from_et(et_element, context))
38
38
 
39
- length_key_ref = odxrequire(
40
- OdxLinkRef.from_et(et_element.find("LENGTH-KEY-REF"), doc_frags))
39
+ length_key_ref = odxrequire(OdxLinkRef.from_et(et_element.find("LENGTH-KEY-REF"), context))
41
40
 
42
41
  return ParamLengthInfoType(length_key_ref=length_key_ref, **kwargs)
43
42
 
44
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
43
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
45
44
  return super()._build_odxlinks()
46
45
 
47
46
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
@@ -74,6 +73,8 @@ class ParamLengthInfoType(DiagCodedType):
74
73
  elif self.base_data_type in [DataType.A_UNICODE2STRING]:
75
74
  bit_length = 16 * len(cast(str, internal_value))
76
75
  elif self.base_data_type in [DataType.A_INT32, DataType.A_UINT32]:
76
+ if not isinstance(internal_value, int):
77
+ odxraise()
77
78
  bit_length = int(internal_value).bit_length()
78
79
  if self.base_data_type == DataType.A_INT32:
79
80
  bit_length += 1
odxtools/parentref.py CHANGED
@@ -1,11 +1,12 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from copy import deepcopy
3
- from dataclasses import dataclass
4
- from typing import TYPE_CHECKING, Any, Dict, List
3
+ from dataclasses import dataclass, field
4
+ from typing import TYPE_CHECKING, Any
5
5
  from xml.etree import ElementTree
6
6
 
7
7
  from .exceptions import odxrequire
8
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
8
+ from .odxdoccontext import OdxDocContext
9
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
9
10
  from .snrefcontext import SnRefContext
10
11
  from .utils import dataclass_fields_asdict
11
12
 
@@ -13,23 +14,24 @@ if TYPE_CHECKING:
13
14
  from .diaglayers.diaglayer import DiagLayer
14
15
 
15
16
 
16
- @dataclass
17
+ @dataclass(kw_only=True)
17
18
  class ParentRef:
18
19
  layer_ref: OdxLinkRef
19
- not_inherited_diag_comms: List[str] # short_name references
20
- not_inherited_variables: List[str] # short_name references
21
- not_inherited_dops: List[str] # short_name references
22
- not_inherited_tables: List[str] # short_name references
23
- not_inherited_global_neg_responses: List[str] # short_name references
20
+ not_inherited_diag_comms: list[str] = field(default_factory=list) # short_name references
21
+ not_inherited_variables: list[str] = field(default_factory=list) # short_name references
22
+ not_inherited_dops: list[str] = field(default_factory=list) # short_name references
23
+ not_inherited_tables: list[str] = field(default_factory=list) # short_name references
24
+ not_inherited_global_neg_responses: list[str] = field(
25
+ default_factory=list) # short_name references
24
26
 
25
27
  @property
26
28
  def layer(self) -> "DiagLayer":
27
29
  return self._layer
28
30
 
29
31
  @staticmethod
30
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "ParentRef":
32
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ParentRef":
31
33
 
32
- layer_ref = odxrequire(OdxLinkRef.from_et(et_element, doc_frags))
34
+ layer_ref = odxrequire(OdxLinkRef.from_et(et_element, context))
33
35
 
34
36
  not_inherited_diag_comms = [
35
37
  odxrequire(el.get("SHORT-NAME"))
@@ -69,7 +71,7 @@ class ParentRef:
69
71
  not_inherited_global_neg_responses=not_inherited_global_neg_responses,
70
72
  )
71
73
 
72
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
74
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
73
75
  return {}
74
76
 
75
77
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
@@ -81,7 +83,7 @@ class ParentRef:
81
83
  def _resolve_snrefs(self, context: SnRefContext) -> None:
82
84
  pass
83
85
 
84
- def __deepcopy__(self, memo: Dict[int, Any]) -> Any:
86
+ def __deepcopy__(self, memo: dict[int, Any]) -> Any:
85
87
  cls = self.__class__
86
88
  result = cls.__new__(cls)
87
89
  memo[id(self)] = result
@@ -1,15 +1,16 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List, Optional
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .element import IdentifiableElement
7
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
7
+ from .odxdoccontext import OdxDocContext
8
+ from .odxlink import OdxLinkDatabase, OdxLinkId
8
9
  from .snrefcontext import SnRefContext
9
10
  from .utils import dataclass_fields_asdict
10
11
 
11
12
 
12
- @dataclass
13
+ @dataclass(kw_only=True)
13
14
  class PhysicalDimension(IdentifiableElement):
14
15
  """A physical dimension is a formal definition of a unit.
15
16
 
@@ -41,20 +42,19 @@ class PhysicalDimension(IdentifiableElement):
41
42
  )
42
43
  ```
43
44
  """
44
- length_exp: Optional[int]
45
- mass_exp: Optional[int]
46
- time_exp: Optional[int]
47
- current_exp: Optional[int]
48
- temperature_exp: Optional[int]
49
- molar_amount_exp: Optional[int]
50
- luminous_intensity_exp: Optional[int]
45
+ length_exp: int | None = None
46
+ mass_exp: int | None = None
47
+ time_exp: int | None = None
48
+ current_exp: int | None = None
49
+ temperature_exp: int | None = None
50
+ molar_amount_exp: int | None = None
51
+ luminous_intensity_exp: int | None = None
51
52
 
52
53
  @staticmethod
53
- def from_et(et_element: ElementTree.Element,
54
- doc_frags: List[OdxDocFragment]) -> "PhysicalDimension":
55
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
54
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "PhysicalDimension":
55
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
56
56
 
57
- def read_optional_int(element: ElementTree.Element, name: str) -> Optional[int]:
57
+ def read_optional_int(element: ElementTree.Element, name: str) -> int | None:
58
58
  if (val_str := element.findtext(name)) is not None:
59
59
  return int(val_str)
60
60
  else:
@@ -78,7 +78,7 @@ class PhysicalDimension(IdentifiableElement):
78
78
  luminous_intensity_exp=luminous_intensity_exp,
79
79
  **kwargs)
80
80
 
81
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
81
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
82
82
  return {self.odx_id: self}
83
83
 
84
84
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
odxtools/physicaltype.py CHANGED
@@ -1,15 +1,14 @@
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 .exceptions import odxraise
7
- from .odxlink import OdxDocFragment
6
+ from .odxdoccontext import OdxDocContext
8
7
  from .odxtypes import DataType
9
8
  from .radix import Radix
10
9
 
11
10
 
12
- @dataclass
11
+ @dataclass(kw_only=True)
13
12
  class PhysicalType:
14
13
  """The physical type describes the base data type of a parameter.
15
14
 
@@ -32,20 +31,20 @@ class PhysicalType:
32
31
  PhysicalType(DataType.A_FLOAT64, precision=2)
33
32
  """
34
33
 
35
- precision: Optional[int]
34
+ precision: int | None = None
36
35
  """Number of digits after the decimal point to display to the user
37
36
  The precision is only applicable if the base data type is A_FLOAT32 or A_FLOAT64.
38
37
  """
39
38
 
40
39
  base_data_type: DataType
41
40
 
42
- display_radix: Optional[Radix]
41
+ display_radix: Radix | None = None
43
42
  """The display radix defines how integers are displayed to the user.
44
43
  The display radix is only applicable if the base data type is A_UINT32.
45
44
  """
46
45
 
47
46
  @staticmethod
48
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "PhysicalType":
47
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "PhysicalType":
49
48
  precision_str = et_element.findtext("PRECISION")
50
49
  precision = int(precision_str) if precision_str is not None else None
51
50
 
@@ -1,34 +1,33 @@
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 .exceptions import odxrequire
7
- from .odxlink import OdxDocFragment
6
+ from .odxdoccontext import OdxDocContext
8
7
  from .utils import read_hex_binary
9
8
 
10
9
 
11
10
  # note that the spec has a typo here: it calls the corresponding
12
11
  # XML tag POS-RESPONSE-SUPPRESSABLE...
13
- @dataclass
12
+ @dataclass(kw_only=True)
14
13
  class PosResponseSuppressible:
15
14
  bit_mask: int
16
15
 
17
- coded_const_snref: Optional[str]
18
- coded_const_snpathref: Optional[str]
16
+ coded_const_snref: str | None = None
17
+ coded_const_snpathref: str | None = None
19
18
 
20
- value_snref: Optional[str]
21
- value_snpathref: Optional[str]
19
+ value_snref: str | None = None
20
+ value_snpathref: str | None = None
22
21
 
23
- phys_const_snref: Optional[str]
24
- phys_const_snpathref: Optional[str]
22
+ phys_const_snref: str | None = None
23
+ phys_const_snpathref: str | None = None
25
24
 
26
- table_key_snref: Optional[str]
27
- table_key_snpathref: Optional[str]
25
+ table_key_snref: str | None = None
26
+ table_key_snpathref: str | None = None
28
27
 
29
28
  @staticmethod
30
29
  def from_et(et_element: ElementTree.Element,
31
- doc_frags: List[OdxDocFragment]) -> "PosResponseSuppressible":
30
+ context: OdxDocContext) -> "PosResponseSuppressible":
32
31
 
33
32
  bit_mask = odxrequire(read_hex_binary(et_element.find("BIT-MASK")))
34
33
 
@@ -1,10 +1,11 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, Any, Dict, List, Optional
3
+ from typing import TYPE_CHECKING, Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .exceptions import odxassert, odxrequire
7
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
7
+ from .odxdoccontext import OdxDocContext
8
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
8
9
  from .odxtypes import ParameterValueDict
9
10
  from .parameters.parameter import Parameter
10
11
  from .snrefcontext import SnRefContext
@@ -16,15 +17,15 @@ if TYPE_CHECKING:
16
17
  from .statemachine import StateMachine
17
18
 
18
19
 
19
- @dataclass
20
+ @dataclass(kw_only=True)
20
21
  class PreConditionStateRef(OdxLinkRef):
21
22
  """
22
23
  This class represents the PRE-CONDITION-STATE-REF XML tag.
23
24
  """
24
- value: Optional[str]
25
+ value: str | None = None
25
26
 
26
- in_param_if_snref: Optional[str]
27
- in_param_if_snpathref: Optional[str]
27
+ in_param_if_snref: str | None = None
28
+ in_param_if_snpathref: str | None = None
28
29
 
29
30
  @property
30
31
  def state(self) -> "State":
@@ -32,9 +33,8 @@ class PreConditionStateRef(OdxLinkRef):
32
33
 
33
34
  @staticmethod
34
35
  def from_et( # type: ignore[override]
35
- et_element: ElementTree.Element,
36
- doc_frags: List[OdxDocFragment]) -> "PreConditionStateRef":
37
- kwargs = dataclass_fields_asdict(OdxLinkRef.from_et(et_element, doc_frags))
36
+ et_element: ElementTree.Element, context: OdxDocContext) -> "PreConditionStateRef":
37
+ kwargs = dataclass_fields_asdict(OdxLinkRef.from_et(et_element, context))
38
38
 
39
39
  value = et_element.findtext("VALUE")
40
40
 
@@ -57,7 +57,7 @@ class PreConditionStateRef(OdxLinkRef):
57
57
  odxassert(self.in_param_if_snref is not None or self.in_param_if_snref is not None,
58
58
  "If VALUE is specified, a parameter must be referenced")
59
59
 
60
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
60
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
61
61
  return {}
62
62
 
63
63
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
@@ -66,7 +66,7 @@ class PreConditionStateRef(OdxLinkRef):
66
66
  def _resolve_snrefs(self, context: SnRefContext) -> None:
67
67
  pass
68
68
 
69
- def applies(self, state_machine: "StateMachine", params: List[Parameter],
69
+ def applies(self, state_machine: "StateMachine", params: list[Parameter],
70
70
  param_value_dict: ParameterValueDict) -> bool:
71
71
  """Given a state machine, evaluate whether the precondition is fulfilled or not
72
72
 
odxtools/progcode.py CHANGED
@@ -1,24 +1,25 @@
1
1
  # SPDX-License-Identifier: MIT
2
- from dataclasses import dataclass
3
- from typing import Any, Dict, List, Optional, cast
2
+ from dataclasses import dataclass, field
3
+ from typing import Any, cast
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .exceptions import odxraise, odxrequire
7
7
  from .library import Library
8
8
  from .nameditemlist import NamedItemList
9
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
9
+ from .odxdoccontext import OdxDocContext
10
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
10
11
  from .snrefcontext import SnRefContext
11
12
 
12
13
 
13
- @dataclass
14
+ @dataclass(kw_only=True)
14
15
  class ProgCode:
15
16
  """A reference to code that is executed by a single ECU job"""
16
17
  code_file: str
17
- encryption: Optional[str]
18
+ encryption: str | None = None
18
19
  syntax: str
19
20
  revision: str
20
- entrypoint: Optional[str]
21
- library_refs: List[OdxLinkRef]
21
+ entrypoint: str | None = None
22
+ library_refs: list[OdxLinkRef] = field(default_factory=list)
22
23
 
23
24
  @property
24
25
  def code(self) -> bytes:
@@ -29,7 +30,7 @@ class ProgCode:
29
30
  return self._libraries
30
31
 
31
32
  @staticmethod
32
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "ProgCode":
33
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ProgCode":
33
34
  code_file = odxrequire(et_element.findtext("CODE-FILE"))
34
35
  encryption = et_element.findtext("ENCRYPTION")
35
36
  syntax = odxrequire(et_element.findtext("SYNTAX"))
@@ -37,7 +38,7 @@ class ProgCode:
37
38
  entrypoint = et_element.findtext("ENTRYPOINT")
38
39
 
39
40
  library_refs = [
40
- odxrequire(OdxLinkRef.from_et(el, doc_frags))
41
+ odxrequire(OdxLinkRef.from_et(el, context))
41
42
  for el in et_element.iterfind("LIBRARY-REFS/LIBRARY-REF")
42
43
  ]
43
44
 
@@ -50,7 +51,7 @@ class ProgCode:
50
51
  library_refs=library_refs,
51
52
  )
52
53
 
53
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
54
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
54
55
  return {}
55
56
 
56
57
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
odxtools/protstack.py CHANGED
@@ -1,36 +1,37 @@
1
1
  # SPDX-License-Identifier: MIT
2
- from dataclasses import dataclass
3
- from typing import Any, Dict, List
2
+ from dataclasses import dataclass, field
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .comparamsubset import ComparamSubset
7
7
  from .element import IdentifiableElement
8
8
  from .exceptions import odxrequire
9
9
  from .nameditemlist import NamedItemList
10
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
10
+ from .odxdoccontext import OdxDocContext
11
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
11
12
  from .snrefcontext import SnRefContext
12
13
  from .utils import dataclass_fields_asdict
13
14
 
14
15
 
15
- @dataclass
16
+ @dataclass(kw_only=True)
16
17
  class ProtStack(IdentifiableElement):
17
18
  # mandatory in ODX 2.2, but non existent in ODX 2.0
18
19
  pdu_protocol_type: str
19
20
  physical_link_type: str
20
- comparam_subset_refs: List[OdxLinkRef]
21
+ comparam_subset_refs: list[OdxLinkRef] = field(default_factory=list)
21
22
 
22
23
  @property
23
24
  def comparam_subsets(self) -> NamedItemList[ComparamSubset]:
24
25
  return self._comparam_subsets
25
26
 
26
27
  @staticmethod
27
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "ProtStack":
28
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
28
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ProtStack":
29
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
29
30
 
30
31
  pdu_protocol_type = odxrequire(et_element.findtext("PDU-PROTOCOL-TYPE"))
31
32
  physical_link_type = odxrequire(et_element.findtext("PHYSICAL-LINK-TYPE"))
32
33
  comparam_subset_refs = [
33
- OdxLinkRef.from_et(csr_element, doc_frags)
34
+ OdxLinkRef.from_et(csr_element, context)
34
35
  for csr_element in et_element.iterfind("COMPARAM-SUBSET-REFS/"
35
36
  "COMPARAM-SUBSET-REF")
36
37
  ]
@@ -41,7 +42,7 @@ class ProtStack(IdentifiableElement):
41
42
  comparam_subset_refs=comparam_subset_refs,
42
43
  **kwargs)
43
44
 
44
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
45
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
45
46
  result = {self.odx_id: self}
46
47
  return result
47
48
 
@@ -1,22 +1,21 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import List
4
3
  from xml.etree import ElementTree
5
4
 
6
5
  from .exceptions import odxrequire
7
- from .odxlink import OdxDocFragment, OdxLinkRef
6
+ from .odxdoccontext import OdxDocContext
7
+ from .odxlink import OdxLinkRef
8
8
  from .utils import dataclass_fields_asdict
9
9
 
10
10
 
11
- @dataclass
11
+ @dataclass(kw_only=True)
12
12
  class RelatedDiagCommRef(OdxLinkRef):
13
13
  relation_type: str
14
14
 
15
15
  @staticmethod
16
16
  def from_et( # type: ignore[override]
17
- et_element: ElementTree.Element,
18
- doc_frags: List[OdxDocFragment]) -> "RelatedDiagCommRef":
19
- kwargs = dataclass_fields_asdict(odxrequire(OdxLinkRef.from_et(et_element, doc_frags)))
17
+ et_element: ElementTree.Element, context: OdxDocContext) -> "RelatedDiagCommRef":
18
+ kwargs = dataclass_fields_asdict(odxrequire(OdxLinkRef.from_et(et_element, context)))
20
19
 
21
20
  relation_type = odxrequire(et_element.findtext("RELATION-TYPE"))
22
21
 
odxtools/relateddoc.py CHANGED
@@ -1,32 +1,33 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List, Optional
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .description import Description
7
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
7
+ from .odxdoccontext import OdxDocContext
8
+ from .odxlink import OdxLinkDatabase, OdxLinkId
8
9
  from .snrefcontext import SnRefContext
9
10
  from .xdoc import XDoc
10
11
 
11
12
 
12
- @dataclass
13
+ @dataclass(kw_only=True)
13
14
  class RelatedDoc:
14
- xdoc: Optional[XDoc]
15
- description: Optional[Description]
15
+ xdoc: XDoc | None = None
16
+ description: Description | None = None
16
17
 
17
18
  @staticmethod
18
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "RelatedDoc":
19
- xdoc: Optional[XDoc] = None
19
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "RelatedDoc":
20
+ xdoc: XDoc | None = None
20
21
  if (xdoc_elem := et_element.find("XDOC")) is not None:
21
- xdoc = XDoc.from_et(xdoc_elem, doc_frags)
22
- description = Description.from_et(et_element.find("DESC"), doc_frags)
22
+ xdoc = XDoc.from_et(xdoc_elem, context)
23
+ description = Description.from_et(et_element.find("DESC"), context)
23
24
 
24
25
  return RelatedDoc(
25
26
  xdoc=xdoc,
26
27
  description=description,
27
28
  )
28
29
 
29
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
30
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
30
31
  result = {}
31
32
 
32
33
  if self.xdoc: