odxtools 9.6.1__py3-none-any.whl → 10.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. odxtools/additionalaudience.py +3 -3
  2. odxtools/addressing.py +8 -0
  3. odxtools/admindata.py +8 -8
  4. odxtools/audience.py +10 -10
  5. odxtools/basecomparam.py +7 -20
  6. odxtools/basevariantpattern.py +4 -5
  7. odxtools/basicstructure.py +12 -11
  8. odxtools/cli/_print_utils.py +35 -23
  9. odxtools/cli/browse.py +9 -9
  10. odxtools/cli/compare.py +24 -24
  11. odxtools/cli/decode.py +3 -4
  12. odxtools/cli/find.py +4 -5
  13. odxtools/cli/list.py +7 -7
  14. odxtools/cli/main.py +2 -2
  15. odxtools/cli/snoop.py +3 -3
  16. odxtools/codec.py +3 -186
  17. odxtools/commrelation.py +12 -19
  18. odxtools/commrelationvaluetype.py +9 -0
  19. odxtools/companydata.py +5 -5
  20. odxtools/companydocinfo.py +8 -8
  21. odxtools/companyrevisioninfo.py +5 -5
  22. odxtools/companyspecificinfo.py +5 -5
  23. odxtools/comparam.py +3 -3
  24. odxtools/comparaminstance.py +10 -10
  25. odxtools/comparamspec.py +3 -3
  26. odxtools/comparamsubset.py +5 -5
  27. odxtools/complexcomparam.py +7 -7
  28. odxtools/compositecodec.py +191 -0
  29. odxtools/compumethods/compucategory.py +13 -0
  30. odxtools/compumethods/compucodecompumethod.py +6 -5
  31. odxtools/compumethods/compuconst.py +4 -5
  32. odxtools/compumethods/compudefaultvalue.py +1 -2
  33. odxtools/compumethods/compuinternaltophys.py +6 -6
  34. odxtools/compumethods/compumethod.py +6 -17
  35. odxtools/compumethods/compuphystointernal.py +6 -6
  36. odxtools/compumethods/compurationalcoeffs.py +4 -4
  37. odxtools/compumethods/compuscale.py +9 -10
  38. odxtools/compumethods/createanycompumethod.py +1 -2
  39. odxtools/compumethods/identicalcompumethod.py +1 -2
  40. odxtools/compumethods/intervaltype.py +8 -0
  41. odxtools/compumethods/limit.py +13 -19
  42. odxtools/compumethods/linearcompumethod.py +4 -3
  43. odxtools/compumethods/linearsegment.py +14 -15
  44. odxtools/compumethods/ratfunccompumethod.py +5 -4
  45. odxtools/compumethods/ratfuncsegment.py +7 -8
  46. odxtools/compumethods/scalelinearcompumethod.py +10 -9
  47. odxtools/compumethods/scaleratfunccompumethod.py +6 -5
  48. odxtools/compumethods/tabintpcompumethod.py +19 -20
  49. odxtools/compumethods/texttablecompumethod.py +5 -4
  50. odxtools/createanycomparam.py +2 -4
  51. odxtools/createanydiagcodedtype.py +1 -2
  52. odxtools/database.py +9 -8
  53. odxtools/dataobjectproperty.py +10 -10
  54. odxtools/decodestate.py +5 -5
  55. odxtools/description.py +6 -22
  56. odxtools/determinenumberofitems.py +4 -4
  57. odxtools/diagclasstype.py +11 -0
  58. odxtools/diagcodedtype.py +7 -7
  59. odxtools/diagcomm.py +19 -42
  60. odxtools/diagdatadictionaryspec.py +6 -6
  61. odxtools/diaglayercontainer.py +4 -4
  62. odxtools/diaglayers/basevariant.py +10 -9
  63. odxtools/diaglayers/basevariantraw.py +9 -9
  64. odxtools/diaglayers/diaglayer.py +20 -19
  65. odxtools/diaglayers/diaglayerraw.py +10 -10
  66. odxtools/diaglayers/diaglayertype.py +1 -2
  67. odxtools/diaglayers/ecushareddata.py +4 -4
  68. odxtools/diaglayers/ecushareddataraw.py +6 -6
  69. odxtools/diaglayers/ecuvariant.py +11 -10
  70. odxtools/diaglayers/ecuvariantraw.py +9 -9
  71. odxtools/diaglayers/functionalgroup.py +8 -7
  72. odxtools/diaglayers/functionalgroupraw.py +7 -7
  73. odxtools/diaglayers/hierarchyelement.py +43 -49
  74. odxtools/diaglayers/hierarchyelementraw.py +4 -4
  75. odxtools/diaglayers/protocol.py +4 -4
  76. odxtools/diaglayers/protocolraw.py +6 -6
  77. odxtools/diagnostictroublecode.py +8 -8
  78. odxtools/diagservice.py +21 -97
  79. odxtools/diagvariable.py +14 -14
  80. odxtools/docrevision.py +11 -11
  81. odxtools/dopbase.py +6 -6
  82. odxtools/dtcconnector.py +45 -0
  83. odxtools/dtcdop.py +15 -56
  84. odxtools/dynamicendmarkerfield.py +5 -4
  85. odxtools/dynamiclengthfield.py +5 -4
  86. odxtools/dyndefinedspec.py +7 -159
  87. odxtools/dynenddopref.py +5 -5
  88. odxtools/dyniddefmodeinfo.py +161 -0
  89. odxtools/ecuvariantpattern.py +4 -5
  90. odxtools/element.py +5 -6
  91. odxtools/encodestate.py +11 -11
  92. odxtools/encoding.py +2 -3
  93. odxtools/endofpdufield.py +6 -6
  94. odxtools/envdataconnector.py +49 -0
  95. odxtools/environmentdata.py +3 -4
  96. odxtools/environmentdatadescription.py +11 -11
  97. odxtools/exceptions.py +5 -5
  98. odxtools/externalaccessmethod.py +22 -0
  99. odxtools/externaldoc.py +23 -0
  100. odxtools/field.py +9 -10
  101. odxtools/functionalclass.py +4 -4
  102. odxtools/inputparam.py +6 -6
  103. odxtools/internalconstr.py +4 -5
  104. odxtools/isotp_state_machine.py +12 -11
  105. odxtools/leadinglengthinfotype.py +2 -3
  106. odxtools/library.py +5 -5
  107. odxtools/linkeddtcdop.py +62 -0
  108. odxtools/loadfile.py +5 -6
  109. odxtools/matchingbasevariantparameter.py +2 -3
  110. odxtools/matchingparameter.py +7 -7
  111. odxtools/minmaxlengthtype.py +5 -11
  112. odxtools/modification.py +4 -4
  113. odxtools/multiplexer.py +11 -11
  114. odxtools/multiplexercase.py +6 -6
  115. odxtools/multiplexerdefaultcase.py +6 -6
  116. odxtools/multiplexerswitchkey.py +4 -4
  117. odxtools/nameditemlist.py +14 -14
  118. odxtools/negoutputparam.py +3 -3
  119. odxtools/obd.py +1 -2
  120. odxtools/odxcategory.py +6 -6
  121. odxtools/odxlink.py +19 -20
  122. odxtools/odxtypes.py +21 -18
  123. odxtools/outputparam.py +4 -4
  124. odxtools/parameterinfo.py +2 -2
  125. odxtools/parameters/codedconstparameter.py +5 -5
  126. odxtools/parameters/createanyparameter.py +1 -2
  127. odxtools/parameters/dynamicparameter.py +2 -3
  128. odxtools/parameters/lengthkeyparameter.py +5 -5
  129. odxtools/parameters/matchingrequestparameter.py +3 -4
  130. odxtools/parameters/nrcconstparameter.py +7 -7
  131. odxtools/parameters/parameter.py +11 -11
  132. odxtools/parameters/parameterwithdop.py +9 -9
  133. odxtools/parameters/physicalconstantparameter.py +4 -4
  134. odxtools/parameters/reservedparameter.py +3 -4
  135. odxtools/parameters/rowfragment.py +7 -0
  136. odxtools/parameters/systemparameter.py +2 -3
  137. odxtools/parameters/tableentryparameter.py +4 -9
  138. odxtools/parameters/tablekeyparameter.py +10 -10
  139. odxtools/parameters/tablestructparameter.py +7 -7
  140. odxtools/parameters/valueparameter.py +7 -7
  141. odxtools/paramlengthinfotype.py +5 -3
  142. odxtools/parentref.py +9 -9
  143. odxtools/physicaldimension.py +11 -11
  144. odxtools/physicaltype.py +4 -12
  145. odxtools/posresponsesuppressible.py +72 -0
  146. odxtools/preconditionstateref.py +7 -7
  147. odxtools/progcode.py +6 -6
  148. odxtools/protstack.py +4 -4
  149. odxtools/radix.py +9 -0
  150. odxtools/relateddiagcommref.py +22 -0
  151. odxtools/relateddoc.py +6 -6
  152. odxtools/request.py +14 -12
  153. odxtools/response.py +15 -13
  154. odxtools/scaleconstr.py +4 -12
  155. odxtools/servicebinner.py +5 -5
  156. odxtools/singleecujob.py +4 -4
  157. odxtools/snrefcontext.py +2 -2
  158. odxtools/specialdata.py +5 -5
  159. odxtools/specialdatagroup.py +9 -9
  160. odxtools/specialdatagroupcaption.py +3 -3
  161. odxtools/standardizationlevel.py +9 -0
  162. odxtools/standardlengthtype.py +12 -21
  163. odxtools/state.py +3 -3
  164. odxtools/statechart.py +4 -4
  165. odxtools/statemachine.py +4 -3
  166. odxtools/statetransition.py +5 -18
  167. odxtools/statetransitionref.py +18 -18
  168. odxtools/staticfield.py +5 -4
  169. odxtools/structure.py +2 -3
  170. odxtools/subcomponent.py +12 -245
  171. odxtools/subcomponentparamconnector.py +103 -0
  172. odxtools/subcomponentpattern.py +42 -0
  173. odxtools/swvariable.py +3 -4
  174. odxtools/table.py +17 -55
  175. odxtools/tablediagcommconnector.py +47 -0
  176. odxtools/tablerow.py +30 -30
  177. odxtools/tablerowconnector.py +46 -0
  178. odxtools/teammember.py +11 -11
  179. odxtools/templates/macros/printService.xml.jinja2 +2 -1
  180. odxtools/termination.py +8 -0
  181. odxtools/text.py +2 -3
  182. odxtools/transmode.py +9 -0
  183. odxtools/uds.py +2 -3
  184. odxtools/unit.py +9 -9
  185. odxtools/unitgroup.py +6 -11
  186. odxtools/unitgroupcategory.py +7 -0
  187. odxtools/unitspec.py +6 -6
  188. odxtools/usage.py +9 -0
  189. odxtools/utils.py +31 -2
  190. odxtools/validtype.py +9 -0
  191. odxtools/variablegroup.py +2 -2
  192. odxtools/variantmatcher.py +10 -10
  193. odxtools/variantpattern.py +3 -3
  194. odxtools/version.py +2 -2
  195. odxtools/writepdxfile.py +5 -5
  196. odxtools/xdoc.py +9 -9
  197. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/METADATA +4 -5
  198. odxtools-10.0.0.dist-info/RECORD +264 -0
  199. odxtools-9.6.1.dist-info/RECORD +0 -238
  200. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/WHEEL +0 -0
  201. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/entry_points.txt +0 -0
  202. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/licenses/LICENSE +0 -0
  203. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/top_level.txt +0 -0
odxtools/cli/list.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import argparse
3
- from typing import Callable, List, Optional
3
+ from collections.abc import Callable
4
4
 
5
5
  import rich
6
6
 
@@ -32,11 +32,11 @@ def print_summary(odxdb: Database,
32
32
  print_state_transitions: bool = False,
33
33
  print_audiences: bool = False,
34
34
  allow_unknown_bit_lengths: bool = False,
35
- variants: Optional[List[str]] = None,
35
+ variants: list[str] | None = None,
36
36
  service_filter: Callable[[DiagComm], bool] = lambda x: True) -> None:
37
37
 
38
38
  diag_layer_names = [dl.short_name for dl in odxdb.diag_layers]
39
- diag_layers: List[DiagLayer] = []
39
+ diag_layers: list[DiagLayer] = []
40
40
 
41
41
  if variants is None:
42
42
  variants = diag_layer_names
@@ -59,9 +59,9 @@ def print_summary(odxdb: Database,
59
59
  rich.print(f"Diagnostic layer: '{dl.short_name}'")
60
60
  rich.print(f" Variant Type: {dl.variant_type.value}")
61
61
 
62
- all_services: List[DiagComm] = sorted(dl.services, key=lambda x: x.short_name)
62
+ all_services: list[DiagComm] = sorted(dl.services, key=lambda x: x.short_name)
63
63
 
64
- if isinstance(dl, (BaseVariant, EcuVariant)):
64
+ if isinstance(dl, BaseVariant | EcuVariant):
65
65
  for proto in dl.protocols:
66
66
  if (can_rx_id := dl.get_can_receive_id(proto.short_name)) is not None:
67
67
  rich.print(
@@ -99,7 +99,7 @@ def print_summary(odxdb: Database,
99
99
  else:
100
100
  rich.print(f" Unidentifiable service: {service}")
101
101
  ddd_spec = dl.diag_data_dictionary_spec
102
- data_object_properties: List[
102
+ data_object_properties: list[
103
103
  DataObjectProperty] = [] if ddd_spec is None else ddd_spec.data_object_props
104
104
  if print_dops and len(data_object_properties) > 0:
105
105
  rich.print("\n")
@@ -108,7 +108,7 @@ def print_summary(odxdb: Database,
108
108
  data_object_properties, key=lambda x: (type(x).__name__, x.short_name)):
109
109
  rich.print(" " + str(dop.short_name).replace("\n", "\n "))
110
110
 
111
- comparam_refs: List[ComparamInstance] = []
111
+ comparam_refs: list[ComparamInstance] = []
112
112
  if isinstance(dl, HierarchyElement):
113
113
  comparam_refs = dl.comparam_refs
114
114
 
odxtools/cli/main.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import argparse
3
3
  import importlib
4
- from typing import Any, List
4
+ from typing import Any
5
5
 
6
6
  import odxtools
7
7
  import odxtools.exceptions
@@ -11,7 +11,7 @@ from .dummy_sub_parser import DummyTool
11
11
 
12
12
  # import the tool modules which can be loaded. if a tool
13
13
  # can't be loaded, add a dummy one
14
- tool_modules: List[Any] = []
14
+ tool_modules: list[Any] = []
15
15
  for tool_name in ["list", "browse", "snoop", "find", "decode", "compare"]:
16
16
  try:
17
17
  tool_modules.append(importlib.import_module(f".{tool_name}", package="odxtools.cli"))
odxtools/cli/snoop.py CHANGED
@@ -4,7 +4,7 @@
4
4
  import argparse
5
5
  import asyncio
6
6
  import sys
7
- from typing import Any, List, Optional, Type
7
+ from typing import Any
8
8
 
9
9
  import can
10
10
 
@@ -103,7 +103,7 @@ def handle_telegram(telegram_id: int, payload: bytes) -> None:
103
103
  f"({payload!r}, {len(payload)} bytes)")
104
104
 
105
105
 
106
- def init_verbose_state_machine(BaseClass: Type[IsoTpStateMachine], *args: Any,
106
+ def init_verbose_state_machine(BaseClass: type[IsoTpStateMachine], *args: Any,
107
107
  **kwargs: Any) -> IsoTpStateMachine:
108
108
 
109
109
  class InformativeIsoTpDecoder(BaseClass): # type: ignore[valid-type, misc]
@@ -246,7 +246,7 @@ def run(args: argparse.Namespace) -> None:
246
246
 
247
247
  protocol_name = args.protocol
248
248
  if odx_diag_layer is not None and protocol_name is not None:
249
- protocols: Optional[List[Protocol]] = getattr(odx_diag_layer, "protocols", None)
249
+ protocols: list[Protocol] | None = getattr(odx_diag_layer, "protocols", None)
250
250
 
251
251
  if protocols is None:
252
252
  print(f"ECU variant {odx_diag_layer.short_name} is of type "
odxtools/codec.py CHANGED
@@ -1,15 +1,10 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import typing
3
- from typing import List, Optional, runtime_checkable
3
+ from typing import runtime_checkable
4
4
 
5
5
  from .decodestate import DecodeState
6
6
  from .encodestate import EncodeState
7
- from .exceptions import EncodeError, odxraise
8
7
  from .odxtypes import ParameterValue
9
- from .parameters.codedconstparameter import CodedConstParameter
10
- from .parameters.matchingrequestparameter import MatchingRequestParameter
11
- from .parameters.parameter import Parameter
12
- from .parameters.physicalconstantparameter import PhysicalConstantParameter
13
8
 
14
9
 
15
10
  @runtime_checkable
@@ -22,190 +17,12 @@ class Codec(typing.Protocol):
22
17
  def short_name(self) -> str:
23
18
  return ""
24
19
 
25
- def encode_into_pdu(self, physical_value: Optional[ParameterValue],
20
+ def encode_into_pdu(self, physical_value: ParameterValue | None,
26
21
  encode_state: EncodeState) -> None:
27
22
  ...
28
23
 
29
24
  def decode_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
30
25
  ...
31
26
 
32
- def get_static_bit_length(self) -> Optional[int]:
27
+ def get_static_bit_length(self) -> int | None:
33
28
  ...
34
-
35
-
36
- @runtime_checkable
37
- class CompositeCodec(Codec, typing.Protocol):
38
- """Any object which can be en- or decoded to be transferred over
39
- the wire which is composed of multiple parameter implements this
40
- API.
41
-
42
- """
43
-
44
- @property
45
- def parameters(self) -> List[Parameter]:
46
- return []
47
-
48
- @property
49
- def required_parameters(self) -> List[Parameter]:
50
- return []
51
-
52
- @property
53
- def free_parameters(self) -> List[Parameter]:
54
- return []
55
-
56
-
57
- # some helper functions useful for composite codec objects
58
- def composite_codec_get_static_bit_length(codec: CompositeCodec) -> Optional[int]:
59
- """Compute the length of a composite codec object in bits
60
-
61
- This is basically the sum of the lengths of all parameters. If the
62
- length of any parameter can only determined at runtime, `None` is
63
- returned.
64
- """
65
-
66
- cursor = 0
67
- byte_length = 0
68
- for param in codec.parameters:
69
- param_bit_length = param.get_static_bit_length()
70
- if param_bit_length is None:
71
- # We were not able to calculate a static bit length
72
- return None
73
- elif param.byte_position is not None:
74
- cursor = param.byte_position
75
-
76
- cursor += ((param.bit_position or 0) + param_bit_length + 7) // 8
77
- byte_length = max(byte_length, cursor)
78
-
79
- return byte_length * 8
80
-
81
-
82
- def composite_codec_get_required_parameters(codec: CompositeCodec) -> List[Parameter]:
83
- """Return the list of parameters which are required to be
84
- specified for encoding the composite codec object
85
-
86
- I.e., all free parameters that do not exhibit a default value.
87
- """
88
- return [p for p in codec.parameters if p.is_required]
89
-
90
-
91
- def composite_codec_get_free_parameters(codec: CompositeCodec) -> List[Parameter]:
92
- """Return the list of parameters which can be freely specified by
93
- the user when encoding the composite codec object
94
-
95
- This means all required parameters plus parameters that can be
96
- omitted because they specify a default.
97
- """
98
- return [p for p in codec.parameters if p.is_settable]
99
-
100
-
101
- def composite_codec_get_coded_const_prefix(codec: CompositeCodec,
102
- request_prefix: bytes = b'') -> bytes:
103
- encode_state = EncodeState(coded_message=bytearray(), triggering_request=request_prefix)
104
-
105
- for param in codec.parameters:
106
- if (isinstance(param, MatchingRequestParameter) and param.request_byte_position < len(request_prefix)) or \
107
- isinstance(param, (CodedConstParameter, PhysicalConstantParameter)):
108
- param.encode_into_pdu(physical_value=None, encode_state=encode_state)
109
- else:
110
- break
111
-
112
- return encode_state.coded_message
113
-
114
-
115
- def composite_codec_encode_into_pdu(codec: CompositeCodec, physical_value: Optional[ParameterValue],
116
- encode_state: EncodeState) -> None:
117
- from .parameters.lengthkeyparameter import LengthKeyParameter
118
- from .parameters.tablekeyparameter import TableKeyParameter
119
-
120
- if not isinstance(physical_value, dict):
121
- odxraise(
122
- f"Expected a dictionary for the values of {codec.short_name}, "
123
- f"got {type(physical_value).__name__}", EncodeError)
124
- elif encode_state.cursor_bit_position != 0:
125
- odxraise(
126
- f"Compositional codec objecs must be byte aligned, but "
127
- f"{codec.short_name} requested to be at bit position "
128
- f"{encode_state.cursor_bit_position}", EncodeError)
129
- encode_state.bit_position = 0
130
-
131
- orig_origin = encode_state.origin_byte_position
132
- encode_state.origin_byte_position = encode_state.cursor_byte_position
133
-
134
- orig_is_end_of_pdu = encode_state.is_end_of_pdu
135
- encode_state.is_end_of_pdu = False
136
-
137
- # ensure that no values for unknown parameters are specified.
138
- if not encode_state.allow_unknown_parameters:
139
- param_names = {param.short_name for param in codec.parameters}
140
- for param_value_name in physical_value:
141
- if param_value_name not in param_names:
142
- odxraise(f"Value for unknown parameter '{param_value_name}' specified "
143
- f"for composite codec object {codec.short_name}")
144
-
145
- for param in codec.parameters:
146
- if id(param) == id(codec.parameters[-1]):
147
- # The last parameter of the composite codec object is at
148
- # the end of the PDU if the codec object itself is at the
149
- # end of the PDU.
150
- #
151
- # TODO: This assumes that the last parameter specified in
152
- # the ODX is located last in the PDU...
153
- encode_state.is_end_of_pdu = orig_is_end_of_pdu
154
-
155
- if isinstance(param, (LengthKeyParameter, TableKeyParameter)):
156
- # At this point, we encode a placeholder value for length-
157
- # and table keys, since these can be specified
158
- # implicitly (i.e., by means of parameters that use
159
- # these keys). To avoid getting an "overlapping
160
- # parameter" warning, we must encode a value of zero
161
- # into the PDU here and add the real value of the
162
- # parameter in a post-processing step.
163
- param.encode_placeholder_into_pdu(
164
- physical_value=physical_value.get(param.short_name), encode_state=encode_state)
165
-
166
- continue
167
-
168
- if param.is_required and param.short_name not in physical_value:
169
- odxraise(f"No value for required parameter {param.short_name} specified", EncodeError)
170
-
171
- param_phys_value = physical_value.get(param.short_name)
172
- param.encode_into_pdu(physical_value=param_phys_value, encode_state=encode_state)
173
-
174
- encode_state.journal.append((param, param_phys_value))
175
-
176
- encode_state.is_end_of_pdu = False
177
-
178
- # encode the length- and table keys. This cannot be done above
179
- # because we allow these to be defined implicitly (i.e. they
180
- # are defined by their respective users)
181
- for param in codec.parameters:
182
- if not isinstance(param, (LengthKeyParameter, TableKeyParameter)):
183
- # the current parameter is neither a length- nor a table key
184
- continue
185
-
186
- # Encode the value of the key parameter into the message
187
- param.encode_value_into_pdu(encode_state=encode_state)
188
-
189
- encode_state.origin_byte_position = orig_origin
190
-
191
-
192
- def composite_codec_decode_from_pdu(codec: CompositeCodec,
193
- decode_state: DecodeState) -> ParameterValue:
194
- # move the origin since positions specified by sub-parameters of
195
- # composite codec objects are relative to the beginning of the
196
- # object.
197
- orig_origin = decode_state.origin_byte_position
198
- decode_state.origin_byte_position = decode_state.cursor_byte_position
199
-
200
- result = {}
201
- for param in codec.parameters:
202
- value = param.decode_from_pdu(decode_state)
203
-
204
- decode_state.journal.append((param, value))
205
- result[param.short_name] = value
206
-
207
- # decoding of the composite codec object finished. go back the
208
- # original origin.
209
- decode_state.origin_byte_position = orig_origin
210
-
211
- return result
odxtools/commrelation.py CHANGED
@@ -1,10 +1,10 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import warnings
3
3
  from dataclasses import dataclass
4
- from enum import Enum
5
- from typing import Any, Dict, List, Optional
4
+ from typing import Any
6
5
  from xml.etree import ElementTree
7
6
 
7
+ from .commrelationvaluetype import CommRelationValueType
8
8
  from .description import Description
9
9
  from .diagcomm import DiagComm
10
10
  from .diagservice import DiagService
@@ -14,35 +14,28 @@ from .parameters.parameter import Parameter
14
14
  from .snrefcontext import SnRefContext
15
15
 
16
16
 
17
- class CommRelationValueType(Enum):
18
- CURRENT = "CURRENT"
19
- STORED = "STORED"
20
- STATIC = "STATIC"
21
- SUBSTITUTED = "SUBSTITUTED"
22
-
23
-
24
17
  @dataclass
25
18
  class CommRelation:
26
- description: Optional[Description]
19
+ description: Description | None
27
20
  relation_type: str
28
- diag_comm_ref: Optional[OdxLinkRef]
29
- diag_comm_snref: Optional[str]
30
- in_param_if_snref: Optional[str]
21
+ diag_comm_ref: OdxLinkRef | None
22
+ diag_comm_snref: str | None
23
+ in_param_if_snref: str | None
31
24
  #in_param_if_snpathref: Optional[str] # TODO
32
- out_param_if_snref: Optional[str]
25
+ out_param_if_snref: str | None
33
26
  #out_param_if_snpathref: Optional[str] # TODO
34
- value_type_raw: Optional[CommRelationValueType]
27
+ value_type_raw: CommRelationValueType | None
35
28
 
36
29
  @property
37
30
  def diag_comm(self) -> DiagComm:
38
31
  return self._diag_comm
39
32
 
40
33
  @property
41
- def in_param_if(self) -> Optional[Parameter]:
34
+ def in_param_if(self) -> Parameter | None:
42
35
  return self._in_param_if
43
36
 
44
37
  @property
45
- def out_param_if(self) -> Optional[Parameter]:
38
+ def out_param_if(self) -> Parameter | None:
46
39
  return self._out_param_if
47
40
 
48
41
  @property
@@ -53,7 +46,7 @@ class CommRelation:
53
46
  return self.value_type_raw
54
47
 
55
48
  @staticmethod
56
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "CommRelation":
49
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "CommRelation":
57
50
  description = Description.from_et(et_element.find("DESC"), doc_frags)
58
51
  relation_type = odxrequire(et_element.findtext("RELATION-TYPE"))
59
52
 
@@ -92,7 +85,7 @@ class CommRelation:
92
85
  out_param_if_snref=out_param_if_snref,
93
86
  value_type_raw=value_type_raw)
94
87
 
95
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
88
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
96
89
  return {}
97
90
 
98
91
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
@@ -0,0 +1,9 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from enum import Enum
3
+
4
+
5
+ class CommRelationValueType(Enum):
6
+ CURRENT = "CURRENT"
7
+ STORED = "STORED"
8
+ STATIC = "STATIC"
9
+ SUBSTITUTED = "SUBSTITUTED"
odxtools/companydata.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List, Optional
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .companyspecificinfo import CompanySpecificInfo
@@ -15,12 +15,12 @@ from .utils import dataclass_fields_asdict
15
15
 
16
16
  @dataclass
17
17
  class CompanyData(IdentifiableElement):
18
- roles: List[str]
18
+ roles: list[str]
19
19
  team_members: NamedItemList[TeamMember]
20
- company_specific_info: Optional[CompanySpecificInfo]
20
+ company_specific_info: CompanySpecificInfo | None
21
21
 
22
22
  @staticmethod
23
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "CompanyData":
23
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "CompanyData":
24
24
 
25
25
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
26
26
 
@@ -43,7 +43,7 @@ class CompanyData(IdentifiableElement):
43
43
  **kwargs,
44
44
  )
45
45
 
46
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
46
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
47
47
  result = {self.odx_id: self}
48
48
 
49
49
  for tm in self.team_members:
@@ -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 .companydata import CompanyData
@@ -14,21 +14,21 @@ from .teammember import TeamMember
14
14
  @dataclass
15
15
  class CompanyDocInfo:
16
16
  company_data_ref: OdxLinkRef
17
- team_member_ref: Optional[OdxLinkRef]
18
- doc_label: Optional[str]
19
- sdgs: List[SpecialDataGroup]
17
+ team_member_ref: OdxLinkRef | None
18
+ doc_label: str | None
19
+ sdgs: list[SpecialDataGroup]
20
20
 
21
21
  @property
22
22
  def company_data(self) -> CompanyData:
23
23
  return self._company_data
24
24
 
25
25
  @property
26
- def team_member(self) -> Optional[TeamMember]:
26
+ def team_member(self) -> TeamMember | None:
27
27
  return self._team_member
28
28
 
29
29
  @staticmethod
30
30
  def from_et(et_element: ElementTree.Element,
31
- doc_frags: List[OdxDocFragment]) -> "CompanyDocInfo":
31
+ doc_frags: list[OdxDocFragment]) -> "CompanyDocInfo":
32
32
  # the company data reference is mandatory
33
33
  company_data_ref = odxrequire(
34
34
  OdxLinkRef.from_et(et_element.find("COMPANY-DATA-REF"), doc_frags))
@@ -45,7 +45,7 @@ class CompanyDocInfo:
45
45
  sdgs=sdgs,
46
46
  )
47
47
 
48
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
48
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
49
49
  result = {}
50
50
 
51
51
  for sdg in self.sdgs:
@@ -56,7 +56,7 @@ class CompanyDocInfo:
56
56
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
57
57
  self._company_data = odxlinks.resolve(self.company_data_ref, CompanyData)
58
58
 
59
- self._team_member: Optional[TeamMember] = None
59
+ self._team_member: TeamMember | None = None
60
60
  if self.team_member_ref is not None:
61
61
  self._team_member = odxlinks.resolve(self.team_member_ref, TeamMember)
62
62
 
@@ -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 .companydata import CompanyData
@@ -12,8 +12,8 @@ from .snrefcontext import SnRefContext
12
12
  @dataclass
13
13
  class CompanyRevisionInfo:
14
14
  company_data_ref: OdxLinkRef
15
- revision_label: Optional[str]
16
- state: Optional[str]
15
+ revision_label: str | None
16
+ state: str | None
17
17
 
18
18
  @property
19
19
  def company_data(self) -> CompanyData:
@@ -21,7 +21,7 @@ class CompanyRevisionInfo:
21
21
 
22
22
  @staticmethod
23
23
  def from_et(et_element: ElementTree.Element,
24
- doc_frags: List[OdxDocFragment]) -> "CompanyRevisionInfo":
24
+ doc_frags: list[OdxDocFragment]) -> "CompanyRevisionInfo":
25
25
 
26
26
  company_data_ref = odxrequire(
27
27
  OdxLinkRef.from_et(et_element.find("COMPANY-DATA-REF"), doc_frags))
@@ -31,7 +31,7 @@ class CompanyRevisionInfo:
31
31
  return CompanyRevisionInfo(
32
32
  company_data_ref=company_data_ref, revision_label=revision_label, state=state)
33
33
 
34
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
34
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
35
35
  return {}
36
36
 
37
37
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
@@ -11,12 +11,12 @@ from .specialdatagroup import SpecialDataGroup
11
11
 
12
12
  @dataclass
13
13
  class CompanySpecificInfo:
14
- related_docs: List[RelatedDoc]
15
- sdgs: List[SpecialDataGroup]
14
+ related_docs: list[RelatedDoc]
15
+ sdgs: list[SpecialDataGroup]
16
16
 
17
17
  @staticmethod
18
18
  def from_et(et_element: ElementTree.Element,
19
- doc_frags: List[OdxDocFragment]) -> "CompanySpecificInfo":
19
+ doc_frags: list[OdxDocFragment]) -> "CompanySpecificInfo":
20
20
  related_docs = [
21
21
  RelatedDoc.from_et(rd, doc_frags)
22
22
  for rd in et_element.iterfind("RELATED-DOCS/RELATED-DOC")
@@ -28,7 +28,7 @@ class CompanySpecificInfo:
28
28
 
29
29
  return CompanySpecificInfo(related_docs=related_docs, sdgs=sdgs)
30
30
 
31
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
31
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
32
32
  result = {}
33
33
 
34
34
  for rd in self.related_docs:
odxtools/comparam.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .basecomparam import BaseComparam
@@ -27,7 +27,7 @@ class Comparam(BaseComparam):
27
27
  return self._dop
28
28
 
29
29
  @staticmethod
30
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "Comparam":
30
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Comparam":
31
31
  kwargs = dataclass_fields_asdict(BaseComparam.from_et(et_element, doc_frags))
32
32
 
33
33
  physical_default_value_raw = odxrequire(et_element.findtext("PHYSICAL-DEFAULT-VALUE"))
@@ -36,7 +36,7 @@ class Comparam(BaseComparam):
36
36
  return Comparam(
37
37
  dop_ref=dop_ref, physical_default_value_raw=physical_default_value_raw, **kwargs)
38
38
 
39
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
39
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
40
40
  return super()._build_odxlinks()
41
41
 
42
42
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
@@ -1,7 +1,7 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import warnings
3
3
  from dataclasses import dataclass
4
- from typing import Any, Dict, List, Optional, Union
4
+ from typing import Any
5
5
  from xml.etree import ElementTree
6
6
 
7
7
  from .basecomparam import BaseComparam
@@ -20,10 +20,10 @@ class ComparamInstance:
20
20
 
21
21
  Be aware that the ODX specification calls this class COMPARAM-REF!
22
22
  """
23
- value: Union[str, ComplexValue]
24
- description: Optional[Description]
25
- protocol_snref: Optional[str]
26
- prot_stack_snref: Optional[str]
23
+ value: str | ComplexValue
24
+ description: Description | None
25
+ protocol_snref: str | None
26
+ prot_stack_snref: str | None
27
27
  spec_ref: OdxLinkRef
28
28
 
29
29
  @property
@@ -36,13 +36,13 @@ class ComparamInstance:
36
36
 
37
37
  @staticmethod
38
38
  def from_et(et_element: ElementTree.Element,
39
- doc_frags: List[OdxDocFragment]) -> "ComparamInstance":
39
+ doc_frags: list[OdxDocFragment]) -> "ComparamInstance":
40
40
  spec_ref = odxrequire(OdxLinkRef.from_et(et_element, doc_frags))
41
41
 
42
42
  # ODX standard v2.0.0 defined only VALUE. ODX v2.0.1 decided
43
43
  # to break things and change it to a choice between SIMPLE-VALUE
44
44
  # and COMPLEX-VALUE
45
- value: Union[str, List[Union[str, ComplexValue]]]
45
+ value: str | list[str | ComplexValue]
46
46
  if et_element.find("VALUE") is not None:
47
47
  value = odxrequire(et_element.findtext("VALUE"))
48
48
  elif et_element.find("SIMPLE-VALUE") is not None:
@@ -68,7 +68,7 @@ class ComparamInstance:
68
68
  prot_stack_snref=prot_stack_snref,
69
69
  )
70
70
 
71
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
71
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
72
72
  return {}
73
73
 
74
74
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
@@ -98,7 +98,7 @@ class ComparamInstance:
98
98
 
99
99
  return result
100
100
 
101
- def get_subvalue(self, subparam_name: str) -> Optional[str]:
101
+ def get_subvalue(self, subparam_name: str) -> str | None:
102
102
  """Retrieve the value of a complex communication parameter's sub-parameter by name
103
103
 
104
104
  This takes the default value of the comparam (if any) into
@@ -133,7 +133,7 @@ class ComparamInstance:
133
133
  return None
134
134
 
135
135
  result = value_list[idx]
136
- if result is None and isinstance(subparam, (Comparam, ComplexComparam)):
136
+ if result is None and isinstance(subparam, Comparam | ComplexComparam):
137
137
  result = subparam.physical_default_value
138
138
  if not isinstance(result, str):
139
139
  odxraise()
odxtools/comparamspec.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, Any, Dict, List
3
+ from typing import TYPE_CHECKING, Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .nameditemlist import NamedItemList
@@ -20,7 +20,7 @@ class ComparamSpec(OdxCategory):
20
20
  prot_stacks: NamedItemList[ProtStack]
21
21
 
22
22
  @staticmethod
23
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "ComparamSpec":
23
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "ComparamSpec":
24
24
 
25
25
  base_obj = OdxCategory.category_from_et(
26
26
  et_element, doc_frags, doc_type=DocType.COMPARAM_SPEC)
@@ -34,7 +34,7 @@ class ComparamSpec(OdxCategory):
34
34
 
35
35
  return ComparamSpec(prot_stacks=prot_stacks, **kwargs)
36
36
 
37
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
37
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
38
38
  odxlinks = super()._build_odxlinks()
39
39
 
40
40
  for ps in self.prot_stacks: