odxtools 9.6.1__py3-none-any.whl → 10.0.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 (203) hide show
  1. odxtools/additionalaudience.py +3 -3
  2. odxtools/addressing.py +8 -0
  3. odxtools/admindata.py +8 -8
  4. odxtools/audience.py +10 -10
  5. odxtools/basecomparam.py +7 -20
  6. odxtools/basevariantpattern.py +4 -5
  7. odxtools/basicstructure.py +12 -11
  8. odxtools/cli/_print_utils.py +35 -23
  9. odxtools/cli/browse.py +9 -9
  10. odxtools/cli/compare.py +24 -24
  11. odxtools/cli/decode.py +3 -4
  12. odxtools/cli/find.py +4 -5
  13. odxtools/cli/list.py +7 -7
  14. odxtools/cli/main.py +2 -2
  15. odxtools/cli/snoop.py +3 -3
  16. odxtools/codec.py +3 -186
  17. odxtools/commrelation.py +12 -19
  18. odxtools/commrelationvaluetype.py +9 -0
  19. odxtools/companydata.py +5 -5
  20. odxtools/companydocinfo.py +8 -8
  21. odxtools/companyrevisioninfo.py +5 -5
  22. odxtools/companyspecificinfo.py +5 -5
  23. odxtools/comparam.py +3 -3
  24. odxtools/comparaminstance.py +10 -10
  25. odxtools/comparamspec.py +3 -3
  26. odxtools/comparamsubset.py +5 -5
  27. odxtools/complexcomparam.py +7 -7
  28. odxtools/compositecodec.py +191 -0
  29. odxtools/compumethods/compucategory.py +13 -0
  30. odxtools/compumethods/compucodecompumethod.py +6 -5
  31. odxtools/compumethods/compuconst.py +4 -5
  32. odxtools/compumethods/compudefaultvalue.py +1 -2
  33. odxtools/compumethods/compuinternaltophys.py +6 -6
  34. odxtools/compumethods/compumethod.py +6 -17
  35. odxtools/compumethods/compuphystointernal.py +6 -6
  36. odxtools/compumethods/compurationalcoeffs.py +4 -4
  37. odxtools/compumethods/compuscale.py +9 -10
  38. odxtools/compumethods/createanycompumethod.py +1 -2
  39. odxtools/compumethods/identicalcompumethod.py +1 -2
  40. odxtools/compumethods/intervaltype.py +8 -0
  41. odxtools/compumethods/limit.py +13 -19
  42. odxtools/compumethods/linearcompumethod.py +4 -3
  43. odxtools/compumethods/linearsegment.py +14 -15
  44. odxtools/compumethods/ratfunccompumethod.py +5 -4
  45. odxtools/compumethods/ratfuncsegment.py +7 -8
  46. odxtools/compumethods/scalelinearcompumethod.py +10 -9
  47. odxtools/compumethods/scaleratfunccompumethod.py +6 -5
  48. odxtools/compumethods/tabintpcompumethod.py +19 -20
  49. odxtools/compumethods/texttablecompumethod.py +5 -4
  50. odxtools/createanycomparam.py +2 -4
  51. odxtools/createanydiagcodedtype.py +1 -2
  52. odxtools/database.py +9 -8
  53. odxtools/dataobjectproperty.py +10 -10
  54. odxtools/decodestate.py +5 -5
  55. odxtools/description.py +6 -22
  56. odxtools/determinenumberofitems.py +4 -4
  57. odxtools/diagclasstype.py +11 -0
  58. odxtools/diagcodedtype.py +7 -7
  59. odxtools/diagcomm.py +19 -42
  60. odxtools/diagdatadictionaryspec.py +6 -6
  61. odxtools/diaglayercontainer.py +4 -4
  62. odxtools/diaglayers/basevariant.py +10 -9
  63. odxtools/diaglayers/basevariantraw.py +9 -9
  64. odxtools/diaglayers/diaglayer.py +20 -19
  65. odxtools/diaglayers/diaglayerraw.py +10 -10
  66. odxtools/diaglayers/diaglayertype.py +1 -2
  67. odxtools/diaglayers/ecushareddata.py +4 -4
  68. odxtools/diaglayers/ecushareddataraw.py +6 -6
  69. odxtools/diaglayers/ecuvariant.py +11 -10
  70. odxtools/diaglayers/ecuvariantraw.py +9 -9
  71. odxtools/diaglayers/functionalgroup.py +8 -7
  72. odxtools/diaglayers/functionalgroupraw.py +7 -7
  73. odxtools/diaglayers/hierarchyelement.py +43 -49
  74. odxtools/diaglayers/hierarchyelementraw.py +4 -4
  75. odxtools/diaglayers/protocol.py +4 -4
  76. odxtools/diaglayers/protocolraw.py +6 -6
  77. odxtools/diagnostictroublecode.py +8 -8
  78. odxtools/diagservice.py +21 -97
  79. odxtools/diagvariable.py +14 -14
  80. odxtools/docrevision.py +11 -11
  81. odxtools/dopbase.py +6 -6
  82. odxtools/dtcconnector.py +45 -0
  83. odxtools/dtcdop.py +15 -56
  84. odxtools/dynamicendmarkerfield.py +5 -4
  85. odxtools/dynamiclengthfield.py +5 -4
  86. odxtools/dyndefinedspec.py +7 -159
  87. odxtools/dynenddopref.py +5 -5
  88. odxtools/dyniddefmodeinfo.py +161 -0
  89. odxtools/ecuvariantpattern.py +4 -5
  90. odxtools/element.py +5 -6
  91. odxtools/encodestate.py +11 -11
  92. odxtools/encoding.py +2 -3
  93. odxtools/endofpdufield.py +6 -6
  94. odxtools/envdataconnector.py +49 -0
  95. odxtools/environmentdata.py +3 -4
  96. odxtools/environmentdatadescription.py +11 -11
  97. odxtools/exceptions.py +5 -5
  98. odxtools/externalaccessmethod.py +22 -0
  99. odxtools/externaldoc.py +23 -0
  100. odxtools/field.py +9 -10
  101. odxtools/functionalclass.py +4 -4
  102. odxtools/inputparam.py +6 -6
  103. odxtools/internalconstr.py +4 -5
  104. odxtools/isotp_state_machine.py +12 -11
  105. odxtools/leadinglengthinfotype.py +2 -3
  106. odxtools/library.py +5 -5
  107. odxtools/linkeddtcdop.py +62 -0
  108. odxtools/loadfile.py +5 -6
  109. odxtools/matchingbasevariantparameter.py +2 -3
  110. odxtools/matchingparameter.py +7 -7
  111. odxtools/minmaxlengthtype.py +5 -11
  112. odxtools/modification.py +4 -4
  113. odxtools/multiplexer.py +11 -11
  114. odxtools/multiplexercase.py +6 -6
  115. odxtools/multiplexerdefaultcase.py +6 -6
  116. odxtools/multiplexerswitchkey.py +4 -4
  117. odxtools/nameditemlist.py +14 -14
  118. odxtools/negoutputparam.py +3 -3
  119. odxtools/obd.py +1 -2
  120. odxtools/odxcategory.py +6 -6
  121. odxtools/odxlink.py +19 -20
  122. odxtools/odxtypes.py +21 -18
  123. odxtools/outputparam.py +4 -4
  124. odxtools/parameterinfo.py +2 -2
  125. odxtools/parameters/codedconstparameter.py +5 -5
  126. odxtools/parameters/createanyparameter.py +1 -2
  127. odxtools/parameters/dynamicparameter.py +2 -3
  128. odxtools/parameters/lengthkeyparameter.py +5 -5
  129. odxtools/parameters/matchingrequestparameter.py +3 -4
  130. odxtools/parameters/nrcconstparameter.py +7 -7
  131. odxtools/parameters/parameter.py +11 -11
  132. odxtools/parameters/parameterwithdop.py +9 -9
  133. odxtools/parameters/physicalconstantparameter.py +4 -4
  134. odxtools/parameters/reservedparameter.py +3 -4
  135. odxtools/parameters/rowfragment.py +7 -0
  136. odxtools/parameters/systemparameter.py +2 -3
  137. odxtools/parameters/tableentryparameter.py +4 -9
  138. odxtools/parameters/tablekeyparameter.py +10 -10
  139. odxtools/parameters/tablestructparameter.py +7 -7
  140. odxtools/parameters/valueparameter.py +7 -7
  141. odxtools/paramlengthinfotype.py +5 -3
  142. odxtools/parentref.py +9 -9
  143. odxtools/physicaldimension.py +11 -11
  144. odxtools/physicaltype.py +4 -12
  145. odxtools/posresponsesuppressible.py +72 -0
  146. odxtools/preconditionstateref.py +7 -7
  147. odxtools/progcode.py +6 -6
  148. odxtools/protstack.py +4 -4
  149. odxtools/radix.py +9 -0
  150. odxtools/relateddiagcommref.py +22 -0
  151. odxtools/relateddoc.py +6 -6
  152. odxtools/request.py +14 -12
  153. odxtools/response.py +15 -13
  154. odxtools/scaleconstr.py +4 -12
  155. odxtools/servicebinner.py +5 -5
  156. odxtools/singleecujob.py +4 -4
  157. odxtools/snrefcontext.py +2 -2
  158. odxtools/specialdata.py +5 -5
  159. odxtools/specialdatagroup.py +9 -9
  160. odxtools/specialdatagroupcaption.py +3 -3
  161. odxtools/standardizationlevel.py +9 -0
  162. odxtools/standardlengthtype.py +12 -21
  163. odxtools/state.py +3 -3
  164. odxtools/statechart.py +4 -4
  165. odxtools/statemachine.py +4 -3
  166. odxtools/statetransition.py +5 -18
  167. odxtools/statetransitionref.py +18 -18
  168. odxtools/staticfield.py +5 -4
  169. odxtools/structure.py +2 -3
  170. odxtools/subcomponent.py +12 -245
  171. odxtools/subcomponentparamconnector.py +103 -0
  172. odxtools/subcomponentpattern.py +42 -0
  173. odxtools/swvariable.py +3 -4
  174. odxtools/table.py +17 -55
  175. odxtools/tablediagcommconnector.py +47 -0
  176. odxtools/tablerow.py +30 -30
  177. odxtools/tablerowconnector.py +46 -0
  178. odxtools/teammember.py +11 -11
  179. odxtools/templates/macros/printService.xml.jinja2 +2 -1
  180. odxtools/termination.py +8 -0
  181. odxtools/text.py +2 -3
  182. odxtools/transmode.py +9 -0
  183. odxtools/uds.py +2 -3
  184. odxtools/unit.py +9 -9
  185. odxtools/unitgroup.py +6 -11
  186. odxtools/unitgroupcategory.py +7 -0
  187. odxtools/unitspec.py +6 -6
  188. odxtools/usage.py +9 -0
  189. odxtools/utils.py +31 -2
  190. odxtools/validtype.py +9 -0
  191. odxtools/variablegroup.py +2 -2
  192. odxtools/variantmatcher.py +10 -10
  193. odxtools/variantpattern.py +3 -3
  194. odxtools/version.py +2 -2
  195. odxtools/writepdxfile.py +5 -5
  196. odxtools/xdoc.py +9 -9
  197. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/METADATA +4 -5
  198. odxtools-10.0.0.dist-info/RECORD +264 -0
  199. odxtools-9.6.1.dist-info/RECORD +0 -238
  200. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/WHEEL +0 -0
  201. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/entry_points.txt +0 -0
  202. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/licenses/LICENSE +0 -0
  203. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/top_level.txt +0 -0
