odxtools 9.7.0__py3-none-any.whl → 10.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. odxtools/additionalaudience.py +7 -7
  2. odxtools/admindata.py +14 -13
  3. odxtools/audience.py +17 -17
  4. odxtools/basecomparam.py +9 -8
  5. odxtools/basevariantpattern.py +9 -10
  6. odxtools/basicstructure.py +15 -15
  7. odxtools/cli/_print_utils.py +34 -22
  8. odxtools/cli/browse.py +8 -8
  9. odxtools/cli/compare.py +24 -24
  10. odxtools/cli/decode.py +3 -4
  11. odxtools/cli/find.py +4 -5
  12. odxtools/cli/list.py +6 -6
  13. odxtools/cli/main.py +2 -2
  14. odxtools/cli/snoop.py +3 -3
  15. odxtools/codec.py +3 -3
  16. odxtools/commrelation.py +18 -17
  17. odxtools/companydata.py +13 -13
  18. odxtools/companydocinfo.py +15 -17
  19. odxtools/companyrevisioninfo.py +9 -9
  20. odxtools/companyspecificinfo.py +11 -13
  21. odxtools/comparam.py +8 -7
  22. odxtools/comparaminstance.py +14 -14
  23. odxtools/comparamspec.py +10 -11
  24. odxtools/comparamsubset.py +17 -25
  25. odxtools/complexcomparam.py +14 -14
  26. odxtools/complexdop.py +1 -1
  27. odxtools/compositecodec.py +8 -8
  28. odxtools/compumethods/compucodecompumethod.py +7 -7
  29. odxtools/compumethods/compuconst.py +5 -6
  30. odxtools/compumethods/compudefaultvalue.py +2 -3
  31. odxtools/compumethods/compuinternaltophys.py +13 -12
  32. odxtools/compumethods/compumethod.py +10 -9
  33. odxtools/compumethods/compuphystointernal.py +13 -12
  34. odxtools/compumethods/compurationalcoeffs.py +7 -7
  35. odxtools/compumethods/compuscale.py +15 -16
  36. odxtools/compumethods/createanycompumethod.py +12 -13
  37. odxtools/compumethods/identicalcompumethod.py +4 -5
  38. odxtools/compumethods/limit.py +14 -14
  39. odxtools/compumethods/linearcompumethod.py +5 -5
  40. odxtools/compumethods/linearsegment.py +10 -11
  41. odxtools/compumethods/ratfunccompumethod.py +6 -6
  42. odxtools/compumethods/ratfuncsegment.py +7 -8
  43. odxtools/compumethods/scalelinearcompumethod.py +9 -9
  44. odxtools/compumethods/scaleratfunccompumethod.py +7 -7
  45. odxtools/compumethods/tabintpcompumethod.py +10 -13
  46. odxtools/compumethods/texttablecompumethod.py +6 -6
  47. odxtools/createanycomparam.py +5 -7
  48. odxtools/createanydiagcodedtype.py +7 -8
  49. odxtools/database.py +34 -31
  50. odxtools/dataobjectproperty.py +19 -20
  51. odxtools/decodestate.py +5 -5
  52. odxtools/description.py +9 -9
  53. odxtools/determinenumberofitems.py +8 -7
  54. odxtools/diagcodedtype.py +10 -10
  55. odxtools/diagcomm.py +29 -30
  56. odxtools/diagdatadictionaryspec.py +36 -36
  57. odxtools/diaglayercontainer.py +35 -34
  58. odxtools/diaglayers/basevariant.py +14 -12
  59. odxtools/diaglayers/basevariantraw.py +22 -23
  60. odxtools/diaglayers/diaglayer.py +24 -22
  61. odxtools/diaglayers/diaglayerraw.py +43 -52
  62. odxtools/diaglayers/diaglayertype.py +1 -2
  63. odxtools/diaglayers/ecushareddata.py +9 -9
  64. odxtools/diaglayers/ecushareddataraw.py +15 -16
  65. odxtools/diaglayers/ecuvariant.py +15 -13
  66. odxtools/diaglayers/ecuvariantraw.py +21 -22
  67. odxtools/diaglayers/functionalgroup.py +12 -11
  68. odxtools/diaglayers/functionalgroupraw.py +17 -18
  69. odxtools/diaglayers/hierarchyelement.py +48 -54
  70. odxtools/diaglayers/hierarchyelementraw.py +10 -11
  71. odxtools/diaglayers/protocol.py +7 -7
  72. odxtools/diaglayers/protocolraw.py +13 -14
  73. odxtools/diagnostictroublecode.py +15 -17
  74. odxtools/diagservice.py +28 -27
  75. odxtools/diagvariable.py +24 -25
  76. odxtools/docrevision.py +18 -17
  77. odxtools/dopbase.py +13 -14
  78. odxtools/dtcconnector.py +8 -7
  79. odxtools/dtcdop.py +24 -20
  80. odxtools/dynamicendmarkerfield.py +10 -9
  81. odxtools/dynamiclengthfield.py +10 -9
  82. odxtools/dyndefinedspec.py +10 -10
  83. odxtools/dynenddopref.py +9 -9
  84. odxtools/dyniddefmodeinfo.py +21 -21
  85. odxtools/ecuvariantpattern.py +8 -10
  86. odxtools/element.py +12 -13
  87. odxtools/encodestate.py +11 -11
  88. odxtools/encoding.py +2 -3
  89. odxtools/endofpdufield.py +9 -10
  90. odxtools/envdataconnector.py +8 -8
  91. odxtools/environmentdata.py +7 -9
  92. odxtools/environmentdatadescription.py +18 -17
  93. odxtools/exceptions.py +5 -5
  94. odxtools/externalaccessmethod.py +4 -6
  95. odxtools/externaldoc.py +6 -6
  96. odxtools/field.py +15 -15
  97. odxtools/functionalclass.py +9 -9
  98. odxtools/inputparam.py +11 -10
  99. odxtools/internalconstr.py +10 -11
  100. odxtools/isotp_state_machine.py +12 -11
  101. odxtools/leadinglengthinfotype.py +4 -6
  102. odxtools/library.py +9 -8
  103. odxtools/linkeddtcdop.py +9 -8
  104. odxtools/loadfile.py +5 -6
  105. odxtools/matchingbasevariantparameter.py +5 -6
  106. odxtools/matchingparameter.py +10 -10
  107. odxtools/message.py +1 -1
  108. odxtools/minmaxlengthtype.py +6 -7
  109. odxtools/modification.py +7 -6
  110. odxtools/multiplexer.py +54 -18
  111. odxtools/multiplexercase.py +13 -13
  112. odxtools/multiplexerdefaultcase.py +11 -10
  113. odxtools/multiplexerswitchkey.py +8 -8
  114. odxtools/nameditemlist.py +13 -13
  115. odxtools/negoutputparam.py +8 -8
  116. odxtools/obd.py +1 -2
  117. odxtools/odxcategory.py +14 -26
  118. odxtools/odxdoccontext.py +16 -0
  119. odxtools/odxlink.py +23 -25
  120. odxtools/odxtypes.py +18 -15
  121. odxtools/outputparam.py +9 -8
  122. odxtools/parameterinfo.py +1 -1
  123. odxtools/parameters/codedconstparameter.py +10 -10
  124. odxtools/parameters/createanyparameter.py +15 -16
  125. odxtools/parameters/dynamicparameter.py +5 -7
  126. odxtools/parameters/lengthkeyparameter.py +10 -10
  127. odxtools/parameters/matchingrequestparameter.py +6 -7
  128. odxtools/parameters/nrcconstparameter.py +13 -13
  129. odxtools/parameters/parameter.py +17 -18
  130. odxtools/parameters/parameterwithdop.py +13 -13
  131. odxtools/parameters/physicalconstantparameter.py +8 -7
  132. odxtools/parameters/reservedparameter.py +6 -8
  133. odxtools/parameters/systemparameter.py +5 -7
  134. odxtools/parameters/tableentryparameter.py +8 -8
  135. odxtools/parameters/tablekeyparameter.py +17 -17
  136. odxtools/parameters/tablestructparameter.py +11 -11
  137. odxtools/parameters/valueparameter.py +11 -11
  138. odxtools/paramlengthinfotype.py +10 -9
  139. odxtools/parentref.py +15 -13
  140. odxtools/physicaldimension.py +15 -15
  141. odxtools/physicaltype.py +5 -6
  142. odxtools/posresponsesuppressible.py +11 -12
  143. odxtools/preconditionstateref.py +11 -11
  144. odxtools/progcode.py +11 -10
  145. odxtools/protstack.py +10 -9
  146. odxtools/relateddiagcommref.py +5 -6
  147. odxtools/relateddoc.py +11 -10
  148. odxtools/request.py +18 -19
  149. odxtools/response.py +19 -20
  150. odxtools/scaleconstr.py +8 -9
  151. odxtools/servicebinner.py +5 -5
  152. odxtools/singleecujob.py +16 -15
  153. odxtools/snrefcontext.py +3 -3
  154. odxtools/specialdata.py +8 -7
  155. odxtools/specialdatagroup.py +17 -17
  156. odxtools/specialdatagroupcaption.py +7 -6
  157. odxtools/standardlengthtype.py +14 -22
  158. odxtools/state.py +7 -6
  159. odxtools/statechart.py +12 -11
  160. odxtools/statemachine.py +4 -3
  161. odxtools/statetransition.py +9 -9
  162. odxtools/statetransitionref.py +19 -19
  163. odxtools/staticfield.py +9 -7
  164. odxtools/structure.py +5 -6
  165. odxtools/subcomponent.py +20 -18
  166. odxtools/subcomponentparamconnector.py +10 -9
  167. odxtools/subcomponentpattern.py +9 -9
  168. odxtools/swvariable.py +6 -7
  169. odxtools/table.py +25 -26
  170. odxtools/tablediagcommconnector.py +9 -8
  171. odxtools/tablerow.py +64 -43
  172. odxtools/tablerowconnector.py +8 -8
  173. odxtools/teammember.py +16 -15
  174. odxtools/templates/macros/printParentRef.xml.jinja2 +3 -1
  175. odxtools/text.py +4 -5
  176. odxtools/uds.py +2 -3
  177. odxtools/unit.py +14 -13
  178. odxtools/unitgroup.py +11 -10
  179. odxtools/unitspec.py +18 -19
  180. odxtools/utils.py +3 -3
  181. odxtools/variablegroup.py +5 -6
  182. odxtools/variantmatcher.py +10 -10
  183. odxtools/variantpattern.py +5 -6
  184. odxtools/version.py +2 -2
  185. odxtools/writepdxfile.py +5 -24
  186. odxtools/xdoc.py +13 -12
  187. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/METADATA +4 -5
  188. odxtools-10.1.0.dist-info/RECORD +265 -0
  189. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/WHEEL +1 -1
  190. odxtools-9.7.0.dist-info/RECORD +0 -264
  191. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/entry_points.txt +0 -0
  192. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/licenses/LICENSE +0 -0
  193. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,13 @@
1
1
  # SPDX-License-Identifier: MIT
2
- from dataclasses import dataclass
3
- from typing import Any, Dict, List, Union
2
+ from dataclasses import dataclass, field
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from ..diagvariable import DiagVariable
7
7
  from ..exceptions import odxraise
8
8
  from ..nameditemlist import NamedItemList
9
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
9
+ from ..odxdoccontext import OdxDocContext
10
+ from ..odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
10
11
  from ..parentref import ParentRef
11
12
  from ..snrefcontext import SnRefContext
12
13
  from ..utils import dataclass_fields_asdict
@@ -14,50 +15,48 @@ from ..variablegroup import VariableGroup
14
15
  from .hierarchyelementraw import HierarchyElementRaw
15
16
 
16
17
 
17
- @dataclass
18
+ @dataclass(kw_only=True)
18
19
  class FunctionalGroupRaw(HierarchyElementRaw):
19
20
  """This is a diagnostic layer for common functionality of an ECU
20
21
  """
21
22
 
22
- diag_variables_raw: List[Union[DiagVariable, OdxLinkRef]]
23
- variable_groups: NamedItemList[VariableGroup]
24
- parent_refs: List[ParentRef]
23
+ diag_variables_raw: list[DiagVariable | OdxLinkRef] = field(default_factory=list)
24
+ variable_groups: NamedItemList[VariableGroup] = field(default_factory=NamedItemList)
25
+ parent_refs: list[ParentRef] = field(default_factory=list)
25
26
 
26
27
  @property
27
28
  def diag_variables(self) -> NamedItemList[DiagVariable]:
28
29
  return self._diag_variables
29
30
 
30
31
  @staticmethod
31
- def from_et(et_element: ElementTree.Element,
32
- doc_frags: List[OdxDocFragment]) -> "FunctionalGroupRaw":
32
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "FunctionalGroupRaw":
33
33
  # objects contained by diagnostic layers exibit an additional
34
34
  # document fragment for the diag layer, so we use the document
35
35
  # fragments of the odx id of the diag layer for IDs of
36
36
  # contained objects.
37
- her = HierarchyElementRaw.from_et(et_element, doc_frags)
37
+ her = HierarchyElementRaw.from_et(et_element, context)
38
38
  kwargs = dataclass_fields_asdict(her)
39
- doc_frags = her.odx_id.doc_fragments
40
39
 
41
- diag_variables_raw: List[Union[DiagVariable, OdxLinkRef]] = []
40
+ diag_variables_raw: list[DiagVariable | OdxLinkRef] = []
42
41
  if (dv_elems := et_element.find("DIAG-VARIABLES")) is not None:
43
42
  for dv_proxy_elem in dv_elems:
44
- dv_proxy: Union[OdxLinkRef, DiagVariable]
43
+ dv_proxy: OdxLinkRef | DiagVariable
45
44
  if dv_proxy_elem.tag == "DIAG-VARIABLE-REF":
46
- dv_proxy = OdxLinkRef.from_et(dv_proxy_elem, doc_frags)
45
+ dv_proxy = OdxLinkRef.from_et(dv_proxy_elem, context)
47
46
  elif dv_proxy_elem.tag == "DIAG-VARIABLE":
48
- dv_proxy = DiagVariable.from_et(dv_proxy_elem, doc_frags)
47
+ dv_proxy = DiagVariable.from_et(dv_proxy_elem, context)
49
48
  else:
50
49
  odxraise()
51
50
 
52
51
  diag_variables_raw.append(dv_proxy)
53
52
 
54
53
  variable_groups = NamedItemList([
55
- VariableGroup.from_et(vg_elem, doc_frags)
54
+ VariableGroup.from_et(vg_elem, context)
56
55
  for vg_elem in et_element.iterfind("VARIABLE-GROUPS/VARIABLE-GROUP")
57
56
  ])
58
57
 
59
58
  parent_refs = [
60
- ParentRef.from_et(pr_elem, doc_frags)
59
+ ParentRef.from_et(pr_elem, context)
61
60
  for pr_elem in et_element.iterfind("PARENT-REFS/PARENT-REF")
62
61
  ]
63
62
 
@@ -67,7 +66,7 @@ class FunctionalGroupRaw(HierarchyElementRaw):
67
66
  parent_refs=parent_refs,
68
67
  **kwargs)
69
68
 
70
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
69
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
71
70
  result = super()._build_odxlinks()
72
71
 
73
72
  for dv_proxy in self.diag_variables_raw:
@@ -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
@@ -17,7 +17,8 @@ from ..diagservice import DiagService
17
17
  from ..exceptions import OdxWarning, odxassert, odxraise
18
18
  from ..functionalclass import FunctionalClass
19
19
  from ..nameditemlist import NamedItemList, OdxNamed
20
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
20
+ from ..odxdoccontext import OdxDocContext
21
+ from ..odxlink import OdxLinkDatabase, OdxLinkId
21
22
  from ..parentref import ParentRef
22
23
  from ..response import Response
23
24
  from ..singleecujob import SingleEcuJob
@@ -30,13 +31,13 @@ from .diaglayer import DiagLayer
30
31
  from .hierarchyelementraw import HierarchyElementRaw
31
32
 
32
33
  if TYPE_CHECKING:
33
- from .database import Database
34
+ from ..database import Database
34
35
  from .protocol import Protocol
35
36
 
36
37
  TNamed = TypeVar("TNamed", bound=OdxNamed)
37
38
 
38
39
 
39
- @dataclass
40
+ @dataclass(kw_only=True)
40
41
  class HierarchyElement(DiagLayer):
41
42
  """This is the base class for diagnostic layers that may be involved in value inheritance
42
43
  """
@@ -46,9 +47,8 @@ class HierarchyElement(DiagLayer):
46
47
  return cast(HierarchyElementRaw, self.diag_layer_raw)
47
48
 
48
49
  @staticmethod
49
- def from_et(et_element: ElementTree.Element,
50
- doc_frags: List[OdxDocFragment]) -> "HierarchyElement":
51
- hierarchy_element_raw = HierarchyElementRaw.from_et(et_element, doc_frags)
50
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "HierarchyElement":
51
+ hierarchy_element_raw = HierarchyElementRaw.from_et(et_element, context)
52
52
 
53
53
  return HierarchyElement(diag_layer_raw=hierarchy_element_raw)
54
54
 
@@ -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 = 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 = 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 = 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,43 +1,42 @@
1
1
  # SPDX-License-Identifier: MIT
2
- from dataclasses import dataclass
3
- from typing import Any, Dict, List
2
+ from dataclasses import dataclass, field
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from ..comparaminstance import ComparamInstance
7
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
7
+ from ..odxdoccontext import OdxDocContext
8
+ from ..odxlink import OdxLinkDatabase, OdxLinkId
8
9
  from ..snrefcontext import SnRefContext
9
10
  from ..utils import dataclass_fields_asdict
10
11
  from .diaglayerraw import DiagLayerRaw
11
12
 
12
13
 
13
- @dataclass
14
+ @dataclass(kw_only=True)
14
15
  class HierarchyElementRaw(DiagLayerRaw):
15
16
  """This is the base class for diagnostic layers that may be involved in value inheritance
16
17
 
17
18
  This class represents the data present in the XML, not the "logical" view.
18
19
  """
19
20
 
20
- comparam_refs: List[ComparamInstance]
21
+ comparam_refs: list[ComparamInstance] = field(default_factory=list)
21
22
 
22
23
  @staticmethod
23
- def from_et(et_element: ElementTree.Element,
24
- doc_frags: List[OdxDocFragment]) -> "HierarchyElementRaw":
24
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "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
28
28
  # contained objects.
29
- dlr = DiagLayerRaw.from_et(et_element, doc_frags)
29
+ dlr = DiagLayerRaw.from_et(et_element, context)
30
30
  kwargs = dataclass_fields_asdict(dlr)
31
- doc_frags = dlr.odx_id.doc_fragments
32
31
 
33
32
  comparam_refs = [
34
- ComparamInstance.from_et(el, doc_frags)
33
+ ComparamInstance.from_et(el, context)
35
34
  for el in et_element.iterfind("COMPARAM-REFS/COMPARAM-REF")
36
35
  ]
37
36
 
38
37
  return HierarchyElementRaw(comparam_refs=comparam_refs, **kwargs)
39
38
 
40
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
39
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
41
40
  result = super()._build_odxlinks()
42
41
 
43
42
  for comparam_ref in self.comparam_refs:
@@ -1,18 +1,18 @@
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
8
8
  from ..exceptions import odxassert
9
- from ..odxlink import OdxDocFragment
9
+ from ..odxdoccontext import OdxDocContext
10
10
  from ..protstack import ProtStack
11
11
  from .hierarchyelement import HierarchyElement
12
12
  from .protocolraw import ProtocolRaw
13
13
 
14
14
 
15
- @dataclass
15
+ @dataclass(kw_only=True)
16
16
  class Protocol(HierarchyElement):
17
17
  """This is the class for primitives that are common for a given communication protocol
18
18
 
@@ -29,12 +29,12 @@ 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":
37
- protocol_raw = ProtocolRaw.from_et(et_element, doc_frags)
36
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Protocol":
37
+ protocol_raw = ProtocolRaw.from_et(et_element, context)
38
38
 
39
39
  return Protocol(diag_layer_raw=protocol_raw)
40
40
 
@@ -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,20 +1,20 @@
1
1
  # SPDX-License-Identifier: MIT
2
- from dataclasses import dataclass
3
- from typing import Any, Dict, List, Optional
2
+ from dataclasses import dataclass, field
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from ..comparamspec import ComparamSpec
7
7
  from ..exceptions import odxrequire
8
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
8
+ from ..odxdoccontext import OdxDocContext
9
+ from ..odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
9
10
  from ..parentref import ParentRef
10
11
  from ..protstack import ProtStack
11
12
  from ..snrefcontext import SnRefContext
12
13
  from ..utils import dataclass_fields_asdict
13
- #from .comparaminstance import ComparamInstance
14
14
  from .hierarchyelementraw import HierarchyElementRaw
15
15
 
16
16
 
17
- @dataclass
17
+ @dataclass(kw_only=True)
18
18
  class ProtocolRaw(HierarchyElementRaw):
19
19
  """This is the base class for diagnostic layers that describe a
20
20
  protocol which can be used to communicate with an ECU
@@ -24,36 +24,35 @@ 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 = None
28
+ parent_refs: list[ParentRef] = field(default_factory=list)
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, context: OdxDocContext) -> "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
43
43
  # contained objects.
44
- her = HierarchyElementRaw.from_et(et_element, doc_frags)
44
+ her = HierarchyElementRaw.from_et(et_element, context)
45
45
  kwargs = dataclass_fields_asdict(her)
46
- doc_frags = her.odx_id.doc_fragments
47
46
 
48
47
  comparam_spec_ref = OdxLinkRef.from_et(
49
- odxrequire(et_element.find("COMPARAM-SPEC-REF")), doc_frags)
48
+ odxrequire(et_element.find("COMPARAM-SPEC-REF")), context)
50
49
 
51
50
  prot_stack_snref = None
52
51
  if (prot_stack_snref_elem := et_element.find("PROT-STACK-SNREF")) is not None:
53
52
  prot_stack_snref = odxrequire(prot_stack_snref_elem.get("SHORT-NAME"))
54
53
 
55
54
  parent_refs = [
56
- ParentRef.from_et(pr_el, doc_frags)
55
+ ParentRef.from_et(pr_el, context)
57
56
  for pr_el in et_element.iterfind("PARENT-REFS/PARENT-REF")
58
57
  ]
59
58
 
@@ -63,7 +62,7 @@ class ProtocolRaw(HierarchyElementRaw):
63
62
  parent_refs=parent_refs,
64
63
  **kwargs)
65
64
 
66
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
65
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
67
66
  result = super()._build_odxlinks()
68
67
 
69
68
  for parent_ref in self.parent_refs: