odxtools 10.0.0__py3-none-any.whl → 10.1.1__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 (175) hide show
  1. odxtools/additionalaudience.py +5 -5
  2. odxtools/admindata.py +10 -9
  3. odxtools/audience.py +15 -15
  4. odxtools/basecomparam.py +7 -6
  5. odxtools/basevariantpattern.py +7 -7
  6. odxtools/basicstructure.py +9 -9
  7. odxtools/cli/_print_utils.py +1 -1
  8. odxtools/cli/browse.py +1 -1
  9. odxtools/cli/compare.py +143 -170
  10. odxtools/cli/list.py +1 -1
  11. odxtools/commrelation.py +14 -13
  12. odxtools/companydata.py +11 -11
  13. odxtools/companydocinfo.py +11 -13
  14. odxtools/companyrevisioninfo.py +7 -7
  15. odxtools/companyspecificinfo.py +9 -11
  16. odxtools/comparam.py +6 -5
  17. odxtools/comparaminstance.py +10 -10
  18. odxtools/comparamspec.py +8 -9
  19. odxtools/comparamsubset.py +14 -22
  20. odxtools/complexcomparam.py +10 -10
  21. odxtools/complexdop.py +1 -1
  22. odxtools/compositecodec.py +3 -3
  23. odxtools/compumethods/compucodecompumethod.py +4 -4
  24. odxtools/compumethods/compuconst.py +3 -3
  25. odxtools/compumethods/compudefaultvalue.py +2 -2
  26. odxtools/compumethods/compuinternaltophys.py +11 -10
  27. odxtools/compumethods/compumethod.py +8 -7
  28. odxtools/compumethods/compuphystointernal.py +11 -10
  29. odxtools/compumethods/compurationalcoeffs.py +6 -6
  30. odxtools/compumethods/compuscale.py +14 -14
  31. odxtools/compumethods/createanycompumethod.py +12 -12
  32. odxtools/compumethods/identicalcompumethod.py +4 -4
  33. odxtools/compumethods/limit.py +8 -8
  34. odxtools/compumethods/linearcompumethod.py +4 -4
  35. odxtools/compumethods/linearsegment.py +8 -8
  36. odxtools/compumethods/ratfunccompumethod.py +4 -4
  37. odxtools/compumethods/ratfuncsegment.py +8 -8
  38. odxtools/compumethods/scalelinearcompumethod.py +5 -5
  39. odxtools/compumethods/scaleratfunccompumethod.py +4 -4
  40. odxtools/compumethods/tabintpcompumethod.py +12 -12
  41. odxtools/compumethods/texttablecompumethod.py +4 -4
  42. odxtools/createanycomparam.py +4 -4
  43. odxtools/createanydiagcodedtype.py +7 -7
  44. odxtools/database.py +28 -26
  45. odxtools/dataobjectproperty.py +15 -16
  46. odxtools/description.py +7 -7
  47. odxtools/determinenumberofitems.py +6 -5
  48. odxtools/diagcodedtype.py +6 -6
  49. odxtools/diagcomm.py +26 -27
  50. odxtools/diagdatadictionaryspec.py +34 -34
  51. odxtools/diaglayercontainer.py +32 -31
  52. odxtools/diaglayers/basevariant.py +5 -4
  53. odxtools/diaglayers/basevariantraw.py +18 -19
  54. odxtools/diaglayers/diaglayer.py +5 -4
  55. odxtools/diaglayers/diaglayerraw.py +39 -48
  56. odxtools/diaglayers/ecushareddata.py +6 -6
  57. odxtools/diaglayers/ecushareddataraw.py +11 -12
  58. odxtools/diaglayers/ecuvariant.py +5 -4
  59. odxtools/diaglayers/ecuvariantraw.py +17 -18
  60. odxtools/diaglayers/functionalgroup.py +5 -5
  61. odxtools/diaglayers/functionalgroupraw.py +13 -14
  62. odxtools/diaglayers/hierarchyelement.py +9 -9
  63. odxtools/diaglayers/hierarchyelementraw.py +8 -9
  64. odxtools/diaglayers/protocol.py +4 -4
  65. odxtools/diaglayers/protocolraw.py +10 -11
  66. odxtools/diagnostictroublecode.py +12 -14
  67. odxtools/diagservice.py +19 -18
  68. odxtools/diagvariable.py +19 -20
  69. odxtools/docrevision.py +14 -13
  70. odxtools/dopbase.py +10 -11
  71. odxtools/dtcconnector.py +6 -5
  72. odxtools/dtcdop.py +15 -15
  73. odxtools/dynamicendmarkerfield.py +6 -6
  74. odxtools/dynamiclengthfield.py +6 -6
  75. odxtools/dyndefinedspec.py +7 -7
  76. odxtools/dynenddopref.py +7 -7
  77. odxtools/dyniddefmodeinfo.py +17 -17
  78. odxtools/ecuvariantpattern.py +6 -7
  79. odxtools/element.py +12 -12
  80. odxtools/endofpdufield.py +6 -7
  81. odxtools/envdataconnector.py +6 -6
  82. odxtools/environmentdata.py +7 -8
  83. odxtools/environmentdatadescription.py +13 -12
  84. odxtools/externalaccessmethod.py +4 -5
  85. odxtools/externaldoc.py +4 -4
  86. odxtools/field.py +12 -11
  87. odxtools/functionalclass.py +7 -7
  88. odxtools/inputparam.py +9 -8
  89. odxtools/internalconstr.py +10 -10
  90. odxtools/leadinglengthinfotype.py +5 -6
  91. odxtools/library.py +7 -6
  92. odxtools/linkeddtcdop.py +7 -6
  93. odxtools/matchingbasevariantparameter.py +5 -5
  94. odxtools/matchingparameter.py +6 -6
  95. odxtools/message.py +1 -1
  96. odxtools/minmaxlengthtype.py +6 -7
  97. odxtools/modification.py +5 -4
  98. odxtools/multiplexer.py +48 -12
  99. odxtools/multiplexercase.py +10 -10
  100. odxtools/multiplexerdefaultcase.py +8 -7
  101. odxtools/multiplexerswitchkey.py +6 -6
  102. odxtools/nameditemlist.py +1 -1
  103. odxtools/negoutputparam.py +6 -6
  104. odxtools/odxcategory.py +12 -24
  105. odxtools/odxdoccontext.py +16 -0
  106. odxtools/odxlink.py +11 -12
  107. odxtools/odxtypes.py +3 -3
  108. odxtools/outputparam.py +7 -6
  109. odxtools/parameters/codedconstparameter.py +6 -6
  110. odxtools/parameters/createanyparameter.py +15 -15
  111. odxtools/parameters/dynamicparameter.py +4 -5
  112. odxtools/parameters/lengthkeyparameter.py +6 -6
  113. odxtools/parameters/matchingrequestparameter.py +4 -4
  114. odxtools/parameters/nrcconstparameter.py +8 -8
  115. odxtools/parameters/parameter.py +12 -13
  116. odxtools/parameters/parameterwithdop.py +9 -9
  117. odxtools/parameters/physicalconstantparameter.py +5 -4
  118. odxtools/parameters/reservedparameter.py +4 -5
  119. odxtools/parameters/systemparameter.py +4 -5
  120. odxtools/parameters/tableentryparameter.py +6 -6
  121. odxtools/parameters/tablekeyparameter.py +12 -12
  122. odxtools/parameters/tablestructparameter.py +9 -9
  123. odxtools/parameters/valueparameter.py +6 -6
  124. odxtools/paramlengthinfotype.py +6 -7
  125. odxtools/parentref.py +12 -10
  126. odxtools/physicaldimension.py +12 -12
  127. odxtools/physicaltype.py +5 -5
  128. odxtools/posresponsesuppressible.py +11 -11
  129. odxtools/preconditionstateref.py +8 -8
  130. odxtools/progcode.py +9 -8
  131. odxtools/protstack.py +8 -7
  132. odxtools/relateddiagcommref.py +5 -5
  133. odxtools/relateddoc.py +8 -7
  134. odxtools/request.py +12 -13
  135. odxtools/response.py +12 -13
  136. odxtools/scaleconstr.py +8 -8
  137. odxtools/singleecujob.py +14 -13
  138. odxtools/snrefcontext.py +1 -1
  139. odxtools/specialdata.py +6 -5
  140. odxtools/specialdatagroup.py +13 -13
  141. odxtools/specialdatagroupcaption.py +5 -4
  142. odxtools/standardlengthtype.py +5 -13
  143. odxtools/state.py +5 -4
  144. odxtools/statechart.py +10 -9
  145. odxtools/statemachine.py +2 -2
  146. odxtools/statetransition.py +7 -7
  147. odxtools/statetransitionref.py +11 -11
  148. odxtools/staticfield.py +5 -4
  149. odxtools/structure.py +5 -5
  150. odxtools/subcomponent.py +18 -16
  151. odxtools/subcomponentparamconnector.py +8 -7
  152. odxtools/subcomponentpattern.py +7 -7
  153. odxtools/swvariable.py +6 -6
  154. odxtools/table.py +20 -21
  155. odxtools/tablediagcommconnector.py +7 -6
  156. odxtools/tablerow.py +57 -36
  157. odxtools/tablerowconnector.py +6 -6
  158. odxtools/teammember.py +14 -13
  159. odxtools/templates/macros/printParentRef.xml.jinja2 +3 -1
  160. odxtools/text.py +4 -4
  161. odxtools/unit.py +9 -8
  162. odxtools/unitgroup.py +9 -8
  163. odxtools/unitspec.py +15 -16
  164. odxtools/variablegroup.py +4 -5
  165. odxtools/variantpattern.py +3 -4
  166. odxtools/version.py +2 -2
  167. odxtools/writepdxfile.py +0 -19
  168. odxtools/xdoc.py +11 -10
  169. {odxtools-10.0.0.dist-info → odxtools-10.1.1.dist-info}/METADATA +1 -1
  170. odxtools-10.1.1.dist-info/RECORD +265 -0
  171. {odxtools-10.0.0.dist-info → odxtools-10.1.1.dist-info}/WHEEL +1 -1
  172. odxtools-10.0.0.dist-info/RECORD +0 -264
  173. {odxtools-10.0.0.dist-info → odxtools-10.1.1.dist-info}/entry_points.txt +0 -0
  174. {odxtools-10.0.0.dist-info → odxtools-10.1.1.dist-info}/licenses/LICENSE +0 -0
  175. {odxtools-10.0.0.dist-info → odxtools-10.1.1.dist-info}/top_level.txt +0 -0
odxtools/odxcategory.py CHANGED
@@ -1,14 +1,14 @@
1
1
  # SPDX-License-Identifier: MIT
2
- from dataclasses import dataclass
2
+ from dataclasses import dataclass, field
3
3
  from typing import TYPE_CHECKING, Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .admindata import AdminData
7
7
  from .companydata import CompanyData
8
8
  from .element import IdentifiableElement
9
- from .exceptions import odxrequire
10
9
  from .nameditemlist import NamedItemList
11
- from .odxlink import DocType, OdxDocFragment, OdxLinkDatabase, OdxLinkId
10
+ from .odxdoccontext import OdxDocContext
11
+ from .odxlink import OdxLinkDatabase, OdxLinkId
12
12
  from .snrefcontext import SnRefContext
13
13
  from .specialdatagroup import SpecialDataGroup
14
14
  from .utils import dataclass_fields_asdict
@@ -17,37 +17,25 @@ if TYPE_CHECKING:
17
17
  from .database import Database
18
18
 
19
19
 
20
- @dataclass
20
+ @dataclass(kw_only=True)
21
21
  class OdxCategory(IdentifiableElement):
22
22
  """This is the base class for all top-level container classes in ODX"""
23
23
 
24
- admin_data: AdminData | None
25
- company_datas: NamedItemList[CompanyData]
26
- sdgs: list[SpecialDataGroup]
24
+ admin_data: AdminData | None = None
25
+ company_datas: NamedItemList[CompanyData] = field(default_factory=NamedItemList)
26
+ sdgs: list[SpecialDataGroup] = field(default_factory=list)
27
27
 
28
28
  @staticmethod
29
- def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "OdxCategory":
30
- raise Exception("Calling `._from_et()` is not allowed for OdxCategory. "
31
- "Use `OdxCategory.category_from_et()`!")
29
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "OdxCategory":
32
30
 
33
- @staticmethod
34
- def category_from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment], *,
35
- doc_type: DocType) -> "OdxCategory":
36
-
37
- short_name = odxrequire(et_element.findtext("SHORT-NAME"))
38
- # create the current ODX "document fragment" (description of the
39
- # current document for references and IDs)
40
- doc_frags = [OdxDocFragment(short_name, doc_type)]
41
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
31
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
42
32
 
43
- admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
33
+ admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), context)
44
34
  company_datas = NamedItemList([
45
- CompanyData.from_et(cde, doc_frags)
35
+ CompanyData.from_et(cde, context)
46
36
  for cde in et_element.iterfind("COMPANY-DATAS/COMPANY-DATA")
47
37
  ])
48
- sdgs = [
49
- SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
50
- ]
38
+ sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
51
39
 
52
40
  return OdxCategory(admin_data=admin_data, company_datas=company_datas, sdgs=sdgs, **kwargs)
53
41
 
@@ -0,0 +1,16 @@
1
+ from dataclasses import dataclass
2
+ from typing import TYPE_CHECKING
3
+
4
+ from packaging.version import Version
5
+
6
+ if TYPE_CHECKING:
7
+ from odxtools.odxlink import OdxDocFragment
8
+
9
+
10
+ @dataclass(slots=True, frozen=True)
11
+ class OdxDocContext:
12
+ version: Version
13
+
14
+ # the doc_fragments are either tuple(doc_frag(category),)
15
+ # or tuple(doc_frag(category), doc_frag(diag_layer))
16
+ doc_fragments: tuple["OdxDocFragment"] | tuple["OdxDocFragment", "OdxDocFragment"]
odxtools/odxlink.py CHANGED
@@ -8,6 +8,7 @@ from xml.etree import ElementTree
8
8
 
9
9
  from .exceptions import OdxWarning, odxassert, odxraise, odxrequire
10
10
  from .nameditemlist import OdxNamed, TNamed
11
+ from .odxdoccontext import OdxDocContext
11
12
 
12
13
 
13
14
  class DocType(Enum):
@@ -45,7 +46,7 @@ class OdxLinkId:
45
46
 
46
47
  #: The name and type of the document fragment to which the
47
48
  #: `local_id` is relative to
48
- doc_fragments: list[OdxDocFragment]
49
+ doc_fragments: tuple[OdxDocFragment] | tuple[OdxDocFragment, OdxDocFragment]
49
50
 
50
51
  def __hash__(self) -> int:
51
52
  # we do not hash about the document fragment here, because
@@ -68,8 +69,7 @@ class OdxLinkId:
68
69
  return f"OdxLinkId('{self.local_id}')"
69
70
 
70
71
  @staticmethod
71
- def from_et(et: ElementTree.Element,
72
- doc_fragments: list[OdxDocFragment]) -> Optional["OdxLinkId"]:
72
+ def from_et(et: ElementTree.Element, context: OdxDocContext) -> Optional["OdxLinkId"]:
73
73
  """Construct an OdxLinkId for a given XML node (ElementTree object).
74
74
 
75
75
  Returns None if the given XML node does not exhibit an ID.
@@ -79,7 +79,7 @@ class OdxLinkId:
79
79
  if local_id is None:
80
80
  return None
81
81
 
82
- return OdxLinkId(local_id, doc_fragments)
82
+ return OdxLinkId(local_id, context.doc_fragments)
83
83
 
84
84
 
85
85
  @dataclass
@@ -95,7 +95,7 @@ class OdxLinkRef:
95
95
  ref_id: str
96
96
 
97
97
  #: The document fragments to which the `ref_id` refers to (in reverse order)
98
- ref_docs: list[OdxDocFragment]
98
+ ref_docs: tuple[OdxDocFragment, ...]
99
99
 
100
100
  # TODO: this is difficult because OdxLinkRef is derived from and
101
101
  # we do not want having to specify it mandatorily
@@ -103,17 +103,16 @@ class OdxLinkRef:
103
103
 
104
104
  @overload
105
105
  @staticmethod
106
- def from_et(et: None, source_doc_frags: list[OdxDocFragment]) -> None:
106
+ def from_et(et: None, context: OdxDocContext) -> None:
107
107
  ...
108
108
 
109
109
  @overload
110
110
  @staticmethod
111
- def from_et(et: ElementTree.Element, source_doc_frags: list[OdxDocFragment]) -> "OdxLinkRef":
111
+ def from_et(et: ElementTree.Element, context: OdxDocContext) -> "OdxLinkRef":
112
112
  ...
113
113
 
114
114
  @staticmethod
115
- def from_et(et: ElementTree.Element | None,
116
- source_doc_frags: list[OdxDocFragment]) -> Optional["OdxLinkRef"]:
115
+ def from_et(et: ElementTree.Element | None, context: OdxDocContext) -> Optional["OdxLinkRef"]:
117
116
  """Construct an OdxLinkRef for a given XML node (ElementTree object).
118
117
 
119
118
  Returns None if the given XML node does not represent a reference.
@@ -144,10 +143,10 @@ class OdxLinkRef:
144
143
  # if the target document fragment is specified by the
145
144
  # reference, use it, else use the document fragment containing
146
145
  # the reference.
147
- if docref is not None:
148
- doc_frags = [OdxDocFragment(docref, odxrequire(doctype))]
146
+ if docref is None:
147
+ doc_frags = context.doc_fragments
149
148
  else:
150
- doc_frags = source_doc_frags
149
+ doc_frags = (OdxDocFragment(docref, odxrequire(doctype)),)
151
150
 
152
151
  return OdxLinkRef(id_ref, doc_frags)
153
152
 
odxtools/odxtypes.py CHANGED
@@ -109,8 +109,8 @@ def compare_odx_values(a: AtomicOdxType, b: AtomicOdxType) -> int:
109
109
  # specification. (cf section 7.3.6.5)
110
110
 
111
111
  # numeric values are compared numerically (duh!)
112
- if isinstance(a, int | float):
113
- if not isinstance(b, int | float):
112
+ if isinstance(a, (int, float)):
113
+ if not isinstance(b, (int, float)):
114
114
  odxraise()
115
115
 
116
116
  tmp = a - b
@@ -239,7 +239,7 @@ class DataType(Enum):
239
239
  expected_type = self.python_type
240
240
  if isinstance(value, expected_type):
241
241
  return True
242
- elif expected_type is float and isinstance(value, int | float):
242
+ elif expected_type is float and isinstance(value, (int, float)):
243
243
  return True
244
244
  elif self == DataType.A_BYTEFIELD and isinstance(value, BytesTypes):
245
245
  return True
odxtools/outputparam.py CHANGED
@@ -8,15 +8,16 @@ from deprecation import deprecated
8
8
  from .dopbase import DopBase
9
9
  from .element import IdentifiableElement
10
10
  from .exceptions import odxrequire
11
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
11
+ from .odxdoccontext import OdxDocContext
12
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
12
13
  from .snrefcontext import SnRefContext
13
14
  from .utils import dataclass_fields_asdict
14
15
 
15
16
 
16
- @dataclass
17
+ @dataclass(kw_only=True)
17
18
  class OutputParam(IdentifiableElement):
18
19
  dop_base_ref: OdxLinkRef
19
- semantic: str | None
20
+ semantic: str | None = None
20
21
 
21
22
  @property
22
23
  def dop(self) -> DopBase:
@@ -27,11 +28,11 @@ class OutputParam(IdentifiableElement):
27
28
  return self._dop
28
29
 
29
30
  @staticmethod
30
- def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "OutputParam":
31
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "OutputParam":
31
32
 
32
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
33
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
33
34
 
34
- dop_base_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DOP-BASE-REF"), doc_frags))
35
+ dop_base_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DOP-BASE-REF"), context))
35
36
  semantic = et_element.get("SEMANTIC")
36
37
 
37
38
  return OutputParam(dop_base_ref=dop_base_ref, semantic=semantic, **kwargs)
@@ -11,13 +11,14 @@ from ..decodestate import DecodeState
11
11
  from ..diagcodedtype import DiagCodedType
12
12
  from ..encodestate import EncodeState
13
13
  from ..exceptions import DecodeError, EncodeError, odxraise, odxrequire
14
- from ..odxlink import OdxDocFragment, OdxLinkId
14
+ from ..odxdoccontext import OdxDocContext
15
+ from ..odxlink import OdxLinkId
15
16
  from ..odxtypes import AtomicOdxType, DataType, ParameterValue
16
17
  from ..utils import dataclass_fields_asdict
17
18
  from .parameter import Parameter, ParameterType
18
19
 
19
20
 
20
- @dataclass
21
+ @dataclass(kw_only=True)
21
22
  class CodedConstParameter(Parameter):
22
23
 
23
24
  coded_value_raw: str
@@ -44,14 +45,13 @@ class CodedConstParameter(Parameter):
44
45
 
45
46
  @staticmethod
46
47
  @override
47
- def from_et(et_element: ElementTree.Element,
48
- doc_frags: list[OdxDocFragment]) -> "CodedConstParameter":
48
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "CodedConstParameter":
49
49
 
50
- kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
50
+ kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, context))
51
51
 
52
52
  coded_value_raw = odxrequire(et_element.findtext("CODED-VALUE"))
53
53
  dct_elem = odxrequire(et_element.find("DIAG-CODED-TYPE"))
54
- diag_coded_type = create_any_diag_coded_type_from_et(dct_elem, doc_frags)
54
+ diag_coded_type = create_any_diag_coded_type_from_et(dct_elem, context)
55
55
 
56
56
  return CodedConstParameter(
57
57
  coded_value_raw=coded_value_raw, diag_coded_type=diag_coded_type, **kwargs)
@@ -3,7 +3,7 @@ from xml.etree import ElementTree
3
3
 
4
4
  from ..exceptions import odxraise
5
5
  from ..globals import xsi
6
- from ..odxlink import OdxDocFragment
6
+ from ..odxdoccontext import OdxDocContext
7
7
  from .codedconstparameter import CodedConstParameter
8
8
  from .dynamicparameter import DynamicParameter
9
9
  from .lengthkeyparameter import LengthKeyParameter
@@ -20,35 +20,35 @@ from .valueparameter import ValueParameter
20
20
 
21
21
 
22
22
  def create_any_parameter_from_et(et_element: ElementTree.Element,
23
- doc_frags: list[OdxDocFragment]) \
23
+ context: OdxDocContext) \
24
24
  -> Parameter:
25
25
  parameter_type = et_element.get(f"{xsi}type")
26
26
 
27
27
  # Which attributes are set depends on the type of the parameter.
28
28
  if parameter_type == "VALUE":
29
- return ValueParameter.from_et(et_element, doc_frags)
29
+ return ValueParameter.from_et(et_element, context)
30
30
  elif parameter_type == "CODED-CONST":
31
- return CodedConstParameter.from_et(et_element, doc_frags)
31
+ return CodedConstParameter.from_et(et_element, context)
32
32
  elif parameter_type == "PHYS-CONST":
33
- return PhysicalConstantParameter.from_et(et_element, doc_frags)
33
+ return PhysicalConstantParameter.from_et(et_element, context)
34
34
  elif parameter_type == "SYSTEM":
35
- return SystemParameter.from_et(et_element, doc_frags)
35
+ return SystemParameter.from_et(et_element, context)
36
36
  elif parameter_type == "LENGTH-KEY":
37
- return LengthKeyParameter.from_et(et_element, doc_frags)
37
+ return LengthKeyParameter.from_et(et_element, context)
38
38
  elif parameter_type == "NRC-CONST":
39
- return NrcConstParameter.from_et(et_element, doc_frags)
39
+ return NrcConstParameter.from_et(et_element, context)
40
40
  elif parameter_type == "RESERVED":
41
- return ReservedParameter.from_et(et_element, doc_frags)
41
+ return ReservedParameter.from_et(et_element, context)
42
42
  elif parameter_type == "MATCHING-REQUEST-PARAM":
43
- return MatchingRequestParameter.from_et(et_element, doc_frags)
43
+ return MatchingRequestParameter.from_et(et_element, context)
44
44
  elif parameter_type == "DYNAMIC":
45
- return DynamicParameter.from_et(et_element, doc_frags)
45
+ return DynamicParameter.from_et(et_element, context)
46
46
  elif parameter_type == "TABLE-STRUCT":
47
- return TableStructParameter.from_et(et_element, doc_frags)
47
+ return TableStructParameter.from_et(et_element, context)
48
48
  elif parameter_type == "TABLE-KEY":
49
- return TableKeyParameter.from_et(et_element, doc_frags)
49
+ return TableKeyParameter.from_et(et_element, context)
50
50
  elif parameter_type == "TABLE-ENTRY":
51
- return TableEntryParameter.from_et(et_element, doc_frags)
51
+ return TableEntryParameter.from_et(et_element, context)
52
52
 
53
53
  odxraise(f"I don't know about parameters of type {parameter_type}", NotImplementedError)
54
- return Parameter.from_et(et_element, doc_frags)
54
+ return Parameter.from_et(et_element, context)
@@ -6,13 +6,13 @@ from typing_extensions import override
6
6
 
7
7
  from ..decodestate import DecodeState
8
8
  from ..encodestate import EncodeState
9
- from ..odxlink import OdxDocFragment
9
+ from ..odxdoccontext import OdxDocContext
10
10
  from ..odxtypes import ParameterValue
11
11
  from ..utils import dataclass_fields_asdict
12
12
  from .parameter import Parameter, ParameterType
13
13
 
14
14
 
15
- @dataclass
15
+ @dataclass(kw_only=True)
16
16
  class DynamicParameter(Parameter):
17
17
 
18
18
  @property
@@ -32,10 +32,9 @@ class DynamicParameter(Parameter):
32
32
 
33
33
  @staticmethod
34
34
  @override
35
- def from_et(et_element: ElementTree.Element,
36
- doc_frags: list[OdxDocFragment]) -> "DynamicParameter":
35
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DynamicParameter":
37
36
 
38
- kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
37
+ kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, context))
39
38
 
40
39
  return DynamicParameter(**kwargs)
41
40
 
@@ -8,14 +8,15 @@ from typing_extensions import final, override
8
8
  from ..decodestate import DecodeState
9
9
  from ..encodestate import EncodeState
10
10
  from ..exceptions import EncodeError, odxraise, odxrequire
11
- from ..odxlink import OdxDocFragment, OdxLinkId
11
+ from ..odxdoccontext import OdxDocContext
12
+ from ..odxlink import OdxLinkId
12
13
  from ..odxtypes import ParameterValue
13
14
  from ..utils import dataclass_fields_asdict
14
15
  from .parameter import ParameterType
15
16
  from .parameterwithdop import ParameterWithDOP
16
17
 
17
18
 
18
- @dataclass
19
+ @dataclass(kw_only=True)
19
20
  class LengthKeyParameter(ParameterWithDOP):
20
21
  """Length Keys specify the bit (!) length of another parameter.
21
22
 
@@ -48,12 +49,11 @@ class LengthKeyParameter(ParameterWithDOP):
48
49
 
49
50
  @staticmethod
50
51
  @override
51
- def from_et(et_element: ElementTree.Element,
52
- doc_frags: list[OdxDocFragment]) -> "LengthKeyParameter":
52
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "LengthKeyParameter":
53
53
 
54
- kwargs = dataclass_fields_asdict(ParameterWithDOP.from_et(et_element, doc_frags))
54
+ kwargs = dataclass_fields_asdict(ParameterWithDOP.from_et(et_element, context))
55
55
 
56
- odx_id = odxrequire(OdxLinkId.from_et(et_element, doc_frags))
56
+ odx_id = odxrequire(OdxLinkId.from_et(et_element, context))
57
57
 
58
58
  return LengthKeyParameter(odx_id=odx_id, **kwargs)
59
59
 
@@ -7,13 +7,13 @@ from typing_extensions import override
7
7
  from ..decodestate import DecodeState
8
8
  from ..encodestate import EncodeState
9
9
  from ..exceptions import EncodeError, odxraise, odxrequire
10
- from ..odxlink import OdxDocFragment
10
+ from ..odxdoccontext import OdxDocContext
11
11
  from ..odxtypes import DataType, ParameterValue
12
12
  from ..utils import dataclass_fields_asdict
13
13
  from .parameter import Parameter, ParameterType
14
14
 
15
15
 
16
- @dataclass
16
+ @dataclass(kw_only=True)
17
17
  class MatchingRequestParameter(Parameter):
18
18
  request_byte_position: int
19
19
  byte_length: int
@@ -36,9 +36,9 @@ class MatchingRequestParameter(Parameter):
36
36
  @staticmethod
37
37
  @override
38
38
  def from_et(et_element: ElementTree.Element,
39
- doc_frags: list[OdxDocFragment]) -> "MatchingRequestParameter":
39
+ context: OdxDocContext) -> "MatchingRequestParameter":
40
40
 
41
- kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
41
+ kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, context))
42
42
 
43
43
  request_byte_position = int(odxrequire(et_element.findtext("REQUEST-BYTE-POS")))
44
44
  byte_length = int(odxrequire(et_element.findtext("BYTE-LENGTH")))
@@ -1,5 +1,5 @@
1
1
  # SPDX-License-Identifier: MIT
2
- from dataclasses import dataclass
2
+ from dataclasses import dataclass, field
3
3
  from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
@@ -10,13 +10,14 @@ from ..decodestate import DecodeState
10
10
  from ..diagcodedtype import DiagCodedType
11
11
  from ..encodestate import EncodeState
12
12
  from ..exceptions import DecodeMismatch, EncodeError, odxraise, odxrequire
13
- from ..odxlink import OdxDocFragment, OdxLinkId
13
+ from ..odxdoccontext import OdxDocContext
14
+ from ..odxlink import OdxLinkId
14
15
  from ..odxtypes import AtomicOdxType, DataType, ParameterValue
15
16
  from ..utils import dataclass_fields_asdict
16
17
  from .parameter import Parameter, ParameterType
17
18
 
18
19
 
19
- @dataclass
20
+ @dataclass(kw_only=True)
20
21
  class NrcConstParameter(Parameter):
21
22
  """A parameter of type NRC-CONST defines a set of values to be
22
23
  matched for a negative response object to apply
@@ -34,7 +35,7 @@ class NrcConstParameter(Parameter):
34
35
 
35
36
  """
36
37
 
37
- coded_values_raw: list[str]
38
+ coded_values_raw: list[str] = field(default_factory=list)
38
39
  diag_coded_type: DiagCodedType
39
40
 
40
41
  @property
@@ -62,16 +63,15 @@ class NrcConstParameter(Parameter):
62
63
 
63
64
  @staticmethod
64
65
  @override
65
- def from_et(et_element: ElementTree.Element,
66
- doc_frags: list[OdxDocFragment]) -> "NrcConstParameter":
66
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "NrcConstParameter":
67
67
 
68
- kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
68
+ kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, context))
69
69
 
70
70
  coded_values_raw = [
71
71
  odxrequire(x.text) for x in et_element.iterfind("CODED-VALUES/CODED-VALUE")
72
72
  ]
73
73
  dct_elem = odxrequire(et_element.find("DIAG-CODED-TYPE"))
74
- diag_coded_type = create_any_diag_coded_type_from_et(dct_elem, doc_frags)
74
+ diag_coded_type = create_any_diag_coded_type_from_et(dct_elem, context)
75
75
 
76
76
  return NrcConstParameter(
77
77
  coded_values_raw=coded_values_raw, diag_coded_type=diag_coded_type, **kwargs)
@@ -1,5 +1,5 @@
1
1
  # SPDX-License-Identifier: MIT
2
- from dataclasses import dataclass
2
+ from dataclasses import dataclass, field
3
3
  from typing import Any, Literal
4
4
  from xml.etree import ElementTree
5
5
 
@@ -8,7 +8,8 @@ from typing_extensions import final, override
8
8
  from ..decodestate import DecodeState
9
9
  from ..element import NamedElement
10
10
  from ..encodestate import EncodeState
11
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
11
+ from ..odxdoccontext import OdxDocContext
12
+ from ..odxlink import OdxLinkDatabase, OdxLinkId
12
13
  from ..odxtypes import ParameterValue
13
14
  from ..snrefcontext import SnRefContext
14
15
  from ..specialdatagroup import SpecialDataGroup
@@ -30,7 +31,7 @@ ParameterType = Literal[
30
31
  ]
31
32
 
32
33
 
33
- @dataclass
34
+ @dataclass(kw_only=True)
34
35
  class Parameter(NamedElement):
35
36
  """This class corresponds to POSITIONABLE-PARAM in the ODX
36
37
  specification
@@ -42,11 +43,11 @@ class Parameter(NamedElement):
42
43
  non-positionable parameter types.
43
44
 
44
45
  """
45
- sdgs: list[SpecialDataGroup]
46
- semantic: str | None
47
- oid: str | None
48
- byte_position: int | None
49
- bit_position: int | None
46
+ sdgs: list[SpecialDataGroup] = field(default_factory=list)
47
+ semantic: str | None = None
48
+ oid: str | None = None
49
+ byte_position: int | None = None
50
+ bit_position: int | None = None
50
51
 
51
52
  @property
52
53
  def parameter_type(self) -> ParameterType:
@@ -78,13 +79,11 @@ class Parameter(NamedElement):
78
79
 
79
80
  @staticmethod
80
81
  @override
81
- def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Parameter":
82
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Parameter":
82
83
 
83
- kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
84
+ kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context))
84
85
 
85
- sdgs = [
86
- SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
87
- ]
86
+ sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
88
87
  semantic = et_element.attrib.get("SEMANTIC")
89
88
  oid = et_element.attrib.get("OID")
90
89
  byte_position_str = et_element.findtext("BYTE-POSITION")
@@ -11,7 +11,8 @@ from ..dopbase import DopBase
11
11
  from ..dtcdop import DtcDop
12
12
  from ..encodestate import EncodeState
13
13
  from ..exceptions import odxassert, odxrequire
14
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
14
+ from ..odxdoccontext import OdxDocContext
15
+ from ..odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
15
16
  from ..odxtypes import AtomicOdxType, ParameterValue
16
17
  from ..physicaltype import PhysicalType
17
18
  from ..snrefcontext import SnRefContext
@@ -19,10 +20,10 @@ from ..utils import dataclass_fields_asdict
19
20
  from .parameter import Parameter
20
21
 
21
22
 
22
- @dataclass
23
+ @dataclass(kw_only=True)
23
24
  class ParameterWithDOP(Parameter):
24
- dop_ref: OdxLinkRef | None
25
- dop_snref: str | None
25
+ dop_ref: OdxLinkRef | None = None
26
+ dop_snref: str | None = None
26
27
 
27
28
  @property
28
29
  def dop(self) -> DopBase:
@@ -32,12 +33,11 @@ class ParameterWithDOP(Parameter):
32
33
 
33
34
  @staticmethod
34
35
  @override
35
- def from_et(et_element: ElementTree.Element,
36
- doc_frags: list[OdxDocFragment]) -> "ParameterWithDOP":
36
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ParameterWithDOP":
37
37
 
38
- kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
38
+ kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, context))
39
39
 
40
- dop_ref = OdxLinkRef.from_et(et_element.find("DOP-REF"), doc_frags)
40
+ dop_ref = OdxLinkRef.from_et(et_element.find("DOP-REF"), context)
41
41
  dop_snref = None
42
42
  if (dop_snref_elem := et_element.find("DOP-SNREF")) is not None:
43
43
  dop_snref = odxrequire(dop_snref_elem.get("SHORT-NAME"))
@@ -78,7 +78,7 @@ class ParameterWithDOP(Parameter):
78
78
 
79
79
  @property
80
80
  def physical_type(self) -> PhysicalType | None:
81
- if isinstance(self.dop, DataObjectProperty | DtcDop):
81
+ if isinstance(self.dop, (DataObjectProperty, DtcDop)):
82
82
  return self.dop.physical_type
83
83
  else:
84
84
  return None
@@ -9,7 +9,8 @@ from ..dataobjectproperty import DataObjectProperty
9
9
  from ..decodestate import DecodeState
10
10
  from ..encodestate import EncodeState
11
11
  from ..exceptions import DecodeError, EncodeError, odxraise, odxrequire
12
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
12
+ from ..odxdoccontext import OdxDocContext
13
+ from ..odxlink import OdxLinkDatabase, OdxLinkId
13
14
  from ..odxtypes import ParameterValue
14
15
  from ..snrefcontext import SnRefContext
15
16
  from ..utils import dataclass_fields_asdict
@@ -17,7 +18,7 @@ from .parameter import ParameterType
17
18
  from .parameterwithdop import ParameterWithDOP
18
19
 
19
20
 
20
- @dataclass
21
+ @dataclass(kw_only=True)
21
22
  class PhysicalConstantParameter(ParameterWithDOP):
22
23
  physical_constant_value_raw: str
23
24
 
@@ -43,9 +44,9 @@ class PhysicalConstantParameter(ParameterWithDOP):
43
44
  @staticmethod
44
45
  @override
45
46
  def from_et(et_element: ElementTree.Element,
46
- doc_frags: list[OdxDocFragment]) -> "PhysicalConstantParameter":
47
+ context: OdxDocContext) -> "PhysicalConstantParameter":
47
48
 
48
- kwargs = dataclass_fields_asdict(ParameterWithDOP.from_et(et_element, doc_frags))
49
+ kwargs = dataclass_fields_asdict(ParameterWithDOP.from_et(et_element, context))
49
50
 
50
51
  physical_constant_value_raw = odxrequire(et_element.findtext("PHYS-CONSTANT-VALUE"))
51
52
 
@@ -7,13 +7,13 @@ from typing_extensions import override
7
7
  from ..decodestate import DecodeState
8
8
  from ..encodestate import EncodeState
9
9
  from ..exceptions import odxrequire
10
- from ..odxlink import OdxDocFragment
10
+ from ..odxdoccontext import OdxDocContext
11
11
  from ..odxtypes import DataType, ParameterValue
12
12
  from ..utils import dataclass_fields_asdict
13
13
  from .parameter import Parameter, ParameterType
14
14
 
15
15
 
16
- @dataclass
16
+ @dataclass(kw_only=True)
17
17
  class ReservedParameter(Parameter):
18
18
  bit_length: int
19
19
 
@@ -34,9 +34,8 @@ class ReservedParameter(Parameter):
34
34
 
35
35
  @staticmethod
36
36
  @override
37
- def from_et(et_element: ElementTree.Element,
38
- doc_frags: list[OdxDocFragment]) -> "ReservedParameter":
39
- kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
37
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ReservedParameter":
38
+ kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, context))
40
39
 
41
40
  bit_length = int(odxrequire(et_element.findtext("BIT-LENGTH")))
42
41
 
@@ -8,7 +8,7 @@ from typing_extensions import override
8
8
 
9
9
  from ..encodestate import EncodeState
10
10
  from ..exceptions import odxraise, odxrequire
11
- from ..odxlink import OdxDocFragment
11
+ from ..odxdoccontext import OdxDocContext
12
12
  from ..odxtypes import ParameterValue
13
13
  from ..utils import dataclass_fields_asdict
14
14
  from .parameter import ParameterType
@@ -24,7 +24,7 @@ PREDEFINED_SYSPARAM_VALUES = [
24
24
  ]
25
25
 
26
26
 
27
- @dataclass
27
+ @dataclass(kw_only=True)
28
28
  class SystemParameter(ParameterWithDOP):
29
29
  sysparam: str
30
30
 
@@ -48,9 +48,8 @@ class SystemParameter(ParameterWithDOP):
48
48
 
49
49
  @staticmethod
50
50
  @override
51
- def from_et(et_element: ElementTree.Element,
52
- doc_frags: list[OdxDocFragment]) -> "SystemParameter":
53
- kwargs = dataclass_fields_asdict(ParameterWithDOP.from_et(et_element, doc_frags))
51
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "SystemParameter":
52
+ kwargs = dataclass_fields_asdict(ParameterWithDOP.from_et(et_element, context))
54
53
 
55
54
  sysparam = odxrequire(et_element.get("SYSPARAM"))
56
55