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,11 +1,11 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import re
3
3
  import warnings
4
+ from collections.abc import Callable, Iterable
4
5
  from copy import deepcopy
5
6
  from dataclasses import dataclass
6
7
  from functools import cached_property
7
- from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Optional, Tuple, TypeVar,
8
- Union, cast)
8
+ from typing import TYPE_CHECKING, Any, TypeVar, Union, cast
9
9
  from xml.etree import ElementTree
10
10
 
11
11
  from ..additionalaudience import AdditionalAudience
@@ -47,7 +47,7 @@ class HierarchyElement(DiagLayer):
47
47
 
48
48
  @staticmethod
49
49
  def from_et(et_element: ElementTree.Element,
50
- doc_frags: List[OdxDocFragment]) -> "HierarchyElement":
50
+ doc_frags: list[OdxDocFragment]) -> "HierarchyElement":
51
51
  hierarchy_element_raw = HierarchyElementRaw.from_et(et_element, doc_frags)
52
52
 
53
53
  return HierarchyElement(diag_layer_raw=hierarchy_element_raw)
@@ -62,7 +62,7 @@ class HierarchyElement(DiagLayer):
62
62
  "The raw diagnostic layer passed to HierarchyElement "
63
63
  "must be a HierarchyElementRaw")
64
64
 
65
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
65
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
66
66
  result = super()._build_odxlinks()
67
67
 
68
68
  return result
@@ -73,7 +73,7 @@ class HierarchyElement(DiagLayer):
73
73
  def _resolve_snrefs(self, context: SnRefContext) -> None:
74
74
  super()._resolve_snrefs(context)
75
75
 