odxtools/physicaltype.py CHANGED
@@ -1,19 +1,11 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from enum import IntEnum
4
- from typing import List, Optional
5
3
  from xml.etree import ElementTree
6
4
 
7
5
  from .exceptions import odxraise
8
6
  from .odxlink import OdxDocFragment
9
7
  from .odxtypes import DataType
10
-
11
-
12
- class Radix(IntEnum):
13
- HEX = 16
14
- DEC = 10
15
- BIN = 2
16
- OCT = 8
8
+ from .radix import Radix
17
9
 
18
10
 
19
11
  @dataclass
@@ -39,20 +31,20 @@ class PhysicalType:
39
31
  PhysicalType(DataType.A_FLOAT64, precision=2)
40
32
  """
41
33
 
42
- precision: Optional[int]
34
+ precision: int | None
43
35
  """Number of digits after the decimal point to display to the user
44
36
  The precision is only applicable if the base data type is A_FLOAT32 or A_FLOAT64.
45
37
  """
46
38
 
47
39
  base_data_type: DataType
48
40
 
49
- display_radix: Optional[Radix]
41
+ display_radix: Radix | None
50
42
  """The display radix defines how integers are displayed to the user.
51
43
  The display radix is only applicable if the base data type is A_UINT32.
52
44
  """
53
45
 
54
46
  @staticmethod
55
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "PhysicalType":
47
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "PhysicalType":
56
48
  precision_str = et_element.findtext("PRECISION")
57
49
  precision = int(precision_str) if precision_str is not None else None
58
50
 
@@ -0,0 +1,72 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass
3
+ from xml.etree import ElementTree
4
+
5
+ from .exceptions import odxrequire
6
+ from .odxlink import OdxDocFragment
7
+ from .utils import read_hex_binary
8
+
9
+
10
+ # note that the spec has a typo here: it calls the corresponding
11
+ # XML tag POS-RESPONSE-SUPPRESSABLE...
12
+ @dataclass
13
+ class PosResponseSuppressible:
14
+ bit_mask: int
15
+
16
+ coded_const_snref: str | None
17
+ coded_const_snpathref: str | None
18
+
19
+ value_snref: str | None
20
+ value_snpathref: str | None
21
+
22
+ phys_const_snref: str | None
23
+ phys_const_snpathref: str | None
24
+
25
+ table_key_snref: str | None
26
+ table_key_snpathref: str | None
27
+
28
+ @staticmethod
29
+ def from_et(et_element: ElementTree.Element,
30
+ doc_frags: list[OdxDocFragment]) -> "PosResponseSuppressible":
31
+
32
+ bit_mask = odxrequire(read_hex_binary(et_element.find("BIT-MASK")))
33
+
34
+ coded_const_snref = None
35
+ if (cc_snref_elem := et_element.find("CODED-CONST-SNREF")) is not None:
36
+ coded_const_snref = cc_snref_elem.attrib["SHORT-NAME"]
37
+ coded_const_snpathref = None
38
+ if (cc_snpathref_elem := et_element.find("CODED-CONST-SNPATHREF")) is not None:
39
+ coded_const_snpathref = cc_snpathref_elem.attrib["SHORT-NAME-PATH"]
40
+
41
+ value_snref = None
42
+ if (cc_snref_elem := et_element.find("VALUE-SNREF")) is not None:
43
+ value_snref = cc_snref_elem.attrib["SHORT-NAME"]
44
+ value_snpathref = None
45
+ if (cc_snpathref_elem := et_element.find("VALUE-SNPATHREF")) is not None:
46
+ value_snpathref = cc_snpathref_elem.attrib["SHORT-NAME-PATH"]
47
+
48
+ phys_const_snref = None
49
+ if (cc_snref_elem := et_element.find("PHYS-CONST-SNREF")) is not None:
50
+ phys_const_snref = cc_snref_elem.attrib["SHORT-NAME"]
51
+ phys_const_snpathref = None
52
+ if (cc_snpathref_elem := et_element.find("PHYS-CONST-SNPATHREF")) is not None:
53
+ phys_const_snpathref = cc_snpathref_elem.attrib["SHORT-NAME-PATH"]
54
+
55
+ table_key_snref = None
56
+ if (cc_snref_elem := et_element.find("TABLE-KEY-SNREF")) is not None:
57
+ table_key_snref = cc_snref_elem.attrib["SHORT-NAME"]
58
+ table_key_snpathref = None
59
+ if (cc_snpathref_elem := et_element.find("TABLE-KEY-SNPATHREF")) is not None:
60
+ table_key_snpathref = cc_snpathref_elem.attrib["SHORT-NAME-PATH"]
61
+
62
+ return PosResponseSuppressible(
63
+ bit_mask=bit_mask,
64
+ coded_const_snref=coded_const_snref,
65
+ coded_const_snpathref=coded_const_snpathref,
66
+ value_snref=value_snref,
67
+ value_snpathref=value_snpathref,
68
+ phys_const_snref=phys_const_snref,
69
+ phys_const_snpathref=phys_const_snpathref,
70
+ table_key_snref=table_key_snref,
71
+ table_key_snpathref=table_key_snpathref,
72
+ )
@@ -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
3
+ from typing import TYPE_CHECKING, Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .exceptions import odxassert, odxrequire
@@ -21,10 +21,10 @@ class PreConditionStateRef(OdxLinkRef):
21
21
  """
