odxtools 10.0.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 (174) 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/list.py +1 -1
  10. odxtools/commrelation.py +14 -13
  11. odxtools/companydata.py +11 -11
  12. odxtools/companydocinfo.py +11 -13
  13. odxtools/companyrevisioninfo.py +7 -7
  14. odxtools/companyspecificinfo.py +9 -11
  15. odxtools/comparam.py +6 -5
  16. odxtools/comparaminstance.py +10 -10
  17. odxtools/comparamspec.py +8 -9
  18. odxtools/comparamsubset.py +14 -22
  19. odxtools/complexcomparam.py +10 -10
  20. odxtools/complexdop.py +1 -1
  21. odxtools/compositecodec.py +3 -3
  22. odxtools/compumethods/compucodecompumethod.py +4 -4
  23. odxtools/compumethods/compuconst.py +3 -3
  24. odxtools/compumethods/compudefaultvalue.py +2 -2
  25. odxtools/compumethods/compuinternaltophys.py +11 -10
  26. odxtools/compumethods/compumethod.py +8 -7
  27. odxtools/compumethods/compuphystointernal.py +11 -10
  28. odxtools/compumethods/compurationalcoeffs.py +6 -6
  29. odxtools/compumethods/compuscale.py +14 -14
  30. odxtools/compumethods/createanycompumethod.py +12 -12
  31. odxtools/compumethods/identicalcompumethod.py +4 -4
  32. odxtools/compumethods/limit.py +8 -8
  33. odxtools/compumethods/linearcompumethod.py +4 -4
  34. odxtools/compumethods/linearsegment.py +8 -8
  35. odxtools/compumethods/ratfunccompumethod.py +4 -4
  36. odxtools/compumethods/ratfuncsegment.py +8 -8
  37. odxtools/compumethods/scalelinearcompumethod.py +5 -5
  38. odxtools/compumethods/scaleratfunccompumethod.py +4 -4
  39. odxtools/compumethods/tabintpcompumethod.py +12 -12
  40. odxtools/compumethods/texttablecompumethod.py +4 -4
  41. odxtools/createanycomparam.py +4 -4
  42. odxtools/createanydiagcodedtype.py +7 -7
  43. odxtools/database.py +28 -26
  44. odxtools/dataobjectproperty.py +15 -16
  45. odxtools/description.py +7 -7
  46. odxtools/determinenumberofitems.py +6 -5
  47. odxtools/diagcodedtype.py +6 -6
  48. odxtools/diagcomm.py +26 -27
  49. odxtools/diagdatadictionaryspec.py +34 -34
  50. odxtools/diaglayercontainer.py +32 -31
  51. odxtools/diaglayers/basevariant.py +5 -4
  52. odxtools/diaglayers/basevariantraw.py +18 -19
  53. odxtools/diaglayers/diaglayer.py +5 -4
  54. odxtools/diaglayers/diaglayerraw.py +39 -48
  55. odxtools/diaglayers/ecushareddata.py +6 -6
  56. odxtools/diaglayers/ecushareddataraw.py +11 -12
  57. odxtools/diaglayers/ecuvariant.py +5 -4
  58. odxtools/diaglayers/ecuvariantraw.py +17 -18
  59. odxtools/diaglayers/functionalgroup.py +5 -5
  60. odxtools/diaglayers/functionalgroupraw.py +13 -14
  61. odxtools/diaglayers/hierarchyelement.py +9 -9
  62. odxtools/diaglayers/hierarchyelementraw.py +8 -9
  63. odxtools/diaglayers/protocol.py +4 -4
  64. odxtools/diaglayers/protocolraw.py +10 -11
  65. odxtools/diagnostictroublecode.py +12 -14
  66. odxtools/diagservice.py +19 -18
  67. odxtools/diagvariable.py +19 -20
  68. odxtools/docrevision.py +14 -13
  69. odxtools/dopbase.py +10 -11
  70. odxtools/dtcconnector.py +6 -5
  71. odxtools/dtcdop.py +15 -15
  72. odxtools/dynamicendmarkerfield.py +6 -6
  73. odxtools/dynamiclengthfield.py +6 -6
  74. odxtools/dyndefinedspec.py +7 -7
  75. odxtools/dynenddopref.py +7 -7
  76. odxtools/dyniddefmodeinfo.py +17 -17
  77. odxtools/ecuvariantpattern.py +6 -7
  78. odxtools/element.py +12 -12
  79. odxtools/endofpdufield.py +6 -7
  80. odxtools/envdataconnector.py +6 -6
  81. odxtools/environmentdata.py +7 -8
  82. odxtools/environmentdatadescription.py +13 -12
  83. odxtools/externalaccessmethod.py +4 -5
  84. odxtools/externaldoc.py +4 -4
  85. odxtools/field.py +12 -11
  86. odxtools/functionalclass.py +7 -7
  87. odxtools/inputparam.py +9 -8
  88. odxtools/internalconstr.py +10 -10
  89. odxtools/leadinglengthinfotype.py +5 -6
  90. odxtools/library.py +7 -6
  91. odxtools/linkeddtcdop.py +7 -6
  92. odxtools/matchingbasevariantparameter.py +5 -5
  93. odxtools/matchingparameter.py +6 -6
  94. odxtools/message.py +1 -1
  95. odxtools/minmaxlengthtype.py +6 -7
  96. odxtools/modification.py +5 -4
  97. odxtools/multiplexer.py +48 -12
  98. odxtools/multiplexercase.py +10 -10
  99. odxtools/multiplexerdefaultcase.py +8 -7
  100. odxtools/multiplexerswitchkey.py +6 -6
  101. odxtools/nameditemlist.py +1 -1
  102. odxtools/negoutputparam.py +6 -6
  103. odxtools/odxcategory.py +12 -24
  104. odxtools/odxdoccontext.py +16 -0
  105. odxtools/odxlink.py +11 -12
  106. odxtools/odxtypes.py +3 -3
  107. odxtools/outputparam.py +7 -6
  108. odxtools/parameters/codedconstparameter.py +6 -6
  109. odxtools/parameters/createanyparameter.py +15 -15
  110. odxtools/parameters/dynamicparameter.py +4 -5
  111. odxtools/parameters/lengthkeyparameter.py +6 -6
  112. odxtools/parameters/matchingrequestparameter.py +4 -4
  113. odxtools/parameters/nrcconstparameter.py +8 -8
  114. odxtools/parameters/parameter.py +12 -13
  115. odxtools/parameters/parameterwithdop.py +9 -9
  116. odxtools/parameters/physicalconstantparameter.py +5 -4
  117. odxtools/parameters/reservedparameter.py +4 -5
  118. odxtools/parameters/systemparameter.py +4 -5
  119. odxtools/parameters/tableentryparameter.py +6 -6
  120. odxtools/parameters/tablekeyparameter.py +12 -12
  121. odxtools/parameters/tablestructparameter.py +9 -9
  122. odxtools/parameters/valueparameter.py +6 -6
  123. odxtools/paramlengthinfotype.py +6 -7
  124. odxtools/parentref.py +12 -10
  125. odxtools/physicaldimension.py +12 -12
  126. odxtools/physicaltype.py +5 -5
  127. odxtools/posresponsesuppressible.py +11 -11
  128. odxtools/preconditionstateref.py +8 -8
  129. odxtools/progcode.py +9 -8
  130. odxtools/protstack.py +8 -7
  131. odxtools/relateddiagcommref.py +5 -5
  132. odxtools/relateddoc.py +8 -7
  133. odxtools/request.py +12 -13
  134. odxtools/response.py +12 -13
  135. odxtools/scaleconstr.py +8 -8
  136. odxtools/singleecujob.py +14 -13
  137. odxtools/snrefcontext.py +1 -1
  138. odxtools/specialdata.py +6 -5
  139. odxtools/specialdatagroup.py +13 -13
  140. odxtools/specialdatagroupcaption.py +5 -4
  141. odxtools/standardlengthtype.py +5 -13
  142. odxtools/state.py +5 -4
  143. odxtools/statechart.py +10 -9
  144. odxtools/statemachine.py +2 -2
  145. odxtools/statetransition.py +7 -7
  146. odxtools/statetransitionref.py +11 -11
  147. odxtools/staticfield.py +5 -4
  148. odxtools/structure.py +5 -5
  149. odxtools/subcomponent.py +18 -16
  150. odxtools/subcomponentparamconnector.py +8 -7
  151. odxtools/subcomponentpattern.py +7 -7
  152. odxtools/swvariable.py +6 -6
  153. odxtools/table.py +20 -21
  154. odxtools/tablediagcommconnector.py +7 -6
  155. odxtools/tablerow.py +57 -36
  156. odxtools/tablerowconnector.py +6 -6
  157. odxtools/teammember.py +14 -13
  158. odxtools/templates/macros/printParentRef.xml.jinja2 +3 -1
  159. odxtools/text.py +4 -4
  160. odxtools/unit.py +9 -8
  161. odxtools/unitgroup.py +9 -8
  162. odxtools/unitspec.py +15 -16
  163. odxtools/variablegroup.py +4 -5
  164. odxtools/variantpattern.py +3 -4
  165. odxtools/version.py +2 -2
  166. odxtools/writepdxfile.py +0 -19
  167. odxtools/xdoc.py +11 -10
  168. {odxtools-10.0.0.dist-info → odxtools-10.1.0.dist-info}/METADATA +1 -1
  169. odxtools-10.1.0.dist-info/RECORD +265 -0
  170. {odxtools-10.0.0.dist-info → odxtools-10.1.0.dist-info}/WHEEL +1 -1
  171. odxtools-10.0.0.dist-info/RECORD +0 -264
  172. {odxtools-10.0.0.dist-info → odxtools-10.1.0.dist-info}/entry_points.txt +0 -0
  173. {odxtools-10.0.0.dist-info → odxtools-10.1.0.dist-info}/licenses/LICENSE +0 -0
  174. {odxtools-10.0.0.dist-info → odxtools-10.1.0.dist-info}/top_level.txt +0 -0
@@ -1,20 +1,20 @@
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
 
6
6
  from ..comparamspec import ComparamSpec
7
7
  from ..exceptions import odxrequire
8
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
8
+ from ..odxdoccontext import OdxDocContext
9
+ from ..odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
9
10
  from ..parentref import ParentRef
10
11
  from ..protstack import ProtStack
11
12
  from ..snrefcontext import SnRefContext
12
13
  from ..utils import dataclass_fields_asdict
13
- #from .comparaminstance import ComparamInstance
14
14
  from .hierarchyelementraw import HierarchyElementRaw
15
15
 
16
16
 
17
- @dataclass
17
+ @dataclass(kw_only=True)
18
18
  class ProtocolRaw(HierarchyElementRaw):
19
19
  """This is the base class for diagnostic layers that describe a
20
20
  protocol which can be used to communicate with an ECU
@@ -24,8 +24,8 @@ class ProtocolRaw(HierarchyElementRaw):
24
24
  """
25
25
 
26
26
  comparam_spec_ref: OdxLinkRef
27
- prot_stack_snref: str | None
28
- parent_refs: list[ParentRef]
27
+ prot_stack_snref: str | None = None
28
+ parent_refs: list[ParentRef] = field(default_factory=list)
29
29
 
30
30
  @property
31
31
  def comparam_spec(self) -> ComparamSpec:
@@ -36,24 +36,23 @@ class ProtocolRaw(HierarchyElementRaw):
36
36
  return self._prot_stack
37
37
 
38
38
  @staticmethod
39
- def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "ProtocolRaw":
39
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ProtocolRaw":
40
40
  # objects contained by diagnostic layers exibit an additional
41
41
  # document fragment for the diag layer, so we use the document
42
42
  # fragments of the odx id of the diag layer for IDs of
43
43
  # contained objects.
44
- her = HierarchyElementRaw.from_et(et_element, doc_frags)
44
+ her = HierarchyElementRaw.from_et(et_element, context)
45
45
  kwargs = dataclass_fields_asdict(her)
46
- doc_frags = her.odx_id.doc_fragments
47
46
 
48
47
  comparam_spec_ref = OdxLinkRef.from_et(
49
- odxrequire(et_element.find("COMPARAM-SPEC-REF")), doc_frags)
48
+ odxrequire(et_element.find("COMPARAM-SPEC-REF")), context)
50
49
 
51
50
  prot_stack_snref = None
52
51
  if (prot_stack_snref_elem := et_element.find("PROT-STACK-SNREF")) is not None:
53
52
  prot_stack_snref = odxrequire(prot_stack_snref_elem.get("SHORT-NAME"))
54
53
 
55
54
  parent_refs = [
56
- ParentRef.from_et(pr_el, doc_frags)
55
+ ParentRef.from_et(pr_el, context)
57
56
  for pr_el in et_element.iterfind("PARENT-REFS/PARENT-REF")
58
57
  ]
59
58
 
@@ -1,11 +1,12 @@
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
 
6
6
  from .element import IdentifiableElement
7
7
  from .exceptions import odxrequire
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 .specialdatagroup import SpecialDataGroup
@@ -13,34 +14,31 @@ from .text import Text
13
14
  from .utils import dataclass_fields_asdict
14
15
 
15
16
 
16
- @dataclass
17
+ @dataclass(kw_only=True)
17
18
  class DiagnosticTroubleCode(IdentifiableElement):
18
19
  trouble_code: int
19
- display_trouble_code: str | None
20
+ display_trouble_code: str | None = None
20
21
  text: Text
21
- level: int | None
22
- sdgs: list[SpecialDataGroup]
22
+ level: int | None = None
23
+ sdgs: list[SpecialDataGroup] = field(default_factory=list)
23
24
 
24
- is_temporary_raw: bool | None
25
+ is_temporary_raw: bool | None = None
25
26
 
26
27
  @property
27
28
  def is_temporary(self) -> bool:
28
29
  return self.is_temporary_raw is True
29
30
 
30
31
  @staticmethod
31
- def from_et(et_element: ElementTree.Element,
32
- doc_frags: list[OdxDocFragment]) -> "DiagnosticTroubleCode":
33
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
32
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DiagnosticTroubleCode":
33
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
34
34
 
35
35
  trouble_code = int(odxrequire(et_element.findtext("TROUBLE-CODE")))
36
36
  display_trouble_code = et_element.findtext("DISPLAY-TROUBLE-CODE")
37
- text = Text.from_et(odxrequire(et_element.find("TEXT")), doc_frags)
37
+ text = Text.from_et(odxrequire(et_element.find("TEXT")), context)
38
38
  level = None
39
39
  if (level_str := et_element.findtext("LEVEL")) is not None:
40
40
  level = int(level_str)
41
- sdgs = [
42
- SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
43
- ]
41
+ sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
44
42
 
45
43
  is_temporary_raw = odxstr_to_bool(et_element.attrib.get("IS-TEMPORARY"))
46
44
 
odxtools/diagservice.py CHANGED
@@ -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, cast
4
4
  from xml.etree import ElementTree
5
5
 
@@ -9,7 +9,8 @@ from .diagcomm import DiagComm
9
9
  from .exceptions import DecodeError, DecodeMismatch, odxassert, odxraise, odxrequire
10
10
  from .message import Message
11
11
  from .nameditemlist import NamedItemList
12
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
12
+ from .odxdoccontext import OdxDocContext
13
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
13
14
  from .odxtypes import ParameterValue, odxstr_to_bool
14
15
  from .parameters.parameter import Parameter
15
16
  from .posresponsesuppressible import PosResponseSuppressible
@@ -20,21 +21,21 @@ from .transmode import TransMode
20
21
  from .utils import dataclass_fields_asdict
21
22
 
22
23
 
23
- @dataclass
24
+ @dataclass(kw_only=True)
24
25
  class DiagService(DiagComm):
25
26
  """Representation of a diagnostic service description.
26
27
  """
27
28
 
28
- comparam_refs: list[ComparamInstance]
29
+ comparam_refs: list[ComparamInstance] = field(default_factory=list)
29
30
  request_ref: OdxLinkRef
30
- pos_response_refs: list[OdxLinkRef]
31
- neg_response_refs: list[OdxLinkRef]
32
- pos_response_suppressible: PosResponseSuppressible | None
31
+ pos_response_refs: list[OdxLinkRef] = field(default_factory=list)
32
+ neg_response_refs: list[OdxLinkRef] = field(default_factory=list)
33
+ pos_response_suppressible: PosResponseSuppressible | None = None
33
34
 
34
- is_cyclic_raw: bool | None
35
- is_multiple_raw: bool | None
36
- addressing_raw: Addressing | None
37
- transmission_mode_raw: TransMode | None
35
+ is_cyclic_raw: bool | None = None
36
+ is_multiple_raw: bool | None = None
37
+ addressing_raw: Addressing | None = None
38
+ transmission_mode_raw: TransMode | None = None
38
39
 
39
40
  @property
40
41
  def comparams(self) -> NamedItemList[ComparamInstance]:
@@ -76,30 +77,30 @@ class DiagService(DiagComm):
76
77
  return self.request.free_parameters if self.request is not None else []
77
78
 
78
79
  @staticmethod
79
- def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "DiagService":
80
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DiagService":
80
81
 
81
- kwargs = dataclass_fields_asdict(DiagComm.from_et(et_element, doc_frags))
82
+ kwargs = dataclass_fields_asdict(DiagComm.from_et(et_element, context))
82
83
 
83
84
  comparam_refs = [
84
- ComparamInstance.from_et(el, doc_frags)
85
+ ComparamInstance.from_et(el, context)
85
86
  for el in et_element.iterfind("COMPARAM-REFS/COMPARAM-REF")
86
87
  ]
87
88
 
88
- request_ref = odxrequire(OdxLinkRef.from_et(et_element.find("REQUEST-REF"), doc_frags))
89
+ request_ref = odxrequire(OdxLinkRef.from_et(et_element.find("REQUEST-REF"), context))
89
90
 
90
91
  pos_response_refs = [
91
- odxrequire(OdxLinkRef.from_et(el, doc_frags))
92
+ odxrequire(OdxLinkRef.from_et(el, context))
92
93
  for el in et_element.iterfind("POS-RESPONSE-REFS/POS-RESPONSE-REF")
93
94
  ]
94
95
 
95
96
  neg_response_refs = [
96
- odxrequire(OdxLinkRef.from_et(el, doc_frags))
97
+ odxrequire(OdxLinkRef.from_et(el, context))
97
98
  for el in et_element.iterfind("NEG-RESPONSE-REFS/NEG-RESPONSE-REF")
98
99
  ]
99
100
 
100
101
  pos_response_suppressible = None
101
102
  if (prs_elem := et_element.find("POS-RESPONSE-SUPPRESSABLE")) is not None:
102
- pos_response_suppressible = PosResponseSuppressible.from_et(prs_elem, doc_frags)
103
+ pos_response_suppressible = PosResponseSuppressible.from_et(prs_elem, context)
103
104
 
104
105
  is_cyclic_raw = odxstr_to_bool(et_element.get("IS-CYCLIC"))
105
106
  is_multiple_raw = odxstr_to_bool(et_element.get("IS-MULTIPLE"))
odxtools/diagvariable.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import typing
3
- from dataclasses import dataclass
3
+ from dataclasses import dataclass, field
4
4
  from typing import Any, runtime_checkable
5
5
  from xml.etree import ElementTree
6
6
 
@@ -9,7 +9,8 @@ from .commrelation import CommRelation
9
9
  from .element import IdentifiableElement
10
10
  from .exceptions import odxrequire
11
11
  from .nameditemlist import NamedItemList
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 .odxtypes import odxstr_to_bool
14
15
  from .snrefcontext import SnRefContext
15
16
  from .specialdatagroup import SpecialDataGroup
@@ -28,26 +29,26 @@ class HasDiagVariables(typing.Protocol):
28
29
  ...
29
30
 
30
31
 
31
- @dataclass
32
+ @dataclass(kw_only=True)
32
33
  class DiagVariable(IdentifiableElement):
33
34
  """Representation of a diagnostic variable
34
35
  """
35
36
 
36
- admin_data: AdminData | None
37
- variable_group_ref: OdxLinkRef | None
38
- sw_variables: list[SwVariable]
37
+ admin_data: AdminData | None = None
38
+ variable_group_ref: OdxLinkRef | None = None
39
+ sw_variables: list[SwVariable] = field(default_factory=list)
39
40
 
40
41
  # a diag variable must specify either COMM-RELATIONS or a
41
42
  # reference to a table row
42
- comm_relations: list[CommRelation]
43
+ comm_relations: list[CommRelation] = field(default_factory=list)
43
44
 
44
45
  # these are nested inside the SNREF-TO-TABLEROW tag
45
- table_snref: str | None
46
- table_row_snref: str | None
46
+ table_snref: str | None = None
47
+ table_row_snref: str | None = None
47
48
 
48
- sdgs: list[SpecialDataGroup]
49
+ sdgs: list[SpecialDataGroup] = field(default_factory=list)
49
50
 
50
- is_read_before_write_raw: bool | None
51
+ is_read_before_write_raw: bool | None = None
51
52
 
52
53
  @property
53
54
  def table(self) -> Table | None:
@@ -66,17 +67,17 @@ class DiagVariable(IdentifiableElement):
66
67
  return self.is_read_before_write_raw is True
67
68
 
68
69
  @staticmethod
69
- def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "DiagVariable":
70
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
70
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DiagVariable":
71
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
71
72
 
72
- admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
73
- variable_group_ref = OdxLinkRef.from_et(et_element.find("VARIABLE-GROUP-REF"), doc_frags)
73
+ admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), context)
74
+ variable_group_ref = OdxLinkRef.from_et(et_element.find("VARIABLE-GROUP-REF"), context)
74
75
  sw_variables = NamedItemList([
75
- SwVariable.from_et(swv_elem, doc_frags)
76
+ SwVariable.from_et(swv_elem, context)
76
77
  for swv_elem in et_element.iterfind("SW-VARIABLES/SW-VARIABLE")
77
78
  ])
78
79
  comm_relations = [
79
- CommRelation.from_et(cr_elem, doc_frags)
80
+ CommRelation.from_et(cr_elem, context)
80
81
  for cr_elem in et_element.iterfind("COMM-RELATIONS/COMM-RELATION")
81
82
  ]
82
83
 
@@ -89,9 +90,7 @@ class DiagVariable(IdentifiableElement):
89
90
  table_row_snref_elem = odxrequire(snref_to_tablerow_elem.find("TABLE-ROW-SNREF"))
90
91
  table_row_snref = odxrequire(table_row_snref_elem.attrib.get("SHORT-NAME"))
91
92
 
92
- sdgs = [
93
- SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
94
- ]
93
+ sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
95
94
 
96
95
  is_read_before_write_raw = odxstr_to_bool(et_element.get("IS-READ-BEFORE-WRITE"))
97
96
 
odxtools/docrevision.py CHANGED
@@ -1,51 +1,52 @@
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
 
6
6
  from .companyrevisioninfo import CompanyRevisionInfo
7
7
  from .exceptions import odxrequire
8
8
  from .modification import Modification
9
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
9
+ from .odxdoccontext import OdxDocContext
10
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
10
11
  from .snrefcontext import SnRefContext
11
12
  from .teammember import TeamMember
12
13
 
13
14
 
14
- @dataclass
15
+ @dataclass(kw_only=True)
15
16
  class DocRevision:
16
17
  """
17
18
  Representation of a single revision of the relevant object.
18
19
  """
19
20
 
20
- team_member_ref: OdxLinkRef | None
21
- revision_label: str | None
22
- state: str | None
21
+ team_member_ref: OdxLinkRef | None = None
22
+ revision_label: str | None = None
23
+ state: str | None = None
23
24
  date: str
24
- tool: str | None
25
- company_revision_infos: list[CompanyRevisionInfo]
26
- modifications: list[Modification]
25
+ tool: str | None = None
26
+ company_revision_infos: list[CompanyRevisionInfo] = field(default_factory=list)
27
+ modifications: list[Modification] = field(default_factory=list)
27
28
 
28
29
  @property
29
30
  def team_member(self) -> TeamMember | None:
30
31
  return self._team_member
31
32
 
32
33
  @staticmethod
33
- def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "DocRevision":
34
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DocRevision":
34
35
 
35
- team_member_ref = OdxLinkRef.from_et(et_element.find("TEAM-MEMBER-REF"), doc_frags)
36
+ team_member_ref = OdxLinkRef.from_et(et_element.find("TEAM-MEMBER-REF"), context)
36
37
  revision_label = et_element.findtext("REVISION-LABEL")
37
38
  state = et_element.findtext("STATE")
38
39
  date = odxrequire(et_element.findtext("DATE"))
39
40
  tool = et_element.findtext("TOOL")
40
41
 
41
42
  company_revision_infos = [
42
- CompanyRevisionInfo.from_et(cri_elem, doc_frags)
43
+ CompanyRevisionInfo.from_et(cri_elem, context)
43
44
  for cri_elem in et_element.iterfind("COMPANY-REVISION-INFOS/"
44
45
  "COMPANY-REVISION-INFO")
45
46
  ]
46
47
 
47
48
  modifications = [
48
- Modification.from_et(mod_elem, doc_frags)
49
+ Modification.from_et(mod_elem, context)
49
50
  for mod_elem in et_element.iterfind("MODIFICATIONS/MODIFICATION")
50
51
  ]
51
52
 
odxtools/dopbase.py CHANGED
@@ -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
 
@@ -7,14 +7,15 @@ from .admindata import AdminData
7
7
  from .decodestate import DecodeState
8
8
  from .element import IdentifiableElement
9
9
  from .encodestate import EncodeState
10
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
10
+ from .odxdoccontext import OdxDocContext
11
+ from .odxlink import OdxLinkDatabase, OdxLinkId
11
12
  from .odxtypes import ParameterValue
12
13
  from .snrefcontext import SnRefContext
13
14
  from .specialdatagroup import SpecialDataGroup
14
15
  from .utils import dataclass_fields_asdict
15
16
 
16
17
 
17
- @dataclass
18
+ @dataclass(kw_only=True)
18
19
  class DopBase(IdentifiableElement):
19
20
  """Base class for all (simple and complex) data object properties.
20
21
 
@@ -24,21 +25,19 @@ class DopBase(IdentifiableElement):
24
25
 
25
26
  """
26
27
 
27
- admin_data: AdminData | None
28
- sdgs: list[SpecialDataGroup]
28
+ admin_data: AdminData | None = None
29
+ sdgs: list[SpecialDataGroup] = field(default_factory=list)
29
30
 
30
31
  @staticmethod
31
- def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "DopBase":
32
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DopBase":
32
33
 
33
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
34
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
34
35
 
35
36
  admin_data = None
36
37
  if (admin_data_elem := et_element.find("ADMIN-DATA")) is not None:
37
- admin_data = AdminData.from_et(admin_data_elem, doc_frags)
38
+ admin_data = AdminData.from_et(admin_data_elem, context)
38
39
 
39
- sdgs = [
40
- SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
41
- ]
40
+ sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
42
41
 
43
42
  return DopBase(admin_data=admin_data, sdgs=sdgs, **kwargs)
44
43
 
odxtools/dtcconnector.py CHANGED
@@ -7,12 +7,13 @@ from .diagnostictroublecode import DiagnosticTroubleCode
7
7
  from .dtcdop import DtcDop
8
8
  from .element import NamedElement
9
9
  from .exceptions import odxrequire
10
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
10
+ from .odxdoccontext import OdxDocContext
11
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
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 DtcConnector(NamedElement):
17
18
  dtc_dop_ref: OdxLinkRef
18
19
  dtc_snref: str
@@ -26,10 +27,10 @@ class DtcConnector(NamedElement):
26
27
  return self._dtc
27
28
 
28
29
  @staticmethod
29
- def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "DtcConnector":
30
- kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
30
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DtcConnector":
31
+ kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context))
31
32
 
32
- dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"), doc_frags))
33
+ dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"), context))
33
34
  dtc_snref_el = odxrequire(et_element.find("DTC-SNREF"))
34
35
  dtc_snref = odxrequire(dtc_snref_el.get("SHORT-NAME"))
35
36
 
odxtools/dtcdop.py CHANGED
@@ -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, cast
4
4
  from xml.etree import ElementTree
5
5
 
@@ -16,23 +16,24 @@ from .encodestate import EncodeState
16
16
  from .exceptions import DecodeError, EncodeError, odxassert, odxraise, odxrequire
17
17
  from .linkeddtcdop import LinkedDtcDop
18
18
  from .nameditemlist import NamedItemList
19
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
19
+ from .odxdoccontext import OdxDocContext
20
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
20
21
  from .odxtypes import ParameterValue, odxstr_to_bool
21
22
  from .physicaltype import PhysicalType
22
23
  from .snrefcontext import SnRefContext
23
24
  from .utils import dataclass_fields_asdict
24
25
 
25
26
 
26
- @dataclass
27
+ @dataclass(kw_only=True)
27
28
  class DtcDop(DopBase):
28
29
  """A DOP describing a diagnostic trouble code"""
29
30
 
30
31
  diag_coded_type: DiagCodedType
31
32
  physical_type: PhysicalType
32
33
  compu_method: CompuMethod
33
- dtcs_raw: list[DiagnosticTroubleCode | OdxLinkRef]
34
- linked_dtc_dops_raw: list[LinkedDtcDop]
35
- is_visible_raw: bool | None
34
+ dtcs_raw: list[DiagnosticTroubleCode | OdxLinkRef] = field(default_factory=list)
35
+ linked_dtc_dops_raw: list[LinkedDtcDop] = field(default_factory=list)
36
+ is_visible_raw: bool | None = None
36
37
 
37
38
  @property
38
39
  def dtcs(self) -> NamedItemList[DiagnosticTroubleCode]:
@@ -47,17 +48,16 @@ class DtcDop(DopBase):
47
48
  return self.is_visible_raw is True
48
49
 
49
50
  @staticmethod
50
- def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "DtcDop":
51
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DtcDop":
51
52
  """Reads a DTC-DOP."""
52
- kwargs = dataclass_fields_asdict(DopBase.from_et(et_element, doc_frags))
53
+ kwargs = dataclass_fields_asdict(DopBase.from_et(et_element, context))
53
54
 
54
55
  diag_coded_type = create_any_diag_coded_type_from_et(
55
- odxrequire(et_element.find("DIAG-CODED-TYPE")), doc_frags)
56
- physical_type = PhysicalType.from_et(
57
- odxrequire(et_element.find("PHYSICAL-TYPE")), doc_frags)
56
+ odxrequire(et_element.find("DIAG-CODED-TYPE")), context)
57
+ physical_type = PhysicalType.from_et(odxrequire(et_element.find("PHYSICAL-TYPE")), context)
58
58
  compu_method = create_any_compu_method_from_et(
59
59
  odxrequire(et_element.find("COMPU-METHOD")),
60
- doc_frags,
60
+ context,
61
61
  internal_type=diag_coded_type.base_data_type,
62
62
  physical_type=physical_type.base_data_type,
63
63
  )
@@ -65,12 +65,12 @@ class DtcDop(DopBase):
65
65
  if (dtcs_elem := et_element.find("DTCS")) is not None:
66
66
  for dtc_proxy_elem in dtcs_elem:
67
67
  if dtc_proxy_elem.tag == "DTC":
68
- dtcs_raw.append(DiagnosticTroubleCode.from_et(dtc_proxy_elem, doc_frags))
68
+ dtcs_raw.append(DiagnosticTroubleCode.from_et(dtc_proxy_elem, context))
69
69
  elif dtc_proxy_elem.tag == "DTC-REF":
70
- dtcs_raw.append(OdxLinkRef.from_et(dtc_proxy_elem, doc_frags))
70
+ dtcs_raw.append(OdxLinkRef.from_et(dtc_proxy_elem, context))
71
71
 
72
72
  linked_dtc_dops_raw = [
73
- LinkedDtcDop.from_et(dtc_ref_elem, doc_frags)
73
+ LinkedDtcDop.from_et(dtc_ref_elem, context)
74
74
  for dtc_ref_elem in et_element.iterfind("LINKED-DTC-DOPS/"
75
75
  "LINKED-DTC-DOP")
76
76
  ]
@@ -12,13 +12,14 @@ from .dynenddopref import DynEndDopRef
12
12
  from .encodestate import EncodeState
13
13
  from .exceptions import DecodeError, EncodeError, odxassert, odxraise, odxrequire
14
14
  from .field import Field
15
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
15
+ from .odxdoccontext import OdxDocContext
16
+ from .odxlink import OdxLinkDatabase, OdxLinkId
16
17
  from .odxtypes import AtomicOdxType, ParameterValue
17
18
  from .snrefcontext import SnRefContext
18
19
  from .utils import dataclass_fields_asdict
19
20
 
20
21
 
21
- @dataclass
22
+ @dataclass(kw_only=True)
22
23
  class DynamicEndmarkerField(Field):
23
24
  """Array of a structure with variable length determined by a termination sequence"""
24
25
 
@@ -33,14 +34,13 @@ class DynamicEndmarkerField(Field):
33
34
  return self._termination_value
34
35
 
35
36
  @staticmethod
36
- def from_et(et_element: ElementTree.Element,
37
- doc_frags: list[OdxDocFragment]) -> "DynamicEndmarkerField":
38
- kwargs = dataclass_fields_asdict(Field.from_et(et_element, doc_frags))
37
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DynamicEndmarkerField":
38
+ kwargs = dataclass_fields_asdict(Field.from_et(et_element, context))
39
39
 
40
40
  # ODX 2.0 uses DATA-OBJECT-PROP-REF
41
41
  # ODX 2.2 uses DYN-END-DOP-REF
42
42
  dop_ref = et_element.find("DYN-END-DOP-REF") or et_element.find("DATA-OBJECT-PROP-REF")
43
- dyn_end_dop_ref = DynEndDopRef.from_et(odxrequire(dop_ref), doc_frags)
43
+ dyn_end_dop_ref = DynEndDopRef.from_et(odxrequire(dop_ref), context)
44
44
 
45
45
  return DynamicEndmarkerField(dyn_end_dop_ref=dyn_end_dop_ref, **kwargs)
46
46
 
@@ -11,27 +11,27 @@ from .determinenumberofitems import DetermineNumberOfItems
11
11
  from .encodestate import EncodeState
12
12
  from .exceptions import DecodeError, EncodeError, odxassert, odxraise, odxrequire
13
13
  from .field import Field
14
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
14
+ from .odxdoccontext import OdxDocContext
15
+ from .odxlink import OdxLinkDatabase, OdxLinkId
15
16
  from .odxtypes import ParameterValue
16
17
  from .snrefcontext import SnRefContext
17
18
  from .utils import dataclass_fields_asdict
18
19
 
19
20
 
20
- @dataclass
21
+ @dataclass(kw_only=True)
21
22
  class DynamicLengthField(Field):
22
23
  """Array of structure with length field"""
23
24
  offset: int
24
25
  determine_number_of_items: DetermineNumberOfItems
25
26
 
26
27
  @staticmethod
27
- def from_et(et_element: ElementTree.Element,
28
- doc_frags: list[OdxDocFragment]) -> "DynamicLengthField":
29
- kwargs = dataclass_fields_asdict(Field.from_et(et_element, doc_frags))
28
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DynamicLengthField":
29
+ kwargs = dataclass_fields_asdict(Field.from_et(et_element, context))
30
30
 
31
31
  offset = int(odxrequire(et_element.findtext('OFFSET')))
32
32
  determine_number_of_items = DetermineNumberOfItems.from_et(
33
33
  odxrequire(et_element.find('DETERMINE-NUMBER-OF-ITEMS')),
34
- doc_frags,
34
+ context,
35
35
  )
36
36
 
37
37
  return DynamicLengthField(
@@ -1,22 +1,22 @@
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
 
6
6
  from .dyniddefmodeinfo import DynIdDefModeInfo
7
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
7
+ from .odxdoccontext import OdxDocContext
8
+ from .odxlink import OdxLinkDatabase, OdxLinkId
8
9
  from .snrefcontext import SnRefContext
9
10
 
10
11
 
11
- @dataclass
12
+ @dataclass(kw_only=True)
12
13
  class DynDefinedSpec:
13
- dyn_id_def_mode_infos: list[DynIdDefModeInfo]
14
+ dyn_id_def_mode_infos: list[DynIdDefModeInfo] = field(default_factory=list)
14
15
 
15
16
  @staticmethod
16
- def from_et(et_element: ElementTree.Element,
17
- doc_frags: list[OdxDocFragment]) -> "DynDefinedSpec":
17
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DynDefinedSpec":
18
18
  dyn_id_def_mode_infos = [
19
- DynIdDefModeInfo.from_et(x, doc_frags)
19
+ DynIdDefModeInfo.from_et(x, context)
20
20
  for x in et_element.iterfind("DYN-ID-DEF-MODE-INFOS/DYN-ID-DEF-MODE-INFO")
21
21
  ]
22
22
  return DynDefinedSpec(dyn_id_def_mode_infos=dyn_id_def_mode_infos)