76
- def __deepcopy__(self, memo: Dict[int, Any]) -> Any:
76
+ def __deepcopy__(self, memo: dict[int, Any]) -> Any:
77
77
  """Create a deep copy of the hierarchy element
78
78
 
79
79
  Note that the copied diagnostic layer is not fully
@@ -121,13 +121,13 @@ class HierarchyElement(DiagLayer):
121
121
  unit_groups = self._compute_available_unit_groups()
122
122
 
123
123
  # convenience variable for the locally-defined unit spec
124
- local_unit_spec: Optional[UnitSpec]
124
+ local_unit_spec: UnitSpec | None
125
125
  if self.diag_layer_raw.diag_data_dictionary_spec is not None:
126
126
  local_unit_spec = self.diag_layer_raw.diag_data_dictionary_spec.unit_spec
127
127
  else:
128
128
  local_unit_spec = None
129
129
 
130
- unit_spec: Optional[UnitSpec]
130
+ unit_spec: UnitSpec | None
131
131
  if local_unit_spec is None and not unit_groups:
132
132
  # no locally defined unit spec and no inherited unit groups
133
133
  unit_spec = None
@@ -188,8 +188,8 @@ class HierarchyElement(DiagLayer):
188
188
  tables = self._compute_available_ddd_spec_items(
189
189
  lambda ddd_spec: ddd_spec.tables, lambda parent_ref: parent_ref.not_inherited_tables)
190
190
 
191
- ddds_admin_data: Optional[AdminData] = None
192
- ddds_sdgs: List[SpecialDataGroup] = []
191
+ ddds_admin_data: AdminData | None = None
192
+ ddds_sdgs: list[SpecialDataGroup] = []
193
193
  if self.diag_layer_raw.diag_data_dictionary_spec:
194
194
  ddds_admin_data = self.diag_layer_raw.diag_data_dictionary_spec.admin_data
195
195
  ddds_sdgs = self.diag_layer_raw.diag_data_dictionary_spec.sdgs
@@ -291,7 +291,7 @@ class HierarchyElement(DiagLayer):
291
291
 
292
292
  local_objects = get_local_objects(self)
293
293
  local_object_short_names = {x.short_name for x in local_objects}
294
- result_dict: Dict[str, Tuple[TNamed, DiagLayer]] = {}
294
+ result_dict: dict[str, tuple[TNamed, DiagLayer]] = {}
295
295
 
296
296
  # populate the result dictionary with the inherited objects
297
297
  for parent_ref in self._get_parent_refs_sorted_by_priority(reverse=True):
@@ -361,7 +361,7 @@ class HierarchyElement(DiagLayer):
361
361
  def get_local_objects_fn(dl: DiagLayer) -> Iterable[DiagComm]:
362
362
  return dl._get_local_diag_comms(odxlinks)
363
363
 
364
- def not_inherited_fn(parent_ref: ParentRef) -> List[str]:
364
+ def not_inherited_fn(parent_ref: ParentRef) -> list[str]:
365
365
  return parent_ref.not_inherited_diag_comms
366
366
 
367
367
  return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
@@ -372,7 +372,7 @@ class HierarchyElement(DiagLayer):
372
372
  def get_local_objects_fn(dl: DiagLayer) -> Iterable[Response]:
373
373
  return dl.diag_layer_raw.global_negative_responses
374
374
 
375
- def not_inherited_fn(parent_ref: ParentRef) -> List[str]:
375
+ def not_inherited_fn(parent_ref: ParentRef) -> list[str]:
376
376
  return parent_ref.not_inherited_global_neg_responses
377
377
 
378
378
  return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
@@ -380,7 +380,7 @@ class HierarchyElement(DiagLayer):
380
380
  def _compute_available_ddd_spec_items(
381
381
  self,
382
382
  include: Callable[[DiagDataDictionarySpec], Iterable[TNamed]],
383
- exclude: Callable[["ParentRef"], List[str]],
383
+ exclude: Callable[["ParentRef"], list[str]],
384
384
  ) -> NamedItemList[TNamed]:
385
385
 
386
386
  def get_local_objects_fn(dl: DiagLayer) -> Iterable[TNamed]:
@@ -396,7 +396,7 @@ class HierarchyElement(DiagLayer):
396
396
  def get_local_objects_fn(dl: DiagLayer) -> Iterable[FunctionalClass]:
397
397
  return dl.diag_layer_raw.functional_classes
398
398
 
399
- def not_inherited_fn(parent_ref: ParentRef) -> List[str]:
399
+ def not_inherited_fn(parent_ref: ParentRef) -> list[str]:
400
400
  return []
401
401
 
402
402
  return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
@@ -406,7 +406,7 @@ class HierarchyElement(DiagLayer):
406
406
  def get_local_objects_fn(dl: DiagLayer) -> Iterable[AdditionalAudience]:
407
407
  return dl.diag_layer_raw.additional_audiences
408
408
 
409
- def not_inherited_fn(parent_ref: ParentRef) -> List[str]:
409
+ def not_inherited_fn(parent_ref: ParentRef) -> list[str]:
410
410
  return []
411
411
 
412
412
  return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
@@ -416,7 +416,7 @@ class HierarchyElement(DiagLayer):
416
416
  def get_local_objects_fn(dl: DiagLayer) -> Iterable[StateChart]:
417
417
  return dl.diag_layer_raw.state_charts
418
418
 
419
- def not_inherited_fn(parent_ref: ParentRef) -> List[str]:
419
+ def not_inherited_fn(parent_ref: ParentRef) -> list[str]:
420
420
  return []
421
421
 
422
422
  return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
@@ -426,7 +426,7 @@ class HierarchyElement(DiagLayer):
426
426
  def get_local_objects_fn(dl: DiagLayer) -> Iterable[UnitGroup]:
427
427
  return dl._get_local_unit_groups()
428
428
 
429
- def not_inherited_fn(parent_ref: ParentRef) -> List[str]:
429
+ def not_inherited_fn(parent_ref: ParentRef) -> list[str]:
430
430
  return []
431
431
 
432
432
  return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
@@ -502,7 +502,7 @@ class HierarchyElement(DiagLayer):
502
502
  #####
503
503
  # <communication parameter handling>
504
504
  #####
505
- def _compute_available_commmunication_parameters(self) -> List[ComparamInstance]:
505
+ def _compute_available_commmunication_parameters(self) -> list[ComparamInstance]:
506
506
  """Compute the list of communication parameters that apply to
507
507
  the diagnostic layer
508
508
 
@@ -526,7 +526,7 @@ class HierarchyElement(DiagLayer):
526
526
  without a specified protocol are taken as fallbacks...
527
527
 
528
528
  """
529
- com_params_dict: Dict[Tuple[str, Optional[str]], ComparamInstance] = {}
529
+ com_params_dict: dict[tuple[str, str | None], ComparamInstance] = {}
530
530
 
531
531
  # Look in parent refs for inherited communication
532
532
  # parameters. First fetch the communication parameters from
@@ -564,7 +564,7 @@ class HierarchyElement(DiagLayer):
564
564
  """
565
565
  from .protocol import Protocol
566
566
 
567
- result_dict: Dict[str, Protocol] = {}
567
+ result_dict: dict[str, Protocol] = {}
568
568
 
569
569
  for parent_ref in getattr(self, "parent_refs", []):
570
570
  for prot in getattr(parent_ref.layer, "protocols", []):
@@ -579,15 +579,15 @@ class HierarchyElement(DiagLayer):
579
579
  self,
580
580
  cp_short_name: str,
581
581
  *,
582
- protocol: Optional[Union[str, "Protocol"]] = None,
583
- ) -> Optional[ComparamInstance]:
582
+ protocol: Union[str, "Protocol"] | None = None,
583
+ ) -> ComparamInstance | None:
584
584
  """Find a specific communication parameter according to some criteria.
585
585
 
586
586
  Setting a given parameter to `None` means "don't care"."""
587
587
 
588
588
  from .protocol import Protocol
589
589
 
590
- protocol_name: Optional[str]
590
+ protocol_name: str | None
591
591
  if isinstance(protocol, Protocol):
592
592
  protocol_name = protocol.short_name
593
593
  else:
@@ -611,8 +611,7 @@ class HierarchyElement(DiagLayer):
611
611
  return cps[0]
612
612
 
613
613
  def get_max_can_payload_size(self,
614
- protocol: Optional[Union[str,
615
- "Protocol"]] = None) -> Optional[int]:
614
+ protocol: Union[str, "Protocol"] | None = None) -> int | None:
616
615
  """Return the maximum size of a CAN frame payload that can be
617
616
  transmitted in bytes.
618
617
 
@@ -642,13 +641,13 @@ class HierarchyElement(DiagLayer):
642
641
  # unexpected format of parameter value
643
642
  return 8
644
643
 
645
- def uses_can(self, protocol: Optional[Union[str, "Protocol"]] = None) -> bool:
644
+ def uses_can(self, protocol: Union[str, "Protocol"] | None = None) -> bool:
646
645
  """
647
646
  Check if CAN ought to be used as the link layer protocol.
648
647
  """
649
648
  return self.get_can_receive_id(protocol=protocol) is not None
650
649
 
651
- def uses_can_fd(self, protocol: Optional[Union[str, "Protocol"]] = None) -> bool:
650
+ def uses_can_fd(self, protocol: Union[str, "Protocol"] | None = None) -> bool:
652
651
  """Check if CAN-FD ought to be used.
653
652
 
654
653
  If the ECU is not using CAN-FD for the specified protocol, `False`
@@ -667,7 +666,7 @@ class HierarchyElement(DiagLayer):
667
666
 
668
667
  return "CANFD" in com_param.value
669
668
 
