odxtools 7.1.1__py3-none-any.whl → 7.3.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 (135) hide show
  1. odxtools/__init__.py +6 -4
  2. odxtools/additionalaudience.py +3 -5
  3. odxtools/admindata.py +5 -7
  4. odxtools/audience.py +3 -5
  5. odxtools/basecomparam.py +3 -5
  6. odxtools/basicstructure.py +19 -23
  7. odxtools/cli/_parser_utils.py +1 -1
  8. odxtools/cli/_print_utils.py +3 -2
  9. odxtools/cli/compare.py +1 -1
  10. odxtools/companydata.py +5 -7
  11. odxtools/companydocinfo.py +7 -8
  12. odxtools/companyrevisioninfo.py +3 -5
  13. odxtools/companyspecificinfo.py +8 -9
  14. odxtools/comparam.py +4 -6
  15. odxtools/comparaminstance.py +6 -8
  16. odxtools/comparamspec.py +14 -13
  17. odxtools/comparamsubset.py +17 -16
  18. odxtools/complexcomparam.py +5 -7
  19. odxtools/compumethods/compuconst.py +31 -0
  20. odxtools/compumethods/compudefaultvalue.py +27 -0
  21. odxtools/compumethods/compuinternaltophys.py +39 -0
  22. odxtools/compumethods/compuinversevalue.py +7 -0
  23. odxtools/compumethods/compumethod.py +67 -12
  24. odxtools/compumethods/compuphystointernal.py +39 -0
  25. odxtools/compumethods/compuscale.py +15 -26
  26. odxtools/compumethods/createanycompumethod.py +14 -160
  27. odxtools/compumethods/identicalcompumethod.py +31 -6
  28. odxtools/compumethods/linearcompumethod.py +69 -189
  29. odxtools/compumethods/linearsegment.py +191 -0
  30. odxtools/compumethods/scalelinearcompumethod.py +132 -26
  31. odxtools/compumethods/tabintpcompumethod.py +119 -99
  32. odxtools/compumethods/texttablecompumethod.py +107 -43
  33. odxtools/createanydiagcodedtype.py +10 -67
  34. odxtools/database.py +84 -72
  35. odxtools/dataobjectproperty.py +10 -19
  36. odxtools/decodestate.py +8 -2
  37. odxtools/description.py +47 -0
  38. odxtools/determinenumberofitems.py +4 -5
  39. odxtools/diagcodedtype.py +29 -12
  40. odxtools/diagcomm.py +10 -6
  41. odxtools/diagdatadictionaryspec.py +20 -21
  42. odxtools/diaglayer.py +39 -9
  43. odxtools/diaglayercontainer.py +17 -11
  44. odxtools/diaglayerraw.py +20 -21
  45. odxtools/diagnostictroublecode.py +8 -9
  46. odxtools/diagservice.py +42 -27
  47. odxtools/docrevision.py +5 -7
  48. odxtools/dopbase.py +7 -8
  49. odxtools/dtcdop.py +44 -22
  50. odxtools/dynamicendmarkerfield.py +22 -9
  51. odxtools/dynamiclengthfield.py +5 -11
  52. odxtools/element.py +4 -3
  53. odxtools/encodestate.py +14 -2
  54. odxtools/endofpdufield.py +0 -2
  55. odxtools/environmentdatadescription.py +137 -19
  56. odxtools/exceptions.py +11 -2
  57. odxtools/field.py +9 -9
  58. odxtools/functionalclass.py +3 -5
  59. odxtools/inputparam.py +3 -5
  60. odxtools/leadinglengthinfotype.py +15 -2
  61. odxtools/loadfile.py +64 -0
  62. odxtools/minmaxlengthtype.py +20 -2
  63. odxtools/modification.py +3 -5
  64. odxtools/multiplexer.py +98 -69
  65. odxtools/multiplexercase.py +10 -11
  66. odxtools/multiplexerdefaultcase.py +11 -12
  67. odxtools/multiplexerswitchkey.py +4 -5
  68. odxtools/negoutputparam.py +3 -5
  69. odxtools/odxlink.py +12 -26
  70. odxtools/odxtypes.py +1 -1
  71. odxtools/outputparam.py +3 -5
  72. odxtools/parameterinfo.py +5 -5
  73. odxtools/parameters/codedconstparameter.py +2 -14
  74. odxtools/parameters/lengthkeyparameter.py +3 -17
  75. odxtools/parameters/nrcconstparameter.py +29 -50
  76. odxtools/parameters/parameter.py +22 -22
  77. odxtools/parameters/parameterwithdop.py +6 -8
  78. odxtools/parameters/physicalconstantparameter.py +5 -8
  79. odxtools/parameters/reservedparameter.py +4 -3
  80. odxtools/parameters/systemparameter.py +1 -1
  81. odxtools/parameters/tablekeyparameter.py +6 -9
  82. odxtools/parameters/tablestructparameter.py +6 -8
  83. odxtools/parameters/valueparameter.py +5 -8
  84. odxtools/paramlengthinfotype.py +19 -6
  85. odxtools/parentref.py +15 -1
  86. odxtools/physicaldimension.py +3 -5
  87. odxtools/progcode.py +18 -7
  88. odxtools/protstack.py +3 -5
  89. odxtools/relateddoc.py +7 -9
  90. odxtools/request.py +8 -0
  91. odxtools/response.py +8 -0
  92. odxtools/scaleconstr.py +3 -3
  93. odxtools/singleecujob.py +12 -10
  94. odxtools/snrefcontext.py +29 -0
  95. odxtools/specialdata.py +3 -5
  96. odxtools/specialdatagroup.py +5 -7
  97. odxtools/specialdatagroupcaption.py +3 -6
  98. odxtools/standardlengthtype.py +27 -2
  99. odxtools/state.py +3 -5
  100. odxtools/statechart.py +9 -11
  101. odxtools/statetransition.py +4 -9
  102. odxtools/staticfield.py +4 -8
  103. odxtools/table.py +7 -8
  104. odxtools/tablerow.py +7 -6
  105. odxtools/teammember.py +3 -5
  106. odxtools/templates/comparam-spec.odx-c.xml.jinja2 +2 -5
  107. odxtools/templates/comparam-subset.odx-cs.xml.jinja2 +2 -5
  108. odxtools/templates/macros/printCompanyData.xml.jinja2 +2 -5
  109. odxtools/templates/macros/printComparamRef.xml.jinja2 +5 -12
  110. odxtools/templates/macros/printCompuMethod.xml.jinja2 +153 -0
  111. odxtools/templates/macros/printDOP.xml.jinja2 +10 -132
  112. odxtools/templates/macros/printDescription.xml.jinja2 +18 -0
  113. odxtools/templates/macros/printElementId.xml.jinja2 +3 -3
  114. odxtools/templates/macros/printMux.xml.jinja2 +3 -2
  115. odxtools/templates/macros/printTable.xml.jinja2 +2 -3
  116. odxtools/unit.py +3 -5
  117. odxtools/unitgroup.py +3 -5
  118. odxtools/unitspec.py +9 -10
  119. odxtools/utils.py +1 -26
  120. odxtools/version.py +2 -2
  121. odxtools/{write_pdx_file.py → writepdxfile.py} +19 -10
  122. odxtools/xdoc.py +3 -5
  123. {odxtools-7.1.1.dist-info → odxtools-7.3.0.dist-info}/METADATA +1 -1
  124. odxtools-7.3.0.dist-info/RECORD +192 -0
  125. {odxtools-7.1.1.dist-info → odxtools-7.3.0.dist-info}/WHEEL +1 -1
  126. odxtools/createcompanydatas.py +0 -17
  127. odxtools/createsdgs.py +0 -19
  128. odxtools/load_file.py +0 -13
  129. odxtools/load_odx_d_file.py +0 -6
  130. odxtools/load_pdx_file.py +0 -8
  131. odxtools-7.1.1.dist-info/RECORD +0 -186
  132. /odxtools/templates/{index.xml.xml.jinja2 → index.xml.jinja2} +0 -0
  133. {odxtools-7.1.1.dist-info → odxtools-7.3.0.dist-info}/LICENSE +0 -0
  134. {odxtools-7.1.1.dist-info → odxtools-7.3.0.dist-info}/entry_points.txt +0 -0
  135. {odxtools-7.1.1.dist-info → odxtools-7.3.0.dist-info}/top_level.txt +0 -0
odxtools/__init__.py CHANGED
@@ -62,11 +62,13 @@ References
62
62
  - _`[ISO22901]` The ISO 22901 Standard: https://www.iso.org/standard/41207.html
63
63
 
64
64
  """
65
- from .load_file import load_file as load_file # noqa: F401
66
- from .load_odx_d_file import load_odx_d_file as load_odx_d_file # noqa: F401
67
- from .load_pdx_file import load_pdx_file as load_pdx_file # noqa: F401
65
+ from .loadfile import load_directory as load_directory # noqa: F401
66
+ from .loadfile import load_file as load_file # noqa: F401
67
+ from .loadfile import load_files # noqa: F401
68
+ from .loadfile import load_odx_d_file as load_odx_d_file # noqa: F401
69
+ from .loadfile import load_pdx_file as load_pdx_file # noqa: F401
68
70
  from .version import __version__ as __version__ # noqa: F401
69
- from .write_pdx_file import write_pdx_file as write_pdx_file # noqa: F401
71
+ from .writepdxfile import write_pdx_file as write_pdx_file # noqa: F401
70
72
 
71
73
  __author__ = "Katrin Bauer"
72
74
 
@@ -1,15 +1,13 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, Any, Dict, List
3
+ from typing import Any, Dict, List
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .element import IdentifiableElement
7
7
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
8
+ from .snrefcontext import SnRefContext
8
9
  from .utils import dataclass_fields_asdict
9
10
 
10
- if TYPE_CHECKING:
11
- from .diaglayer import DiagLayer
12
-
13
11
 
14
12
  @dataclass
15
13
  class AdditionalAudience(IdentifiableElement):
@@ -30,5 +28,5 @@ class AdditionalAudience(IdentifiableElement):
30
28
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
31
29
  pass
32
30
 
33
- def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
31
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
34
32
  pass
odxtools/admindata.py CHANGED
@@ -1,14 +1,12 @@
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, Dict, List, Optional
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .companydocinfo import CompanyDocInfo
7
7
  from .docrevision import DocRevision
8
8
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
9
-
10
- if TYPE_CHECKING:
11
- from .diaglayer import DiagLayer
9
+ from .snrefcontext import SnRefContext
12
10
 
13
11
 
14
12
  @dataclass
@@ -54,9 +52,9 @@ class AdminData:
54
52
  for dr in self.doc_revisions:
55
53
  dr._resolve_odxlinks(odxlinks)
56
54
 
57
- def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
55
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
58
56
  for cdi in self.company_doc_infos:
59
- cdi._resolve_snrefs(diag_layer)
57
+ cdi._resolve_snrefs(context)
60
58
 
61
59
  for dr in self.doc_revisions:
62
- dr._resolve_snrefs(diag_layer)
60
+ dr._resolve_snrefs(context)
odxtools/audience.py CHANGED
@@ -1,14 +1,12 @@
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, Dict, List, Optional
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .additionalaudience import AdditionalAudience
7
7
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
8
8
  from .odxtypes import odxstr_to_bool
9
-
10
- if TYPE_CHECKING:
11
- from .diaglayer import DiagLayer
9
+ from .snrefcontext import SnRefContext
12
10
 
13
11
 
14
12
  @dataclass
@@ -94,5 +92,5 @@ class Audience:
94
92
  odxlinks.resolve(ref, AdditionalAudience) for ref in self.disabled_audience_refs
95
93
  ]
96
94
 
97
- def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
95
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
98
96
  pass
odxtools/basecomparam.py CHANGED
@@ -1,17 +1,15 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
3
  from enum import Enum
4
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast
4
+ from typing import Any, Dict, List, Optional, cast
5
5
  from xml.etree import ElementTree
6
6
 
7
7
  from .element import IdentifiableElement
8
8
  from .exceptions import odxraise, odxrequire
9
9
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
10
+ from .snrefcontext import SnRefContext
10
11
  from .utils import dataclass_fields_asdict
11
12
 
12
- if TYPE_CHECKING:
13
- from .diaglayer import DiagLayer
14
-
15
13
 
16
14
  class StandardizationLevel(Enum):
17
15
  STANDARD = "STANDARD"
@@ -74,5 +72,5 @@ class BaseComparam(IdentifiableElement):
74
72
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
75
73
  pass
76
74
 
77
- def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
75
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
78
76
  pass
@@ -1,7 +1,7 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import warnings
3
3
  from dataclasses import dataclass
4
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast
4
+ from typing import Any, Dict, List, Optional, cast
5
5
  from xml.etree import ElementTree
6
6
 
7
7
  from typing_extensions import override
@@ -10,7 +10,7 @@ from .complexdop import ComplexDop
10
10
  from .dataobjectproperty import DataObjectProperty
11
11
  from .decodestate import DecodeState
12
12
  from .encodestate import EncodeState
13
- from .exceptions import DecodeError, EncodeError, OdxWarning, odxassert, odxraise, strict_mode
13
+ from .exceptions import EncodeError, OdxWarning, odxassert, odxraise
14
14
  from .nameditemlist import NamedItemList
15
15
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
16
16
  from .odxtypes import ParameterDict, ParameterValue, ParameterValueDict
@@ -18,16 +18,13 @@ from .parameters.codedconstparameter import CodedConstParameter
18
18
  from .parameters.createanyparameter import create_any_parameter_from_et
19
19
  from .parameters.lengthkeyparameter import LengthKeyParameter
20
20
  from .parameters.matchingrequestparameter import MatchingRequestParameter
21
- from .parameters.nrcconstparameter import NrcConstParameter
22
21
  from .parameters.parameter import Parameter
23
22
  from .parameters.parameterwithdop import ParameterWithDOP
24
23
  from .parameters.physicalconstantparameter import PhysicalConstantParameter
25
24
  from .parameters.tablekeyparameter import TableKeyParameter
25
+ from .snrefcontext import SnRefContext
26
26
  from .utils import dataclass_fields_asdict
27
27
 
28
- if TYPE_CHECKING:
29
- from .diaglayer import DiagLayer
30
-
31
28
 
32
29
  @dataclass
33
30
  class BasicStructure(ComplexDop):
@@ -77,10 +74,11 @@ class BasicStructure(ComplexDop):
77
74
 
78
75
  for param in self.parameters:
79
76
  if (isinstance(param, MatchingRequestParameter) and param.request_byte_position < len(request_prefix)) or \
80
- isinstance(param, (CodedConstParameter, NrcConstParameter, PhysicalConstantParameter)):
77
+ isinstance(param, (CodedConstParameter, PhysicalConstantParameter)):
81
78
  param.encode_into_pdu(physical_value=None, encode_state=encode_state)
82
79
  else:
83
80
  break
81
+
84
82
  return encode_state.coded_message
85
83
 
86
84
  @property
@@ -156,15 +154,14 @@ class BasicStructure(ComplexDop):
156
154
  f"{encode_state.cursor_bit_position}", EncodeError)
157
155
  encode_state.bit_position = 0
158
156
 
159
- orig_cursor = encode_state.cursor_byte_position
160
157
  orig_origin = encode_state.origin_byte_position
161
158
  encode_state.origin_byte_position = encode_state.cursor_byte_position
162
159
 
163
160
  orig_is_end_of_pdu = encode_state.is_end_of_pdu
164
161
  encode_state.is_end_of_pdu = False
165
162
 
166
- # in strict mode, ensure that no values for unknown parameters are specified.
167
- if strict_mode:
163
+ # ensure that no values for unknown parameters are specified.
164
+ if not encode_state.allow_unknown_parameters:
168
165
  param_names = {param.short_name for param in self.parameters}
169
166
  for param_value_name in physical_value:
170
167
  if param_value_name not in param_names:
@@ -196,8 +193,10 @@ class BasicStructure(ComplexDop):
196
193
  odxraise(f"No value for required parameter {param.short_name} specified",
197
194
  EncodeError)
198
195
 
199
- param.encode_into_pdu(
200
- physical_value=physical_value.get(param.short_name), encode_state=encode_state)
196
+ param_phys_value = physical_value.get(param.short_name)
197
+ param.encode_into_pdu(physical_value=param_phys_value, encode_state=encode_state)
198
+
199
+ encode_state.journal.append((param, param_phys_value))
201
200
 
202
201
  encode_state.is_end_of_pdu = False
203
202
  if self.byte_size is not None:
@@ -227,7 +226,6 @@ class BasicStructure(ComplexDop):
227
226
  encode_state.origin_byte_position)
228
227
 
229
228
  encode_state.origin_byte_position = orig_origin
230
- encode_state.cursor_byte_position = max(orig_cursor, encode_state.cursor_byte_position)
231
229
 
232
230
  @override
233
231
  def decode_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
@@ -240,6 +238,7 @@ class BasicStructure(ComplexDop):
240
238
  for param in self.parameters:
241
239
  value = param.decode_from_pdu(decode_state)
242
240
 
241
+ decode_state.journal.append((param, value))
243
242
  result[param.short_name] = value
244
243
 
245
244
  # decoding of the structure finished. go back the original origin.
@@ -251,13 +250,6 @@ class BasicStructure(ComplexDop):
251
250
  decode_state = DecodeState(coded_message=message)
252
251
  param_values = self.decode_from_pdu(decode_state)
253
252
 
254
- if len(message) != decode_state.cursor_byte_position:
255
- odxraise(
256
- f"The message {message.hex()} probably could not be completely parsed:"
257
- f" Expected length of {decode_state.cursor_byte_position} but got {len(message)}.",
258
- DecodeError)
259
- return {}
260
-
261
253
  if not isinstance(param_values, dict):
262
254
  odxraise("Decoding structures must result in a dictionary")
263
255
 
@@ -301,9 +293,13 @@ class BasicStructure(ComplexDop):
301
293
  for param in self.parameters:
302
294
  param._resolve_odxlinks(odxlinks)
303
295
 
304
- def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
296
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
305
297
  """Recursively resolve any references (odxlinks or sn-refs)"""
306
- super()._resolve_snrefs(diag_layer)
298
+ context.parameters = self.parameters
299
+
300
+ super()._resolve_snrefs(context)
307
301
 
308
302
  for param in self.parameters:
309
- param._parameter_resolve_snrefs(diag_layer, param_list=self.parameters)
303
+ param._resolve_snrefs(context)
304
+
305
+ context.parameters = None
@@ -5,7 +5,7 @@ import argparse
5
5
  from typing import Any, Protocol, runtime_checkable
6
6
 
7
7
  from ..database import Database
8
- from ..load_file import load_file as _load_file
8
+ from ..loadfile import load_file as _load_file
9
9
 
10
10
 
11
11
  @runtime_checkable
@@ -6,6 +6,7 @@ from typing import Any, Callable, Dict, List, Optional, Union
6
6
  import markdownify
7
7
  from tabulate import tabulate # TODO: switch to rich tables
8
8
 
9
+ from ..description import Description
9
10
  from ..diaglayer import DiagLayer
10
11
  from ..diagservice import DiagService
11
12
  from ..parameters.codedconstparameter import CodedConstParameter
@@ -17,9 +18,9 @@ from ..parameters.valueparameter import ValueParameter
17
18
  from ..singleecujob import SingleEcuJob
18
19
 
19
20
 
20
- def format_desc(desc: str, indent: int = 0) -> str:
21
+ def format_desc(description: Description, indent: int = 0) -> str:
21
22
  # Collapse whitespaces
22
- desc = re.sub(r"\s+", " ", desc)
23
+ desc = re.sub(r"\s+", " ", str(description))
23
24
  # Covert XHTML to Markdown
24
25
  desc = markdownify.markdownify(desc)
25
26
  # Collapse blank lines
odxtools/cli/compare.py CHANGED
@@ -11,7 +11,7 @@ from tabulate import tabulate # TODO: switch to rich tables
11
11
  from ..database import Database
12
12
  from ..diaglayer import DiagLayer
13
13
  from ..diagservice import DiagService
14
- from ..load_file import load_file
14
+ from ..loadfile import load_file
15
15
  from ..odxtypes import AtomicOdxType
16
16
  from ..parameters.codedconstparameter import CodedConstParameter
17
17
  from ..parameters.nrcconstparameter import NrcConstParameter
odxtools/companydata.py CHANGED
@@ -1,6 +1,6 @@
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, Dict, List, Optional
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .companyspecificinfo import CompanySpecificInfo
@@ -8,12 +8,10 @@ from .element import IdentifiableElement
8
8
  from .exceptions import odxrequire
9
9
  from .nameditemlist import NamedItemList
10
10
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
11
+ from .snrefcontext import SnRefContext
11
12
  from .teammember import TeamMember
12
13
  from .utils import dataclass_fields_asdict
13
14
 
14
- if TYPE_CHECKING:
15
- from .diaglayer import DiagLayer
16
-
17
15
 
18
16
  @dataclass
19
17
  class CompanyData(IdentifiableElement):
@@ -64,9 +62,9 @@ class CompanyData(IdentifiableElement):
64
62
  if self.company_specific_info:
65
63
  self.company_specific_info._resolve_odxlinks(odxlinks)
66
64
 
67
- def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
65
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
68
66
  for tm in self.team_members:
69
- tm._resolve_snrefs(diag_layer)
67
+ tm._resolve_snrefs(context)
70
68
 
71
69
  if self.company_specific_info:
72
- self.company_specific_info._resolve_snrefs(diag_layer)
70
+ self.company_specific_info._resolve_snrefs(context)
@@ -1,18 +1,15 @@
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, Dict, List, Optional
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .companydata import CompanyData
7
- from .createsdgs import create_sdgs_from_et
8
7
  from .exceptions import odxrequire
9
8
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
9
+ from .snrefcontext import SnRefContext
10
10
  from .specialdatagroup import SpecialDataGroup
11
11
  from .teammember import TeamMember
12
12
 
13
- if TYPE_CHECKING:
14
- from .diaglayer import DiagLayer
15
-
16
13
 
17
14
  @dataclass
18
15
  class CompanyDocInfo:
@@ -37,7 +34,9 @@ class CompanyDocInfo:
37
34
  OdxLinkRef.from_et(et_element.find("COMPANY-DATA-REF"), doc_frags))
38
35
  team_member_ref = OdxLinkRef.from_et(et_element.find("TEAM-MEMBER-REF"), doc_frags)
39
36
  doc_label = et_element.findtext("DOC-LABEL")
40
- sdgs = create_sdgs_from_et(et_element.find("SDGS"), doc_frags)
37
+ sdgs = [
38
+ SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
39
+ ]
41
40
 
42
41
  return CompanyDocInfo(
43
42
  company_data_ref=company_data_ref,
@@ -64,6 +63,6 @@ class CompanyDocInfo:
64
63
  for sdg in self.sdgs:
65
64
  sdg._resolve_odxlinks(odxlinks)
66
65
 
67
- def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
66
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
68
67
  for sdg in self.sdgs:
69
- sdg._resolve_snrefs(diag_layer)
68
+ sdg._resolve_snrefs(context)
@@ -1,14 +1,12 @@
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, Dict, List, Optional
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .companydata import CompanyData
7
7
  from .exceptions import odxrequire
8
8
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
9
-
10
- if TYPE_CHECKING:
11
- from .diaglayer import DiagLayer
9
+ from .snrefcontext import SnRefContext
12
10
 
13
11
 
14
12
  @dataclass
@@ -39,5 +37,5 @@ class CompanyRevisionInfo:
39
37
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
40
38
  self._company_data = odxlinks.resolve(self.company_data_ref, CompanyData)
41
39
 
42
- def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
40
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
43
41
  pass
@@ -1,16 +1,13 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, Any, Dict, List
3
+ from typing import Any, Dict, List
4
4
  from xml.etree import ElementTree
5
5
 
6
- from .createsdgs import create_sdgs_from_et
7
6
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
8
7
  from .relateddoc import RelatedDoc
8
+ from .snrefcontext import SnRefContext
9
9
  from .specialdatagroup import SpecialDataGroup
10
10
 
11
- if TYPE_CHECKING:
12
- from .diaglayer import DiagLayer
13
-
14
11
 
15
12
  @dataclass
16
13
  class CompanySpecificInfo:
@@ -25,7 +22,9 @@ class CompanySpecificInfo:
25
22
  for rd in et_element.iterfind("RELATED-DOCS/RELATED-DOC")
26
23
  ]
27
24
 
28
- sdgs = create_sdgs_from_et(et_element.find("SDGS"), doc_frags)
25
+ sdgs = [
26
+ SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
27
+ ]
29
28
 
30
29
  return CompanySpecificInfo(related_docs=related_docs, sdgs=sdgs)
31
30
 
@@ -44,9 +43,9 @@ class CompanySpecificInfo:
44
43
  for sdg in self.sdgs:
45
44
  sdg._resolve_odxlinks(odxlinks)
46
45
 
47
- def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
46
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
48
47
  for rd in self.related_docs:
49
- rd._resolve_snrefs(diag_layer)
48
+ rd._resolve_snrefs(context)
50
49
 
51
50
  for sdg in self.sdgs:
52
- sdg._resolve_snrefs(diag_layer)
51
+ sdg._resolve_snrefs(context)
odxtools/comparam.py CHANGED
@@ -1,17 +1,15 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, Any, Dict, List
3
+ from typing import Any, Dict, List
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .basecomparam import BaseComparam
7
7
  from .dataobjectproperty import DataObjectProperty
8
8
  from .exceptions import odxrequire
9
9
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
10
+ from .snrefcontext import SnRefContext
10
11
  from .utils import dataclass_fields_asdict
11
12
 
12
- if TYPE_CHECKING:
13
- from .diaglayer import DiagLayer
14
-
15
13
 
16
14
  @dataclass
17
15
  class Comparam(BaseComparam):
@@ -41,5 +39,5 @@ class Comparam(BaseComparam):
41
39
 
42
40
  self._dop = odxlinks.resolve(self.dop_ref, DataObjectProperty)
43
41
 
44
- def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
45
- super()._resolve_snrefs(diag_layer)
42
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
43
+ super()._resolve_snrefs(context)
@@ -1,18 +1,16 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import warnings
3
3
  from dataclasses import dataclass
4
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
4
+ from typing import Any, Dict, List, Optional, Union
5
5
  from xml.etree import ElementTree
6
6
 
7
7
  from .basecomparam import BaseComparam
8
8
  from .comparam import Comparam
9
9
  from .complexcomparam import ComplexComparam, ComplexValue, create_complex_value_from_et
10
+ from .description import Description
10
11
  from .exceptions import OdxWarning, odxraise, odxrequire
11
12
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
12
- from .utils import create_description_from_et
13
-
14
- if TYPE_CHECKING:
15
- from .diaglayer import DiagLayer
13
+ from .snrefcontext import SnRefContext
16
14
 
17
15
 
18
16
  @dataclass
@@ -23,7 +21,7 @@ class ComparamInstance:
23
21
  Be aware that the ODX specification calls this class COMPARAM-REF!
24
22
  """
25
23
  value: Union[str, ComplexValue]
26
- description: Optional[str]
24
+ description: Optional[Description]
27
25
  protocol_snref: Optional[str]
28
26
  prot_stack_snref: Optional[str]
29
27
  spec_ref: OdxLinkRef
@@ -44,7 +42,7 @@ class ComparamInstance:
44
42
  else:
45
43
  value = create_complex_value_from_et(odxrequire(et_element.find("COMPLEX-VALUE")))
46
44
 
47
- description = create_description_from_et(et_element.find("DESC"))
45
+ description = Description.from_et(et_element.find("DESC"), doc_frags)
48
46
 
49
47
  prot_stack_snref = None
50
48
  if (psnref_elem := et_element.find("PROT-STACK-SNREF")) is not None:
@@ -68,7 +66,7 @@ class ComparamInstance:
68
66
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
69
67
  self._spec = odxlinks.resolve(self.spec_ref, BaseComparam)
70
68
 
71
- def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
69
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
72
70
  pass
73
71
 
74
72
  @property
odxtools/comparamspec.py CHANGED
@@ -1,23 +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, Dict, List, Optional
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .admindata import AdminData
7
7
  from .companydata import CompanyData
8
- from .createcompanydatas import create_company_datas_from_et
9
- from .createsdgs import create_sdgs_from_et
10
8
  from .element import IdentifiableElement
11
9
  from .exceptions import odxrequire
12
10
  from .nameditemlist import NamedItemList
13
11
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
14
12
  from .protstack import ProtStack
13
+ from .snrefcontext import SnRefContext
15
14
  from .specialdatagroup import SpecialDataGroup
16
15
  from .utils import dataclass_fields_asdict
17
16
 
18
- if TYPE_CHECKING:
19
- from .diaglayer import DiagLayer
20
-
21
17
 
22
18
  @dataclass
23
19
  class ComparamSpec(IdentifiableElement):
@@ -34,8 +30,13 @@ class ComparamSpec(IdentifiableElement):
34
30
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
35
31
 
36
32
  admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
37
- company_datas = create_company_datas_from_et(et_element.find("COMPANY-DATAS"), doc_frags)
38
- sdgs = create_sdgs_from_et(et_element.find("SDGS"), doc_frags)
33
+ company_datas = NamedItemList([
34
+ CompanyData.from_et(cde, doc_frags)
35
+ for cde in et_element.iterfind("COMPANY-DATAS/COMPANY-DATA")
36
+ ])
37
+ sdgs = [
38
+ SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
39
+ ]
39
40
  prot_stacks = NamedItemList([
40
41
  ProtStack.from_et(dl_element, doc_frags)
41
42
  for dl_element in et_element.iterfind("PROT-STACKS/PROT-STACK")
@@ -80,15 +81,15 @@ class ComparamSpec(IdentifiableElement):
80
81
  for ps in self.prot_stacks:
81
82
  ps._resolve_odxlinks(odxlinks)
82
83
 
83
- def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
84
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
84
85
  if self.admin_data is not None:
85
- self.admin_data._resolve_snrefs(diag_layer)
86
+ self.admin_data._resolve_snrefs(context)
86
87
 
87
88
  for cd in self.company_datas:
88
- cd._resolve_snrefs(diag_layer)
89
+ cd._resolve_snrefs(context)
89
90
 
90
91
  for sdg in self.sdgs:
91
- sdg._resolve_snrefs(diag_layer)
92
+ sdg._resolve_snrefs(context)
92
93
 
93
94
  for ps in self.prot_stacks:
94
- ps._resolve_snrefs(diag_layer)
95
+ ps._resolve_snrefs(context)
@@ -1,26 +1,22 @@
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, Dict, List, Optional
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .admindata import AdminData
7
7
  from .companydata import CompanyData
8
8
  from .comparam import Comparam
9
9
  from .complexcomparam import ComplexComparam
10
- from .createcompanydatas import create_company_datas_from_et
11
- from .createsdgs import create_sdgs_from_et
12
10
  from .dataobjectproperty import DataObjectProperty
13
11
  from .element import IdentifiableElement
14
12
  from .exceptions import odxrequire
15
13
  from .nameditemlist import NamedItemList
16
14
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
15
+ from .snrefcontext import SnRefContext
17
16
  from .specialdatagroup import SpecialDataGroup
18
17
  from .unitspec import UnitSpec
19
18
  from .utils import dataclass_fields_asdict
20
19
 
21
- if TYPE_CHECKING:
22
- from .diaglayer import DiagLayer
23
-
24
20
 
25
21
  @dataclass
26
22
  class ComparamSubset(IdentifiableElement):
@@ -45,7 +41,10 @@ class ComparamSubset(IdentifiableElement):
45
41
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
46
42
 
47
43
  admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
48
- company_datas = create_company_datas_from_et(et_element.find("COMPANY-DATAS"), doc_frags)
44
+ company_datas = NamedItemList([
45
+ CompanyData.from_et(cde, doc_frags)
46
+ for cde in et_element.iterfind("COMPANY-DATAS/COMPANY-DATA")
47
+ ])
49
48
 
50
49
  data_object_props = NamedItemList([
51
50
  DataObjectProperty.from_et(el, doc_frags)
@@ -62,7 +61,9 @@ class ComparamSubset(IdentifiableElement):
62
61
  else:
63
62
  unit_spec = None
64
63
 
65
- sdgs = create_sdgs_from_et(et_element.find("SDGS"), doc_frags)
64
+ sdgs = [
65
+ SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
66
+ ]
66
67
 
67
68
  return ComparamSubset(
68
69
  category=category,
@@ -127,25 +128,25 @@ class ComparamSubset(IdentifiableElement):
127
128
  for sdg in self.sdgs:
128
129
  sdg._resolve_odxlinks(odxlinks)
129
130
 
130
- def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
131
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
131
132
  for dop in self.data_object_props:
132
- dop._resolve_snrefs(diag_layer)
133
+ dop._resolve_snrefs(context)
133
134
 
134
135
  for comparam in self.comparams:
135
- comparam._resolve_snrefs(diag_layer)
136
+ comparam._resolve_snrefs(context)
136
137
 
137
138
  for ccomparam in self.complex_comparams:
138
- ccomparam._resolve_snrefs(diag_layer)
139
+ ccomparam._resolve_snrefs(context)
139
140
 
140
141
  if self.unit_spec:
141
- self.unit_spec._resolve_snrefs(diag_layer)
142
+ self.unit_spec._resolve_snrefs(context)
142
143
 
143
144
  if self.admin_data is not None:
144
- self.admin_data._resolve_snrefs(diag_layer)
145
+ self.admin_data._resolve_snrefs(context)
145
146
 
146
147
  if self.company_datas is not None:
147
148
  for cd in self.company_datas:
148
- cd._resolve_snrefs(diag_layer)
149
+ cd._resolve_snrefs(context)
149
150
 
150
151
  for sdg in self.sdgs:
151
- sdg._resolve_snrefs(diag_layer)
152
+ sdg._resolve_snrefs(context)