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
odxtools/statechart.py CHANGED
@@ -1,40 +1,41 @@
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 .element import IdentifiableElement
7
7
  from .exceptions import odxrequire
8
8
  from .nameditemlist import NamedItemList
9
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, resolve_snref
9
+ from .odxdoccontext import OdxDocContext
10
+ from .odxlink import OdxLinkDatabase, OdxLinkId, resolve_snref
10
11
  from .snrefcontext import SnRefContext
11
12
  from .state import State
12
13
  from .statetransition import StateTransition
13
14
  from .utils import dataclass_fields_asdict
14
15
 
15
16
 
16
- @dataclass
17
+ @dataclass(kw_only=True)
17
18
  class StateChart(IdentifiableElement):
18
19
  """
19
20
  Corresponds to STATE-CHART.
20
21
  """
21
22
  semantic: str
22
- state_transitions: List[StateTransition]
23
+ state_transitions: list[StateTransition] = field(default_factory=list)
23
24
  start_state_snref: str
24
- states: NamedItemList[State]
25
+ states: NamedItemList[State] = field(default_factory=NamedItemList)
25
26
 
26
27
  @property
27
28
  def start_state(self) -> State:
28
29
  return self._start_state
29
30
 
30
31
  @staticmethod
31
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "StateChart":
32
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
32
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "StateChart":
33
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
33
34
 
34
35
  semantic: str = odxrequire(et_element.findtext("SEMANTIC"))
35
36
 
36
37
  state_transitions = [
37
- StateTransition.from_et(st_elem, doc_frags)
38
+ StateTransition.from_et(st_elem, context)
38
39
  for st_elem in et_element.iterfind("STATE-TRANSITIONS/STATE-TRANSITION")
39
40
  ]
40
41
 
@@ -42,7 +43,7 @@ class StateChart(IdentifiableElement):
42
43
  start_state_snref = start_state_snref_elem.attrib["SHORT-NAME"]
43
44
 
44
45
  states = [
45
- State.from_et(st_elem, doc_frags) for st_elem in et_element.iterfind("STATES/STATE")
46
+ State.from_et(st_elem, context) for st_elem in et_element.iterfind("STATES/STATE")
46
47
  ]
47
48
 
48
49
  return StateChart(
@@ -52,7 +53,7 @@ class StateChart(IdentifiableElement):
52
53
  states=NamedItemList(states),
53
54
  **kwargs)
54
55
 
55
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
56
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
56
57
  odxlinks = {self.odx_id: self}
57
58
 
58
59
  for strans in self.state_transitions:
odxtools/statemachine.py CHANGED
@@ -1,6 +1,7 @@
1
1
  # SPDX-License-Identifier: MIT
2
+ from collections.abc import Generator
2
3
  from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, Any, Generator, Union
4
+ from typing import TYPE_CHECKING, Any
4
5
 
5
6
  from .exceptions import odxraise
6
7
  from .odxtypes import ParameterValueDict
@@ -12,7 +13,7 @@ if TYPE_CHECKING:
12
13
  from .diagservice import DiagService
13
14
 
14
15
 
15
- @dataclass
16
+ @dataclass(kw_only=True)
16
17
  class StateMachine:
17
18
  """Objects of this class represent the runtime state of a state chart
18
19
 
@@ -97,7 +98,7 @@ class StateMachine:
97
98
  self._active_state = state_chart.start_state
98
99
 
99
100
  def execute(self, service: "DiagService", **service_params: Any
100
- ) -> Generator[bytes, Union[bytes, bytearray, ParameterValueDict], None]:
101
+ ) -> Generator[bytes, bytes | bytearray | ParameterValueDict, None]:
101
102
  """Run a diagnostic service and update the state machine
102
103
  depending on the outcome.
103
104
 
@@ -1,25 +1,26 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List, Optional
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .element import IdentifiableElement
7
7
  from .exceptions import odxrequire
8
8
  from .externalaccessmethod import ExternalAccessMethod
9
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, resolve_snref
9
+ from .odxdoccontext import OdxDocContext
10
+ from .odxlink import OdxLinkDatabase, OdxLinkId, resolve_snref
10
11
  from .snrefcontext import SnRefContext
11
12
  from .state import State
12
13
  from .utils import dataclass_fields_asdict
13
14
 
14
15
 
15
- @dataclass
16
+ @dataclass(kw_only=True)
16
17
  class StateTransition(IdentifiableElement):
17
18
  """
18
19
  Corresponds to STATE-TRANSITION.
19
20
  """
20
21
  source_snref: str
21
22
  target_snref: str
22
- external_access_method: Optional[ExternalAccessMethod]
23
+ external_access_method: ExternalAccessMethod | None = None
23
24
 
24
25
  @property
25
26
  def source_state(self) -> State:
@@ -30,10 +31,9 @@ class StateTransition(IdentifiableElement):
30
31
  return self._target_state
31
32
 
32
33
  @staticmethod
33
- def from_et(et_element: ElementTree.Element,
34
- doc_frags: List[OdxDocFragment]) -> "StateTransition":
34
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "StateTransition":
35
35
 
36
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
36
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
37
37
 
38
38
  source_snref_elem = odxrequire(et_element.find("SOURCE-SNREF"))
39
39
  source_snref = odxrequire(source_snref_elem.attrib["SHORT-NAME"])
@@ -43,14 +43,14 @@ class StateTransition(IdentifiableElement):
43
43
 
44
44
  external_access_method = None
45
45
  if (eam_elem := et_element.find("EXTERNAL-ACCESS-METHOD")) is not None:
46
- external_access_method = ExternalAccessMethod.from_et(eam_elem, doc_frags)
46
+ external_access_method = ExternalAccessMethod.from_et(eam_elem, context)
47
47
  return StateTransition(
48
48
  source_snref=source_snref,
49
49
  target_snref=target_snref,
50
50
  external_access_method=external_access_method,
51
51
  **kwargs)
52
52
 
53
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
53
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
54
54
  return {self.odx_id: self}
55
55
 
56
56
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
@@ -1,12 +1,13 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
3
+ from typing import TYPE_CHECKING, Any, Union
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .basicstructure import BasicStructure
7
7
  from .dataobjectproperty import DataObjectProperty
8
8
  from .exceptions import odxassert, odxraise, odxrequire
9
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
9
+ from .odxdoccontext import OdxDocContext
10
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
10
11
  from .odxtypes import ParameterValue, ParameterValueDict
11
12
  from .parameters.codedconstparameter import CodedConstParameter
12
13
  from .parameters.parameter import Parameter
@@ -27,11 +28,11 @@ if TYPE_CHECKING:
27
28
 
28
29
 
29
30
  def _resolve_in_param(
30
- in_param_if_snref: Optional[str],
31
- in_param_if_snpathref: Optional[str],
32
- params: List[Parameter],
31
+ in_param_if_snref: str | None,
32
+ in_param_if_snpathref: str | None,
33
+ params: list[Parameter],
33
34
  param_dict: ParameterValueDict,
34
- ) -> Tuple[Optional[Parameter], Optional[ParameterValue]]:
35
+ ) -> tuple[Parameter | None, ParameterValue | None]:
35
36
 
36
37
  if in_param_if_snref is not None:
37
38
  path_chunks = [in_param_if_snref]
@@ -44,10 +45,10 @@ def _resolve_in_param(
44
45
 
45
46
 
46
47
  def _resolve_in_param_helper(
47
- params: List[Parameter],
48
+ params: list[Parameter],
48
49
  param_dict: ParameterValueDict,
49
- path_chunks: List[str],
50
- ) -> Tuple[Optional[Parameter], Optional[ParameterValue]]:
50
+ path_chunks: list[str],
51
+ ) -> tuple[Parameter | None, ParameterValue | None]:
51
52
 
52
53
  inner_param = resolve_snref(path_chunks[0], params, Parameter, lenient=True)
53
54
  if inner_param is None:
@@ -90,7 +91,7 @@ def _resolve_in_param_helper(
90
91
 
91
92
  def _check_applies(ref: Union["StateTransitionRef",
92
93
  "PreConditionStateRef"], state_machine: "StateMachine",
93
- params: List[Parameter], param_value_dict: ParameterValueDict) -> bool:
94
+ params: list[Parameter], param_value_dict: ParameterValueDict) -> bool:
94
95
  if state_machine.active_state != ref.state:
95
96
  # if the active state of the state machine is not the
96
97
  # specified one, the precondition does not apply
@@ -146,7 +147,7 @@ def _check_applies(ref: Union["StateTransitionRef",
146
147
  return True
147
148
 
148
149
 
149
- @dataclass
150
+ @dataclass(kw_only=True)
150
151
  class StateTransitionRef(OdxLinkRef):
151
152
  """Describes a state transition that is to be potentially taken if
152
153
  a diagnostic communication is executed
@@ -155,10 +156,10 @@ class StateTransitionRef(OdxLinkRef):
155
156
  may also be conditional on the observed response of the ECU.
156
157
 
157
158
  """
158
- value: Optional[str]
159
+ value: str | None = None
159
160
 
160
- in_param_if_snref: Optional[str]
161
- in_param_if_snpathref: Optional[str]
161
+ in_param_if_snref: str | None = None
162
+ in_param_if_snpathref: str | None = None
162
163
 
163
164
  @property
164
165
  def state_transition(self) -> StateTransition:
@@ -170,9 +171,8 @@ class StateTransitionRef(OdxLinkRef):
170
171
 
171
172
  @staticmethod
172
173
  def from_et( # type: ignore[override]
173
- et_element: ElementTree.Element,
174
- doc_frags: List[OdxDocFragment]) -> "StateTransitionRef":
175
- kwargs = dataclass_fields_asdict(OdxLinkRef.from_et(et_element, doc_frags))
174
+ et_element: ElementTree.Element, context: OdxDocContext) -> "StateTransitionRef":
175
+ kwargs = dataclass_fields_asdict(OdxLinkRef.from_et(et_element, context))
176
176
 
177
177
  value = et_element.findtext("VALUE")
178
178
 
@@ -195,7 +195,7 @@ class StateTransitionRef(OdxLinkRef):
195
195
  odxassert(self.in_param_if_snref is not None or self.in_param_if_snref is not None,
196
196
  "If VALUE is specified, a parameter must be referenced")
197
197
 
198
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
198
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
199
199
  return {}
200
200
 
201
201
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
@@ -204,7 +204,7 @@ class StateTransitionRef(OdxLinkRef):
204
204
  def _resolve_snrefs(self, context: SnRefContext) -> None:
205
205
  pass
206
206
 
207
- def execute(self, state_machine: StateMachine, params: List[Parameter],
207
+ def execute(self, state_machine: StateMachine, params: list[Parameter],
208
208
  param_value_dict: ParameterValueDict) -> bool:
209
209
  """Update a StateMachine object if the state transition ought
210
210
  to be executed based on the response received after executing a
odxtools/staticfield.py CHANGED
@@ -1,6 +1,7 @@
1
1
  # SPDX-License-Identifier: MIT
2
+ from collections.abc import Sequence
2
3
  from dataclasses import dataclass
3
- from typing import Any, Dict, List, Sequence
4
+ from typing import Any
4
5
  from xml.etree import ElementTree
5
6
 
6
7
  from typing_extensions import override
@@ -9,13 +10,14 @@ from .decodestate import DecodeState
9
10
  from .encodestate import EncodeState
10
11
  from .exceptions import odxassert, odxraise, odxrequire
11
12
  from .field import Field
12
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
13
+ from .odxdoccontext import OdxDocContext
14
+ from .odxlink import OdxLinkDatabase, OdxLinkId
13
15
  from .odxtypes import ParameterValue
14
16
  from .snrefcontext import SnRefContext
15
17
  from .utils import dataclass_fields_asdict
16
18
 
17
19
 
18
- @dataclass
20
+ @dataclass(kw_only=True)
19
21
  class StaticField(Field):
20
22
  """Array of a fixed number of structure objects"""
21
23
  fixed_number_of_items: int
@@ -23,8 +25,8 @@ class StaticField(Field):
23
25
 
24
26
  @staticmethod
25
27
  @override
26
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "StaticField":
27
- kwargs = dataclass_fields_asdict(Field.from_et(et_element, doc_frags))
28
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "StaticField":
29
+ kwargs = dataclass_fields_asdict(Field.from_et(et_element, context))
28
30
 
29
31
  fixed_number_of_items = int(odxrequire(et_element.findtext('FIXED-NUMBER-OF-ITEMS')))
30
32
  item_byte_size = int(odxrequire(et_element.findtext('ITEM-BYTE-SIZE')))
@@ -33,7 +35,7 @@ class StaticField(Field):
33
35
  fixed_number_of_items=fixed_number_of_items, item_byte_size=item_byte_size, **kwargs)
34
36
 
35
37
  @override
36
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
38
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
37
39
  odxlinks = super()._build_odxlinks()
38
40
  return odxlinks
39
41
 
@@ -89,7 +91,7 @@ class StaticField(Field):
89
91
  orig_origin = decode_state.origin_byte_position
90
92
  decode_state.origin_byte_position = decode_state.cursor_byte_position
91
93
 
92
- result: List[ParameterValue] = []
94
+ result: list[ParameterValue] = []
93
95
  for _ in range(self.fixed_number_of_items):
94
96
  orig_cursor = decode_state.cursor_byte_position
95
97
 
odxtools/structure.py CHANGED
@@ -1,26 +1,25 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import List, Optional
4
3
  from xml.etree import ElementTree
5
4
 
6
5
  from .basicstructure import BasicStructure
7
- from .odxlink import OdxDocFragment
6
+ from .odxdoccontext import OdxDocContext
8
7
  from .odxtypes import odxstr_to_bool
9
8
  from .utils import dataclass_fields_asdict
10
9
 
11
10
 
12
- @dataclass
11
+ @dataclass(kw_only=True)
13
12
  class Structure(BasicStructure):
14
- is_visible_raw: Optional[bool]
13
+ is_visible_raw: bool | None = None
15
14
 
16
15
  @property
17
16
  def is_visible(self) -> bool:
18
17
  return self.is_visible_raw in (True, None)
19
18
 
20
19
  @staticmethod
21
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "Structure":
20
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Structure":
22
21
  """Read a STRUCTURE element from XML."""
23
- kwargs = dataclass_fields_asdict(BasicStructure.from_et(et_element, doc_frags))
22
+ kwargs = dataclass_fields_asdict(BasicStructure.from_et(et_element, context))
24
23
 
25
24
  is_visible_raw = odxstr_to_bool(et_element.get("IS-VISIBLE"))
26
25
 
odxtools/subcomponent.py CHANGED
@@ -1,13 +1,14 @@
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 .dtcconnector import DtcConnector
7
7
  from .element import IdentifiableElement
8
8
  from .envdataconnector import EnvDataConnector
9
9
  from .nameditemlist import NamedItemList
10
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
10
+ from .odxdoccontext import OdxDocContext
11
+ from .odxlink import OdxLinkDatabase, OdxLinkId
11
12
  from .snrefcontext import SnRefContext
12
13
  from .subcomponentparamconnector import SubComponentParamConnector
13
14
  from .subcomponentpattern import SubComponentPattern
@@ -15,7 +16,7 @@ from .tablerowconnector import TableRowConnector
15
16
  from .utils import dataclass_fields_asdict
16
17
 
17
18
 
18
- @dataclass
19
+ @dataclass(kw_only=True)
19
20
  class SubComponent(IdentifiableElement):
20
21
  """Sub-components describe collections of related diagnostic variables
21
22
 
@@ -25,38 +26,39 @@ class SubComponent(IdentifiableElement):
25
26
 
26
27
  """
27
28
 
28
- sub_component_patterns: List[SubComponentPattern]
29
- sub_component_param_connectors: NamedItemList[SubComponentParamConnector]
30
- table_row_connectors: NamedItemList[TableRowConnector]
31
- env_data_connectors: NamedItemList[EnvDataConnector]
32
- dtc_connectors: NamedItemList[DtcConnector]
29
+ sub_component_patterns: list[SubComponentPattern] = field(default_factory=list)
30
+ sub_component_param_connectors: NamedItemList[SubComponentParamConnector] = field(
31
+ default_factory=NamedItemList)
32
+ table_row_connectors: NamedItemList[TableRowConnector] = field(default_factory=NamedItemList)
33
+ env_data_connectors: NamedItemList[EnvDataConnector] = field(default_factory=NamedItemList)
34
+ dtc_connectors: NamedItemList[DtcConnector] = field(default_factory=NamedItemList)
33
35
 
34
- semantic: Optional[str]
36
+ semantic: str | None = None
35
37
 
36
38
  @staticmethod
37
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "SubComponent":
38
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
39
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "SubComponent":
40
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
39
41
 
40
42
  semantic = et_element.get("SEMANTIC")
41
43
 
42
44
  sub_component_patterns = [
43
- SubComponentPattern.from_et(el, doc_frags)
45
+ SubComponentPattern.from_et(el, context)
44
46
  for el in et_element.iterfind("SUB-COMPONENT-PATTERNS/SUB-COMPONENT-PATTERN")
45
47
  ]
46
48
  sub_component_param_connectors = [
47
- SubComponentParamConnector.from_et(el, doc_frags) for el in et_element.iterfind(
49
+ SubComponentParamConnector.from_et(el, context) for el in et_element.iterfind(
48
50
  "SUB-COMPONENT-PARAM-CONNECTORS/SUB-COMPONENT-PARAM-CONNECTOR")
49
51
  ]
50
52
  table_row_connectors = [
51
- TableRowConnector.from_et(el, doc_frags)
53
+ TableRowConnector.from_et(el, context)
52
54
  for el in et_element.iterfind("TABLE-ROW-CONNECTORS/TABLE-ROW-CONNECTOR")
53
55
  ]
54
56
  env_data_connectors = [
55
- EnvDataConnector.from_et(el, doc_frags)
57
+ EnvDataConnector.from_et(el, context)
56
58
  for el in et_element.iterfind("ENV-DATA-CONNECTORS/ENV-DATA-CONNECTOR")
57
59
  ]
58
60
  dtc_connectors = [
59
- DtcConnector.from_et(el, doc_frags)
61
+ DtcConnector.from_et(el, context)
60
62
  for el in et_element.iterfind("DTC-CONNECTORS/DTC-CONNECTOR")
61
63
  ]
62
64
 
@@ -69,7 +71,7 @@ class SubComponent(IdentifiableElement):
69
71
  dtc_connectors=NamedItemList(dtc_connectors),
70
72
  **kwargs)
71
73
 
72
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
74
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
73
75
  result = {}
74
76
 
75
77
  for scp in self.sub_component_patterns:
@@ -1,25 +1,26 @@
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 .diagservice import DiagService
7
7
  from .element import IdentifiableElement
8
8
  from .exceptions import odxassert, odxraise, odxrequire
9
9
  from .nameditemlist import NamedItemList
10
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, resolve_snref
10
+ from .odxdoccontext import OdxDocContext
11
+ from .odxlink import OdxLinkDatabase, OdxLinkId, resolve_snref
11
12
  from .parameters.parameter import Parameter
12
13
  from .snrefcontext import SnRefContext
13
14
  from .utils import dataclass_fields_asdict
14
15
 
15
16
 
16
- @dataclass
17
+ @dataclass(kw_only=True)
17
18
  class SubComponentParamConnector(IdentifiableElement):
18
19
  diag_comm_snref: str
19
20
 
20
21
  # TODO: we currently only support SNREFs, not SNPATHREFs
21
- out_param_if_refs: List[str]
22
- in_param_if_refs: List[str]
22
+ out_param_if_refs: list[str] = field(default_factory=list)
23
+ in_param_if_refs: list[str] = field(default_factory=list)
23
24
 
24
25
  @property
25
26
  def service(self) -> DiagService:
@@ -35,8 +36,8 @@ class SubComponentParamConnector(IdentifiableElement):
35
36
 
36
37
  @staticmethod
37
38
  def from_et(et_element: ElementTree.Element,
38
- doc_frags: List[OdxDocFragment]) -> "SubComponentParamConnector":
39
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
39
+ context: OdxDocContext) -> "SubComponentParamConnector":
40
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
40
41
 
41
42
  diag_comm_snref = odxrequire(
42
43
  odxrequire(et_element.find("DIAG-COMM-SNREF")).get("SHORT-NAME"))
@@ -65,7 +66,7 @@ class SubComponentParamConnector(IdentifiableElement):
65
66
  in_param_if_refs=in_param_if_refs,
66
67
  **kwargs)
67
68
 
68
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
69
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
69
70
  return {}
70
71
 
71
72
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
@@ -1,32 +1,32 @@
1
1
  # SPDX-License-Identifier: MIT
2
- from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, Any, Dict, List
2
+ from dataclasses import dataclass, field
3
+ from typing import TYPE_CHECKING, Any
4
4
  from xml.etree import ElementTree
5
5
 
6
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
6
+ from .odxdoccontext import OdxDocContext
7
+ from .odxlink import OdxLinkDatabase, OdxLinkId
7
8
  from .snrefcontext import SnRefContext
8
9
 
9
10
  if TYPE_CHECKING:
10
11
  from .matchingparameter import MatchingParameter
11
12
 
12
13
 
13
- @dataclass
14
+ @dataclass(kw_only=True)
14
15
  class SubComponentPattern:
15
- matching_parameters: List["MatchingParameter"]
16
+ matching_parameters: list["MatchingParameter"] = field(default_factory=list)
16
17
 
17
18
  @staticmethod
18
- def from_et(et_element: ElementTree.Element,
19
- doc_frags: List[OdxDocFragment]) -> "SubComponentPattern":
19
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "SubComponentPattern":
20
20
  from .matchingparameter import MatchingParameter
21
21
 
22
22
  matching_parameters = [
23
- MatchingParameter.from_et(el, doc_frags)
23
+ MatchingParameter.from_et(el, context)
24
24
  for el in et_element.iterfind("MATCHING-PARAMETERS/MATCHING-PARAMETER")
25
25
  ]
26
26
 
27
27
  return SubComponentPattern(matching_parameters=matching_parameters)
28
28
 
29
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
29
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
30
30
  result = {}
31
31
  for mp in self.matching_parameters:
32
32
  result.update(mp._build_odxlinks())
odxtools/swvariable.py CHANGED
@@ -1,21 +1,20 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import List, Optional
4
3
  from xml.etree import ElementTree
5
4
 
6
5
  from .element import NamedElement
7
- from .odxlink import OdxDocFragment
6
+ from .odxdoccontext import OdxDocContext
8
7
  from .utils import dataclass_fields_asdict
9
8
 
10
9
 
11
- @dataclass
10
+ @dataclass(kw_only=True)
12
11
  class SwVariable(NamedElement):
13
- origin: Optional[str]
14
- oid: Optional[str]
12
+ origin: str | None = None
13
+ oid: str | None = None
15
14
 
16
15
  @staticmethod
17
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "SwVariable":
18
- kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
16
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "SwVariable":
17
+ kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context))
19
18
 
20
19
  origin = et_element.findtext("ORIGIN")
21
20
  oid = et_element.attrib.get("OID")