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
@@ -17,7 +17,8 @@ from ..diagservice import DiagService
17
17
  from ..exceptions import OdxWarning, odxassert, odxraise
18
18
  from ..functionalclass import FunctionalClass
19
19
  from ..nameditemlist import NamedItemList, OdxNamed
20
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
20
+ from ..odxdoccontext import OdxDocContext
21
+ from ..odxlink import OdxLinkDatabase, OdxLinkId
21
22
  from ..parentref import ParentRef
22
23
  from ..response import Response
23
24
  from ..singleecujob import SingleEcuJob
@@ -30,13 +31,13 @@ from .diaglayer import DiagLayer
30
31
  from .hierarchyelementraw import HierarchyElementRaw
31
32
 
32
33
  if TYPE_CHECKING:
33
- from .database import Database
34
+ from ..database import Database
34
35
  from .protocol import Protocol
35
36
 
36
37
  TNamed = TypeVar("TNamed", bound=OdxNamed)
37
38
 
38
39
 
39
- @dataclass
40
+ @dataclass(kw_only=True)
40
41
  class HierarchyElement(DiagLayer):
41
42
  """This is the base class for diagnostic layers that may be involved in value inheritance
42
43
  """
@@ -46,9 +47,8 @@ class HierarchyElement(DiagLayer):
46
47
  return cast(HierarchyElementRaw, self.diag_layer_raw)
47
48
 
48
49
  @staticmethod
49
- def from_et(et_element: ElementTree.Element,
50
- doc_frags: list[OdxDocFragment]) -> "HierarchyElement":
51
- hierarchy_element_raw = HierarchyElementRaw.from_et(et_element, doc_frags)
50
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "HierarchyElement":
51
+ hierarchy_element_raw = HierarchyElementRaw.from_et(et_element, context)
52
52
 
53
53
  return HierarchyElement(diag_layer_raw=hierarchy_element_raw)
54
54
 
@@ -121,13 +121,13 @@ class HierarchyElement(DiagLayer):
121
121
  unit_groups = self._compute_available_unit_groups()
122
122
 
123
123
  # convenience variable for the locally-defined unit spec
124
- local_unit_spec: UnitSpec | None
124
+ local_unit_spec: UnitSpec | None = None
125
125
  if self.diag_layer_raw.diag_data_dictionary_spec is not None:
126
126
  local_unit_spec = self.diag_layer_raw.diag_data_dictionary_spec.unit_spec
127
127
  else:
128
128
  local_unit_spec = None
129
129
 
130
- unit_spec: UnitSpec | None
130
+ unit_spec: UnitSpec | None = None
131
131
  if local_unit_spec is None and not unit_groups:
132
132
  # no locally defined unit spec and no inherited unit groups
133
133
  unit_spec = None
@@ -587,7 +587,7 @@ class HierarchyElement(DiagLayer):
587
587
 
588
588
  from .protocol import Protocol
589
589
 
590
- protocol_name: str | None
590
+ protocol_name: str | None = None
591
591
  if isinstance(protocol, Protocol):
592
592
  protocol_name = protocol.short_name
593
593
  else:
@@ -1,37 +1,36 @@
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 ..comparaminstance import ComparamInstance
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
  from ..utils import dataclass_fields_asdict
10
11
  from .diaglayerraw import DiagLayerRaw
11
12
 
12
13
 
13
- @dataclass
14
+ @dataclass(kw_only=True)
14
15
  class HierarchyElementRaw(DiagLayerRaw):
15
16
  """This is the base class for diagnostic layers that may be involved in value inheritance
16
17
 
17
18
  This class represents the data present in the XML, not the "logical" view.
18
19
  """
19
20
 
20
- comparam_refs: list[ComparamInstance]
21
+ comparam_refs: list[ComparamInstance] = field(default_factory=list)
21
22
 
22
23
  @staticmethod
23
- def from_et(et_element: ElementTree.Element,
24
- doc_frags: list[OdxDocFragment]) -> "HierarchyElementRaw":
24
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "HierarchyElementRaw":
25
25
  # objects contained by diagnostic layers exibit an additional
26
26
  # document fragment for the diag layer, so we use the document
27
27
  # fragments of the odx id of the diag layer for IDs of
28
28
  # contained objects.
29
- dlr = DiagLayerRaw.from_et(et_element, doc_frags)
29
+ dlr = DiagLayerRaw.from_et(et_element, context)
30
30
  kwargs = dataclass_fields_asdict(dlr)
31
- doc_frags = dlr.odx_id.doc_fragments
32
31
 
33
32
  comparam_refs = [
34
- ComparamInstance.from_et(el, doc_frags)
33
+ ComparamInstance.from_et(el, context)
35
34
  for el in et_element.iterfind("COMPARAM-REFS/COMPARAM-REF")
36
35
  ]
37
36
 
@@ -6,13 +6,13 @@ from xml.etree import ElementTree
6
6
 
7
7
  from ..comparamspec import ComparamSpec
8
8
  from ..exceptions import odxassert
9
- from ..odxlink import OdxDocFragment
9
+ from ..odxdoccontext import OdxDocContext
10
10
  from ..protstack import ProtStack
11
11
  from .hierarchyelement import HierarchyElement
12
12
  from .protocolraw import ProtocolRaw
13
13
 
14
14
 
15
- @dataclass
15
+ @dataclass(kw_only=True)
16
16
  class Protocol(HierarchyElement):
17
17
  """This is the class for primitives that are common for a given communication protocol
18
18
 
@@ -33,8 +33,8 @@ class Protocol(HierarchyElement):
33
33
  return self.protocol_raw.prot_stack
34
34
 
35
35
  @staticmethod
36
- def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Protocol":
37
- protocol_raw = ProtocolRaw.from_et(et_element, doc_frags)
36
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Protocol":
37
+ protocol_raw = ProtocolRaw.from_et(et_element, context)
38
38
 
39
39
  return Protocol(diag_layer_raw=protocol_raw)
40
40
 
@@ -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
  ]