22
22
  This class represents the PRE-CONDITION-STATE-REF XML tag.
23
23
  """
24
- value: Optional[str]
24
+ value: str | None
25
25
 
26
- in_param_if_snref: Optional[str]
27
- in_param_if_snpathref: Optional[str]
26
+ in_param_if_snref: str | None
27
+ in_param_if_snpathref: str | None
28
28
 
29
29
  @property
30
30
  def state(self) -> "State":
@@ -33,7 +33,7 @@ class PreConditionStateRef(OdxLinkRef):
33
33
  @staticmethod
34
34
  def from_et( # type: ignore[override]
35
35
  et_element: ElementTree.Element,
36
- doc_frags: List[OdxDocFragment]) -> "PreConditionStateRef":
36
+ doc_frags: list[OdxDocFragment]) -> "PreConditionStateRef":
37
37
  kwargs = dataclass_fields_asdict(OdxLinkRef.from_et(et_element, doc_frags))
38
38
 
39
39
  value = et_element.findtext("VALUE")
@@ -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,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List, Optional, cast
3
+ from typing import Any, cast
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .exceptions import odxraise, odxrequire
@@ -14,11 +14,11 @@ from .snrefcontext import SnRefContext
14
14
  class ProgCode:
15
15
  """A reference to code that is executed by a single ECU job"""
16
16
  code_file: str
17
- encryption: Optional[str]
17
+ encryption: str | None
18
18
  syntax: str
19
19
  revision: str
20
- entrypoint: Optional[str]
21
- library_refs: List[OdxLinkRef]
20
+ entrypoint: str | None
21
+ library_refs: list[OdxLinkRef]
22
22
 
23
23
  @property
24
24
  def code(self) -> bytes:
@@ -29,7 +29,7 @@ class ProgCode:
29
29
  return self._libraries
30
30
 
31
31
  @staticmethod
32
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "ProgCode":
32
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "ProgCode":
33
33
  code_file = odxrequire(et_element.findtext("CODE-FILE"))
34
34
  encryption = et_element.findtext("ENCRYPTION")
35
35
  syntax = odxrequire(et_element.findtext("SYNTAX"))
@@ -50,7 +50,7 @@ class ProgCode:
50
50
  library_refs=library_refs,
51
51
  )
52
52
 
53
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
53
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
54
54
  return {}
55
55
 
56
56
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
odxtools/protstack.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .comparamsubset import ComparamSubset
@@ -17,14 +17,14 @@ class ProtStack(IdentifiableElement):
17
17
  # mandatory in ODX 2.2, but non existent in ODX 2.0
18
18
  pdu_protocol_type: str
19
19
  physical_link_type: str
20
- comparam_subset_refs: List[OdxLinkRef]
20
+ comparam_subset_refs: list[OdxLinkRef]
21
21
 
22
22
  @property
23
23
  def comparam_subsets(self) -> NamedItemList[ComparamSubset]:
24
24
  return self._comparam_subsets
25
25
 
26
26
  @staticmethod
27
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "ProtStack":
27
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "ProtStack":
28
28
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
29
29
 
30
30
  pdu_protocol_type = odxrequire(et_element.findtext("PDU-PROTOCOL-TYPE"))
@@ -41,7 +41,7 @@ class ProtStack(IdentifiableElement):
41
41
  comparam_subset_refs=comparam_subset_refs,
42
42
  **kwargs)
43
43
 
44
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
44
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
45
45
  result = {self.odx_id: self}
46
46
  return result
47
47
 
odxtools/radix.py ADDED
@@ -0,0 +1,9 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from enum import IntEnum
3
+
4
+
5
+ class Radix(IntEnum):
6
+ HEX = 16
7
+ DEC = 10
8
+ BIN = 2
9
+ OCT = 8
@@ -0,0 +1,22 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass
3
+ from xml.etree import ElementTree
4
+
5
+ from .exceptions import odxrequire
6
+ from .odxlink import OdxDocFragment, OdxLinkRef
7
+ from .utils import dataclass_fields_asdict
8
+
9
+
10
+ @dataclass
11
+ class RelatedDiagCommRef(OdxLinkRef):
12
+ relation_type: str
13
+
14
+ @staticmethod
15
+ def from_et( # type: ignore[override]
16
+ et_element: ElementTree.Element,
17
+ doc_frags: list[OdxDocFragment]) -> "RelatedDiagCommRef":
18
+ kwargs = dataclass_fields_asdict(odxrequire(OdxLinkRef.from_et(et_element, doc_frags)))
19
+
20
+ relation_type = odxrequire(et_element.findtext("RELATION-TYPE"))
21
+
22
+ return RelatedDiagCommRef(relation_type=relation_type, **kwargs)
odxtools/relateddoc.py CHANGED
@@ -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 .description import Description
@@ -11,12 +11,12 @@ from .xdoc import XDoc
11
11
 
12
12
  @dataclass
13
13
  class RelatedDoc:
14
- xdoc: Optional[XDoc]
15
- description: Optional[Description]
14
+ xdoc: XDoc | None
15
+ description: Description | None
16
16
 
17
17
  @staticmethod
18
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "RelatedDoc":
19
- xdoc: Optional[XDoc] = None
18
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "RelatedDoc":
19
+ xdoc: XDoc | None = None
20
20
  if (xdoc_elem := et_element.find("XDOC")) is not None:
21
21
  xdoc = XDoc.from_et(xdoc_elem, doc_frags)
22
22
  description = Description.from_et(et_element.find("DESC"), doc_frags)
@@ -26,7 +26,7 @@ class RelatedDoc:
26
26
  description=description,
27
27
  )
28
28
 
29
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
29
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
30
30
  result = {}
31
31
 
32
32
  if self.xdoc:
odxtools/request.py CHANGED
@@ -1,12 +1,14 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List, Optional, cast
3
+ from typing import Any, cast
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .admindata import AdminData
7
- from .codec import (composite_codec_decode_from_pdu, composite_codec_encode_into_pdu,
8
- composite_codec_get_coded_const_prefix, composite_codec_get_free_parameters,
9
- composite_codec_get_required_parameters, composite_codec_get_static_bit_length)
7
+ from .compositecodec import (composite_codec_decode_from_pdu, composite_codec_encode_into_pdu,
8
+ composite_codec_get_coded_const_prefix,
9
+ composite_codec_get_free_parameters,
10
+ composite_codec_get_required_parameters,
11
+ composite_codec_get_static_bit_length)
10
12
  from .decodestate import DecodeState
11
13
  from .element import IdentifiableElement
12
14
  from .encodestate import EncodeState
@@ -27,20 +29,20 @@ class Request(IdentifiableElement):
27
29
 
28
30
  This class implements the `CompositeCodec` interface.
29
31
  """
30
- admin_data: Optional[AdminData]
32
+ admin_data: AdminData | None
31
33
  parameters: NamedItemList[Parameter]
32
- sdgs: List[SpecialDataGroup]
34
+ sdgs: list[SpecialDataGroup]
33
35
 
34
36
  @property
35
- def required_parameters(self) -> List[Parameter]:
37
+ def required_parameters(self) -> list[Parameter]:
36
38
  return composite_codec_get_required_parameters(self)
37
39
 
38
40
  @property
39
- def free_parameters(self) -> List[Parameter]:
41
+ def free_parameters(self) -> list[Parameter]:
40
42
  return composite_codec_get_free_parameters(self)
41
43
 
42
44
  @staticmethod
43
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "Request":
45
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Request":
44
46
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
45
47
 
46
48
  admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
@@ -54,7 +56,7 @@ class Request(IdentifiableElement):
54
56
 
55
57
  return Request(admin_data=admin_data, parameters=parameters, sdgs=sdgs, **kwargs)
56
58
 
57
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
59
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
58
60
  result = {self.odx_id: self}
59
61
 
60
62
  if self.admin_data is not None:
@@ -94,7 +96,7 @@ class Request(IdentifiableElement):
94
96
  context.request = None
95
97
  context.parameters = None
96
98
 
97
- def get_static_bit_length(self) -> Optional[int]:
99
+ def get_static_bit_length(self) -> int | None:
98
100
  return composite_codec_get_static_bit_length(self)
99
101
 
100
102
  def print_free_parameters_info(self) -> None:
@@ -121,7 +123,7 @@ class Request(IdentifiableElement):
121
123
 
122
124
  return cast(ParameterValueDict, param_values)
123
125
 
124
- def encode_into_pdu(self, physical_value: Optional[ParameterValue],
126
+ def encode_into_pdu(self, physical_value: ParameterValue | None,
125
127
  encode_state: EncodeState) -> None:
126
128
  composite_codec_encode_into_pdu(self, physical_value, encode_state)
127
129
 
odxtools/response.py CHANGED
@@ -1,13 +1,15 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
3
  from enum import Enum
4
- from typing import Any, Dict, List, Optional, cast
4
+ from typing import Any, cast
5
5
  from xml.etree import ElementTree
6
6
 
7
7
  from .admindata import AdminData
8
- from .codec import (composite_codec_decode_from_pdu, composite_codec_encode_into_pdu,
9
- composite_codec_get_coded_const_prefix, composite_codec_get_free_parameters,
10
- composite_codec_get_required_parameters, composite_codec_get_static_bit_length)
8
+ from .compositecodec import (composite_codec_decode_from_pdu, composite_codec_encode_into_pdu,
9
+ composite_codec_get_coded_const_prefix,
10
+ composite_codec_get_free_parameters,
11
+ composite_codec_get_required_parameters,
12
+ composite_codec_get_static_bit_length)
11
13
  from .decodestate import DecodeState
12
14
  from .element import IdentifiableElement
13
15
  from .encodestate import EncodeState
@@ -37,12 +39,12 @@ class Response(IdentifiableElement):
37
39
 
38
40
  response_type: ResponseType
39
41
 
40
- admin_data: Optional[AdminData]
42
+ admin_data: AdminData | None
41
43
  parameters: NamedItemList[Parameter]
42
- sdgs: List[SpecialDataGroup]
44
+ sdgs: list[SpecialDataGroup]
43
45
 
44
46
  @staticmethod
45
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "Response":
47
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Response":
46
48
  """Reads a response."""
47
49
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
48
50
 
@@ -68,7 +70,7 @@ class Response(IdentifiableElement):
68
70
  sdgs=sdgs,
69
71
  **kwargs)
70
72
 
71
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
73
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
72
74
  result = {self.odx_id: self}
73
75
 
74
76
  if self.admin_data is not None:
@@ -108,7 +110,7 @@ class Response(IdentifiableElement):
108
110
  context.response = None
109
111
  context.parameters = None
110
112
 
111
- def encode(self, coded_request: Optional[bytes] = None, **kwargs: ParameterValue) -> bytearray:
113
+ def encode(self, coded_request: bytes | None = None, **kwargs: ParameterValue) -> bytearray:
112
114
  encode_state = EncodeState(triggering_request=coded_request, is_end_of_pdu=True)
113
115
 
114
116
  self.encode_into_pdu(physical_value=kwargs, encode_state=encode_state)
@@ -124,22 +126,22 @@ class Response(IdentifiableElement):
124
126
 
125
127
  return cast(ParameterValueDict, param_values)
126
128
 
127
- def encode_into_pdu(self, physical_value: Optional[ParameterValue],
129
+ def encode_into_pdu(self, physical_value: ParameterValue | None,
128
130
  encode_state: EncodeState) -> None:
129
131
  composite_codec_encode_into_pdu(self, physical_value, encode_state)
130
132
 
131
133
  def decode_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
132
134
  return composite_codec_decode_from_pdu(self, decode_state)
133
135
 
134
- def get_static_bit_length(self) -> Optional[int]:
136
+ def get_static_bit_length(self) -> int | None:
135
137
  return composite_codec_get_static_bit_length(self)
136
138
 
137
139
  @property
138
- def required_parameters(self) -> List[Parameter]:
140
+ def required_parameters(self) -> list[Parameter]:
139
141
  return composite_codec_get_required_parameters(self)
140
142
 
141
143
  @property
142
- def free_parameters(self) -> List[Parameter]:
144
+ def free_parameters(self) -> list[Parameter]:
143
145
  return composite_codec_get_free_parameters(self)
144
146
 
145
147
  def print_free_parameters_info(self) -> None:
odxtools/scaleconstr.py CHANGED
@@ -1,7 +1,5 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from enum import Enum
4
- from typing import List, Optional
5
3
  from xml.etree import ElementTree
6
4
 
7
5
  from .compumethods.limit import Limit
@@ -9,13 +7,7 @@ from .description import Description
9
7
  from .exceptions import odxraise, odxrequire
10
8
  from .odxlink import OdxDocFragment
11
9
  from .odxtypes import DataType
12
-
13
-
14
- class ValidType(Enum):
15
- VALID = "VALID"
16
- NOT_VALID = "NOT-VALID"
17
- NOT_DEFINED = "NOT-DEFINED"
18
- NOT_AVAILABLE = "NOT-AVAILABLE"
10
+ from .validtype import ValidType
19
11
 
20
12
 
21
13
  @dataclass
@@ -23,15 +15,15 @@ class ScaleConstr:
23
15
  """This class represents a SCALE-CONSTR.
24
16
  """
25
17
 
26
- short_label: Optional[str]
27
- description: Optional[Description]
18
+ short_label: str | None
19
+ description: Description | None
28
20
  lower_limit: Limit
29
21
  upper_limit: Limit
30
22
  validity: ValidType
31
23
  value_type: DataType
32
24
 
33
25
  @staticmethod
34
- def scale_constr_from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment], *,
26
+ def scale_constr_from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment], *,
35
27
  value_type: DataType) -> "ScaleConstr":
36
28
  short_label = et_element.findtext("SHORT-LABEL")
37
29
  description = Description.from_et(et_element.find("DESC"), doc_frags)
odxtools/servicebinner.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
+ from collections.abc import Iterable, Iterator
2
3
  from io import StringIO
3
- from typing import Dict, Iterable, Iterator, Optional
4
4
 
5
5
  from . import obd, uds
6
6
  from .diagservice import DiagService
@@ -21,7 +21,7 @@ class ServiceBinner:
21
21
  """
22
22
 
23
23
  def __init__(self, services: Iterable[DiagService]):
24
- service_groups: Dict[Optional[int], NamedItemList[DiagService]] = {}
24
+ service_groups: dict[int | None, NamedItemList[DiagService]] = {}
25
25
  for service in services:
26
26
  SID = self.__extract_sid(service)
27
27
 
@@ -32,7 +32,7 @@ class ServiceBinner:
32
32
 
33
33
  self._service_groups = service_groups
34
34
 
35
- def __extract_sid(self, service: DiagService) -> Optional[int]:
35
+ def __extract_sid(self, service: DiagService) -> int | None:
36
36
  # diagnostic services without requests are possible; just like
37
37
  # aircraft without wings...
38
38
  if service.request is None:
@@ -96,10 +96,10 @@ class ServiceBinner:
96
96
 
97
97
  return result.getvalue()
98
98
 
99
- def __iter__(self) -> Iterator[Optional[int]]:
99
+ def __iter__(self) -> Iterator[int | None]:
100
100
  return iter(self._service_groups)
101
101
 
102
- def __getitem__(self, sid: Optional[int]) -> NamedItemList[DiagService]:
102
+ def __getitem__(self, sid: int | None) -> NamedItemList[DiagService]:
103
103
  if sid is None:
104
104
  return self._service_groups.get(sid, NamedItemList())
105
105
 
odxtools/singleecujob.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .diagcomm import DiagComm
@@ -30,13 +30,13 @@ class SingleEcuJob(DiagComm):
30
30
  standard.
31
31
  """
32
32
 
33
- prog_codes: List[ProgCode]
33
+ prog_codes: list[ProgCode]
34
34
  input_params: NamedItemList[InputParam]
35
35
  output_params: NamedItemList[OutputParam]
36
36
  neg_output_params: NamedItemList[NegOutputParam]
37
37
 
38
38
  @staticmethod
39
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "SingleEcuJob":
39
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "SingleEcuJob":
40
40
  kwargs = dataclass_fields_asdict(DiagComm.from_et(et_element, doc_frags))
41
41
 
42
42
  prog_codes = [
@@ -64,7 +64,7 @@ class SingleEcuJob(DiagComm):
64
64
  neg_output_params=neg_output_params,
65
65
  **kwargs)
66
66
 
67
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
67
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
68
68
  result = super()._build_odxlinks()
69
69
 
70
70
  for prog_code in self.prog_codes:
odxtools/snrefcontext.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, List, Optional
3
+ from typing import TYPE_CHECKING, Optional
4
4
 
5
5
  if TYPE_CHECKING:
6
6
  from .database import Database
@@ -25,5 +25,5 @@ class SnRefContext:
25
25
  single_ecu_job: Optional["SingleEcuJob"] = None
26
26
  request: Optional["Request"] = None
27
27
  response: Optional["Response"] = None
28
- parameters: Optional[List["Parameter"]] = None
28
+ parameters: list["Parameter"] | None = None
29
29
  state_chart: Optional["StateChart"] = None
odxtools/specialdata.py CHANGED
@@ -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 .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
@@ -10,12 +10,12 @@ from .snrefcontext import SnRefContext
10
10
  @dataclass
11
11
  class SpecialData:
12
12
  """This corresponds to the SD XML tag"""
13
- semantic_info: Optional[str] # the "SI" attribute
14
- text_identifier: Optional[str] # the "TI" attribute, specifies the language used
13
+ semantic_info: str | None # the "SI" attribute
14
+ text_identifier: str | None # the "TI" attribute, specifies the language used
15
15
  value: str
16
16
 
17
17
  @staticmethod
18
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "SpecialData":
18
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "SpecialData":
19
19
  semantic_info = et_element.get("SI")
20
20
  text_identifier = et_element.get("TI")
21
21
  value = et_element.text or ""
@@ -23,7 +23,7 @@ class SpecialData:
23
23
  return SpecialData(
24
24
  semantic_info=semantic_info, text_identifier=text_identifier, value=value)
25
25
 
26
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
26
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
27
27
  return {}
28
28
 
29
29
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List, Optional, Union
3
+ from typing import Any, Union
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
@@ -12,14 +12,14 @@ from .specialdatagroupcaption import SpecialDataGroupCaption
12
12
  @dataclass
13
13
  class SpecialDataGroup:
14
14
  """This corresponds to the SDG XML tag"""
15
- sdg_caption: Optional[SpecialDataGroupCaption]
16
- sdg_caption_ref: Optional[OdxLinkRef]
17
- values: List[Union["SpecialDataGroup", SpecialData]]
18
- semantic_info: Optional[str] # the "SI" attribute
15
+ sdg_caption: SpecialDataGroupCaption | None
16
+ sdg_caption_ref: OdxLinkRef | None
17
+ values: list[Union["SpecialDataGroup", SpecialData]]
18
+ semantic_info: str | None # the "SI" attribute
19
19
 
20
20
  @staticmethod
21
21
  def from_et(et_element: ElementTree.Element,
22
- doc_frags: List[OdxDocFragment]) -> "SpecialDataGroup":
22
+ doc_frags: list[OdxDocFragment]) -> "SpecialDataGroup":
23
23
 
24
24
  sdg_caption = None
25
25
  if caption_elem := et_element.find("SDG-CAPTION"):
@@ -31,9 +31,9 @@ class SpecialDataGroup:
31
31
 
32
32
  semantic_info = et_element.get("SI")
33
33
 
34
- values: List[Union[SpecialData, SpecialDataGroup]] = []
34
+ values: list[SpecialData | SpecialDataGroup] = []
35
35
  for value_elem in et_element:
36
- next_entry: Optional[Union[SpecialData, SpecialDataGroup]] = None
36
+ next_entry: SpecialData | SpecialDataGroup | None = None
37
37
  if value_elem.tag == "SDG":
38
38
  next_entry = SpecialDataGroup.from_et(value_elem, doc_frags)
39
39
  elif value_elem.tag == "SD":
@@ -49,7 +49,7 @@ class SpecialDataGroup:
49
49
  values=values,
50
50
  )
51
51
 
52
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
52
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
53
53
  result = {}
54
54
 
55
55
  if self.sdg_caption_ref is None and self.sdg_caption is not None: