odxtools 9.7.0__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 (189) hide show
  1. odxtools/additionalaudience.py +3 -3
  2. odxtools/admindata.py +8 -8
  3. odxtools/audience.py +10 -10
  4. odxtools/basecomparam.py +5 -5
  5. odxtools/basevariantpattern.py +4 -5
  6. odxtools/basicstructure.py +8 -8
  7. odxtools/cli/_print_utils.py +35 -23
  8. odxtools/cli/browse.py +9 -9
  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 +7 -7
  13. odxtools/cli/main.py +2 -2
  14. odxtools/cli/snoop.py +3 -3
  15. odxtools/codec.py +3 -3
  16. odxtools/commrelation.py +11 -11
  17. odxtools/companydata.py +5 -5
  18. odxtools/companydocinfo.py +8 -8
  19. odxtools/companyrevisioninfo.py +5 -5
  20. odxtools/companyspecificinfo.py +5 -5
  21. odxtools/comparam.py +3 -3
  22. odxtools/comparaminstance.py +10 -10
  23. odxtools/comparamspec.py +3 -3
  24. odxtools/comparamsubset.py +5 -5
  25. odxtools/complexcomparam.py +7 -7
  26. odxtools/compositecodec.py +11 -11
  27. odxtools/compumethods/compucodecompumethod.py +4 -4
  28. odxtools/compumethods/compuconst.py +4 -5
  29. odxtools/compumethods/compudefaultvalue.py +1 -2
  30. odxtools/compumethods/compuinternaltophys.py +6 -6
  31. odxtools/compumethods/compumethod.py +5 -5
  32. odxtools/compumethods/compuphystointernal.py +6 -6
  33. odxtools/compumethods/compurationalcoeffs.py +4 -4
  34. odxtools/compumethods/compuscale.py +9 -10
  35. odxtools/compumethods/createanycompumethod.py +1 -2
  36. odxtools/compumethods/identicalcompumethod.py +1 -2
  37. odxtools/compumethods/limit.py +12 -12
  38. odxtools/compumethods/linearcompumethod.py +2 -2
  39. odxtools/compumethods/linearsegment.py +14 -15
  40. odxtools/compumethods/ratfunccompumethod.py +3 -3
  41. odxtools/compumethods/ratfuncsegment.py +7 -8
  42. odxtools/compumethods/scalelinearcompumethod.py +7 -7
  43. odxtools/compumethods/scaleratfunccompumethod.py +4 -4
  44. odxtools/compumethods/tabintpcompumethod.py +15 -18
  45. odxtools/compumethods/texttablecompumethod.py +3 -3
  46. odxtools/createanycomparam.py +2 -4
  47. odxtools/createanydiagcodedtype.py +1 -2
  48. odxtools/database.py +9 -8
  49. odxtools/dataobjectproperty.py +10 -10
  50. odxtools/decodestate.py +5 -5
  51. odxtools/description.py +5 -5
  52. odxtools/determinenumberofitems.py +4 -4
  53. odxtools/diagcodedtype.py +7 -7
  54. odxtools/diagcomm.py +17 -17
  55. odxtools/diagdatadictionaryspec.py +6 -6
  56. odxtools/diaglayercontainer.py +4 -4
  57. odxtools/diaglayers/basevariant.py +10 -9
  58. odxtools/diaglayers/basevariantraw.py +9 -9
  59. odxtools/diaglayers/diaglayer.py +20 -19
  60. odxtools/diaglayers/diaglayerraw.py +10 -10
  61. odxtools/diaglayers/diaglayertype.py +1 -2
  62. odxtools/diaglayers/ecushareddata.py +4 -4
  63. odxtools/diaglayers/ecushareddataraw.py +6 -6
  64. odxtools/diaglayers/ecuvariant.py +11 -10
  65. odxtools/diaglayers/ecuvariantraw.py +9 -9
  66. odxtools/diaglayers/functionalgroup.py +8 -7
  67. odxtools/diaglayers/functionalgroupraw.py +7 -7
  68. odxtools/diaglayers/hierarchyelement.py +43 -49
  69. odxtools/diaglayers/hierarchyelementraw.py +4 -4
  70. odxtools/diaglayers/protocol.py +4 -4
  71. odxtools/diaglayers/protocolraw.py +6 -6
  72. odxtools/diagnostictroublecode.py +8 -8
  73. odxtools/diagservice.py +18 -18
  74. odxtools/diagvariable.py +14 -14
  75. odxtools/docrevision.py +11 -11
  76. odxtools/dopbase.py +6 -6
  77. odxtools/dtcconnector.py +3 -3
  78. odxtools/dtcdop.py +13 -9
  79. odxtools/dynamicendmarkerfield.py +5 -4
  80. odxtools/dynamiclengthfield.py +5 -4
  81. odxtools/dyndefinedspec.py +5 -5
  82. odxtools/dynenddopref.py +5 -5
  83. odxtools/dyniddefmodeinfo.py +13 -13
  84. odxtools/ecuvariantpattern.py +4 -5
  85. odxtools/element.py +5 -6
  86. odxtools/encodestate.py +11 -11
  87. odxtools/encoding.py +2 -3
  88. odxtools/endofpdufield.py +6 -6
  89. odxtools/envdataconnector.py +3 -3
  90. odxtools/environmentdata.py +3 -4
  91. odxtools/environmentdatadescription.py +11 -11
  92. odxtools/exceptions.py +5 -5
  93. odxtools/externalaccessmethod.py +1 -2
  94. odxtools/externaldoc.py +4 -4
  95. odxtools/field.py +9 -10
  96. odxtools/functionalclass.py +4 -4
  97. odxtools/inputparam.py +6 -6
  98. odxtools/internalconstr.py +4 -5
  99. odxtools/isotp_state_machine.py +12 -11
  100. odxtools/leadinglengthinfotype.py +2 -3
  101. odxtools/library.py +5 -5
  102. odxtools/linkeddtcdop.py +4 -4
  103. odxtools/loadfile.py +5 -6
  104. odxtools/matchingbasevariantparameter.py +2 -3
  105. odxtools/matchingparameter.py +7 -7
  106. odxtools/minmaxlengthtype.py +4 -4
  107. odxtools/modification.py +4 -4
  108. odxtools/multiplexer.py +11 -11
  109. odxtools/multiplexercase.py +6 -6
  110. odxtools/multiplexerdefaultcase.py +6 -6
  111. odxtools/multiplexerswitchkey.py +4 -4
  112. odxtools/nameditemlist.py +14 -14
  113. odxtools/negoutputparam.py +3 -3
  114. odxtools/obd.py +1 -2
  115. odxtools/odxcategory.py +6 -6
  116. odxtools/odxlink.py +19 -20
  117. odxtools/odxtypes.py +21 -18
  118. odxtools/outputparam.py +4 -4
  119. odxtools/parameterinfo.py +1 -1
  120. odxtools/parameters/codedconstparameter.py +5 -5
  121. odxtools/parameters/createanyparameter.py +1 -2
  122. odxtools/parameters/dynamicparameter.py +2 -3
  123. odxtools/parameters/lengthkeyparameter.py +5 -5
  124. odxtools/parameters/matchingrequestparameter.py +3 -4
  125. odxtools/parameters/nrcconstparameter.py +7 -7
  126. odxtools/parameters/parameter.py +11 -11
  127. odxtools/parameters/parameterwithdop.py +9 -9
  128. odxtools/parameters/physicalconstantparameter.py +4 -4
  129. odxtools/parameters/reservedparameter.py +3 -4
  130. odxtools/parameters/systemparameter.py +2 -3
  131. odxtools/parameters/tableentryparameter.py +3 -3
  132. odxtools/parameters/tablekeyparameter.py +10 -10
  133. odxtools/parameters/tablestructparameter.py +7 -7
  134. odxtools/parameters/valueparameter.py +7 -7
  135. odxtools/paramlengthinfotype.py +5 -3
  136. odxtools/parentref.py +9 -9
  137. odxtools/physicaldimension.py +11 -11
  138. odxtools/physicaltype.py +3 -4
  139. odxtools/posresponsesuppressible.py +9 -10
  140. odxtools/preconditionstateref.py +7 -7
  141. odxtools/progcode.py +6 -6
  142. odxtools/protstack.py +4 -4
  143. odxtools/relateddiagcommref.py +1 -2
  144. odxtools/relateddoc.py +6 -6
  145. odxtools/request.py +9 -9
  146. odxtools/response.py +10 -10
  147. odxtools/scaleconstr.py +3 -4
  148. odxtools/servicebinner.py +5 -5
  149. odxtools/singleecujob.py +4 -4
  150. odxtools/snrefcontext.py +2 -2
  151. odxtools/specialdata.py +5 -5
  152. odxtools/specialdatagroup.py +9 -9
  153. odxtools/specialdatagroupcaption.py +3 -3
  154. odxtools/standardlengthtype.py +10 -10
  155. odxtools/state.py +3 -3
  156. odxtools/statechart.py +4 -4
  157. odxtools/statemachine.py +4 -3
  158. odxtools/statetransition.py +4 -4
  159. odxtools/statetransitionref.py +18 -18
  160. odxtools/staticfield.py +5 -4
  161. odxtools/structure.py +2 -3
  162. odxtools/subcomponent.py +5 -5
  163. odxtools/subcomponentparamconnector.py +5 -5
  164. odxtools/subcomponentpattern.py +4 -4
  165. odxtools/swvariable.py +3 -4
  166. odxtools/table.py +14 -14
  167. odxtools/tablediagcommconnector.py +5 -5
  168. odxtools/tablerow.py +30 -30
  169. odxtools/tablerowconnector.py +3 -3
  170. odxtools/teammember.py +11 -11
  171. odxtools/text.py +2 -3
  172. odxtools/uds.py +2 -3
  173. odxtools/unit.py +9 -9
  174. odxtools/unitgroup.py +5 -5
  175. odxtools/unitspec.py +6 -6
  176. odxtools/utils.py +3 -3
  177. odxtools/variablegroup.py +2 -2
  178. odxtools/variantmatcher.py +10 -10
  179. odxtools/variantpattern.py +3 -3
  180. odxtools/version.py +2 -2
  181. odxtools/writepdxfile.py +5 -5
  182. odxtools/xdoc.py +9 -9
  183. {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/METADATA +4 -5
  184. odxtools-10.0.0.dist-info/RECORD +264 -0
  185. odxtools-9.7.0.dist-info/RECORD +0 -264
  186. {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/WHEEL +0 -0
  187. {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/entry_points.txt +0 -0
  188. {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/licenses/LICENSE +0 -0
  189. {odxtools-9.7.0.dist-info → odxtools-10.0.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 Any, Dict, List
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .element import IdentifiableElement
@@ -17,12 +17,12 @@ class AdditionalAudience(IdentifiableElement):
17
17
 
18
18
  @staticmethod
19
19
  def from_et(et_element: ElementTree.Element,
20
- doc_frags: List[OdxDocFragment]) -> "AdditionalAudience":
20
+ doc_frags: list[OdxDocFragment]) -> "AdditionalAudience":
21
21
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
22
22
 
23
23
  return AdditionalAudience(**kwargs)
24
24
 
25
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
25
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
26
26
  return {self.odx_id: self}
27
27
 
28
28
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
odxtools/admindata.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, Optional
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .companydocinfo import CompanyDocInfo
@@ -11,13 +11,13 @@ from .snrefcontext import SnRefContext
11
11
 
12
12
  @dataclass
13
13
  class AdminData:
14
- language: Optional[str]
15
- company_doc_infos: List[CompanyDocInfo]
16
- doc_revisions: List[DocRevision]
14
+ language: str | None
15
+ company_doc_infos: list[CompanyDocInfo]
16
+ doc_revisions: list[DocRevision]
17
17
 
18
18
  @staticmethod
19
- def from_et(et_element: Optional[ElementTree.Element],
20
- doc_frags: List[OdxDocFragment]) -> Optional["AdminData"]:
19
+ def from_et(et_element: ElementTree.Element | None,
20
+ doc_frags: list[OdxDocFragment]) -> Optional["AdminData"]:
21
21
 
22
22
  if et_element is None:
23
23
  return None
@@ -37,8 +37,8 @@ class AdminData:
37
37
  return AdminData(
38
38
  language=language, company_doc_infos=company_doc_infos, doc_revisions=doc_revisions)
39
39
 
40
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
41
- result: Dict[OdxLinkId, Any] = {}
40
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
41
+ result: dict[OdxLinkId, Any] = {}
42
42
 
43
43
  for cdi in self.company_doc_infos:
44
44
  result.update(cdi._build_odxlinks())
odxtools/audience.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 .additionalaudience import AdditionalAudience
@@ -12,14 +12,14 @@ from .snrefcontext import SnRefContext
12
12
 
13
13
  @dataclass
14
14
  class Audience:
15
- enabled_audience_refs: List[OdxLinkRef]
16
- disabled_audience_refs: List[OdxLinkRef]
15
+ enabled_audience_refs: list[OdxLinkRef]
16
+ disabled_audience_refs: list[OdxLinkRef]
17
17
 
18
- is_supplier_raw: Optional[bool]
19
- is_development_raw: Optional[bool]
20
- is_manufacturing_raw: Optional[bool]
21
- is_aftersales_raw: Optional[bool]
22
- is_aftermarket_raw: Optional[bool]
18
+ is_supplier_raw: bool | None
19
+ is_development_raw: bool | None
20
+ is_manufacturing_raw: bool | None
21
+ is_aftersales_raw: bool | None
22
+ is_aftermarket_raw: bool | None
23
23
 
24
24
  @property
25
25
  def is_supplier(self) -> bool:
@@ -50,7 +50,7 @@ class Audience:
50
50
  return self._disabled_audiences
51
51
 
52
52
  @staticmethod
53
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "Audience":
53
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Audience":
54
54
 
55
55
  enabled_audience_refs = [
56
56
  OdxLinkRef.from_et(ref, doc_frags)
@@ -78,7 +78,7 @@ class Audience:
78
78
  is_aftermarket_raw=is_aftermarket_raw,
79
79
  )
80
80
 
81
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
81
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
82
82
  return {}
83
83
 
84
84
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
odxtools/basecomparam.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 .element import IdentifiableElement
@@ -16,11 +16,11 @@ from .utils import dataclass_fields_asdict
16
16
  class BaseComparam(IdentifiableElement):
17
17
  param_class: str
18
18
  cptype: StandardizationLevel
19
- display_level: Optional[int]
20
- cpusage: Optional[Usage] # Required in ODX 2.2, missing in ODX 2.0
19
+ display_level: int | None
20
+ cpusage: Usage | None # Required in ODX 2.2, missing in ODX 2.0
21
21
 
22
22
  @staticmethod
23
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "BaseComparam":
23
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "BaseComparam":
24
24
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
25
25
 
26
26
  param_class = odxrequire(et_element.attrib.get("PARAM-CLASS"))
@@ -52,7 +52,7 @@ class BaseComparam(IdentifiableElement):
52
52
  cpusage=cpusage,
53
53
  **kwargs)
54
54
 
55
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
55
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
56
56
  return {self.odx_id: self}
57
57
 
58
58
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
@@ -1,6 +1,5 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import List, Union
4
3
  from xml.etree import ElementTree
5
4
 
6
5
  from typing_extensions import override
@@ -17,11 +16,11 @@ class BaseVariantPattern(VariantPattern):
17
16
  """Base variant patterns are variant patterns used to identify the
18
17
  base variant of an ECU.
19
18
  """
20
- matching_base_variant_parameters: List[MatchingBaseVariantParameter]
19
+ matching_base_variant_parameters: list[MatchingBaseVariantParameter]
21
20
 
22
21
  @staticmethod
23
22
  def from_et(et_element: ElementTree.Element,
24
- doc_frags: List[OdxDocFragment]) -> "BaseVariantPattern":
23
+ doc_frags: list[OdxDocFragment]) -> "BaseVariantPattern":
25
24
 
26
25
  matching_base_variant_parameters = [
27
26
  MatchingBaseVariantParameter.from_et(mbvp_el, doc_frags)
@@ -33,6 +32,6 @@ class BaseVariantPattern(VariantPattern):
33
32
  return BaseVariantPattern(matching_base_variant_parameters=matching_base_variant_parameters)
34
33
 
35
34
  @override
36
- def get_matching_parameters(
37
- self) -> Union[List[MatchingParameter], List[MatchingBaseVariantParameter]]:
35
+ def get_matching_parameters(self
36
+ ) -> list[MatchingParameter] | list[MatchingBaseVariantParameter]:
38
37
  return self.matching_base_variant_parameters
@@ -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
@@ -30,20 +30,20 @@ class BasicStructure(ComplexDop):
30
30
  data objects. All structure-like objects adhere to the
31
31
  `CompositeCodec` type protocol.
32
32
  """
33
- byte_size: Optional[int]
33
+ byte_size: int | None
34
34
  parameters: NamedItemList[Parameter]
35
35
 
36
36
  @property
37
- def required_parameters(self) -> List[Parameter]:
37
+ def required_parameters(self) -> list[Parameter]:
38
38
  return composite_codec_get_required_parameters(self)
39
39
 
40
40
  @property
41
- def free_parameters(self) -> List[Parameter]:
41
+ def free_parameters(self) -> list[Parameter]:
42
42
  return composite_codec_get_free_parameters(self)
43
43
 
44
44
  @staticmethod
45
45
  def from_et(et_element: ElementTree.Element,
46
- doc_frags: List[OdxDocFragment]) -> "BasicStructure":
46
+ doc_frags: list[OdxDocFragment]) -> "BasicStructure":
47
47
  """Read a BASIC-STRUCTURE."""
48
48
  kwargs = dataclass_fields_asdict(ComplexDop.from_et(et_element, doc_frags))
49
49
 
@@ -56,7 +56,7 @@ class BasicStructure(ComplexDop):
56
56
 
57
57
  return BasicStructure(byte_size=byte_size, parameters=parameters, **kwargs)
58
58
 
59
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
59
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
60
60
  result = super()._build_odxlinks()
61
61
 
62
62
  for param in self.parameters:
@@ -79,7 +79,7 @@ class BasicStructure(ComplexDop):
79
79
 
80
80
  context.parameters = None
81
81
 
82
- def get_static_bit_length(self) -> Optional[int]:
82
+ def get_static_bit_length(self) -> int | None:
83
83
  # Explicit size was specified, so we do not need to look at
84
84
  # the list of parameters
85
85
  if self.byte_size is not None:
@@ -96,7 +96,7 @@ class BasicStructure(ComplexDop):
96
96
  print(parameter_info(self.free_parameters), end="")
97
97
 
98
98
  @override
99
- def encode_into_pdu(self, physical_value: Optional[ParameterValue],
99
+ def encode_into_pdu(self, physical_value: ParameterValue | None,
100
100
  encode_state: EncodeState) -> None:
101
101
  orig_pos = encode_state.cursor_byte_position
102
102
 
@@ -1,7 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import re
3
3
  import textwrap
4
- from typing import List, Optional, Tuple, Union
5
4
 
6
5
  import markdownify
7
6
  from rich import print as rich_print
@@ -113,9 +112,9 @@ def print_service_parameters(service: DiagService,
113
112
  rich_print("\n")
114
113
 
115
114
 
116
- def extract_service_tabulation_data(services: List[DiagService],
115
+ def extract_service_tabulation_data(services: list[DiagService],
117
116
  *,
118
- additional_columns: Optional[List[Tuple[str, List[str]]]] = None
117
+ additional_columns: list[tuple[str, list[str]]] | None = None
119
118
  ) -> RichTable:
120
119
  """Extracts data of diagnostic services into Dictionary which can
121
120
  be printed by tabulate module
@@ -125,9 +124,9 @@ def extract_service_tabulation_data(services: List[DiagService],
125
124
  table = RichTable(
126
125
  title="", show_header=True, header_style="bold cyan", border_style="blue", show_lines=True)
127
126
 
128
- name_column: List[str] = []
129
- semantic_column: List[str] = []
130
- request_column: List[str] = []
127
+ name_column: list[str] = []
128
+ semantic_column: list[str] = []
129
+ request_column: list[str] = []
131
130
 
132
131
  for service in services:
133
132
  name_column.append(service.short_name)
@@ -147,15 +146,19 @@ def extract_service_tabulation_data(services: List[DiagService],
147
146
  for ac_title, _ in additional_columns:
148
147
  table.add_column(ac_title, justify="left", style="white")
149
148
 
150
- rows = zip(name_column, semantic_column, request_column,
151
- *[ac[1] for ac in additional_columns])
149
+ rows = zip(
150
+ name_column,
151
+ semantic_column,
152
+ request_column,
153
+ *[ac[1] for ac in additional_columns],
154
+ strict=False)
152
155
  for row in rows:
153
156
  table.add_row(*map(str, row))
154
157
 
155
158
  return table
156
159
 
157
160
 
158
- def extract_parameter_tabulation_data(parameters: List[Parameter]) -> RichTable:
161
+ def extract_parameter_tabulation_data(parameters: list[Parameter]) -> RichTable:
159
162
  # extracts data of parameters of diagnostic services into
160
163
  # a RichTable object that can be printed
161
164
 
@@ -174,15 +177,15 @@ def extract_parameter_tabulation_data(parameters: List[Parameter]) -> RichTable:
174
177
  table.add_column("Value Type", justify="left", style="white")
175
178
  table.add_column("Linked DOP", justify="left", style="white")
176
179
 
177
- name_column: List[str] = []
178
- byte_column: List[str] = []
179
- bit_length_column: List[str] = []
180
- semantic_column: List[str] = []
181
- param_type_column: List[str] = []
182
- value_column: List[str] = []
183
- value_type_column: List[str] = []
184
- data_type_column: List[str] = []
185
- dop_column: List[str] = []
180
+ name_column: list[str] = []
181
+ byte_column: list[str] = []
182
+ bit_length_column: list[str] = []
183
+ semantic_column: list[str] = []
184
+ param_type_column: list[str] = []
185
+ value_column: list[str] = []
186
+ value_type_column: list[str] = []
187
+ data_type_column: list[str] = []
188
+ dop_column: list[str] = []
186
189
 
187
190
  for param in parameters:
188
191
  name_column.append(param.short_name)
@@ -211,7 +214,7 @@ def extract_parameter_tabulation_data(parameters: List[Parameter]) -> RichTable:
211
214
  value_column.append(str(param.coded_values))
212
215
  value_type_column.append('coded values')
213
216
  dop_column.append("")
214
- elif isinstance(param, (PhysicalConstantParameter, SystemParameter, ValueParameter)):
217
+ elif isinstance(param, PhysicalConstantParameter | SystemParameter | ValueParameter):
215
218
  # this is a hack to make this routine work for parameters
216
219
  # which reference DOPs of a type that a is not yet
217
220
  # internalized. (all parameter objects of the tested types
@@ -250,15 +253,24 @@ def extract_parameter_tabulation_data(parameters: List[Parameter]) -> RichTable:
250
253
  dop_column.append("")
251
254
 
252
255
  # Add all rows at once by zipping dictionary values
253
- rows = zip(name_column, byte_column, bit_length_column, semantic_column, param_type_column,
254
- data_type_column, value_column, value_type_column, dop_column)
256
+ rows = zip(
257
+ name_column,
258
+ byte_column,
259
+ bit_length_column,
260
+ semantic_column,
261
+ param_type_column,
262
+ data_type_column,
263
+ value_column,
264
+ value_type_column,
265
+ dop_column,
266
+ strict=False)
255
267
  for row in rows:
256
268
  table.add_row(*map(str, row))
257
269
 
258
270
  return table
259
271
 
260
272
 
261
- def print_dl_metrics(variants: List[DiagLayer]) -> None:
273
+ def print_dl_metrics(variants: list[DiagLayer]) -> None:
262
274
  """
263
275
  Print diagnostic layer metrics using Rich tables.
264
276
  Args:
@@ -278,7 +290,7 @@ def print_dl_metrics(variants: List[DiagLayer]) -> None:
278
290
  # Process each variant
279
291
  for variant in variants:
280
292
  assert isinstance(variant, DiagLayer)
281
- all_services: List[Union[DiagService, SingleEcuJob]] = sorted(
293
+ all_services: list[DiagService | SingleEcuJob] = sorted(
282
294
  variant.services, key=lambda x: x.short_name)
283
295
  ddds = variant.diag_data_dictionary_spec
284
296
 
odxtools/cli/browse.py CHANGED
@@ -2,7 +2,7 @@
2
2
  import argparse
3
3
  import logging
4
4
  import sys
5
- from typing import List, Optional, Union, cast
5
+ from typing import cast
6
6
 
7
7
  import InquirerPy.prompt as IP_prompt
8
8
 
@@ -66,7 +66,7 @@ def _validate_string_value(input: str, parameter: Parameter) -> bool:
66
66
  return input != ""
67
67
 
68
68
 
69
- def prompt_single_parameter_value(parameter: Parameter) -> Optional[AtomicOdxType]:
69
+ def prompt_single_parameter_value(parameter: Parameter) -> AtomicOdxType | None:
70
70
  if not isinstance(parameter, ValueParameter):
71
71
  odxraise("Only the value of ValueParameters can be queried")
72
72
  if parameter.physical_type is None:
@@ -113,7 +113,7 @@ def prompt_single_parameter_value(parameter: Parameter) -> Optional[AtomicOdxTyp
113
113
  return cast(str, answer.get(parameter.short_name))
114
114
 
115
115
 
116
- def encode_message_interactively(codec: Union[Request, Response],
116
+ def encode_message_interactively(codec: Request | Response,
117
117
  ask_user_confirmation: bool = False) -> None:
118
118
  if sys.__stdin__ is None or sys.__stdout__ is None or not sys.__stdin__.isatty(
119
119
  ) or not sys.__stdout__.isatty():
@@ -168,7 +168,7 @@ def encode_message_interactively(codec: Union[Request, Response],
168
168
  if (inner_params := getattr(dop := getattr(param, "dop", None), "parameters",
169
169
  None)) is not None:
170
170
  assert isinstance(dop, DopBase)
171
- inner_params = cast(List[Parameter], inner_params)
171
+ inner_params = cast(list[Parameter], inner_params)
172
172
  # param refers to a complex DOP, i.e., the required
173
173
  # value is a key-value dict
174
174
  print(
@@ -201,8 +201,8 @@ def encode_message_interactively(codec: Union[Request, Response],
201
201
 
202
202
 
203
203
  def encode_message_from_string_values(
204
- sub_service: Union[Request, Response],
205
- parameter_values: Optional[ParameterValueDict] = None,
204
+ sub_service: Request | Response,
205
+ parameter_values: ParameterValueDict | None = None,
206
206
  ) -> None:
207
207
  if parameter_values is None:
208
208
  parameter_values = {}
@@ -243,7 +243,7 @@ def encode_message_from_string_values(
243
243
  inner_params = getattr(dop, "parameters", None)
244
244
  assert isinstance(dop, ComplexDop)
245
245
  assert isinstance(inner_params, list)
246
- inner_params = cast(List[Parameter], inner_params)
246
+ inner_params = cast(list[Parameter], inner_params)
247
247
 
248
248
  typed_dict = parameter_value.copy()
249
249
  for inner_param_sn, inner_param_value in parameter_value.items():
@@ -316,7 +316,7 @@ def browse(odxdb: Database) -> None:
316
316
  )
317
317
 
318
318
  while True:
319
- services: List[DiagService] = [
319
+ services: list[DiagService] = [
320
320
  s for s in variant.services if isinstance(s, DiagService)
321
321
  ]
322
322
  # Select a service of the ECU
@@ -370,7 +370,7 @@ def browse(odxdb: Database) -> None:
370
370
 
371
371
  codec = answer.get("message_type")
372
372
  if codec is not None:
373
- assert isinstance(codec, (Request, Response))
373
+ assert isinstance(codec, Request | Response)
374
374
  table = extract_parameter_tabulation_data(codec.parameters)
375
375
  print(table)
376
376
 
odxtools/cli/compare.py CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  import argparse
5
5
  import os
6
- from typing import Any, Dict, List, Optional, Set, Union, cast
6
+ from typing import Any, cast
7
7
 
8
8
  from rich import print as rich_print
9
9
  from rich.padding import Padding as RichPadding
@@ -29,18 +29,18 @@ _odxtools_tool_name_ = "compare"
29
29
 
30
30
  VariantName = str
31
31
  VariantType = str
32
- NewServices = List[DiagService]
33
- DeletedServices = List[DiagService]
34
- RenamedServices = List[List[Union[str, DiagService]]]
35
- ServicesWithParamChanges = List[List[Union[str, DiagService]]]
32
+ NewServices = list[DiagService]
33
+ DeletedServices = list[DiagService]
34
+ RenamedServices = list[list[str | DiagService]]
35
+ ServicesWithParamChanges = list[list[str | DiagService]]
36
36
 
37
- SpecsServiceDict = Dict[str, Union[VariantName, VariantType, NewServices, DeletedServices,
38
- RenamedServices, ServicesWithParamChanges]]
37
+ SpecsServiceDict = dict[str, VariantName | VariantType | NewServices | DeletedServices
38
+ | RenamedServices | ServicesWithParamChanges]
39
39
 
40
- NewVariants = List[DiagLayer]
41
- DeletedVariants = List[DiagLayer]
40
+ NewVariants = list[DiagLayer]
41
+ DeletedVariants = list[DiagLayer]
42
42
 
43
- SpecsChangesVariants = Dict[str, Union[NewVariants, DeletedVariants, SpecsServiceDict]]
43
+ SpecsChangesVariants = dict[str, NewVariants | DeletedVariants | SpecsServiceDict]
44
44
 
45
45
 
46
46
  class Display:
@@ -71,13 +71,13 @@ class Display:
71
71
  f"Changed diagnostic services for diagnostic layer '{service_dict['diag_layer']}' ({service_dict['diag_layer_type']}):"
72
72
  )
73
73
  if service_dict["new_services"]:
74
- assert isinstance(service_dict["new_services"], List)
74
+ assert isinstance(service_dict["new_services"], list)
75
75
  rich_print()
76
76
  rich_print(" [blue]New services[/blue]")
77
77
  rich_print(extract_service_tabulation_data(
78
78
  service_dict["new_services"])) # type: ignore[arg-type]
79
79
  if service_dict["deleted_services"]:
80
- assert isinstance(service_dict["deleted_services"], List)
80
+ assert isinstance(service_dict["deleted_services"], list)
81
81
  rich_print()
82
82
  rich_print(" [blue]Deleted services[/blue]")
83
83
  rich_print(extract_service_tabulation_data(
@@ -123,7 +123,7 @@ class Display:
123
123
  show_lines=True)
124
124
  for header in detailed_info:
125
125
  table.add_column(header)
126
- rows = zip(*detailed_info.values())
126
+ rows = zip(*detailed_info.values(), strict=False)
127
127
  for row in rows:
128
128
  table.add_row(*map(str, row))
129
129
 
@@ -159,9 +159,9 @@ class Display:
159
159
 
160
160
 
161
161
  class Comparison(Display):
162
- databases: List[Database] = [] # storage of database objects
163
- diagnostic_layers: List[DiagLayer] = [] # storage of DiagLayer objects
164
- diagnostic_layer_names: Set[str] = set() # storage of diagnostic layer names
162
+ databases: list[Database] = [] # storage of database objects
163
+ diagnostic_layers: list[DiagLayer] = [] # storage of DiagLayer objects
164
+ diagnostic_layer_names: set[str] = set() # storage of diagnostic layer names
165
165
 
166
166
  db_indicator_1: int
167
167
  db_indicator_2: int
@@ -169,7 +169,7 @@ class Comparison(Display):
169
169
  def __init__(self) -> None:
170
170
  pass
171
171
 
172
- def compare_parameters(self, param1: Parameter, param2: Parameter) -> Dict[str, Any]:
172
+ def compare_parameters(self, param1: Parameter, param2: Parameter) -> dict[str, Any]:
173
173
  # checks whether properties of param1 and param2 differ
174
174
  # checked properties: Name, Byte Position, Bit Length, Semantic, Parameter Type, Value (Coded, Constant, Default etc.), Data Type, Data Object Property (Name, Physical Data Type, Unit)
175
175
 
@@ -177,8 +177,8 @@ class Comparison(Display):
177
177
  old = []
178
178
  new = []
179
179
 
180
- def append_list(property_name: str, new_property_value: Optional[AtomicOdxType],
181
- old_property_value: Optional[AtomicOdxType]) -> None:
180
+ def append_list(property_name: str, new_property_value: AtomicOdxType | None,
181
+ old_property_value: AtomicOdxType | None) -> None:
182
182
  property.append(property_name)
183
183
  old.append(old_property_value)
184
184
  new.append(new_property_value)
@@ -277,10 +277,10 @@ class Comparison(Display):
277
277
  return {"Property": property, "Old Value": old, "New Value": new}
278
278
 
279
279
  def compare_services(self, service1: DiagService,
280
- service2: DiagService) -> List[SpecsServiceDict]:
280
+ service2: DiagService) -> list[SpecsServiceDict]:
281
281
  # compares request, positive response and negative response parameters of two diagnostic services
282
282
 
283
- information: List[Union[str, Dict[str, Any]]] = [
283
+ information: list[str | dict[str, Any]] = [
284
284
  ] # information = [infotext1, table1, infotext2, table2, ...]
285
285
  changed_params = ""
286
286
 
@@ -438,10 +438,10 @@ class Comparison(Display):
438
438
 
439
439
  # extract the constant prefixes for the requests of all
440
440
  # services (used for duck-typed rename detection)
441
- dl1_request_prefixes: List[Optional[bytes]] = [
441
+ dl1_request_prefixes: list[bytes | None] = [
442
442
  None if s.request is None else s.request.coded_const_prefix() for s in dl1.services
443
443
  ]
444
- dl2_request_prefixes: List[Optional[bytes]] = [
444
+ dl2_request_prefixes: list[bytes | None] = [
445
445
  None if s.request is None else s.request.coded_const_prefix() for s in dl2.services
446
446
  ]
447
447
 
@@ -449,7 +449,7 @@ class Comparison(Display):
449
449
  for service1 in dl1.services:
450
450
 
451
451
  # check for added diagnostic services
452
- rq_prefix: Optional[bytes] = None
452
+ rq_prefix: bytes | None = None
453
453
  if service1.request is not None:
454
454
  rq_prefix = service1.request.coded_const_prefix()
455
455
 
odxtools/cli/decode.py CHANGED
@@ -1,7 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import argparse
3
3
  import re
4
- from typing import Dict, List, Optional
5
4
 
6
5
  from ..database import Database
7
6
  from ..diagservice import DiagService
@@ -26,13 +25,13 @@ def get_display_value(v: ParameterValue) -> str:
26
25
 
27
26
  def print_summary(
28
27
  odxdb: Database,
29
- ecu_variants: Optional[List[str]] = None,
28
+ ecu_variants: list[str] | None = None,
30
29
  data: bytes = b'',
31
30
  decode: bool = False,
32
31
  ) -> None:
33
32
  ecu_names = ecu_variants if ecu_variants else [ecu.short_name for ecu in odxdb.ecus]
34
- service_db: Dict[str, DiagService] = {}
35
- service_ecus: Dict[str, List[str]] = {}
33
+ service_db: dict[str, DiagService] = {}
34
+ service_ecus: dict[str, list[str]] = {}
36
35
  for ecu_name in ecu_names:
37
36
  ecu = odxdb.ecus[ecu_name]
38
37
  if not ecu:
odxtools/cli/find.py CHANGED
@@ -1,6 +1,5 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import argparse
3
- from typing import Dict, List, Optional
4
3
 
5
4
  from ..database import Database
6
5
  from ..diagservice import DiagService
@@ -24,13 +23,13 @@ def get_display_value(v: ParameterValue) -> str:
24
23
 
25
24
 
26
25
  def print_summary(odxdb: Database,
27
- service_names: List[str],
28
- ecu_variants: Optional[List[str]] = None,
26
+ service_names: list[str],
27
+ ecu_variants: list[str] | None = None,
29
28
  allow_unknown_bit_lengths: bool = False,
30
29
  print_params: bool = False) -> None:
31
30
  ecu_names = ecu_variants if ecu_variants else [ecu.short_name for ecu in odxdb.ecus]
32
- service_db: Dict[str, DiagService] = {}
33
- service_ecus: Dict[str, List[str]] = {}
31
+ service_db: dict[str, DiagService] = {}
32
+ service_ecus: dict[str, list[str]] = {}
34
33
  for ecu_name in ecu_names:
35
34
  ecu = odxdb.ecus[ecu_name]
36
35
  if not ecu:
odxtools/cli/list.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import argparse
3
- from typing import Callable, List, Optional
3
+ from collections.abc import Callable
4
4
 
5
5
  import rich
6
6
 
@@ -32,11 +32,11 @@ def print_summary(odxdb: Database,
32
32
  print_state_transitions: bool = False,
33
33
  print_audiences: bool = False,
34
34
  allow_unknown_bit_lengths: bool = False,
35
- variants: Optional[List[str]] = None,
35
+ variants: list[str] | None = None,
36
36
  service_filter: Callable[[DiagComm], bool] = lambda x: True) -> None:
37
37
 
38
38
  diag_layer_names = [dl.short_name for dl in odxdb.diag_layers]
39
- diag_layers: List[DiagLayer] = []
39
+ diag_layers: list[DiagLayer] = []
40
40
 
41
41
  if variants is None:
42
42
  variants = diag_layer_names
@@ -59,9 +59,9 @@ def print_summary(odxdb: Database,
59
59
  rich.print(f"Diagnostic layer: '{dl.short_name}'")
60
60
  rich.print(f" Variant Type: {dl.variant_type.value}")
61
61
 
62
- all_services: List[DiagComm] = sorted(dl.services, key=lambda x: x.short_name)
62
+ all_services: list[DiagComm] = sorted(dl.services, key=lambda x: x.short_name)
63
63
 
64
- if isinstance(dl, (BaseVariant, EcuVariant)):
64
+ if isinstance(dl, BaseVariant | EcuVariant):
65
65
  for proto in dl.protocols:
66
66
  if (can_rx_id := dl.get_can_receive_id(proto.short_name)) is not None:
67
67
  rich.print(
@@ -99,7 +99,7 @@ def print_summary(odxdb: Database,
99
99
  else:
100
100
  rich.print(f" Unidentifiable service: {service}")
101
101
  ddd_spec = dl.diag_data_dictionary_spec
102
- data_object_properties: List[
102
+ data_object_properties: list[
103
103
  DataObjectProperty] = [] if ddd_spec is None else ddd_spec.data_object_props
104
104
  if print_dops and len(data_object_properties) > 0:
105
105
  rich.print("\n")
@@ -108,7 +108,7 @@ def print_summary(odxdb: Database,
108
108
  data_object_properties, key=lambda x: (type(x).__name__, x.short_name)):
109
109
  rich.print(" " + str(dop.short_name).replace("\n", "\n "))
110
110
 
111
- comparam_refs: List[ComparamInstance] = []
111
+ comparam_refs: list[ComparamInstance] = []
112
112
  if isinstance(dl, HierarchyElement):
113
113
  comparam_refs = dl.comparam_refs
114
114