670
- def get_can_baudrate(self, protocol: Optional[Union[str, "Protocol"]] = None) -> Optional[int]:
669
+ def get_can_baudrate(self, protocol: Union[str, "Protocol"] | None = None) -> int | None:
671
670
  """Baudrate of the CAN bus which is used by the ECU [bits/s]
672
671
 
673
672
  If the ECU is not using CAN for the specified protocol, None
@@ -684,8 +683,7 @@ class HierarchyElement(DiagLayer):
684
683
 
685
684
  return int(val)
686
685
 
687
- def get_can_fd_baudrate(self,
688
- protocol: Optional[Union[str, "Protocol"]] = None) -> Optional[int]:
686
+ def get_can_fd_baudrate(self, protocol: Union[str, "Protocol"] | None = None) -> int | None:
689
687
  """Data baudrate of the CAN bus which is used by the ECU [bits/s]
690
688
 
691
689
  If the ECU is not using CAN-FD for the specified protocol,
@@ -704,8 +702,7 @@ class HierarchyElement(DiagLayer):
704
702
 
705
703
  return int(val)
706
704
 
707
- def get_can_receive_id(self,
708
- protocol: Optional[Union[str, "Protocol"]] = None) -> Optional[int]:
705
+ def get_can_receive_id(self, protocol: Union[str, "Protocol"] | None = None) -> int | None:
709
706
  """CAN ID to which the ECU listens for diagnostic messages"""
710
707
  com_param = self.get_comparam("CP_UniqueRespIdTable", protocol=protocol)
711
708
  if com_param is None:
@@ -724,7 +721,7 @@ class HierarchyElement(DiagLayer):
724
721
 
725
722
  return int(result)
726
723
 
727
- def get_can_send_id(self, protocol: Optional[Union[str, "Protocol"]] = None) -> Optional[int]:
724
+ def get_can_send_id(self, protocol: Union[str, "Protocol"] | None = None) -> int | None:
728
725
  """CAN ID to which the ECU sends replies to diagnostic messages"""
729
726
 
730
727
  # this hopefully resolves to the 'CP_UniqueRespIdTable'
@@ -749,8 +746,7 @@ class HierarchyElement(DiagLayer):
749
746
 
750
747
  return int(result)
751
748
 
752
- def get_can_func_req_id(self,
753
- protocol: Optional[Union[str, "Protocol"]] = None) -> Optional[int]:
749
+ def get_can_func_req_id(self, protocol: Union[str, "Protocol"] | None = None) -> int | None:
754
750
  """CAN Functional Request Id."""
755
751
  com_param = self.get_comparam("CP_CanFuncReqId", protocol=protocol)
756
752
  if com_param is None:
@@ -764,8 +760,7 @@ class HierarchyElement(DiagLayer):
764
760
  return int(result)
765
761
 
766
762
  def get_doip_logical_ecu_address(self,
767
- protocol: Optional[Union[str,
768
- "Protocol"]] = None) -> Optional[int]:
763
+ protocol: Union[str, "Protocol"] | None = None) -> int | None:
769
764
  """Return the address of the ECU when using functional addressing.
770
765
 
771
766
  The parameter protocol is used to distinguish between
@@ -796,8 +791,8 @@ class HierarchyElement(DiagLayer):
796
791
  return int(ecu_addr)
797
792
 
798
793
  def get_doip_logical_gateway_address(self,
799
- protocol: Optional[Union[str, "Protocol"]] = None
800
- ) -> Optional[int]:
794
+ protocol: Union[str, "Protocol"] | None = None
795
+ ) -> int | None:
801
796
  """The logical gateway address for the diagnosis over IP transport protocol"""
802
797
 
803
798
  # retrieve CP_DoIPLogicalGatewayAddress from the
@@ -814,8 +809,8 @@ class HierarchyElement(DiagLayer):
814
809
  return int(result)
815
810
 
816
811
  def get_doip_logical_tester_address(self,
817
- protocol: Optional[Union[str, "Protocol"]] = None
818
- ) -> Optional[int]:
812
+ protocol: Union[str, "Protocol"] | None = None
813
+ ) -> int | None:
819
814
  """DoIp logical gateway address"""
820
815
 
821
816
  # retrieve CP_DoIPLogicalTesterAddress from the
@@ -832,8 +827,8 @@ class HierarchyElement(DiagLayer):
832
827
  return int(result)
833
828
 
834
829
  def get_doip_logical_functional_address(self,
835
- protocol: Optional[Union[str, "Protocol"]] = None
836
- ) -> Optional[int]:
830
+ protocol: Union[str, "Protocol"] | None = None
831
+ ) -> int | None:
837
832
  """The logical functional DoIP address of the ECU."""
838
833
 
839
834
  # retrieve CP_DoIPLogicalFunctionalAddress from the
@@ -853,8 +848,8 @@ class HierarchyElement(DiagLayer):
853
848
  return int(result)
854
849
 
855
850
  def get_doip_routing_activation_timeout(self,
856
- protocol: Optional[Union[str, "Protocol"]] = None
857
- ) -> Optional[float]:
851
+ protocol: Union[str, "Protocol"] | None = None
852
+ ) -> float | None:
858
853
  """The timout for the DoIP routing activation request in seconds"""
859
854
 
860
855
  # retrieve CP_DoIPRoutingActivationTimeout from the
@@ -871,8 +866,8 @@ class HierarchyElement(DiagLayer):
871
866
  return float(result) / 1e6
872
867
 
873
868
  def get_doip_routing_activation_type(self,
874
- protocol: Optional[Union[str, "Protocol"]] = None
875
- ) -> Optional[int]:
869
+ protocol: Union[str, "Protocol"] | None = None
870
+ ) -> int | None:
876
871
  """The DoIP routing activation type
877
872
 
878
873
  The number returned has the following meaning:
@@ -897,8 +892,7 @@ class HierarchyElement(DiagLayer):
897
892
  return int(result)
898
893
 
899
894
  def get_tester_present_time(self,
900
- protocol: Optional[Union[str,
901
- "Protocol"]] = None) -> Optional[float]:
895
+ protocol: Union[str, "Protocol"] | None = None) -> float | None:
902
896
  """Timeout on inactivity in seconds.
903
897
 
904
898
  This is defined by the communication parameter "CP_TesterPresentTime".
@@ -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 ..comparaminstance import ComparamInstance
@@ -17,11 +17,11 @@ class HierarchyElementRaw(DiagLayerRaw):
17
17
  This class represents the data present in the XML, not the "logical" view.
18
18
  """
19
19
 
20
- comparam_refs: List[ComparamInstance]
20
+ comparam_refs: list[ComparamInstance]
21
21
 
22
22
  @staticmethod
23
23
  def from_et(et_element: ElementTree.Element,
24
- doc_frags: List[OdxDocFragment]) -> "HierarchyElementRaw":
24
+ doc_frags: list[OdxDocFragment]) -> "HierarchyElementRaw":
25
25
  # objects contained by diagnostic layers exibit an additional
26
26
  # document fragment for the diag layer, so we use the document
27
27
  # fragments of the odx id of the diag layer for IDs of
@@ -37,7 +37,7 @@ class HierarchyElementRaw(DiagLayerRaw):
37
37
 
38
38
  return HierarchyElementRaw(comparam_refs=comparam_refs, **kwargs)
39
39
 
40
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
40
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
41
41
  result = super()._build_odxlinks()
42
42
 
43
43
  for comparam_ref in self.comparam_refs:
@@ -1,7 +1,7 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from copy import deepcopy
3
3
  from dataclasses import dataclass
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 ..comparamspec import ComparamSpec
@@ -29,11 +29,11 @@ class Protocol(HierarchyElement):
29
29
  return self.protocol_raw.comparam_spec
30
30
 
31
31
  @property
32
- def prot_stack(self) -> Optional[ProtStack]:
32
+ def prot_stack(self) -> ProtStack | None:
33
33
  return self.protocol_raw.prot_stack
34
34
 
35
35
  @staticmethod
36
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "Protocol":
36
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Protocol":
37
37
  protocol_raw = ProtocolRaw.from_et(et_element, doc_frags)
38
38
 
39
39
  return Protocol(diag_layer_raw=protocol_raw)
@@ -46,7 +46,7 @@ class Protocol(HierarchyElement):
46
46
  "The raw diagnostic layer passed to Protocol "
47
47
  "must be a ProtocolRaw")
48
48
 
49
- def __deepcopy__(self, memo: Dict[int, Any]) -> Any:
49
+ def __deepcopy__(self, memo: dict[int, Any]) -> Any:
50
50
  """Create a deep copy of the protocol layer
51
51
 
52
52
  Note that the copied diagnostic layer is not fully
@@ -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 ..comparamspec import ComparamSpec
@@ -24,19 +24,19 @@ class ProtocolRaw(HierarchyElementRaw):
24
24
  """
25
25
 
26
26
  comparam_spec_ref: OdxLinkRef
27
- prot_stack_snref: Optional[str]
28
- parent_refs: List[ParentRef]
27
+ prot_stack_snref: str | None
28
+ parent_refs: list[ParentRef]
29
29
 
30
30
  @property
31
31
  def comparam_spec(self) -> ComparamSpec:
32
32
  return self._comparam_spec
33
33
 
34
34
  @property
35
- def prot_stack(self) -> Optional[ProtStack]:
35
+ def prot_stack(self) -> ProtStack | None:
36
36
  return self._prot_stack
37
37
 
38
38
  @staticmethod
39
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "ProtocolRaw":
39
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "ProtocolRaw":
40
40
  # objects contained by diagnostic layers exibit an additional
41
41
  # document fragment for the diag layer, so we use the document
42
42
  # fragments of the odx id of the diag layer for IDs of
@@ -63,7 +63,7 @@ class ProtocolRaw(HierarchyElementRaw):
63
63
  parent_refs=parent_refs,
64
64
  **kwargs)
65
65
 
66
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
66
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
67
67
  result = super()._build_odxlinks()
68
68
 
69
69
  for parent_ref in self.parent_refs:
@@ -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 .element import IdentifiableElement
@@ -16,12 +16,12 @@ from .utils import dataclass_fields_asdict
16
16
  @dataclass
17
17
  class DiagnosticTroubleCode(IdentifiableElement):
18
18
  trouble_code: int
19
- display_trouble_code: Optional[str]
19
+ display_trouble_code: str | None
20
20
  text: Text
21
- level: Optional[int]
22
- sdgs: List[SpecialDataGroup]
21
+ level: int | None
22
+ sdgs: list[SpecialDataGroup]
23
23
 
24
- is_temporary_raw: Optional[bool]
24
+ is_temporary_raw: bool | None
25
25
 
26
26
  @property
27
27
  def is_temporary(self) -> bool:
@@ -29,7 +29,7 @@ class DiagnosticTroubleCode(IdentifiableElement):
29
29
 
30
30
  @staticmethod
31
31
  def from_et(et_element: ElementTree.Element,
32
- doc_frags: List[OdxDocFragment]) -> "DiagnosticTroubleCode":
32
+ doc_frags: list[OdxDocFragment]) -> "DiagnosticTroubleCode":
33
33
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
34
34
 
35
35
  trouble_code = int(odxrequire(et_element.findtext("TROUBLE-CODE")))
@@ -53,8 +53,8 @@ class DiagnosticTroubleCode(IdentifiableElement):
53
53
  is_temporary_raw=is_temporary_raw,
54
54
  **kwargs)
55
55
 
56
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
57
- result: Dict[OdxLinkId, Any] = {}
56
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
57
+ result: dict[OdxLinkId, Any] = {}
58
58
 
59
59
  result[self.odx_id] = self
60
60
 
odxtools/diagservice.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, Union, cast
3
+ from typing import Any, cast
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .addressing import Addressing
@@ -25,23 +25,23 @@ class DiagService(DiagComm):
25
25
  """Representation of a diagnostic service description.
26
26
  """
27
27
 
28
- comparam_refs: List[ComparamInstance]
28
+ comparam_refs: list[ComparamInstance]
29
29
  request_ref: OdxLinkRef
30
- pos_response_refs: List[OdxLinkRef]
31
- neg_response_refs: List[OdxLinkRef]
32
- pos_response_suppressible: Optional[PosResponseSuppressible]
30
+ pos_response_refs: list[OdxLinkRef]
31
+ neg_response_refs: list[OdxLinkRef]
32
+ pos_response_suppressible: PosResponseSuppressible | None
33
33
 
34
- is_cyclic_raw: Optional[bool]
35
- is_multiple_raw: Optional[bool]
36
- addressing_raw: Optional[Addressing]
37
- transmission_mode_raw: Optional[TransMode]
34
+ is_cyclic_raw: bool | None
35
+ is_multiple_raw: bool | None
36
+ addressing_raw: Addressing | None
37
+ transmission_mode_raw: TransMode | None
38
38
 
39
39
  @property
40
40
  def comparams(self) -> NamedItemList[ComparamInstance]:
41
41
  return self._comparams
42
42
 
43
43
  @property
44
- def request(self) -> Optional[Request]:
44
+ def request(self) -> Request | None:
45
45
  return self._request
46
46
 
47
47
  @property
@@ -69,14 +69,14 @@ class DiagService(DiagComm):
69
69
  return self.transmission_mode_raw or TransMode.SEND_AND_RECEIVE
70
70
 
71
71
  @property
72
- def free_parameters(self) -> List[Parameter]:
72
+ def free_parameters(self) -> list[Parameter]:
73
73
  """Return the list of parameters which can be freely specified by
74
74
  the user when encoding the service's request.
75
75
  """
76
76
  return self.request.free_parameters if self.request is not None else []
77
77
 
78
78
  @staticmethod
79
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "DiagService":
79
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "DiagService":
80
80
 
81
81
  kwargs = dataclass_fields_asdict(DiagComm.from_et(et_element, doc_frags))
82
82
 
@@ -104,7 +104,7 @@ class DiagService(DiagComm):
104
104
  is_cyclic_raw = odxstr_to_bool(et_element.get("IS-CYCLIC"))
105
105
  is_multiple_raw = odxstr_to_bool(et_element.get("IS-MULTIPLE"))
106
106
 
107
- addressing_raw: Optional[Addressing] = None
107
+ addressing_raw: Addressing | None = None
108
108
  if (addressing_raw_str := et_element.get("ADDRESSING")) is not None:
109
109
  try:
110
110
  addressing_raw = Addressing(addressing_raw_str)
@@ -112,7 +112,7 @@ class DiagService(DiagComm):
112
112
  addressing_raw = cast(Addressing, None)
113
113
  odxraise(f"Encountered unknown addressing type '{addressing_raw_str}'")
114
114
 
115
- transmission_mode_raw: Optional[TransMode] = None
115
+ transmission_mode_raw: TransMode | None = None
116
116
  if (transmission_mode_raw_str := et_element.get("TRANSMISSION-MODE")) is not None:
117
117
  try:
118
118
  transmission_mode_raw = TransMode(transmission_mode_raw_str)
@@ -132,7 +132,7 @@ class DiagService(DiagComm):
132
132
  transmission_mode_raw=transmission_mode_raw,
133
133
  **kwargs)
134
134
 
135
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
135
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
136
136
  result = super()._build_odxlinks()
137
137
 
138
138
  for cpr in self.comparam_refs:
@@ -180,20 +180,20 @@ class DiagService(DiagComm):
180
180
 
181
181
  def decode_message(self, raw_message: bytes) -> Message:
182
182
  request_prefix = b''
183
- candidate_coding_objects: List[Union[Request, Response]] = [
183
+ candidate_coding_objects: list[Request | Response] = [
184
184
  *self.positive_responses, *self.negative_responses
185
185
  ]
186
186
  if self.request is not None:
187
187
  request_prefix = self.request.coded_const_prefix()
188
188
  candidate_coding_objects.append(self.request)
189
189
 
190
- coding_objects: List[Union[Request, Response]] = []
190
+ coding_objects: list[Request | Response] = []
191
191
  for candidate_coding_object in candidate_coding_objects:
192
192
  prefix = candidate_coding_object.coded_const_prefix(request_prefix=request_prefix)
193
193
  if len(raw_message) >= len(prefix) and prefix == raw_message[:len(prefix)]:
194
194
  coding_objects.append(candidate_coding_object)
195
195
 
196
- result_list: List[Message] = []
196
+ result_list: list[Message] = []
197
197
  for coding_object in coding_objects:
198
198
  try:
199
199
  result_list.append(
odxtools/diagvariable.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import typing
3
3
  from dataclasses import dataclass
4
- from typing import Any, Dict, List, Optional, runtime_checkable
4
+ from typing import Any, runtime_checkable
5
5
  from xml.etree import ElementTree
6
6
 
7
7
  from .admindata import AdminData
@@ -33,32 +33,32 @@ class DiagVariable(IdentifiableElement):
33
33
  """Representation of a diagnostic variable
34
34
  """
35
35
 
36
- admin_data: Optional[AdminData]
37
- variable_group_ref: Optional[OdxLinkRef]
38
- sw_variables: List[SwVariable]
36
+ admin_data: AdminData | None
37
+ variable_group_ref: OdxLinkRef | None
38
+ sw_variables: list[SwVariable]
39
39
 
40
40
  # a diag variable must specify either COMM-RELATIONS or a
41
41
  # reference to a table row
42
- comm_relations: List[CommRelation]
42
+ comm_relations: list[CommRelation]
43
43
 
44
44
  # these are nested inside the SNREF-TO-TABLEROW tag
45
- table_snref: Optional[str]
46
- table_row_snref: Optional[str]
45
+ table_snref: str | None
46
+ table_row_snref: str | None
47
47
 
48
- sdgs: List[SpecialDataGroup]
48
+ sdgs: list[SpecialDataGroup]
49
49
 
50
- is_read_before_write_raw: Optional[bool]
50
+ is_read_before_write_raw: bool | None
51
51
 
52
52
  @property
53
- def table(self) -> Optional[Table]:
53
+ def table(self) -> Table | None:
54
54
  return self._table
55
55
 
56
56
  @property
57
- def table_row(self) -> Optional[TableRow]:
57
+ def table_row(self) -> TableRow | None:
58
58
  return self._table_row
59
59
 
60
60
  @property
61
- def variable_group(self) -> Optional[VariableGroup]:
61
+ def variable_group(self) -> VariableGroup | None:
62
62
  return self._variable_group
63
63
 
64
64
  @property
@@ -66,7 +66,7 @@ class DiagVariable(IdentifiableElement):
66
66
  return self.is_read_before_write_raw is True
67
67
 
68
68
  @staticmethod
69
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "DiagVariable":
69
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "DiagVariable":
70
70
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
71
71
 
72
72
  admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
@@ -106,7 +106,7 @@ class DiagVariable(IdentifiableElement):
106
106
  is_read_before_write_raw=is_read_before_write_raw,
107
107
  **kwargs)
108
108
 
109
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
109
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
110
110
  result = {self.odx_id: self}
111
111
 
112
112
  if self.admin_data is not None: