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/cli/decode.py CHANGED
@@ -1,7 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import argparse
3
3
  import re
4
- from typing import Dict, List, Optional
5
4
 
6
5
  from ..database import Database
7
6
  from ..diagservice import DiagService
@@ -26,13 +25,13 @@ def get_display_value(v: ParameterValue) -> str:
26
25
 
27
26
  def print_summary(
28
27
  odxdb: Database,
29
- ecu_variants: Optional[List[str]] = None,
28
+ ecu_variants: list[str] | None = None,
30
29
  data: bytes = b'',
31
30
  decode: bool = False,
32
31
  ) -> None:
33
32
  ecu_names = ecu_variants if ecu_variants else [ecu.short_name for ecu in odxdb.ecus]
34
- service_db: Dict[str, DiagService] = {}
35
- service_ecus: Dict[str, List[str]] = {}
33
+ service_db: dict[str, DiagService] = {}
34
+ service_ecus: dict[str, list[str]] = {}
36
35
  for ecu_name in ecu_names:
37
36
  ecu = odxdb.ecus[ecu_name]
38
37
  if not ecu:
odxtools/cli/find.py CHANGED
@@ -1,6 +1,5 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import argparse
3
- from typing import Dict, List, Optional
4
3
 
5
4
  from ..database import Database
6
5
  from ..diagservice import DiagService
@@ -24,13 +23,13 @@ def get_display_value(v: ParameterValue) -> str:
24
23
 
25
24
 
26
25
  def print_summary(odxdb: Database,
27
- service_names: List[str],
28
- ecu_variants: Optional[List[str]] = None,
26
+ service_names: list[str],
27
+ ecu_variants: list[str] | None = None,
29
28
  allow_unknown_bit_lengths: bool = False,
30
29
  print_params: bool = False) -> None:
31
30
  ecu_names = ecu_variants if ecu_variants else [ecu.short_name for ecu in odxdb.ecus]
32
- service_db: Dict[str, DiagService] = {}
33
- service_ecus: Dict[str, List[str]] = {}
31
+ service_db: dict[str, DiagService] = {}
32
+ service_ecus: dict[str, list[str]] = {}
34
33
  for ecu_name in ecu_names:
35
34
  ecu = odxdb.ecus[ecu_name]
36
35
  if not ecu:
odxtools/cli/list.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import argparse
3
- from typing import Callable, List, Optional
3
+ from collections.abc import Callable
4
4
 
5
5
  import rich
6
6
 
@@ -32,11 +32,11 @@ def print_summary(odxdb: Database,
32
32
  print_state_transitions: bool = False,
33
33
  print_audiences: bool = False,
34
34
  allow_unknown_bit_lengths: bool = False,
35
- variants: Optional[List[str]] = None,
35
+ variants: list[str] | None = None,
36
36
  service_filter: Callable[[DiagComm], bool] = lambda x: True) -> None:
37
37
 
38
38
  diag_layer_names = [dl.short_name for dl in odxdb.diag_layers]
39
- diag_layers: List[DiagLayer] = []
39
+ diag_layers: list[DiagLayer] = []
40
40
 
41
41
  if variants is None:
42
42
  variants = diag_layer_names
@@ -59,7 +59,7 @@ 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
64
  if isinstance(dl, (BaseVariant, EcuVariant)):
65
65
  for proto in dl.protocols:
@@ -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,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import typing
3
- from typing import Optional, runtime_checkable
3
+ from typing import runtime_checkable
4
4
 
5
5
  from .decodestate import DecodeState
6
6
  from .encodestate import EncodeState
@@ -17,12 +17,12 @@ class Codec(typing.Protocol):
17
17
  def short_name(self) -> str:
18
18
  return ""
19
19
 
20
- def encode_into_pdu(self, physical_value: Optional[ParameterValue],
20
+ def encode_into_pdu(self, physical_value: ParameterValue | None,
21
21
  encode_state: EncodeState) -> None:
22
22
  ...
23
23
 
24
24
  def decode_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
25
25
  ...
26
26
 
27
- def get_static_bit_length(self) -> Optional[int]:
27
+ def get_static_bit_length(self) -> int | None:
28
28
  ...
odxtools/commrelation.py CHANGED
@@ -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
4
+ from typing import Any
5
5
  from xml.etree import ElementTree
6
6
 
7
7
  from .commrelationvaluetype import CommRelationValueType
@@ -9,33 +9,34 @@ from .description import Description
9
9
  from .diagcomm import DiagComm
10
10
  from .diagservice import DiagService
11
11
  from .exceptions import OdxWarning, odxraise, odxrequire
12
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
12
+ from .odxdoccontext import OdxDocContext
13
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
13
14
  from .parameters.parameter import Parameter
14
15
  from .snrefcontext import SnRefContext
15
16
 
16
17
 
17
- @dataclass
18
+ @dataclass(kw_only=True)
18
19
  class CommRelation:
19
- description: Optional[Description]
20
+ description: Description | None = None
20
21
  relation_type: str
21
- diag_comm_ref: Optional[OdxLinkRef]
22
- diag_comm_snref: Optional[str]
23
- in_param_if_snref: Optional[str]
24
- #in_param_if_snpathref: Optional[str] # TODO
25
- out_param_if_snref: Optional[str]
26
- #out_param_if_snpathref: Optional[str] # TODO
27
- value_type_raw: Optional[CommRelationValueType]
22
+ diag_comm_ref: OdxLinkRef | None = None
23
+ diag_comm_snref: str | None = None
24
+ in_param_if_snref: str | None = None
25
+ #in_param_if_snpathref: Optional[str] = None # TODO
26
+ out_param_if_snref: str | None = None
27
+ #out_param_if_snpathref: Optional[str] = None # TODO
28
+ value_type_raw: CommRelationValueType | None = None
28
29
 
29
30
  @property
30
31
  def diag_comm(self) -> DiagComm:
31
32
  return self._diag_comm
32
33
 
33
34
  @property
34
- def in_param_if(self) -> Optional[Parameter]:
35
+ def in_param_if(self) -> Parameter | None:
35
36
  return self._in_param_if
36
37
 
37
38
  @property
38
- def out_param_if(self) -> Optional[Parameter]:
39
+ def out_param_if(self) -> Parameter | None:
39
40
  return self._out_param_if
40
41
 
41
42
  @property
@@ -46,11 +47,11 @@ class CommRelation:
46
47
  return self.value_type_raw
47
48
 
48
49
  @staticmethod
49
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "CommRelation":
50
- description = Description.from_et(et_element.find("DESC"), doc_frags)
50
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "CommRelation":
51
+ description = Description.from_et(et_element.find("DESC"), context)
51
52
  relation_type = odxrequire(et_element.findtext("RELATION-TYPE"))
52
53
 
53
- diag_comm_ref = OdxLinkRef.from_et(et_element.find("DIAG-COMM-REF"), doc_frags)
54
+ diag_comm_ref = OdxLinkRef.from_et(et_element.find("DIAG-COMM-REF"), context)
54
55
  diag_comm_snref = None
55
56
  if (diag_comm_snref_elem := et_element.find("DIAG-COMM-SNREF")) is not None:
56
57
  diag_comm_snref = odxrequire(diag_comm_snref_elem.get("SHORT-NAME"))
@@ -85,7 +86,7 @@ class CommRelation:
85
86
  out_param_if_snref=out_param_if_snref,
86
87
  value_type_raw=value_type_raw)
87
88
 
88
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
89
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
89
90
  return {}
90
91
 
91
92
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
odxtools/companydata.py CHANGED
@@ -1,40 +1,40 @@
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 .companyspecificinfo import CompanySpecificInfo
7
7
  from .element import IdentifiableElement
8
8
  from .exceptions import odxrequire
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 .teammember import TeamMember
13
14
  from .utils import dataclass_fields_asdict
14
15
 
15
16
 
16
- @dataclass
17
+ @dataclass(kw_only=True)
17
18
  class CompanyData(IdentifiableElement):
18
- roles: List[str]
19
- team_members: NamedItemList[TeamMember]
20
- company_specific_info: Optional[CompanySpecificInfo]
19
+ roles: list[str] = field(default_factory=list)
20
+ team_members: NamedItemList[TeamMember] = field(default_factory=NamedItemList)
21
+ company_specific_info: CompanySpecificInfo | None = None
21
22
 
22
23
  @staticmethod
23
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "CompanyData":
24
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "CompanyData":
24
25
 
25
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
26
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
26
27
 
27
28
  roles = []
28
29
  if (roles_elem := et_element.find("ROLES")) is not None:
29
30
  roles = [odxrequire(role.text) for role in roles_elem.iterfind("ROLE")]
30
31
  team_members = [
31
- TeamMember.from_et(tm, doc_frags)
32
+ TeamMember.from_et(tm, context)
32
33
  for tm in et_element.iterfind("TEAM-MEMBERS/TEAM-MEMBER")
33
34
  ]
34
35
  company_specific_info = None
35
36
  if (company_specific_info_elem := et_element.find("COMPANY-SPECIFIC-INFO")) is not None:
36
- company_specific_info = CompanySpecificInfo.from_et(company_specific_info_elem,
37
- doc_frags)
37
+ company_specific_info = CompanySpecificInfo.from_et(company_specific_info_elem, context)
38
38
 
39
39
  return CompanyData(
40
40
  roles=roles,
@@ -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,42 +1,40 @@
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 .companydata import CompanyData
7
7
  from .exceptions import odxrequire
8
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
8
+ from .odxdoccontext import OdxDocContext
9
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
9
10
  from .snrefcontext import SnRefContext
10
11
  from .specialdatagroup import SpecialDataGroup
11
12
  from .teammember import TeamMember
12
13
 
13
14
 
14
- @dataclass
15
+ @dataclass(kw_only=True)
15
16
  class CompanyDocInfo:
16
17
  company_data_ref: OdxLinkRef
17
- team_member_ref: Optional[OdxLinkRef]
18
- doc_label: Optional[str]
19
- sdgs: List[SpecialDataGroup]
18
+ team_member_ref: OdxLinkRef | None = None
19
+ doc_label: str | None = None
20
+ sdgs: list[SpecialDataGroup] = field(default_factory=list)
20
21
 
21
22
  @property
22
23
  def company_data(self) -> CompanyData:
23
24
  return self._company_data
24
25
 
25
26
  @property
26
- def team_member(self) -> Optional[TeamMember]:
27
+ def team_member(self) -> TeamMember | None:
27
28
  return self._team_member
28
29
 
29
30
  @staticmethod
30
- def from_et(et_element: ElementTree.Element,
31
- doc_frags: List[OdxDocFragment]) -> "CompanyDocInfo":
31
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "CompanyDocInfo":
32
32
  # the company data reference is mandatory
33
33
  company_data_ref = odxrequire(
34
- OdxLinkRef.from_et(et_element.find("COMPANY-DATA-REF"), doc_frags))
35
- team_member_ref = OdxLinkRef.from_et(et_element.find("TEAM-MEMBER-REF"), doc_frags)
34
+ OdxLinkRef.from_et(et_element.find("COMPANY-DATA-REF"), context))
35
+ team_member_ref = OdxLinkRef.from_et(et_element.find("TEAM-MEMBER-REF"), context)
36
36
  doc_label = et_element.findtext("DOC-LABEL")
37
- sdgs = [
38
- SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
39
- ]
37
+ sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
40
38
 
41
39
  return CompanyDocInfo(
42
40
  company_data_ref=company_data_ref,
@@ -45,7 +43,7 @@ class CompanyDocInfo:
45
43
  sdgs=sdgs,
46
44
  )
47
45
 
48
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
46
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
49
47
  result = {}
50
48
 
51
49
  for sdg in self.sdgs:
@@ -56,7 +54,7 @@ class CompanyDocInfo:
56
54
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
57
55
  self._company_data = odxlinks.resolve(self.company_data_ref, CompanyData)
58
56
 
59
- self._team_member: Optional[TeamMember] = None
57
+ self._team_member: TeamMember | None = None
60
58
  if self.team_member_ref is not None:
61
59
  self._team_member = odxlinks.resolve(self.team_member_ref, TeamMember)
62
60
 
@@ -1,37 +1,37 @@
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
7
7
  from .exceptions import odxrequire
8
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
8
+ from .odxdoccontext import OdxDocContext
9
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
9
10
  from .snrefcontext import SnRefContext
10
11
 
11
12
 
12
- @dataclass
13
+ @dataclass(kw_only=True)
13
14
  class CompanyRevisionInfo:
14
15
  company_data_ref: OdxLinkRef
15
- revision_label: Optional[str]
16
- state: Optional[str]
16
+ revision_label: str | None = None
17
+ state: str | None = None
17
18
 
18
19
  @property
19
20
  def company_data(self) -> CompanyData:
20
21
  return self._company_data
21
22
 
22
23
  @staticmethod
23
- def from_et(et_element: ElementTree.Element,
24
- doc_frags: List[OdxDocFragment]) -> "CompanyRevisionInfo":
24
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "CompanyRevisionInfo":
25
25
 
26
26
  company_data_ref = odxrequire(
27
- OdxLinkRef.from_et(et_element.find("COMPANY-DATA-REF"), doc_frags))
27
+ OdxLinkRef.from_et(et_element.find("COMPANY-DATA-REF"), context))
28
28
  revision_label = et_element.findtext("REVISION-LABEL")
29
29
  state = et_element.findtext("STATE")
30
30
 
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,34 +1,32 @@
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
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
6
+ from .odxdoccontext import OdxDocContext
7
+ from .odxlink import OdxLinkDatabase, OdxLinkId
7
8
  from .relateddoc import RelatedDoc
8
9
  from .snrefcontext import SnRefContext
9
10
  from .specialdatagroup import SpecialDataGroup
10
11
 
11
12
 
12
- @dataclass
13
+ @dataclass(kw_only=True)
13
14
  class CompanySpecificInfo:
14
- related_docs: List[RelatedDoc]
15
- sdgs: List[SpecialDataGroup]
15
+ related_docs: list[RelatedDoc] = field(default_factory=list)
16
+ sdgs: list[SpecialDataGroup] = field(default_factory=list)
16
17
 
17
18
  @staticmethod
18
- def from_et(et_element: ElementTree.Element,
19
- doc_frags: List[OdxDocFragment]) -> "CompanySpecificInfo":
19
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "CompanySpecificInfo":
20
20
  related_docs = [
21
- RelatedDoc.from_et(rd, doc_frags)
21
+ RelatedDoc.from_et(rd, context)
22
22
  for rd in et_element.iterfind("RELATED-DOCS/RELATED-DOC")
23
23
  ]
24
24
 
25
- sdgs = [
26
- SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
27
- ]
25
+ sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
28
26
 
29
27
  return CompanySpecificInfo(related_docs=related_docs, sdgs=sdgs)
30
28
 
31
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
29
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
32
30
  result = {}
33
31
 
34
32
  for rd in self.related_docs:
odxtools/comparam.py CHANGED
@@ -1,18 +1,19 @@
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
7
7
  from .dataobjectproperty import DataObjectProperty
8
8
  from .exceptions import odxrequire
9
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
9
+ from .odxdoccontext import OdxDocContext
10
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
10
11
  from .odxtypes import AtomicOdxType
11
12
  from .snrefcontext import SnRefContext
12
13
  from .utils import dataclass_fields_asdict
13
14
 
14
15
 
15
- @dataclass
16
+ @dataclass(kw_only=True)
16
17
  class Comparam(BaseComparam):
17
18
  physical_default_value_raw: str
18
19
  dop_ref: OdxLinkRef
@@ -27,16 +28,16 @@ class Comparam(BaseComparam):
27
28
  return self._dop
28
29
 
29
30
  @staticmethod
30
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "Comparam":
31
- kwargs = dataclass_fields_asdict(BaseComparam.from_et(et_element, doc_frags))
31
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Comparam":
32
+ kwargs = dataclass_fields_asdict(BaseComparam.from_et(et_element, context))
32
33
 
33
34
  physical_default_value_raw = odxrequire(et_element.findtext("PHYSICAL-DEFAULT-VALUE"))
34
- dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DATA-OBJECT-PROP-REF"), doc_frags))
35
+ dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DATA-OBJECT-PROP-REF"), context))
35
36
 
36
37
  return Comparam(
37
38
  dop_ref=dop_ref, physical_default_value_raw=physical_default_value_raw, **kwargs)
38
39
 
39
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
40
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
40
41
  return super()._build_odxlinks()
41
42
 
42
43
  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
@@ -9,21 +9,22 @@ from .comparam import Comparam
9
9
  from .complexcomparam import ComplexComparam, ComplexValue, create_complex_value_from_et
10
10
  from .description import Description
11
11
  from .exceptions import OdxWarning, odxraise, odxrequire
12
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
12
+ from .odxdoccontext import OdxDocContext
13
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
13
14
  from .snrefcontext import SnRefContext
14
15
 
15
16
 
16
- @dataclass
17
+ @dataclass(kw_only=True)
17
18
  class ComparamInstance:
18
19
  """
19
20
  This class represents a communication parameter.
20
21
 
21
22
  Be aware that the ODX specification calls this class COMPARAM-REF!
22
23
  """
23
- value: Union[str, ComplexValue]
24
- description: Optional[Description]
25
- protocol_snref: Optional[str]
26
- prot_stack_snref: Optional[str]
24
+ value: str | ComplexValue
25
+ description: Description | None = None
26
+ protocol_snref: str | None = None
27
+ prot_stack_snref: str | None = None
27
28
  spec_ref: OdxLinkRef
28
29
 
29
30
  @property
@@ -35,14 +36,13 @@ class ComparamInstance:
35
36
  return self.spec.short_name
36
37
 
37
38
  @staticmethod
38
- def from_et(et_element: ElementTree.Element,
39
- doc_frags: List[OdxDocFragment]) -> "ComparamInstance":
40
- spec_ref = odxrequire(OdxLinkRef.from_et(et_element, doc_frags))
39
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ComparamInstance":
40
+ spec_ref = odxrequire(OdxLinkRef.from_et(et_element, context))
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:
@@ -50,7 +50,7 @@ class ComparamInstance:
50
50
  else:
51
51
  value = create_complex_value_from_et(odxrequire(et_element.find("COMPLEX-VALUE")))
52
52
 
53
- description = Description.from_et(et_element.find("DESC"), doc_frags)
53
+ description = Description.from_et(et_element.find("DESC"), context)
54
54
 
55
55
  protocol_snref = None
56
56
  if (psnref_elem := et_element.find("PROTOCOL-SNREF")) 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
odxtools/comparamspec.py CHANGED
@@ -1,11 +1,12 @@
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
6
  from .nameditemlist import NamedItemList
7
7
  from .odxcategory import OdxCategory
8
- from .odxlink import DocType, OdxDocFragment, OdxLinkDatabase, OdxLinkId
8
+ from .odxdoccontext import OdxDocContext
9
+ from .odxlink import OdxLinkDatabase, OdxLinkId
9
10
  from .protstack import ProtStack
10
11
  from .snrefcontext import SnRefContext
11
12
  from .utils import dataclass_fields_asdict
@@ -14,27 +15,25 @@ if TYPE_CHECKING:
14
15
  from .database import Database
15
16
 
16
17
 
17
- @dataclass
18
+ @dataclass(kw_only=True)
18
19
  class ComparamSpec(OdxCategory):
19
20
 
20
- prot_stacks: NamedItemList[ProtStack]
21
+ prot_stacks: NamedItemList[ProtStack] = field(default_factory=NamedItemList)
21
22
 
22
23
  @staticmethod
23
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "ComparamSpec":
24
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ComparamSpec":
24
25
 
25
- base_obj = OdxCategory.category_from_et(
26
- et_element, doc_frags, doc_type=DocType.COMPARAM_SPEC)
27
- doc_frags = base_obj.odx_id.doc_fragments
26
+ base_obj = OdxCategory.from_et(et_element, context)
28
27
  kwargs = dataclass_fields_asdict(base_obj)
29
28
 
30
29
  prot_stacks = NamedItemList([
31
- ProtStack.from_et(dl_element, doc_frags)
30
+ ProtStack.from_et(dl_element, context)
32
31
  for dl_element in et_element.iterfind("PROT-STACKS/PROT-STACK")
33
32
  ])
34
33
 
35
34
  return ComparamSpec(prot_stacks=prot_stacks, **kwargs)
36
35
 
37
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
36
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
38
37
  odxlinks = super()._build_odxlinks()
39
38
 
40
39
  for ps in self.prot_stacks: