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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. odxtools/additionalaudience.py +7 -7
  2. odxtools/admindata.py +14 -13
  3. odxtools/audience.py +17 -17
  4. odxtools/basecomparam.py +9 -8
  5. odxtools/basevariantpattern.py +9 -10
  6. odxtools/basicstructure.py +15 -15
  7. odxtools/cli/_print_utils.py +34 -22
  8. odxtools/cli/browse.py +8 -8
  9. odxtools/cli/compare.py +24 -24
  10. odxtools/cli/decode.py +3 -4
  11. odxtools/cli/find.py +4 -5
  12. odxtools/cli/list.py +6 -6
  13. odxtools/cli/main.py +2 -2
  14. odxtools/cli/snoop.py +3 -3
  15. odxtools/codec.py +3 -3
  16. odxtools/commrelation.py +18 -17
  17. odxtools/companydata.py +13 -13
  18. odxtools/companydocinfo.py +15 -17
  19. odxtools/companyrevisioninfo.py +9 -9
  20. odxtools/companyspecificinfo.py +11 -13
  21. odxtools/comparam.py +8 -7
  22. odxtools/comparaminstance.py +14 -14
  23. odxtools/comparamspec.py +10 -11
  24. odxtools/comparamsubset.py +17 -25
  25. odxtools/complexcomparam.py +14 -14
  26. odxtools/complexdop.py +1 -1
  27. odxtools/compositecodec.py +8 -8
  28. odxtools/compumethods/compucodecompumethod.py +7 -7
  29. odxtools/compumethods/compuconst.py +5 -6
  30. odxtools/compumethods/compudefaultvalue.py +2 -3
  31. odxtools/compumethods/compuinternaltophys.py +13 -12
  32. odxtools/compumethods/compumethod.py +10 -9
  33. odxtools/compumethods/compuphystointernal.py +13 -12
  34. odxtools/compumethods/compurationalcoeffs.py +7 -7
  35. odxtools/compumethods/compuscale.py +15 -16
  36. odxtools/compumethods/createanycompumethod.py +12 -13
  37. odxtools/compumethods/identicalcompumethod.py +4 -5
  38. odxtools/compumethods/limit.py +14 -14
  39. odxtools/compumethods/linearcompumethod.py +5 -5
  40. odxtools/compumethods/linearsegment.py +10 -11
  41. odxtools/compumethods/ratfunccompumethod.py +6 -6
  42. odxtools/compumethods/ratfuncsegment.py +7 -8
  43. odxtools/compumethods/scalelinearcompumethod.py +9 -9
  44. odxtools/compumethods/scaleratfunccompumethod.py +7 -7
  45. odxtools/compumethods/tabintpcompumethod.py +10 -13
  46. odxtools/compumethods/texttablecompumethod.py +6 -6
  47. odxtools/createanycomparam.py +5 -7
  48. odxtools/createanydiagcodedtype.py +7 -8
  49. odxtools/database.py +34 -31
  50. odxtools/dataobjectproperty.py +19 -20
  51. odxtools/decodestate.py +5 -5
  52. odxtools/description.py +9 -9
  53. odxtools/determinenumberofitems.py +8 -7
  54. odxtools/diagcodedtype.py +10 -10
  55. odxtools/diagcomm.py +29 -30
  56. odxtools/diagdatadictionaryspec.py +36 -36
  57. odxtools/diaglayercontainer.py +35 -34
  58. odxtools/diaglayers/basevariant.py +14 -12
  59. odxtools/diaglayers/basevariantraw.py +22 -23
  60. odxtools/diaglayers/diaglayer.py +24 -22
  61. odxtools/diaglayers/diaglayerraw.py +43 -52
  62. odxtools/diaglayers/diaglayertype.py +1 -2
  63. odxtools/diaglayers/ecushareddata.py +9 -9
  64. odxtools/diaglayers/ecushareddataraw.py +15 -16
  65. odxtools/diaglayers/ecuvariant.py +15 -13
  66. odxtools/diaglayers/ecuvariantraw.py +21 -22
  67. odxtools/diaglayers/functionalgroup.py +12 -11
  68. odxtools/diaglayers/functionalgroupraw.py +17 -18
  69. odxtools/diaglayers/hierarchyelement.py +48 -54
  70. odxtools/diaglayers/hierarchyelementraw.py +10 -11
  71. odxtools/diaglayers/protocol.py +7 -7
  72. odxtools/diaglayers/protocolraw.py +13 -14
  73. odxtools/diagnostictroublecode.py +15 -17
  74. odxtools/diagservice.py +28 -27
  75. odxtools/diagvariable.py +24 -25
  76. odxtools/docrevision.py +18 -17
  77. odxtools/dopbase.py +13 -14
  78. odxtools/dtcconnector.py +8 -7
  79. odxtools/dtcdop.py +24 -20
  80. odxtools/dynamicendmarkerfield.py +10 -9
  81. odxtools/dynamiclengthfield.py +10 -9
  82. odxtools/dyndefinedspec.py +10 -10
  83. odxtools/dynenddopref.py +9 -9
  84. odxtools/dyniddefmodeinfo.py +21 -21
  85. odxtools/ecuvariantpattern.py +8 -10
  86. odxtools/element.py +12 -13
  87. odxtools/encodestate.py +11 -11
  88. odxtools/encoding.py +2 -3
  89. odxtools/endofpdufield.py +9 -10
  90. odxtools/envdataconnector.py +8 -8
  91. odxtools/environmentdata.py +7 -9
  92. odxtools/environmentdatadescription.py +18 -17
  93. odxtools/exceptions.py +5 -5
  94. odxtools/externalaccessmethod.py +4 -6
  95. odxtools/externaldoc.py +6 -6
  96. odxtools/field.py +15 -15
  97. odxtools/functionalclass.py +9 -9
  98. odxtools/inputparam.py +11 -10
  99. odxtools/internalconstr.py +10 -11
  100. odxtools/isotp_state_machine.py +12 -11
  101. odxtools/leadinglengthinfotype.py +4 -6
  102. odxtools/library.py +9 -8
  103. odxtools/linkeddtcdop.py +9 -8
  104. odxtools/loadfile.py +5 -6
  105. odxtools/matchingbasevariantparameter.py +5 -6
  106. odxtools/matchingparameter.py +10 -10
  107. odxtools/message.py +1 -1
  108. odxtools/minmaxlengthtype.py +6 -7
  109. odxtools/modification.py +7 -6
  110. odxtools/multiplexer.py +54 -18
  111. odxtools/multiplexercase.py +13 -13
  112. odxtools/multiplexerdefaultcase.py +11 -10
  113. odxtools/multiplexerswitchkey.py +8 -8
  114. odxtools/nameditemlist.py +13 -13
  115. odxtools/negoutputparam.py +8 -8
  116. odxtools/obd.py +1 -2
  117. odxtools/odxcategory.py +14 -26
  118. odxtools/odxdoccontext.py +16 -0
  119. odxtools/odxlink.py +23 -25
  120. odxtools/odxtypes.py +18 -15
  121. odxtools/outputparam.py +9 -8
  122. odxtools/parameterinfo.py +1 -1
  123. odxtools/parameters/codedconstparameter.py +10 -10
  124. odxtools/parameters/createanyparameter.py +15 -16
  125. odxtools/parameters/dynamicparameter.py +5 -7
  126. odxtools/parameters/lengthkeyparameter.py +10 -10
  127. odxtools/parameters/matchingrequestparameter.py +6 -7
  128. odxtools/parameters/nrcconstparameter.py +13 -13
  129. odxtools/parameters/parameter.py +17 -18
  130. odxtools/parameters/parameterwithdop.py +13 -13
  131. odxtools/parameters/physicalconstantparameter.py +8 -7
  132. odxtools/parameters/reservedparameter.py +6 -8
  133. odxtools/parameters/systemparameter.py +5 -7
  134. odxtools/parameters/tableentryparameter.py +8 -8
  135. odxtools/parameters/tablekeyparameter.py +17 -17
  136. odxtools/parameters/tablestructparameter.py +11 -11
  137. odxtools/parameters/valueparameter.py +11 -11
  138. odxtools/paramlengthinfotype.py +10 -9
  139. odxtools/parentref.py +15 -13
  140. odxtools/physicaldimension.py +15 -15
  141. odxtools/physicaltype.py +5 -6
  142. odxtools/posresponsesuppressible.py +11 -12
  143. odxtools/preconditionstateref.py +11 -11
  144. odxtools/progcode.py +11 -10
  145. odxtools/protstack.py +10 -9
  146. odxtools/relateddiagcommref.py +5 -6
  147. odxtools/relateddoc.py +11 -10
  148. odxtools/request.py +18 -19
  149. odxtools/response.py +19 -20
  150. odxtools/scaleconstr.py +8 -9
  151. odxtools/servicebinner.py +5 -5
  152. odxtools/singleecujob.py +16 -15
  153. odxtools/snrefcontext.py +3 -3
  154. odxtools/specialdata.py +8 -7
  155. odxtools/specialdatagroup.py +17 -17
  156. odxtools/specialdatagroupcaption.py +7 -6
  157. odxtools/standardlengthtype.py +14 -22
  158. odxtools/state.py +7 -6
  159. odxtools/statechart.py +12 -11
  160. odxtools/statemachine.py +4 -3
  161. odxtools/statetransition.py +9 -9
  162. odxtools/statetransitionref.py +19 -19
  163. odxtools/staticfield.py +9 -7
  164. odxtools/structure.py +5 -6
  165. odxtools/subcomponent.py +20 -18
  166. odxtools/subcomponentparamconnector.py +10 -9
  167. odxtools/subcomponentpattern.py +9 -9
  168. odxtools/swvariable.py +6 -7
  169. odxtools/table.py +25 -26
  170. odxtools/tablediagcommconnector.py +9 -8
  171. odxtools/tablerow.py +64 -43
  172. odxtools/tablerowconnector.py +8 -8
  173. odxtools/teammember.py +16 -15
  174. odxtools/templates/macros/printParentRef.xml.jinja2 +3 -1
  175. odxtools/text.py +4 -5
  176. odxtools/uds.py +2 -3
  177. odxtools/unit.py +14 -13
  178. odxtools/unitgroup.py +11 -10
  179. odxtools/unitspec.py +18 -19
  180. odxtools/utils.py +3 -3
  181. odxtools/variablegroup.py +5 -6
  182. odxtools/variantmatcher.py +10 -10
  183. odxtools/variantpattern.py +5 -6
  184. odxtools/version.py +2 -2
  185. odxtools/writepdxfile.py +5 -24
  186. odxtools/xdoc.py +13 -12
  187. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/METADATA +4 -5
  188. odxtools-10.1.0.dist-info/RECORD +265 -0
  189. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/WHEEL +1 -1
  190. odxtools-9.7.0.dist-info/RECORD +0 -264
  191. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/entry_points.txt +0 -0
  192. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/licenses/LICENSE +0 -0
  193. {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
- from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, Any, Dict, List, Optional
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 .comparam import Comparam
@@ -8,7 +8,8 @@ from .complexcomparam import ComplexComparam
8
8
  from .dataobjectproperty import DataObjectProperty
9
9
  from .nameditemlist import NamedItemList
10
10
  from .odxcategory import OdxCategory
11
- from .odxlink import DocType, OdxDocFragment, OdxLinkDatabase, OdxLinkId
11
+ from .odxdoccontext import OdxDocContext
12
+ from .odxlink import OdxLinkDatabase, OdxLinkId
12
13
  from .snrefcontext import SnRefContext
13
14
  from .unitspec import UnitSpec
14
15
  from .utils import dataclass_fields_asdict
@@ -17,44 +18,35 @@ if TYPE_CHECKING:
17
18
  from .database import Database
18
19
 
19
20
 
20
- @dataclass
21
+ @dataclass(kw_only=True)
21
22
  class ComparamSubset(OdxCategory):
22
- comparams: NamedItemList[Comparam]
23
- complex_comparams: NamedItemList[ComplexComparam]
24
- data_object_props: NamedItemList[DataObjectProperty]
25
- unit_spec: Optional[UnitSpec]
26
- category: Optional[str] # mandatory in ODX 2.2, but non-existent in ODX 2.0
23
+ comparams: NamedItemList[Comparam] = field(default_factory=NamedItemList)
24
+ complex_comparams: NamedItemList[ComplexComparam] = field(default_factory=NamedItemList)
25
+ data_object_props: NamedItemList[DataObjectProperty] = field(default_factory=NamedItemList)
26
+ unit_spec: UnitSpec | None = None
27
+ category: str | None # mandatory in ODX 2.2, but non-existent in ODX 2.0
27
28
 
28
29
  @staticmethod
29
- def from_et(et_element: ElementTree.Element,
30
- doc_frags: List[OdxDocFragment]) -> "ComparamSubset":
30
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ComparamSubset":
31
31
 
32
32
  category_attrib = et_element.attrib.get("CATEGORY")
33
33
 
34
- # In ODX 2.0, COMPARAM-SPEC is used, whereas in ODX 2.2, it
35
- # refers to something else and has been replaced by
36
- # COMPARAM-SUBSET.
37
- # - If the 'CATEGORY' attribute is missing (ODX 2.0), use
38
- # COMPARAM_SPEC,
39
- # - else (ODX 2.2), use COMPARAM_SUBSET.
40
- doc_type = DocType.COMPARAM_SUBSET if category_attrib is not None else DocType.COMPARAM_SPEC
41
- base_obj = OdxCategory.category_from_et(et_element, doc_frags, doc_type=doc_type)
42
- doc_frags = base_obj.odx_id.doc_fragments
34
+ base_obj = OdxCategory.from_et(et_element, context)
43
35
  kwargs = dataclass_fields_asdict(base_obj)
44
36
 
45
37
  comparams = NamedItemList(
46
- [Comparam.from_et(el, doc_frags) for el in et_element.iterfind("COMPARAMS/COMPARAM")])
38
+ [Comparam.from_et(el, context) for el in et_element.iterfind("COMPARAMS/COMPARAM")])
47
39
  complex_comparams = NamedItemList([
48
- ComplexComparam.from_et(el, doc_frags)
40
+ ComplexComparam.from_et(el, context)
49
41
  for el in et_element.iterfind("COMPLEX-COMPARAMS/COMPLEX-COMPARAM")
50
42
  ])
51
43
  data_object_props = NamedItemList([
52
- DataObjectProperty.from_et(el, doc_frags)
44
+ DataObjectProperty.from_et(el, context)
53
45
  for el in et_element.iterfind("DATA-OBJECT-PROPS/DATA-OBJECT-PROP")
54
46
  ])
55
47
  unit_spec = None
56
48
  if (unit_spec_elem := et_element.find("UNIT-SPEC")) is not None:
57
- unit_spec = UnitSpec.from_et(unit_spec_elem, doc_frags)
49
+ unit_spec = UnitSpec.from_et(unit_spec_elem, context)
58
50
 
59
51
  return ComparamSubset(
60
52
  category=category_attrib,
@@ -64,7 +56,7 @@ class ComparamSubset(OdxCategory):
64
56
  unit_spec=unit_spec,
65
57
  **kwargs)
66
58
 
67
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
59
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
68
60
  odxlinks = super()._build_odxlinks()
69
61
 
70
62
  for comparam in self.comparams:
@@ -1,16 +1,17 @@
1
1
  # SPDX-License-Identifier: MIT
2
- from dataclasses import dataclass
3
- from typing import Any, Dict, List, Optional, Union
2
+ from dataclasses import dataclass, field
3
+ from typing import Any, Union
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .basecomparam import BaseComparam
7
7
  from .nameditemlist import NamedItemList
8
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
8
+ from .odxdoccontext import OdxDocContext
9
+ from .odxlink import OdxLinkDatabase, OdxLinkId
9
10
  from .odxtypes import odxstr_to_bool
10
11
  from .snrefcontext import SnRefContext
11
12
  from .utils import dataclass_fields_asdict
12
13
 
13
- ComplexValue = List[Union[str, "ComplexValue"]]
14
+ ComplexValue = list[Union[str, "ComplexValue"]]
14
15
 
15
16
 
16
17
  def create_complex_value_from_et(et_element: ElementTree.Element) -> ComplexValue:
@@ -23,20 +24,19 @@ def create_complex_value_from_et(et_element: ElementTree.Element) -> ComplexValu
23
24
  return result
24
25
 
25
26
 
26
- @dataclass
27
+ @dataclass(kw_only=True)
27
28
  class ComplexComparam(BaseComparam):
28
- subparams: NamedItemList[BaseComparam]
29
- physical_default_value: Optional[ComplexValue]
30
- allow_multiple_values_raw: Optional[bool]
29
+ subparams: NamedItemList[BaseComparam] = field(default_factory=NamedItemList)
30
+ physical_default_value: ComplexValue | None = None
31
+ allow_multiple_values_raw: bool | None = None
31
32
 
32
33
  @property
33
34
  def allow_multiple_values(self) -> bool:
34
35
  return self.allow_multiple_values_raw is True
35
36
 
36
37
  @staticmethod
37
- def from_et(et_element: ElementTree.Element,
38
- doc_frags: List[OdxDocFragment]) -> "ComplexComparam":
39
- kwargs = dataclass_fields_asdict(BaseComparam.from_et(et_element, doc_frags))
38
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ComplexComparam":
39
+ kwargs = dataclass_fields_asdict(BaseComparam.from_et(et_element, context))
40
40
 
41
41
  # to avoid a cyclic import, create_any_comparam_from_et cannot
42
42
  # be imported globally. TODO: figure out if this has
@@ -61,14 +61,14 @@ class ComplexComparam(BaseComparam):
61
61
  if elems[i].tag not in ("COMPARAM", "COMPLEX-COMPARAM"):
62
62
  break
63
63
 
64
- subparam = create_any_comparam_from_et(elems[i], doc_frags)
64
+ subparam = create_any_comparam_from_et(elems[i], context)
65
65
  subparams.append(subparam)
66
66
  i += 1
67
67
 
68
68
  # extract the complex physical default value. (what's the
69
69
  # purpose of this? the sub-parameters can define their own
70
70
  # default values if a default is desired...)
71
- complex_physical_default_value: Optional[ComplexValue] = None
71
+ complex_physical_default_value: ComplexValue | None = None
72
72
  if (cpdv_elem := et_element.find("COMPLEX-PHYSICAL-DEFAULT-VALUE")) is not None:
73
73
  complex_physical_default_value = create_complex_value_from_et(cpdv_elem)
74
74
 
@@ -80,7 +80,7 @@ class ComplexComparam(BaseComparam):
80
80
  allow_multiple_values_raw=allow_multiple_values_raw,
81
81
  **kwargs)
82
82
 
83
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
83
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
84
84
  odxlinks = super()._build_odxlinks()
85
85
  for subparam in self.subparams:
86
86
  odxlinks.update(subparam._build_odxlinks())
odxtools/complexdop.py CHANGED
@@ -4,7 +4,7 @@ from dataclasses import dataclass
4
4
  from .dopbase import DopBase
5
5
 
6
6
 
7
- @dataclass
7
+ @dataclass(kw_only=True)
8
8
  class ComplexDop(DopBase):
9
9
  """Base class for all complex data object properties.
10
10
 
@@ -1,6 +1,6 @@
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 .codec import Codec
6
6
  from .decodestate import DecodeState
@@ -22,20 +22,20 @@ class CompositeCodec(Codec, typing.Protocol):
22
22
  """
23
23
 
24
24
  @property
25
- def parameters(self) -> List[Parameter]:
25
+ def parameters(self) -> list[Parameter]:
26
26
  return []
27
27
 
28
28
  @property
29
- def required_parameters(self) -> List[Parameter]:
29
+ def required_parameters(self) -> list[Parameter]:
30
30
  return []
31
31
 
32
32
  @property
33
- def free_parameters(self) -> List[Parameter]:
33
+ def free_parameters(self) -> list[Parameter]:
34
34
  return []
35
35
 
36
36
 
37
37
  # some helper functions useful for composite codec objects
38
- def composite_codec_get_static_bit_length(codec: CompositeCodec) -> Optional[int]:
38
+ def composite_codec_get_static_bit_length(codec: CompositeCodec) -> int | None:
39
39
  """Compute the length of a composite codec object in bits
40
40
 
41
41
  This is basically the sum of the lengths of all parameters. If the
@@ -59,7 +59,7 @@ def composite_codec_get_static_bit_length(codec: CompositeCodec) -> Optional[int
59
59
  return byte_length * 8
60
60
 
61
61
 
62
- def composite_codec_get_required_parameters(codec: CompositeCodec) -> List[Parameter]:
62
+ def composite_codec_get_required_parameters(codec: CompositeCodec) -> list[Parameter]:
63
63
  """Return the list of parameters which are required to be
64
64
  specified for encoding the composite codec object
65
65
 
@@ -68,7 +68,7 @@ def composite_codec_get_required_parameters(codec: CompositeCodec) -> List[Param
68
68
  return [p for p in codec.parameters if p.is_required]
69
69
 
70
70
 
71
- def composite_codec_get_free_parameters(codec: CompositeCodec) -> List[Parameter]:
71
+ def composite_codec_get_free_parameters(codec: CompositeCodec) -> list[Parameter]:
72
72
  """Return the list of parameters which can be freely specified by
73
73
  the user when encoding the composite codec object
74
74
 
@@ -92,7 +92,7 @@ def composite_codec_get_coded_const_prefix(codec: CompositeCodec,
92
92
  return encode_state.coded_message
93
93
 
94
94
 
95
- def composite_codec_encode_into_pdu(codec: CompositeCodec, physical_value: Optional[ParameterValue],
95
+ def composite_codec_encode_into_pdu(codec: CompositeCodec, physical_value: ParameterValue | None,
96
96
  encode_state: EncodeState) -> None:
97
97
  from .parameters.lengthkeyparameter import LengthKeyParameter
98
98
  from .parameters.tablekeyparameter import TableKeyParameter
@@ -1,10 +1,10 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import List, Optional, cast
3
+ from typing import cast
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from ..exceptions import DecodeError, EncodeError, odxassert, odxraise
7
- from ..odxlink import OdxDocFragment
7
+ from ..odxdoccontext import OdxDocContext
8
8
  from ..odxtypes import AtomicOdxType, DataType
9
9
  from ..progcode import ProgCode
10
10
  from ..utils import dataclass_fields_asdict
@@ -12,7 +12,7 @@ from .compucategory import CompuCategory
12
12
  from .compumethod import CompuMethod
13
13
 
14
14
 
15
- @dataclass
15
+ @dataclass(kw_only=True)
16
16
  class CompuCodeCompuMethod(CompuMethod):
17
17
  """A compu method specifies the tranfer functions using Java bytecode
18
18
 
@@ -20,25 +20,25 @@ class CompuCodeCompuMethod(CompuMethod):
20
20
  """
21
21
 
22
22
  @property
23
- def internal_to_phys_code(self) -> Optional[ProgCode]:
23
+ def internal_to_phys_code(self) -> ProgCode | None:
24
24
  if self.compu_internal_to_phys is None:
25
25
  return None
26
26
 
27
27
  return self.compu_internal_to_phys.prog_code
28
28
 
29
29
  @property
30
- def phys_to_internal_code(self) -> Optional[ProgCode]:
30
+ def phys_to_internal_code(self) -> ProgCode | None:
31
31
  if self.compu_phys_to_internal is None:
32
32
  return None
33
33
 
34
34
  return self.compu_phys_to_internal.prog_code
35
35
 
36
36
  @staticmethod
37
- def compu_method_from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment], *,
37
+ def compu_method_from_et(et_element: ElementTree.Element, context: OdxDocContext, *,
38
38
  internal_type: DataType,
39
39
  physical_type: DataType) -> "CompuCodeCompuMethod":
40
40
  cm = CompuMethod.compu_method_from_et(
41
- et_element, doc_frags, internal_type=internal_type, physical_type=physical_type)
41
+ et_element, context, internal_type=internal_type, physical_type=physical_type)
42
42
  kwargs = dataclass_fields_asdict(cm)
43
43
 
44
44
  return CompuCodeCompuMethod(**kwargs)
@@ -1,20 +1,19 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Optional
4
3
  from xml.etree import ElementTree
5
4
 
6
5
  from ..odxtypes import AtomicOdxType, DataType
7
6
 
8
7
 
9
- @dataclass
8
+ @dataclass(kw_only=True)
10
9
  class CompuConst:
11
- v: Optional[str]
12
- vt: Optional[str]
10
+ v: str | None = None
11
+ vt: str | None = None
13
12
 
14
13
  data_type: DataType
15
14
 
16
15
  @property
17
- def value(self) -> Optional[AtomicOdxType]:
16
+ def value(self) -> AtomicOdxType | None:
18
17
  return self._value
19
18
 
20
19
  @staticmethod
@@ -26,6 +25,6 @@ class CompuConst:
26
25
  return CompuConst(v=v, vt=vt, data_type=data_type)
27
26
 
28
27
  def __post_init__(self) -> None:
29
- self._value: Optional[AtomicOdxType] = self.vt
28
+ self._value: AtomicOdxType | None = self.vt
30
29
  if self.v is not None:
31
30
  self._value = self.data_type.from_string(self.v)
@@ -1,6 +1,5 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Optional
4
3
  from xml.etree import ElementTree
5
4
 
6
5
  from ..odxtypes import DataType
@@ -9,9 +8,9 @@ from .compuconst import CompuConst
9
8
  from .compuinversevalue import CompuInverseValue
10
9
 
11
10
 
12
- @dataclass
11
+ @dataclass(kw_only=True)
13
12
  class CompuDefaultValue(CompuConst):
14
- compu_inverse_value: Optional[CompuInverseValue]
13
+ compu_inverse_value: CompuInverseValue | None = None
15
14
 
16
15
  @staticmethod
17
16
  def compuvalue_from_et(et_element: ElementTree.Element, *,
@@ -1,9 +1,10 @@
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
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
6
+ from ..odxdoccontext import OdxDocContext
7
+ from ..odxlink import OdxLinkDatabase, OdxLinkId
7
8
  from ..odxtypes import DataType
8
9
  from ..progcode import ProgCode
9
10
  from ..snrefcontext import SnRefContext
@@ -11,25 +12,25 @@ from .compudefaultvalue import CompuDefaultValue
11
12
  from .compuscale import CompuScale
12
13
 
13
14
 
14
- @dataclass
15
+ @dataclass(kw_only=True)
15
16
  class CompuInternalToPhys:
16
- compu_scales: List[CompuScale]
17
- prog_code: Optional[ProgCode]
18
- compu_default_value: Optional[CompuDefaultValue]
17
+ compu_scales: list[CompuScale] = field(default_factory=list)
18
+ prog_code: ProgCode | None = None
19
+ compu_default_value: CompuDefaultValue | None = None
19
20
 
20
21
  @staticmethod
21
- def compu_internal_to_phys_from_et(et_element: ElementTree.Element,
22
- doc_frags: List[OdxDocFragment], *, internal_type: DataType,
22
+ def compu_internal_to_phys_from_et(et_element: ElementTree.Element, context: OdxDocContext, *,
23
+ internal_type: DataType,
23
24
  physical_type: DataType) -> "CompuInternalToPhys":
24
25
  compu_scales = [
25
26
  CompuScale.compuscale_from_et(
26
- cse, doc_frags, domain_type=internal_type, range_type=physical_type)
27
+ cse, context, domain_type=internal_type, range_type=physical_type)
27
28
  for cse in et_element.iterfind("COMPU-SCALES/COMPU-SCALE")
28
29
  ]
29
30
 
30
31
  prog_code = None
31
32
  if (pce := et_element.find("PROG-CODE")) is not None:
32
- prog_code = ProgCode.from_et(pce, doc_frags)
33
+ prog_code = ProgCode.from_et(pce, context)
33
34
 
34
35
  compu_default_value = None
35
36
  if (cdve := et_element.find("COMPU-DEFAULT-VALUE")) is not None:
@@ -39,7 +40,7 @@ class CompuInternalToPhys:
39
40
  return CompuInternalToPhys(
40
41
  compu_scales=compu_scales, prog_code=prog_code, compu_default_value=compu_default_value)
41
42
 
42
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
43
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
43
44
  result = {}
44
45
 
45
46
  if self.prog_code is not None:
@@ -1,10 +1,11 @@
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 ..exceptions import odxraise
7
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
7
+ from ..odxdoccontext import OdxDocContext
8
+ from ..odxlink import OdxLinkDatabase, OdxLinkId
8
9
  from ..odxtypes import AtomicOdxType, DataType
9
10
  from ..snrefcontext import SnRefContext
10
11
  from .compucategory import CompuCategory
@@ -12,7 +13,7 @@ from .compuinternaltophys import CompuInternalToPhys
12
13
  from .compuphystointernal import CompuPhysToInternal
13
14
 
14
15
 
15
- @dataclass
16
+ @dataclass(kw_only=True)
16
17
  class CompuMethod:
17
18
  """A compu method translates between the internal representation
18
19
  of a value and their physical representation.
@@ -31,14 +32,14 @@ class CompuMethod:
31
32
  """
32
33
 
33
34
  category: CompuCategory
34
- compu_internal_to_phys: Optional[CompuInternalToPhys]
35
- compu_phys_to_internal: Optional[CompuPhysToInternal]
35
+ compu_internal_to_phys: CompuInternalToPhys | None = None
36
+ compu_phys_to_internal: CompuPhysToInternal | None = None
36
37
 
37
38
  physical_type: DataType
38
39
  internal_type: DataType
39
40
 
40
41
  @staticmethod
41
- def compu_method_from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment], *,
42
+ def compu_method_from_et(et_element: ElementTree.Element, context: OdxDocContext, *,
42
43
  internal_type: DataType, physical_type: DataType) -> "CompuMethod":
43
44
  cat_text = et_element.findtext("CATEGORY")
44
45
  if cat_text is None:
@@ -54,11 +55,11 @@ class CompuMethod:
54
55
  compu_internal_to_phys = None
55
56
  if (citp_elem := et_element.find("COMPU-INTERNAL-TO-PHYS")) is not None:
56
57
  compu_internal_to_phys = CompuInternalToPhys.compu_internal_to_phys_from_et(
57
- citp_elem, doc_frags, internal_type=internal_type, physical_type=physical_type)
58
+ citp_elem, context, internal_type=internal_type, physical_type=physical_type)
58
59
  compu_phys_to_internal = None
59
60
  if (cpti_elem := et_element.find("COMPU-PHYS-TO-INTERNAL")) is not None:
60
61
  compu_phys_to_internal = CompuPhysToInternal.compu_phys_to_internal_from_et(
61
- cpti_elem, doc_frags, internal_type=internal_type, physical_type=physical_type)
62
+ cpti_elem, context, internal_type=internal_type, physical_type=physical_type)
62
63
 
63
64
  return CompuMethod(
64
65
  category=category,
@@ -67,7 +68,7 @@ class CompuMethod:
67
68
  physical_type=physical_type,
68
69
  internal_type=internal_type)
69
70
 
70
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
71
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
71
72
  result = {}
72
73
 
73
74
  if self.compu_internal_to_phys is not None:
@@ -1,9 +1,10 @@
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
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
6
+ from ..odxdoccontext import OdxDocContext
7
+ from ..odxlink import OdxLinkDatabase, OdxLinkId
7
8
  from ..odxtypes import DataType
8
9
  from ..progcode import ProgCode
9
10
  from ..snrefcontext import SnRefContext
@@ -11,25 +12,25 @@ from .compudefaultvalue import CompuDefaultValue
11
12
  from .compuscale import CompuScale
12
13
 
13
14
 
14
- @dataclass
15
+ @dataclass(kw_only=True)
15
16
  class CompuPhysToInternal:
16
- compu_scales: List[CompuScale]
17
- prog_code: Optional[ProgCode]
18
- compu_default_value: Optional[CompuDefaultValue]
17
+ compu_scales: list[CompuScale] = field(default_factory=list)
18
+ prog_code: ProgCode | None = None
19
+ compu_default_value: CompuDefaultValue | None = None
19
20
 
20
21
  @staticmethod
21
- def compu_phys_to_internal_from_et(et_element: ElementTree.Element,
22
- doc_frags: List[OdxDocFragment], *, internal_type: DataType,
22
+ def compu_phys_to_internal_from_et(et_element: ElementTree.Element, context: OdxDocContext, *,
23
+ internal_type: DataType,
23
24
  physical_type: DataType) -> "CompuPhysToInternal":
24
25
  compu_scales = [
25
26
  CompuScale.compuscale_from_et(
26
- cse, doc_frags, domain_type=physical_type, range_type=internal_type)
27
+ cse, context, domain_type=physical_type, range_type=internal_type)
27
28
  for cse in et_element.iterfind("COMPU-SCALES/COMPU-SCALE")
28
29
  ]
29
30
 
30
31
  prog_code = None
31
32
  if (pce := et_element.find("PROG-CODE")) is not None:
32
- prog_code = ProgCode.from_et(pce, doc_frags)
33
+ prog_code = ProgCode.from_et(pce, context)
33
34
 
34
35
  compu_default_value = None
35
36
  if (cdve := et_element.find("COMPU-DEFAULT-VALUE")) is not None:
@@ -39,7 +40,7 @@ class CompuPhysToInternal:
39
40
  return CompuPhysToInternal(
40
41
  compu_scales=compu_scales, prog_code=prog_code, compu_default_value=compu_default_value)
41
42
 
42
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
43
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
43
44
  result = {}
44
45
 
45
46
  if self.prog_code is not None:
@@ -1,22 +1,22 @@
1
1
  # SPDX-License-Identifier: MIT
2
- from dataclasses import dataclass
3
- from typing import List, Union, cast
2
+ from dataclasses import dataclass, field
3
+ from typing import cast
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from ..exceptions import odxassert, odxrequire
7
- from ..odxlink import OdxDocFragment
7
+ from ..odxdoccontext import OdxDocContext
8
8
  from ..odxtypes import DataType
9
9
 
10
10
 
11
- @dataclass
11
+ @dataclass(kw_only=True)
12
12
  class CompuRationalCoeffs:
13
13
  value_type: DataType
14
14
 
15
- numerators: List[Union[int, float]]
16
- denominators: List[Union[int, float]]
15
+ numerators: list[int | float] = field(default_factory=list)
16
+ denominators: list[int | float] = field(default_factory=list)
17
17
 
18
18
  @staticmethod
19
- def coeffs_from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment], *,
19
+ def coeffs_from_et(et_element: ElementTree.Element, context: OdxDocContext, *,
20
20
  value_type: DataType) -> "CompuRationalCoeffs":
21
21
  odxassert(
22
22
  value_type
@@ -1,10 +1,9 @@
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 ..description import Description
7
- from ..odxlink import OdxDocFragment
6
+ from ..odxdoccontext import OdxDocContext
8
7
  from ..odxtypes import AtomicOdxType, DataType
9
8
  from .compuconst import CompuConst
10
9
  from .compuinversevalue import CompuInverseValue
@@ -12,18 +11,18 @@ from .compurationalcoeffs import CompuRationalCoeffs
12
11
  from .limit import Limit
13
12
 
14
13
 
15
- @dataclass
14
+ @dataclass(kw_only=True)
16
15
  class CompuScale:
17
16
  """A COMPU-SCALE represents one value range of a COMPU-METHOD.
18
17
  """
19
18
 
20
- short_label: Optional[str]
21
- description: Optional[Description]
22
- lower_limit: Optional[Limit]
23
- upper_limit: Optional[Limit]
24
- compu_inverse_value: Optional[CompuInverseValue]
25
- compu_const: Optional[CompuConst]
26
- compu_rational_coeffs: Optional[CompuRationalCoeffs]
19
+ short_label: str | None = None
20
+ description: Description | None = None
21
+ lower_limit: Limit | None = None
22
+ upper_limit: Limit | None = None
23
+ compu_inverse_value: CompuInverseValue | None = None
24
+ compu_const: CompuConst | None = None
25
+ compu_rational_coeffs: CompuRationalCoeffs | None = None
27
26
 
28
27
  # the following two attributes are not specified for COMPU-SCALE
29
28
  # tags in the XML, but they are required to do anything useful
@@ -38,15 +37,15 @@ class CompuScale:
38
37
  range_type: DataType
39
38
 
40
39
  @staticmethod
41
- def compuscale_from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment], *,
40
+ def compuscale_from_et(et_element: ElementTree.Element, context: OdxDocContext, *,
42
41
  domain_type: DataType, range_type: DataType) -> "CompuScale":
43
42
  short_label = et_element.findtext("SHORT-LABEL")
44
- description = Description.from_et(et_element.find("DESC"), doc_frags)
43
+ description = Description.from_et(et_element.find("DESC"), context)
45
44
 
46
45
  lower_limit = Limit.limit_from_et(
47
- et_element.find("LOWER-LIMIT"), doc_frags, value_type=domain_type)
46
+ et_element.find("LOWER-LIMIT"), context, value_type=domain_type)
48
47
  upper_limit = Limit.limit_from_et(
49
- et_element.find("UPPER-LIMIT"), doc_frags, value_type=domain_type)
48
+ et_element.find("UPPER-LIMIT"), context, value_type=domain_type)
50
49
 
51
50
  compu_inverse_value = None
52
51
  if (cive := et_element.find("COMPU-INVERSE-VALUE")) is not None:
@@ -56,10 +55,10 @@ class CompuScale:
56
55
  if (cce := et_element.find("COMPU-CONST")) is not None:
57
56
  compu_const = CompuConst.compuvalue_from_et(cce, data_type=range_type)
58
57
 
59
- compu_rational_coeffs: Optional[CompuRationalCoeffs] = None
58
+ compu_rational_coeffs: CompuRationalCoeffs | None = None
60
59
  if (crc_elem := et_element.find("COMPU-RATIONAL-COEFFS")) is not None:
61
60
  compu_rational_coeffs = CompuRationalCoeffs.coeffs_from_et(
62
- crc_elem, doc_frags, value_type=range_type)
61
+ crc_elem, context, value_type=range_type)
63
62
 
64
63
  return CompuScale(
65
64
  short_label=short_label,