odxtools 9.6.1__py3-none-any.whl → 10.0.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 (203) hide show
  1. odxtools/additionalaudience.py +3 -3
  2. odxtools/addressing.py +8 -0
  3. odxtools/admindata.py +8 -8
  4. odxtools/audience.py +10 -10
  5. odxtools/basecomparam.py +7 -20
  6. odxtools/basevariantpattern.py +4 -5
  7. odxtools/basicstructure.py +12 -11
  8. odxtools/cli/_print_utils.py +35 -23
  9. odxtools/cli/browse.py +9 -9
  10. odxtools/cli/compare.py +24 -24
  11. odxtools/cli/decode.py +3 -4
  12. odxtools/cli/find.py +4 -5
  13. odxtools/cli/list.py +7 -7
  14. odxtools/cli/main.py +2 -2
  15. odxtools/cli/snoop.py +3 -3
  16. odxtools/codec.py +3 -186
  17. odxtools/commrelation.py +12 -19
  18. odxtools/commrelationvaluetype.py +9 -0
  19. odxtools/companydata.py +5 -5
  20. odxtools/companydocinfo.py +8 -8
  21. odxtools/companyrevisioninfo.py +5 -5
  22. odxtools/companyspecificinfo.py +5 -5
  23. odxtools/comparam.py +3 -3
  24. odxtools/comparaminstance.py +10 -10
  25. odxtools/comparamspec.py +3 -3
  26. odxtools/comparamsubset.py +5 -5
  27. odxtools/complexcomparam.py +7 -7
  28. odxtools/compositecodec.py +191 -0
  29. odxtools/compumethods/compucategory.py +13 -0
  30. odxtools/compumethods/compucodecompumethod.py +6 -5
  31. odxtools/compumethods/compuconst.py +4 -5
  32. odxtools/compumethods/compudefaultvalue.py +1 -2
  33. odxtools/compumethods/compuinternaltophys.py +6 -6
  34. odxtools/compumethods/compumethod.py +6 -17
  35. odxtools/compumethods/compuphystointernal.py +6 -6
  36. odxtools/compumethods/compurationalcoeffs.py +4 -4
  37. odxtools/compumethods/compuscale.py +9 -10
  38. odxtools/compumethods/createanycompumethod.py +1 -2
  39. odxtools/compumethods/identicalcompumethod.py +1 -2
  40. odxtools/compumethods/intervaltype.py +8 -0
  41. odxtools/compumethods/limit.py +13 -19
  42. odxtools/compumethods/linearcompumethod.py +4 -3
  43. odxtools/compumethods/linearsegment.py +14 -15
  44. odxtools/compumethods/ratfunccompumethod.py +5 -4
  45. odxtools/compumethods/ratfuncsegment.py +7 -8
  46. odxtools/compumethods/scalelinearcompumethod.py +10 -9
  47. odxtools/compumethods/scaleratfunccompumethod.py +6 -5
  48. odxtools/compumethods/tabintpcompumethod.py +19 -20
  49. odxtools/compumethods/texttablecompumethod.py +5 -4
  50. odxtools/createanycomparam.py +2 -4
  51. odxtools/createanydiagcodedtype.py +1 -2
  52. odxtools/database.py +9 -8
  53. odxtools/dataobjectproperty.py +10 -10
  54. odxtools/decodestate.py +5 -5
  55. odxtools/description.py +6 -22
  56. odxtools/determinenumberofitems.py +4 -4
  57. odxtools/diagclasstype.py +11 -0
  58. odxtools/diagcodedtype.py +7 -7
  59. odxtools/diagcomm.py +19 -42
  60. odxtools/diagdatadictionaryspec.py +6 -6
  61. odxtools/diaglayercontainer.py +4 -4
  62. odxtools/diaglayers/basevariant.py +10 -9
  63. odxtools/diaglayers/basevariantraw.py +9 -9
  64. odxtools/diaglayers/diaglayer.py +20 -19
  65. odxtools/diaglayers/diaglayerraw.py +10 -10
  66. odxtools/diaglayers/diaglayertype.py +1 -2
  67. odxtools/diaglayers/ecushareddata.py +4 -4
  68. odxtools/diaglayers/ecushareddataraw.py +6 -6
  69. odxtools/diaglayers/ecuvariant.py +11 -10
  70. odxtools/diaglayers/ecuvariantraw.py +9 -9
  71. odxtools/diaglayers/functionalgroup.py +8 -7
  72. odxtools/diaglayers/functionalgroupraw.py +7 -7
  73. odxtools/diaglayers/hierarchyelement.py +43 -49
  74. odxtools/diaglayers/hierarchyelementraw.py +4 -4
  75. odxtools/diaglayers/protocol.py +4 -4
  76. odxtools/diaglayers/protocolraw.py +6 -6
  77. odxtools/diagnostictroublecode.py +8 -8
  78. odxtools/diagservice.py +21 -97
  79. odxtools/diagvariable.py +14 -14
  80. odxtools/docrevision.py +11 -11
  81. odxtools/dopbase.py +6 -6
  82. odxtools/dtcconnector.py +45 -0
  83. odxtools/dtcdop.py +15 -56
  84. odxtools/dynamicendmarkerfield.py +5 -4
  85. odxtools/dynamiclengthfield.py +5 -4
  86. odxtools/dyndefinedspec.py +7 -159
  87. odxtools/dynenddopref.py +5 -5
  88. odxtools/dyniddefmodeinfo.py +161 -0
  89. odxtools/ecuvariantpattern.py +4 -5
  90. odxtools/element.py +5 -6
  91. odxtools/encodestate.py +11 -11
  92. odxtools/encoding.py +2 -3
  93. odxtools/endofpdufield.py +6 -6
  94. odxtools/envdataconnector.py +49 -0
  95. odxtools/environmentdata.py +3 -4
  96. odxtools/environmentdatadescription.py +11 -11
  97. odxtools/exceptions.py +5 -5
  98. odxtools/externalaccessmethod.py +22 -0
  99. odxtools/externaldoc.py +23 -0
  100. odxtools/field.py +9 -10
  101. odxtools/functionalclass.py +4 -4
  102. odxtools/inputparam.py +6 -6
  103. odxtools/internalconstr.py +4 -5
  104. odxtools/isotp_state_machine.py +12 -11
  105. odxtools/leadinglengthinfotype.py +2 -3
  106. odxtools/library.py +5 -5
  107. odxtools/linkeddtcdop.py +62 -0
  108. odxtools/loadfile.py +5 -6
  109. odxtools/matchingbasevariantparameter.py +2 -3
  110. odxtools/matchingparameter.py +7 -7
  111. odxtools/minmaxlengthtype.py +5 -11
  112. odxtools/modification.py +4 -4
  113. odxtools/multiplexer.py +11 -11
  114. odxtools/multiplexercase.py +6 -6
  115. odxtools/multiplexerdefaultcase.py +6 -6
  116. odxtools/multiplexerswitchkey.py +4 -4
  117. odxtools/nameditemlist.py +14 -14
  118. odxtools/negoutputparam.py +3 -3
  119. odxtools/obd.py +1 -2
  120. odxtools/odxcategory.py +6 -6
  121. odxtools/odxlink.py +19 -20
  122. odxtools/odxtypes.py +21 -18
  123. odxtools/outputparam.py +4 -4
  124. odxtools/parameterinfo.py +2 -2
  125. odxtools/parameters/codedconstparameter.py +5 -5
  126. odxtools/parameters/createanyparameter.py +1 -2
  127. odxtools/parameters/dynamicparameter.py +2 -3
  128. odxtools/parameters/lengthkeyparameter.py +5 -5
  129. odxtools/parameters/matchingrequestparameter.py +3 -4
  130. odxtools/parameters/nrcconstparameter.py +7 -7
  131. odxtools/parameters/parameter.py +11 -11
  132. odxtools/parameters/parameterwithdop.py +9 -9
  133. odxtools/parameters/physicalconstantparameter.py +4 -4
  134. odxtools/parameters/reservedparameter.py +3 -4
  135. odxtools/parameters/rowfragment.py +7 -0
  136. odxtools/parameters/systemparameter.py +2 -3
  137. odxtools/parameters/tableentryparameter.py +4 -9
  138. odxtools/parameters/tablekeyparameter.py +10 -10
  139. odxtools/parameters/tablestructparameter.py +7 -7
  140. odxtools/parameters/valueparameter.py +7 -7
  141. odxtools/paramlengthinfotype.py +5 -3
  142. odxtools/parentref.py +9 -9
  143. odxtools/physicaldimension.py +11 -11
  144. odxtools/physicaltype.py +4 -12
  145. odxtools/posresponsesuppressible.py +72 -0
  146. odxtools/preconditionstateref.py +7 -7
  147. odxtools/progcode.py +6 -6
  148. odxtools/protstack.py +4 -4
  149. odxtools/radix.py +9 -0
  150. odxtools/relateddiagcommref.py +22 -0
  151. odxtools/relateddoc.py +6 -6
  152. odxtools/request.py +14 -12
  153. odxtools/response.py +15 -13
  154. odxtools/scaleconstr.py +4 -12
  155. odxtools/servicebinner.py +5 -5
  156. odxtools/singleecujob.py +4 -4
  157. odxtools/snrefcontext.py +2 -2
  158. odxtools/specialdata.py +5 -5
  159. odxtools/specialdatagroup.py +9 -9
  160. odxtools/specialdatagroupcaption.py +3 -3
  161. odxtools/standardizationlevel.py +9 -0
  162. odxtools/standardlengthtype.py +12 -21
  163. odxtools/state.py +3 -3
  164. odxtools/statechart.py +4 -4
  165. odxtools/statemachine.py +4 -3
  166. odxtools/statetransition.py +5 -18
  167. odxtools/statetransitionref.py +18 -18
  168. odxtools/staticfield.py +5 -4
  169. odxtools/structure.py +2 -3
  170. odxtools/subcomponent.py +12 -245
  171. odxtools/subcomponentparamconnector.py +103 -0
  172. odxtools/subcomponentpattern.py +42 -0
  173. odxtools/swvariable.py +3 -4
  174. odxtools/table.py +17 -55
  175. odxtools/tablediagcommconnector.py +47 -0
  176. odxtools/tablerow.py +30 -30
  177. odxtools/tablerowconnector.py +46 -0
  178. odxtools/teammember.py +11 -11
  179. odxtools/templates/macros/printService.xml.jinja2 +2 -1
  180. odxtools/termination.py +8 -0
  181. odxtools/text.py +2 -3
  182. odxtools/transmode.py +9 -0
  183. odxtools/uds.py +2 -3
  184. odxtools/unit.py +9 -9
  185. odxtools/unitgroup.py +6 -11
  186. odxtools/unitgroupcategory.py +7 -0
  187. odxtools/unitspec.py +6 -6
  188. odxtools/usage.py +9 -0
  189. odxtools/utils.py +31 -2
  190. odxtools/validtype.py +9 -0
  191. odxtools/variablegroup.py +2 -2
  192. odxtools/variantmatcher.py +10 -10
  193. odxtools/variantpattern.py +3 -3
  194. odxtools/version.py +2 -2
  195. odxtools/writepdxfile.py +5 -5
  196. odxtools/xdoc.py +9 -9
  197. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/METADATA +4 -5
  198. odxtools-10.0.0.dist-info/RECORD +264 -0
  199. odxtools-9.6.1.dist-info/RECORD +0 -238
  200. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/WHEEL +0 -0
  201. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/entry_points.txt +0 -0
  202. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/licenses/LICENSE +0 -0
  203. {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/top_level.txt +0 -0
odxtools/subcomponent.py CHANGED
@@ -1,252 +1,19 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, Any, Dict, List, Optional
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
- from .diagnostictroublecode import DiagnosticTroubleCode
7
- from .diagservice import DiagService
8
- from .dtcdop import DtcDop
9
- from .element import IdentifiableElement, NamedElement
10
- from .environmentdata import EnvironmentData
11
- from .environmentdatadescription import EnvironmentDataDescription
12
- from .exceptions import odxassert, odxraise, odxrequire
6
+ from .dtcconnector import DtcConnector
7
+ from .element import IdentifiableElement
8
+ from .envdataconnector import EnvDataConnector
13
9
  from .nameditemlist import NamedItemList
14
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
15
- from .parameters.parameter import Parameter
10
+ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
16
11
  from .snrefcontext import SnRefContext
17
- from .table import Table
18
- from .tablerow import TableRow
12
+ from .subcomponentparamconnector import SubComponentParamConnector
13
+ from .subcomponentpattern import SubComponentPattern
14
+ from .tablerowconnector import TableRowConnector
19
15
  from .utils import dataclass_fields_asdict
20
16
 
21
- if TYPE_CHECKING:
22
- from .matchingparameter import MatchingParameter
23
-
24
-
25
- @dataclass
26
- class SubComponentPattern:
27
- matching_parameters: List["MatchingParameter"]
28
-
29
- @staticmethod
30
- def from_et(et_element: ElementTree.Element,
31
- doc_frags: List[OdxDocFragment]) -> "SubComponentPattern":
32
- from .matchingparameter import MatchingParameter
33
-
34
- matching_parameters = [
35
- MatchingParameter.from_et(el, doc_frags)
36
- for el in et_element.iterfind("MATCHING-PARAMETERS/MATCHING-PARAMETER")
37
- ]
38
-
39
- return SubComponentPattern(matching_parameters=matching_parameters)
40
-
41
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
42
- result = {}
43
- for mp in self.matching_parameters:
44
- result.update(mp._build_odxlinks())
45
-
46
- return result
47
-
48
- def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
49
- for mp in self.matching_parameters:
50
- mp._resolve_odxlinks(odxlinks)
51
-
52
- def _resolve_snrefs(self, context: SnRefContext) -> None:
53
- for mp in self.matching_parameters:
54
- mp._resolve_snrefs(context)
55
-
56
-
57
- @dataclass
58
- class SubComponentParamConnector(IdentifiableElement):
59
- diag_comm_snref: str
60
-
61
- # TODO: we currently only support SNREFs, not SNPATHREFs
62
- out_param_if_refs: List[str]
63
- in_param_if_refs: List[str]
64
-
65
- @property
66
- def service(self) -> DiagService:
67
- return self._service
68
-
69
- @property
70
- def out_param_ifs(self) -> NamedItemList[Parameter]:
71
- return self._out_param_ifs
72
-
73
- @property
74
- def in_param_ifs(self) -> NamedItemList[Parameter]:
75
- return self._in_param_ifs
76
-
77
- @staticmethod
78
- def from_et(et_element: ElementTree.Element,
79
- doc_frags: List[OdxDocFragment]) -> "SubComponentParamConnector":
80
- kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
81
-
82
- diag_comm_snref = odxrequire(
83
- odxrequire(et_element.find("DIAG-COMM-SNREF")).get("SHORT-NAME"))
84
-
85
- out_param_if_refs = []
86
- for elem in et_element.find("OUT-PARAM-IF-REFS") or []:
87
- if elem.tag != "OUT-PARAM-IF-SNREF":
88
- odxraise("Currently, only SNREFS are supported for OUT-PARAM-IF-REFS")
89
- continue
90
- else:
91
- odxassert(elem.tag == "OUT-PARAM-IF-SNREF")
92
- out_param_if_refs.append(odxrequire(elem.attrib.get("SHORT-NAME")))
93
-
94
- in_param_if_refs = []
95
- for elem in et_element.find("IN-PARAM-IF-REFS") or []:
96
- if elem.tag != "IN-PARAM-IF-SNREF":
97
- odxraise("Currently, only SNREFS are supported for IN-PARAM-IF-REFS")
98
- continue
99
- else:
100
- odxassert(elem.tag == "IN-PARAM-IF-SNREF")
101
- in_param_if_refs.append(odxrequire(elem.attrib.get("SHORT-NAME")))
102
-
103
- return SubComponentParamConnector(
104
- diag_comm_snref=diag_comm_snref,
105
- out_param_if_refs=out_param_if_refs,
106
- in_param_if_refs=in_param_if_refs,
107
- **kwargs)
108
-
109
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
110
- return {}
111
-
112
- def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
113
- pass
114
-
115
- def _resolve_snrefs(self, context: SnRefContext) -> None:
116
- service = resolve_snref(self.diag_comm_snref,
117
- odxrequire(context.diag_layer).diag_comms, DiagService)
118
- self._service = service
119
-
120
- if self._service.request is not None:
121
- odxraise()
122
- return
123
- if not self._service.positive_responses:
124
- odxraise()
125
- return
126
-
127
- request = odxrequire(service.request)
128
- in_param_ifs = []
129
- for x in self.in_param_if_refs:
130
- in_param_ifs.append(resolve_snref(x, request.parameters, Parameter))
131
-
132
- # TODO: The output parameters are probably part of a response
133
- # (?). If so, they cannot be resolved ahead of time because
134
- # the service in question can have multiple responses
135
- # associated with it and each of these has its own set of
136
- # parameters. In the meantime, we simply use the first
137
- # positive response specified.
138
- response = service.positive_responses[0]
139
- out_param_ifs = []
140
- for x in self.out_param_if_refs:
141
- out_param_ifs.append(resolve_snref(x, response.parameters, Parameter))
142
-
143
- self._in_param_ifs = NamedItemList(in_param_ifs)
144
- self._out_param_ifs = NamedItemList(out_param_ifs)
145
-
146
-
147
- @dataclass
148
- class TableRowConnector(NamedElement):
149
- table_ref: OdxLinkRef
150
- table_row_snref: str
151
-
152
- @property
153
- def table(self) -> Table:
154
- return self._table
155
-
156
- @property
157
- def table_row(self) -> TableRow:
158
- return self._table_row
159
-
160
- @staticmethod
161
- def from_et(et_element: ElementTree.Element,
162
- doc_frags: List[OdxDocFragment]) -> "TableRowConnector":
163
- kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
164
-
165
- table_ref = odxrequire(OdxLinkRef.from_et(et_element.find("TABLE-REF"), doc_frags))
166
- table_row_snref_el = odxrequire(et_element.find("TABLE-ROW-SNREF"))
167
- table_row_snref = odxrequire(table_row_snref_el.get("SHORT-NAME"))
168
-
169
- return TableRowConnector(table_ref=table_ref, table_row_snref=table_row_snref, **kwargs)
170
-
171
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
172
- return {}
173
-
174
- def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
175
- self._table = odxlinks.resolve(self.table_ref, Table)
176
-
177
- def _resolve_snrefs(self, context: SnRefContext) -> None:
178
- self._table_row = resolve_snref(self.table_row_snref, self._table.table_rows, TableRow)
179
-
180
-
181
- @dataclass
182
- class DtcConnector(NamedElement):
183
- dtc_dop_ref: OdxLinkRef
184
- dtc_snref: str
185
-
186
- @property
187
- def dtc_dop(self) -> DtcDop:
188
- return self._dtc_dop
189
-
190
- @property
191
- def dtc(self) -> DiagnosticTroubleCode:
192
- return self._dtc
193
-
194
- @staticmethod
195
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "DtcConnector":
196
- kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
197
-
198
- dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"), doc_frags))
199
- dtc_snref_el = odxrequire(et_element.find("DTC-SNREF"))
200
- dtc_snref = odxrequire(dtc_snref_el.get("SHORT-NAME"))
201
-
202
- return DtcConnector(dtc_dop_ref=dtc_dop_ref, dtc_snref=dtc_snref, **kwargs)
203
-
204
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
205
- return {}
206
-
207
- def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
208
- self._dtc_dop = odxlinks.resolve(self.dtc_dop_ref, DtcDop)
209
-
210
- def _resolve_snrefs(self, context: SnRefContext) -> None:
211
- self._dtc = resolve_snref(self.dtc_snref, self._dtc_dop.dtcs, DiagnosticTroubleCode)
212
-
213
-
214
- @dataclass
215
- class EnvDataConnector(NamedElement):
216
- env_data_desc_ref: OdxLinkRef
217
- env_data_snref: str
218
-
219
- @property
220
- def env_data_desc(self) -> EnvironmentDataDescription:
221
- return self._env_data_desc
222
-
223
- @property
224
- def env_data(self) -> EnvironmentData:
225
- return self._env_data
226
-
227
- @staticmethod
228
- def from_et(et_element: ElementTree.Element,
229
- doc_frags: List[OdxDocFragment]) -> "EnvDataConnector":
230
- kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
231
-
232
- env_data_desc_ref = odxrequire(
233
- OdxLinkRef.from_et(et_element.find("ENV-DATA-DESC-REF"), doc_frags))
234
- env_data_snref_el = odxrequire(et_element.find("ENV-DATA-SNREF"))
235
- env_data_snref = odxrequire(env_data_snref_el.get("SHORT-NAME"))
236
-
237
- return EnvDataConnector(
238
- env_data_desc_ref=env_data_desc_ref, env_data_snref=env_data_snref, **kwargs)
239
-
240
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
241
- return {}
242
-
243
- def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
244
- self._env_data_desc = odxlinks.resolve(self.env_data_desc_ref, EnvironmentDataDescription)
245
-
246
- def _resolve_snrefs(self, context: SnRefContext) -> None:
247
- self._env_data = resolve_snref(self.env_data_snref, self._env_data_desc.env_datas,
248
- EnvironmentData)
249
-
250
17
 
251
18
  @dataclass
252
19
  class SubComponent(IdentifiableElement):
@@ -258,16 +25,16 @@ class SubComponent(IdentifiableElement):
258
25
 
259
26
  """
260
27
 
261
- sub_component_patterns: List[SubComponentPattern]
28
+ sub_component_patterns: list[SubComponentPattern]
262
29
  sub_component_param_connectors: NamedItemList[SubComponentParamConnector]
263
30
  table_row_connectors: NamedItemList[TableRowConnector]
264
31
  env_data_connectors: NamedItemList[EnvDataConnector]
265
32
  dtc_connectors: NamedItemList[DtcConnector]
266
33
 
267
- semantic: Optional[str]
34
+ semantic: str | None
268
35
 
269
36
  @staticmethod
270
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "SubComponent":
37
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "SubComponent":
271
38
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
272
39
 
273
40
  semantic = et_element.get("SEMANTIC")
@@ -302,7 +69,7 @@ class SubComponent(IdentifiableElement):
302
69
  dtc_connectors=NamedItemList(dtc_connectors),
303
70
  **kwargs)
304
71
 
305
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
72
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
306
73
  result = {}
307
74
 
308
75
  for scp in self.sub_component_patterns:
@@ -0,0 +1,103 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass
3
+ from typing import Any
4
+ from xml.etree import ElementTree
5
+
6
+ from .diagservice import DiagService
7
+ from .element import IdentifiableElement
8
+ from .exceptions import odxassert, odxraise, odxrequire
9
+ from .nameditemlist import NamedItemList
10
+ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, resolve_snref
11
+ from .parameters.parameter import Parameter
12
+ from .snrefcontext import SnRefContext
13
+ from .utils import dataclass_fields_asdict
14
+
15
+
16
+ @dataclass
17
+ class SubComponentParamConnector(IdentifiableElement):
18
+ diag_comm_snref: str
19
+
20
+ # TODO: we currently only support SNREFs, not SNPATHREFs
21
+ out_param_if_refs: list[str]
22
+ in_param_if_refs: list[str]
23
+
24
+ @property
25
+ def service(self) -> DiagService:
26
+ return self._service
27
+
28
+ @property
29
+ def out_param_ifs(self) -> NamedItemList[Parameter]:
30
+ return self._out_param_ifs
31
+
32
+ @property
33
+ def in_param_ifs(self) -> NamedItemList[Parameter]:
34
+ return self._in_param_ifs
35
+
36
+ @staticmethod
37
+ def from_et(et_element: ElementTree.Element,
38
+ doc_frags: list[OdxDocFragment]) -> "SubComponentParamConnector":
39
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
40
+
41
+ diag_comm_snref = odxrequire(
42
+ odxrequire(et_element.find("DIAG-COMM-SNREF")).get("SHORT-NAME"))
43
+
44
+ out_param_if_refs = []
45
+ for elem in et_element.find("OUT-PARAM-IF-REFS") or []:
46
+ if elem.tag != "OUT-PARAM-IF-SNREF":
47
+ odxraise("Currently, only SNREFS are supported for OUT-PARAM-IF-REFS")
48
+ continue
49
+ else:
50
+ odxassert(elem.tag == "OUT-PARAM-IF-SNREF")
51
+ out_param_if_refs.append(odxrequire(elem.attrib.get("SHORT-NAME")))
52
+
53
+ in_param_if_refs = []
54
+ for elem in et_element.find("IN-PARAM-IF-REFS") or []:
55
+ if elem.tag != "IN-PARAM-IF-SNREF":
56
+ odxraise("Currently, only SNREFS are supported for IN-PARAM-IF-REFS")
57
+ continue
58
+ else:
59
+ odxassert(elem.tag == "IN-PARAM-IF-SNREF")
60
+ in_param_if_refs.append(odxrequire(elem.attrib.get("SHORT-NAME")))
61
+
62
+ return SubComponentParamConnector(
63
+ diag_comm_snref=diag_comm_snref,
64
+ out_param_if_refs=out_param_if_refs,
65
+ in_param_if_refs=in_param_if_refs,
66
+ **kwargs)
67
+
68
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
69
+ return {}
70
+
71
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
72
+ pass
73
+
74
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
75
+ service = resolve_snref(self.diag_comm_snref,
76
+ odxrequire(context.diag_layer).diag_comms, DiagService)
77
+ self._service = service
78
+
79
+ if self._service.request is not None:
80
+ odxraise()
81
+ return
82
+ if not self._service.positive_responses:
83
+ odxraise()
84
+ return
85
+
86
+ request = odxrequire(service.request)
87
+ in_param_ifs = []
88
+ for x in self.in_param_if_refs:
89
+ in_param_ifs.append(resolve_snref(x, request.parameters, Parameter))
90
+
91
+ # TODO: The output parameters are probably part of a response
92
+ # (?). If so, they cannot be resolved ahead of time because
93
+ # the service in question can have multiple responses
94
+ # associated with it and each of these has its own set of
95
+ # parameters. In the meantime, we simply use the first
96
+ # positive response specified.
97
+ response = service.positive_responses[0]
98
+ out_param_ifs = []
99
+ for x in self.out_param_if_refs:
100
+ out_param_ifs.append(resolve_snref(x, response.parameters, Parameter))
101
+
102
+ self._in_param_ifs = NamedItemList(in_param_ifs)
103
+ self._out_param_ifs = NamedItemList(out_param_ifs)
@@ -0,0 +1,42 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass
3
+ from typing import TYPE_CHECKING, Any
4
+ from xml.etree import ElementTree
5
+
6
+ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
7
+ from .snrefcontext import SnRefContext
8
+
9
+ if TYPE_CHECKING:
10
+ from .matchingparameter import MatchingParameter
11
+
12
+
13
+ @dataclass
14
+ class SubComponentPattern:
15
+ matching_parameters: list["MatchingParameter"]
16
+
17
+ @staticmethod
18
+ def from_et(et_element: ElementTree.Element,
19
+ doc_frags: list[OdxDocFragment]) -> "SubComponentPattern":
20
+ from .matchingparameter import MatchingParameter
21
+
22
+ matching_parameters = [
23
+ MatchingParameter.from_et(el, doc_frags)
24
+ for el in et_element.iterfind("MATCHING-PARAMETERS/MATCHING-PARAMETER")
25
+ ]
26
+
27
+ return SubComponentPattern(matching_parameters=matching_parameters)
28
+
29
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
30
+ result = {}
31
+ for mp in self.matching_parameters:
32
+ result.update(mp._build_odxlinks())
33
+
34
+ return result
35
+
36
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
37
+ for mp in self.matching_parameters:
38
+ mp._resolve_odxlinks(odxlinks)
39
+
40
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
41
+ for mp in self.matching_parameters:
42
+ mp._resolve_snrefs(context)
odxtools/swvariable.py CHANGED
@@ -1,6 +1,5 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import List, Optional
4
3
  from xml.etree import ElementTree
5
4
 
6
5
  from .element import NamedElement
@@ -10,11 +9,11 @@ from .utils import dataclass_fields_asdict
10
9
 
11
10
  @dataclass
12
11
  class SwVariable(NamedElement):
13
- origin: Optional[str]
14
- oid: Optional[str]
12
+ origin: str | None
13
+ oid: str | None
15
14
 
16
15
  @staticmethod
17
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "SwVariable":
16
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "SwVariable":
18
17
  kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
19
18
 
20
19
  origin = et_element.findtext("ORIGIN")
odxtools/table.py CHANGED
@@ -1,73 +1,35 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List, Optional, Union
3
+ from typing import Any
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .admindata import AdminData
7
7
  from .dataobjectproperty import DataObjectProperty
8
- from .diagcomm import DiagComm
9
8
  from .element import IdentifiableElement
10
- from .exceptions import odxassert, odxrequire
9
+ from .exceptions import odxassert
11
10
  from .nameditemlist import NamedItemList
12
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
11
+ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
13
12
  from .snrefcontext import SnRefContext
14
13
  from .specialdatagroup import SpecialDataGroup
14
+ from .tablediagcommconnector import TableDiagCommConnector
15
15
  from .tablerow import TableRow
16
16
  from .utils import dataclass_fields_asdict
17
17
 
18
18
 
19
- @dataclass
20
- class TableDiagCommConnector:
21
- semantic: str
22
-
23
- diag_comm_ref: Optional[OdxLinkRef]
24
- diag_comm_snref: Optional[str]
25
-
26
- @property
27
- def diag_comm(self) -> DiagComm:
28
- return self._diag_comm
29
-
30
- @staticmethod
31
- def from_et(et_element: ElementTree.Element,
32
- doc_frags: List[OdxDocFragment]) -> "TableDiagCommConnector":
33
-
34
- semantic = odxrequire(et_element.findtext("SEMANTIC"))
35
-
36
- diag_comm_ref = OdxLinkRef.from_et(et_element.find("DIAG-COMM-REF"), doc_frags)
37
- diag_comm_snref = None
38
- if (dc_snref_elem := et_element.find("DIAG-COMM-SNREF")) is not None:
39
- diag_comm_snref = odxrequire(dc_snref_elem.get("SHORT-NAME"))
40
-
41
- return TableDiagCommConnector(
42
- semantic=semantic, diag_comm_ref=diag_comm_ref, diag_comm_snref=diag_comm_snref)
43
-
44
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
45
- return {}
46
-
47
- def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
48
- if self.diag_comm_ref is not None:
49
- self._diag_comm = odxlinks.resolve(self.diag_comm_ref, DiagComm)
50
-
51
- def _resolve_snrefs(self, context: SnRefContext) -> None:
52
- if self.diag_comm_snref is not None:
53
- dl = odxrequire(context.diag_layer)
54
- self._diag_comm = resolve_snref(self.diag_comm_snref, dl.diag_comms, DiagComm)
55
-
56
-
57
19
  @dataclass
58
20
  class Table(IdentifiableElement):
59
21
  """This class represents a TABLE."""
60
- key_label: Optional[str]
61
- struct_label: Optional[str]
62
- admin_data: Optional[AdminData]
63
- key_dop_ref: Optional[OdxLinkRef]
64
- table_rows_raw: List[Union[TableRow, OdxLinkRef]]
65
- table_diag_comm_connectors: List[TableDiagCommConnector]
66
- sdgs: List[SpecialDataGroup]
67
- semantic: Optional[str]
22
+ key_label: str | None
23
+ struct_label: str | None
24
+ admin_data: AdminData | None
25
+ key_dop_ref: OdxLinkRef | None
26
+ table_rows_raw: list[TableRow | OdxLinkRef]
27
+ table_diag_comm_connectors: list[TableDiagCommConnector]
28
+ sdgs: list[SpecialDataGroup]
29
+ semantic: str | None
68
30
 
69
31
  @property
70
- def key_dop(self) -> Optional[DataObjectProperty]:
32
+ def key_dop(self) -> DataObjectProperty | None:
71
33
  """The key data object property associated with this table."""
72
34
  return self._key_dop
73
35
 
@@ -77,7 +39,7 @@ class Table(IdentifiableElement):
77
39
  return self._table_rows
78
40
 
79
41
  @staticmethod
80
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "Table":
42
+ def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Table":
81
43
  """Reads a TABLE."""
82
44
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
83
45
  odx_id = kwargs["odx_id"]
@@ -86,7 +48,7 @@ class Table(IdentifiableElement):
86
48
  admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
87
49
  key_dop_ref = OdxLinkRef.from_et(et_element.find("KEY-DOP-REF"), doc_frags)
88
50
 
89
- table_rows_raw: List[Union[OdxLinkRef, TableRow]] = []
51
+ table_rows_raw: list[OdxLinkRef | TableRow] = []
90
52
  for sub_elem in et_element:
91
53
  if sub_elem.tag == "TABLE-ROW":
92
54
  table_rows_raw.append(
@@ -115,7 +77,7 @@ class Table(IdentifiableElement):
115
77
  semantic=semantic,
116
78
  **kwargs)
117
79
 
118
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
80
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
119
81
  result = {self.odx_id: self}
120
82
 
121
83
  for table_row_wrapper in self.table_rows_raw:
@@ -131,7 +93,7 @@ class Table(IdentifiableElement):
131
93
  return result
132
94
 
133
95
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
134
- self._key_dop: Optional[DataObjectProperty] = None
96
+ self._key_dop: DataObjectProperty | None = None
135
97
  if self.key_dop_ref is not None:
136
98
  self._key_dop = odxlinks.resolve(self.key_dop_ref, DataObjectProperty)
137
99
 
@@ -0,0 +1,47 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass
3
+ from typing import Any
4
+ from xml.etree import ElementTree
5
+
6
+ from .diagcomm import DiagComm
7
+ from .exceptions import odxrequire
8
+ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
9
+ from .snrefcontext import SnRefContext
10
+
11
+
12
+ @dataclass
13
+ class TableDiagCommConnector:
14
+ semantic: str
15
+
16
+ diag_comm_ref: OdxLinkRef | None
17
+ diag_comm_snref: str | None
18
+
19
+ @property
20
+ def diag_comm(self) -> DiagComm:
21
+ return self._diag_comm
22
+
23
+ @staticmethod
24
+ def from_et(et_element: ElementTree.Element,
25
+ doc_frags: list[OdxDocFragment]) -> "TableDiagCommConnector":
26
+
27
+ semantic = odxrequire(et_element.findtext("SEMANTIC"))
28
+
29
+ diag_comm_ref = OdxLinkRef.from_et(et_element.find("DIAG-COMM-REF"), doc_frags)
30
+ diag_comm_snref = None
31
+ if (dc_snref_elem := et_element.find("DIAG-COMM-SNREF")) is not None:
32
+ diag_comm_snref = odxrequire(dc_snref_elem.get("SHORT-NAME"))
33
+
34
+ return TableDiagCommConnector(
35
+ semantic=semantic, diag_comm_ref=diag_comm_ref, diag_comm_snref=diag_comm_snref)
36
+
37
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
38
+ return {}
39
+
40
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
41
+ if self.diag_comm_ref is not None:
42
+ self._diag_comm = odxlinks.resolve(self.diag_comm_ref, DiagComm)
43
+
44
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
45
+ if self.diag_comm_snref is not None:
46
+ dl = odxrequire(context.diag_layer)
47
+ self._diag_comm = resolve_snref(self.diag_comm_snref, dl.diag_comms, DiagComm)