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,6 +1,5 @@
1
1
  # SPDX-License-Identifier: MIT
2
- from copy import copy
3
- from dataclasses import dataclass
2
+ from dataclasses import dataclass, field
4
3
  from typing import Any, cast
5
4
  from xml.etree import ElementTree
6
5
 
@@ -11,11 +10,12 @@ from ..diagcomm import DiagComm
11
10
  from ..diagdatadictionaryspec import DiagDataDictionarySpec
12
11
  from ..diagservice import DiagService
13
12
  from ..element import IdentifiableElement
14
- from ..exceptions import odxassert, odxraise, odxrequire
13
+ from ..exceptions import odxassert, odxraise
15
14
  from ..functionalclass import FunctionalClass
16
15
  from ..library import Library
17
16
  from ..nameditemlist import NamedItemList
18
- from ..odxlink import DocType, OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
17
+ from ..odxdoccontext import OdxDocContext
18
+ from ..odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
19
19
  from ..request import Request
20
20
  from ..response import Response
21
21
  from ..singleecujob import SingleEcuJob
@@ -27,7 +27,7 @@ from ..utils import dataclass_fields_asdict
27
27
  from .diaglayertype import DiagLayerType
28
28
 
29
29
 
30
- @dataclass
30
+ @dataclass(kw_only=True)
31
31
  class DiagLayerRaw(IdentifiableElement):
32
32
  """This class internalizes all data represented by the DIAG-LAYER
33
33
  XML tag and its derivatives.
@@ -36,21 +36,21 @@ class DiagLayerRaw(IdentifiableElement):
36
36
  """
37
37
 
38
38
  variant_type: DiagLayerType
39
- admin_data: AdminData | None
40
- company_datas: NamedItemList[CompanyData]
41
- functional_classes: NamedItemList[FunctionalClass]
42
- diag_data_dictionary_spec: DiagDataDictionarySpec | None
43
- diag_comms_raw: list[OdxLinkRef | DiagComm]
44
- requests: NamedItemList[Request]
45
- positive_responses: NamedItemList[Response]
46
- negative_responses: NamedItemList[Response]
47
- global_negative_responses: NamedItemList[Response]
48
- import_refs: list[OdxLinkRef]
49
- state_charts: NamedItemList[StateChart]
50
- additional_audiences: NamedItemList[AdditionalAudience]
51
- sub_components: NamedItemList[SubComponent]
52
- libraries: NamedItemList[Library]
53
- sdgs: list[SpecialDataGroup]
39
+ admin_data: AdminData | None = None
40
+ company_datas: NamedItemList[CompanyData] = field(default_factory=NamedItemList)
41
+ functional_classes: NamedItemList[FunctionalClass] = field(default_factory=NamedItemList)
42
+ diag_data_dictionary_spec: DiagDataDictionarySpec | None = None
43
+ diag_comms_raw: list[OdxLinkRef | DiagComm] = field(default_factory=list)
44
+ requests: NamedItemList[Request] = field(default_factory=NamedItemList)
45
+ positive_responses: NamedItemList[Response] = field(default_factory=NamedItemList)
46
+ negative_responses: NamedItemList[Response] = field(default_factory=NamedItemList)
47
+ global_negative_responses: NamedItemList[Response] = field(default_factory=NamedItemList)
48
+ import_refs: list[OdxLinkRef] = field(default_factory=list)
49
+ state_charts: NamedItemList[StateChart] = field(default_factory=NamedItemList)
50
+ additional_audiences: NamedItemList[AdditionalAudience] = field(default_factory=NamedItemList)
51
+ sub_components: NamedItemList[SubComponent] = field(default_factory=NamedItemList)
52
+ libraries: NamedItemList[Library] = field(default_factory=NamedItemList)
53
+ sdgs: list[SpecialDataGroup] = field(default_factory=list)
54
54
 
55
55
  @property
56
56
  def diag_comms(self) -> NamedItemList[DiagComm]:
@@ -70,98 +70,89 @@ class DiagLayerRaw(IdentifiableElement):
70
70
  return self._single_ecu_jobs
71
71
 
72
72
  @staticmethod
73
- def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "DiagLayerRaw":
73
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DiagLayerRaw":
74
74
  try:
75
75
  variant_type = DiagLayerType(et_element.tag)
76
76
  except ValueError:
77
77
  variant_type = cast(DiagLayerType, None)
78
78
  odxraise(f"Encountered unknown diagnostic layer type '{et_element.tag}'")
79
79
 
80
- short_name = odxrequire(et_element.findtext("SHORT-NAME"))
81
-
82
- # extend the applicable ODX "document fragments" for the diag layer objects
83
- doc_frags = copy(doc_frags)
84
- doc_frags.append(OdxDocFragment(short_name, DocType.LAYER))
85
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
80
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
86
81
 
87
82
  admin_data = None
88
83
  if (admin_data_elem := et_element.find("ADMIN-DATA")) is not None:
89
- admin_data = AdminData.from_et(admin_data_elem, doc_frags)
84
+ admin_data = AdminData.from_et(admin_data_elem, context)
90
85
 
91
86
  company_datas = NamedItemList([
92
- CompanyData.from_et(cd_el, doc_frags)
87
+ CompanyData.from_et(cd_el, context)
93
88
  for cd_el in et_element.iterfind("COMPANY-DATAS/COMPANY-DATA")
94
89
  ])
95
90
 
96
91
  functional_classes = NamedItemList([
97
- FunctionalClass.from_et(fc_el, doc_frags)
92
+ FunctionalClass.from_et(fc_el, context)
98
93
  for fc_el in et_element.iterfind("FUNCT-CLASSS/FUNCT-CLASS")
99
94
  ])
100
95
 
101
96
  diag_data_dictionary_spec = None
102
97
  if (ddds_elem := et_element.find("DIAG-DATA-DICTIONARY-SPEC")) is not None:
103
- diag_data_dictionary_spec = DiagDataDictionarySpec.from_et(ddds_elem, doc_frags)
98
+ diag_data_dictionary_spec = DiagDataDictionarySpec.from_et(ddds_elem, context)
104
99
 
105
100
  diag_comms_raw: list[OdxLinkRef | DiagComm] = []
106
101
  if (dc_elems := et_element.find("DIAG-COMMS")) is not None:
107
102
  for dc_proxy_elem in dc_elems:
108
103
  dc: OdxLinkRef | DiagComm
109
104
  if dc_proxy_elem.tag == "DIAG-COMM-REF":
110
- dc = OdxLinkRef.from_et(dc_proxy_elem, doc_frags)
105
+ dc = OdxLinkRef.from_et(dc_proxy_elem, context)
111
106
  elif dc_proxy_elem.tag == "DIAG-SERVICE":
112
- dc = DiagService.from_et(dc_proxy_elem, doc_frags)
107
+ dc = DiagService.from_et(dc_proxy_elem, context)
113
108
  else:
114
109
  odxassert(dc_proxy_elem.tag == "SINGLE-ECU-JOB")
115
- dc = SingleEcuJob.from_et(dc_proxy_elem, doc_frags)
110
+ dc = SingleEcuJob.from_et(dc_proxy_elem, context)
116
111
 
117
112
  diag_comms_raw.append(dc)
118
113
 
119
114
  requests = NamedItemList([
120
- Request.from_et(rq_elem, doc_frags)
121
- for rq_elem in et_element.iterfind("REQUESTS/REQUEST")
115
+ Request.from_et(rq_elem, context) for rq_elem in et_element.iterfind("REQUESTS/REQUEST")
122
116
  ])
123
117
 
124
118
  positive_responses = NamedItemList([
125
- Response.from_et(rs_elem, doc_frags)
119
+ Response.from_et(rs_elem, context)
126
120
  for rs_elem in et_element.iterfind("POS-RESPONSES/POS-RESPONSE")
127
121
  ])
128
122
 
129
123
  negative_responses = NamedItemList([
130
- Response.from_et(rs_elem, doc_frags)
124
+ Response.from_et(rs_elem, context)
131
125
  for rs_elem in et_element.iterfind("NEG-RESPONSES/NEG-RESPONSE")
132
126
  ])
133
127
 
134
128
  global_negative_responses = NamedItemList([
135
- Response.from_et(rs_elem, doc_frags)
129
+ Response.from_et(rs_elem, context)
136
130
  for rs_elem in et_element.iterfind("GLOBAL-NEG-RESPONSES/GLOBAL-NEG-RESPONSE")
137
131
  ])
138
132
 
139
133
  import_refs = [
140
- OdxLinkRef.from_et(el, doc_frags)
141
- for el in et_element.iterfind("IMPORT-REFS/IMPORT-REF")
134
+ OdxLinkRef.from_et(el, context) for el in et_element.iterfind("IMPORT-REFS/IMPORT-REF")
142
135
  ]
143
136
 
144
137
  state_charts = NamedItemList([
145
- StateChart.from_et(el, doc_frags)
138
+ StateChart.from_et(el, context)
146
139
  for el in et_element.iterfind("STATE-CHARTS/STATE-CHART")
147
140
  ])
148
141
 
149
142
  additional_audiences = NamedItemList([
150
- AdditionalAudience.from_et(el, doc_frags)
143
+ AdditionalAudience.from_et(el, context)
151
144
  for el in et_element.iterfind("ADDITIONAL-AUDIENCES/ADDITIONAL-AUDIENCE")
152
145
  ])
153
146
 
154
147
  sub_components = NamedItemList([
155
- SubComponent.from_et(el, doc_frags)
148
+ SubComponent.from_et(el, context)
156
149
  for el in et_element.iterfind("SUB-COMPONENTS/SUB-COMPONENT")
157
150
  ])
158
151
 
159
152
  libraries = NamedItemList(
160
- [Library.from_et(el, doc_frags) for el in et_element.iterfind("LIBRARYS/LIBRARY")])
153
+ [Library.from_et(el, context) for el in et_element.iterfind("LIBRARYS/LIBRARY")])
161
154
 
162
- sdgs = [
163
- SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
164
- ]
155
+ sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
165
156
 
166
157
  # Create DiagLayer
167
158
  return DiagLayerRaw(
@@ -7,17 +7,18 @@ from xml.etree import ElementTree
7
7
  from ..diagvariable import DiagVariable
8
8
  from ..exceptions import odxassert
9
9
  from ..nameditemlist import NamedItemList
10
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkRef
10
+ from ..odxdoccontext import OdxDocContext
11
+ from ..odxlink import OdxLinkDatabase, OdxLinkRef
11
12
  from ..snrefcontext import SnRefContext
12
13
  from ..variablegroup import VariableGroup
13
14
  from .diaglayer import DiagLayer
14
15
  from .ecushareddataraw import EcuSharedDataRaw
15
16
 
16
17
  if TYPE_CHECKING:
17
- from .database import Database
18
+ from ..database import Database
18
19
 
19
20
 
20
- @dataclass
21
+ @dataclass(kw_only=True)
21
22
  class EcuSharedData(DiagLayer):
22
23
  """This is a diagnostic layer for data shared across others
23
24
  """
@@ -39,9 +40,8 @@ class EcuSharedData(DiagLayer):
39
40
  return self.ecu_shared_data_raw.variable_groups
40
41
 
41
42
  @staticmethod
42
- def from_et(et_element: ElementTree.Element,
43
- doc_frags: list[OdxDocFragment]) -> "EcuSharedData":
44
- ecu_shared_data_raw = EcuSharedDataRaw.from_et(et_element, doc_frags)
43
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "EcuSharedData":
44
+ ecu_shared_data_raw = EcuSharedDataRaw.from_et(et_element, context)
45
45
 
46
46
  return EcuSharedData(diag_layer_raw=ecu_shared_data_raw)
47
47
 
@@ -1,56 +1,55 @@
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 ..diagvariable import DiagVariable
7
7
  from ..exceptions import odxraise
8
8
  from ..nameditemlist import NamedItemList
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 ..utils import dataclass_fields_asdict
12
13
  from ..variablegroup import VariableGroup
13
14
  from .diaglayerraw import DiagLayerRaw
14
15
 
15
16
 
16
- @dataclass
17
+ @dataclass(kw_only=True)
17
18
  class EcuSharedDataRaw(DiagLayerRaw):
18
19
  """This is a diagnostic layer for data shared accross others
19
20
  """
20
21
 
21
- diag_variables_raw: list[DiagVariable | OdxLinkRef]
22
- variable_groups: NamedItemList[VariableGroup]
22
+ diag_variables_raw: list[DiagVariable | OdxLinkRef] = field(default_factory=list)
23
+ variable_groups: NamedItemList[VariableGroup] = field(default_factory=NamedItemList)
23
24
 
24
25
  @property
25
26
  def diag_variables(self) -> NamedItemList[DiagVariable]:
26
27
  return self._diag_variables
27
28
 
28
29
  @staticmethod
29
- def from_et(et_element: ElementTree.Element,
30
- doc_frags: list[OdxDocFragment]) -> "EcuSharedDataRaw":
30
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "EcuSharedDataRaw":
31
31
  # objects contained by diagnostic layers exibit an additional
32
32
  # document fragment for the diag layer, so we use the document
33
33
  # fragments of the odx id of the diag layer for IDs of
34
34
  # contained objects.
35
- dlr = DiagLayerRaw.from_et(et_element, doc_frags)
35
+ dlr = DiagLayerRaw.from_et(et_element, context)
36
36
  kwargs = dataclass_fields_asdict(dlr)
37
- doc_frags = dlr.odx_id.doc_fragments
38
37
 
39
38
  diag_variables_raw: list[DiagVariable | OdxLinkRef] = []
40
39
  if (dv_elems := et_element.find("DIAG-VARIABLES")) is not None:
41
40
  for dv_proxy_elem in dv_elems:
42
41
  dv_proxy: OdxLinkRef | DiagVariable
43
42
  if dv_proxy_elem.tag == "DIAG-VARIABLE-REF":
44
- dv_proxy = OdxLinkRef.from_et(dv_proxy_elem, doc_frags)
43
+ dv_proxy = OdxLinkRef.from_et(dv_proxy_elem, context)
45
44
  elif dv_proxy_elem.tag == "DIAG-VARIABLE":
46
- dv_proxy = DiagVariable.from_et(dv_proxy_elem, doc_frags)
45
+ dv_proxy = DiagVariable.from_et(dv_proxy_elem, context)
47
46
  else:
48
47
  odxraise()
49
48
 
50
49
  diag_variables_raw.append(dv_proxy)
51
50
 
52
51
  variable_groups = NamedItemList([
53
- VariableGroup.from_et(vg_elem, doc_frags)
52
+ VariableGroup.from_et(vg_elem, context)
54
53
  for vg_elem in et_element.iterfind("VARIABLE-GROUPS/VARIABLE-GROUP")
55
54
  ])
56
55
 
@@ -12,7 +12,8 @@ from ..dyndefinedspec import DynDefinedSpec
12
12
  from ..ecuvariantpattern import EcuVariantPattern
13
13
  from ..exceptions import odxassert
14
14
  from ..nameditemlist import NamedItemList
15
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkRef
15
+ from ..odxdoccontext import OdxDocContext
16
+ from ..odxlink import OdxLinkDatabase, OdxLinkRef
16
17
  from ..parentref import ParentRef
17
18
  from ..variablegroup import HasVariableGroups, VariableGroup
18
19
  from .basevariant import BaseVariant
@@ -21,7 +22,7 @@ from .ecuvariantraw import EcuVariantRaw
21
22
  from .hierarchyelement import HierarchyElement
22
23
 
23
24
 
24
- @dataclass
25
+ @dataclass(kw_only=True)
25
26
  class EcuVariant(HierarchyElement):
26
27
 
27
28
  @property
@@ -75,8 +76,8 @@ class EcuVariant(HierarchyElement):
75
76
  #######
76
77
 
77
78
  @staticmethod
78
- def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "EcuVariant":
79
- ecu_variant_raw = EcuVariantRaw.from_et(et_element, doc_frags)
79
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "EcuVariant":
80
+ ecu_variant_raw = EcuVariantRaw.from_et(et_element, context)
80
81
 
81
82
  return EcuVariant(diag_layer_raw=ecu_variant_raw)
82
83
 
@@ -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
 
@@ -8,7 +8,8 @@ from ..dyndefinedspec import DynDefinedSpec
8
8
  from ..ecuvariantpattern import EcuVariantPattern
9
9
  from ..exceptions import odxraise
10
10
  from ..nameditemlist import NamedItemList
11
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
11
+ from ..odxdoccontext import OdxDocContext
12
+ from ..odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
12
13
  from ..parentref import ParentRef
13
14
  from ..snrefcontext import SnRefContext
14
15
  from ..utils import dataclass_fields_asdict
@@ -16,59 +17,57 @@ from ..variablegroup import VariableGroup
16
17
  from .hierarchyelementraw import HierarchyElementRaw
17
18
 
18
19
 
19
- @dataclass
20
+ @dataclass(kw_only=True)
20
21
  class EcuVariantRaw(HierarchyElementRaw):
21
- diag_variables_raw: list[DiagVariable | OdxLinkRef]
22
- variable_groups: NamedItemList[VariableGroup]
23
- ecu_variant_patterns: list[EcuVariantPattern]
24
- dyn_defined_spec: DynDefinedSpec | None
25
- parent_refs: list[ParentRef]
22
+ diag_variables_raw: list[DiagVariable | OdxLinkRef] = field(default_factory=list)
23
+ variable_groups: NamedItemList[VariableGroup] = field(default_factory=NamedItemList)
24
+ ecu_variant_patterns: list[EcuVariantPattern] = field(default_factory=list)
25
+ dyn_defined_spec: DynDefinedSpec | None = None
26
+ parent_refs: list[ParentRef] = field(default_factory=list)
26
27
 
27
28
  @property
28
29
  def diag_variables(self) -> NamedItemList[DiagVariable]:
29
30
  return self._diag_variables
30
31
 
31
32
  @staticmethod
32
- def from_et(et_element: ElementTree.Element,
33
- doc_frags: list[OdxDocFragment]) -> "EcuVariantRaw":
33
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "EcuVariantRaw":
34
34
  # objects contained by diagnostic layers exibit an additional
35
35
  # document fragment for the diag layer, so we use the document
36
36
  # fragments of the odx id of the diag layer for IDs of
37
37
  # contained objects.
38
- her = HierarchyElementRaw.from_et(et_element, doc_frags)
38
+ her = HierarchyElementRaw.from_et(et_element, context)
39
39
  kwargs = dataclass_fields_asdict(her)
40
- doc_frags = her.odx_id.doc_fragments
41
40
 
42
41
  diag_variables_raw: list[DiagVariable | OdxLinkRef] = []
43
42
  if (dv_elems := et_element.find("DIAG-VARIABLES")) is not None:
44
43
  for dv_proxy_elem in dv_elems:
45
44
  dv_proxy: OdxLinkRef | DiagVariable
46
45
  if dv_proxy_elem.tag == "DIAG-VARIABLE-REF":
47
- dv_proxy = OdxLinkRef.from_et(dv_proxy_elem, doc_frags)
46
+ dv_proxy = OdxLinkRef.from_et(dv_proxy_elem, context)
48
47
  elif dv_proxy_elem.tag == "DIAG-VARIABLE":
49
- dv_proxy = DiagVariable.from_et(dv_proxy_elem, doc_frags)
48
+ dv_proxy = DiagVariable.from_et(dv_proxy_elem, context)
50
49
  else:
51
50
  odxraise()
52
51
 
53
52
  diag_variables_raw.append(dv_proxy)
54
53
 
55
54
  variable_groups = NamedItemList([
56
- VariableGroup.from_et(vg_elem, doc_frags)
55
+ VariableGroup.from_et(vg_elem, context)
57
56
  for vg_elem in et_element.iterfind("VARIABLE-GROUPS/VARIABLE-GROUP")
58
57
  ])
59
58
 
60
59
  ecu_variant_patterns = None
61
60
  ecu_variant_patterns = [
62
- EcuVariantPattern.from_et(varpat_elem, doc_frags)
61
+ EcuVariantPattern.from_et(varpat_elem, context)
63
62
  for varpat_elem in et_element.iterfind("ECU-VARIANT-PATTERNS/ECU-VARIANT-PATTERN")
64
63
  ]
65
64
 
66
65
  dyn_defined_spec = None
67
66
  if (dds_elem := et_element.find("DYN-DEFINED-SPEC")) is not None:
68
- dyn_defined_spec = DynDefinedSpec.from_et(dds_elem, doc_frags)
67
+ dyn_defined_spec = DynDefinedSpec.from_et(dds_elem, context)
69
68
 
70
69
  parent_refs = [
71
- ParentRef.from_et(pr_el, doc_frags)
70
+ ParentRef.from_et(pr_el, context)
72
71
  for pr_el in et_element.iterfind("PARENT-REFS/PARENT-REF")
73
72
  ]
74
73
 
@@ -10,7 +10,8 @@ from typing_extensions import override
10
10
  from ..diagvariable import DiagVariable
11
11
  from ..exceptions import odxassert
12
12
  from ..nameditemlist import NamedItemList
13
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkRef
13
+ from ..odxdoccontext import OdxDocContext
14
+ from ..odxlink import OdxLinkDatabase, OdxLinkRef
14
15
  from ..parentref import ParentRef
15
16
  from ..variablegroup import VariableGroup
16
17
  from .diaglayer import DiagLayer
@@ -18,7 +19,7 @@ from .functionalgroupraw import FunctionalGroupRaw
18
19
  from .hierarchyelement import HierarchyElement
19
20
 
20
21
 
21
- @dataclass
22
+ @dataclass(kw_only=True)
22
23
  class FunctionalGroup(HierarchyElement):
23
24
  """This is a diagnostic layer for functionality shared between multiple ECU variants
24
25
  """
@@ -44,9 +45,8 @@ class FunctionalGroup(HierarchyElement):
44
45
  return self.functional_group_raw.parent_refs
45
46
 
46
47
  @staticmethod
47
- def from_et(et_element: ElementTree.Element,
48
- doc_frags: list[OdxDocFragment]) -> "FunctionalGroup":
49
- functional_group_raw = FunctionalGroupRaw.from_et(et_element, doc_frags)
48
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "FunctionalGroup":
49
+ functional_group_raw = FunctionalGroupRaw.from_et(et_element, context)
50
50
 
51
51
  return FunctionalGroup(diag_layer_raw=functional_group_raw)
52
52
 
@@ -1,12 +1,13 @@
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 ..diagvariable import DiagVariable
7
7
  from ..exceptions import odxraise
8
8
  from ..nameditemlist import NamedItemList
9
- from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
9
+ from ..odxdoccontext import OdxDocContext
10
+ from ..odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
10
11
  from ..parentref import ParentRef
11
12
  from ..snrefcontext import SnRefContext
12
13
  from ..utils import dataclass_fields_asdict
@@ -14,50 +15,48 @@ from ..variablegroup import VariableGroup
14
15
  from .hierarchyelementraw import HierarchyElementRaw
15
16
 
16
17
 
17
- @dataclass
18
+ @dataclass(kw_only=True)
18
19
  class FunctionalGroupRaw(HierarchyElementRaw):
19
20
  """This is a diagnostic layer for common functionality of an ECU
20
21
  """
21
22
 
22
- diag_variables_raw: list[DiagVariable | OdxLinkRef]
23
- variable_groups: NamedItemList[VariableGroup]
24
- parent_refs: list[ParentRef]
23
+ diag_variables_raw: list[DiagVariable | OdxLinkRef] = field(default_factory=list)
24
+ variable_groups: NamedItemList[VariableGroup] = field(default_factory=NamedItemList)
25
+ parent_refs: list[ParentRef] = field(default_factory=list)
25
26
 
26
27
  @property
27
28
  def diag_variables(self) -> NamedItemList[DiagVariable]:
28
29
  return self._diag_variables
29
30
 
30
31
  @staticmethod
31
- def from_et(et_element: ElementTree.Element,
32
- doc_frags: list[OdxDocFragment]) -> "FunctionalGroupRaw":
32
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "FunctionalGroupRaw":
33
33
  # objects contained by diagnostic layers exibit an additional
34
34
  # document fragment for the diag layer, so we use the document
35
35
  # fragments of the odx id of the diag layer for IDs of
36
36
  # contained objects.
37
- her = HierarchyElementRaw.from_et(et_element, doc_frags)
37
+ her = HierarchyElementRaw.from_et(et_element, context)
38
38
  kwargs = dataclass_fields_asdict(her)
39
- doc_frags = her.odx_id.doc_fragments
40
39
 
41
40
  diag_variables_raw: list[DiagVariable | OdxLinkRef] = []
42
41
  if (dv_elems := et_element.find("DIAG-VARIABLES")) is not None:
43
42
  for dv_proxy_elem in dv_elems:
44
43
  dv_proxy: OdxLinkRef | DiagVariable
45
44
  if dv_proxy_elem.tag == "DIAG-VARIABLE-REF":
46
- dv_proxy = OdxLinkRef.from_et(dv_proxy_elem, doc_frags)
45
+ dv_proxy = OdxLinkRef.from_et(dv_proxy_elem, context)
47
46
  elif dv_proxy_elem.tag == "DIAG-VARIABLE":
48
- dv_proxy = DiagVariable.from_et(dv_proxy_elem, doc_frags)
47
+ dv_proxy = DiagVariable.from_et(dv_proxy_elem, context)
49
48
  else:
50
49
  odxraise()
51
50
 
52
51
  diag_variables_raw.append(dv_proxy)
53
52
 
54
53
  variable_groups = NamedItemList([
55
- VariableGroup.from_et(vg_elem, doc_frags)
54
+ VariableGroup.from_et(vg_elem, context)
56
55
  for vg_elem in et_element.iterfind("VARIABLE-GROUPS/VARIABLE-GROUP")
57
56
  ])
58
57
 
59
58
  parent_refs = [
60
- ParentRef.from_et(pr_elem, doc_frags)
59
+ ParentRef.from_et(pr_elem, context)
61
60
  for pr_elem in et_element.iterfind("PARENT-REFS/PARENT-REF")
62
61
  ]
63
62
 
@@ -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