odxtools 9.5.0__py3-none-any.whl → 9.6.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 (102) hide show
  1. odxtools/additionalaudience.py +2 -2
  2. odxtools/admindata.py +3 -0
  3. odxtools/audience.py +9 -13
  4. odxtools/basecomparam.py +1 -2
  5. odxtools/basevariantpattern.py +5 -5
  6. odxtools/basicstructure.py +34 -35
  7. odxtools/commrelation.py +2 -1
  8. odxtools/companydata.py +1 -2
  9. odxtools/companyspecificinfo.py +3 -0
  10. odxtools/comparam.py +16 -8
  11. odxtools/comparaminstance.py +12 -12
  12. odxtools/comparamspec.py +4 -3
  13. odxtools/comparamsubset.py +26 -24
  14. odxtools/compumethods/compuconst.py +4 -4
  15. odxtools/compumethods/limit.py +9 -9
  16. odxtools/compumethods/linearsegment.py +8 -8
  17. odxtools/dataobjectproperty.py +16 -18
  18. odxtools/description.py +4 -2
  19. odxtools/determinenumberofitems.py +4 -4
  20. odxtools/diagcodedtype.py +20 -20
  21. odxtools/diagcomm.py +61 -41
  22. odxtools/diagdatadictionaryspec.py +51 -55
  23. odxtools/diaglayercontainer.py +25 -25
  24. odxtools/diaglayers/diaglayerraw.py +26 -27
  25. odxtools/diagnostictroublecode.py +13 -10
  26. odxtools/diagservice.py +48 -50
  27. odxtools/diagvariable.py +10 -8
  28. odxtools/docrevision.py +5 -5
  29. odxtools/dtcdop.py +17 -17
  30. odxtools/dynamicendmarkerfield.py +8 -8
  31. odxtools/dynamiclengthfield.py +2 -0
  32. odxtools/dyndefinedspec.py +21 -8
  33. odxtools/encodestate.py +1 -2
  34. odxtools/endofpdufield.py +7 -9
  35. odxtools/environmentdatadescription.py +9 -20
  36. odxtools/field.py +21 -21
  37. odxtools/inputparam.py +15 -14
  38. odxtools/leadinglengthinfotype.py +4 -4
  39. odxtools/matchingparameter.py +2 -3
  40. odxtools/minmaxlengthtype.py +7 -7
  41. odxtools/multiplexer.py +38 -39
  42. odxtools/multiplexercase.py +3 -6
  43. odxtools/multiplexerdefaultcase.py +3 -6
  44. odxtools/multiplexerswitchkey.py +4 -4
  45. odxtools/negoutputparam.py +6 -9
  46. odxtools/odxlink.py +21 -5
  47. odxtools/odxtypes.py +4 -4
  48. odxtools/outputparam.py +9 -8
  49. odxtools/parameterinfo.py +1 -1
  50. odxtools/parameters/codedconstparameter.py +28 -27
  51. odxtools/parameters/dynamicparameter.py +9 -9
  52. odxtools/parameters/lengthkeyparameter.py +18 -18
  53. odxtools/parameters/matchingrequestparameter.py +15 -15
  54. odxtools/parameters/nrcconstparameter.py +32 -24
  55. odxtools/parameters/parameter.py +35 -37
  56. odxtools/parameters/parameterwithdop.py +6 -6
  57. odxtools/parameters/physicalconstantparameter.py +19 -20
  58. odxtools/parameters/reservedparameter.py +10 -11
  59. odxtools/parameters/systemparameter.py +10 -11
  60. odxtools/parameters/tableentryparameter.py +19 -20
  61. odxtools/parameters/tablekeyparameter.py +0 -2
  62. odxtools/parameters/tablestructparameter.py +27 -21
  63. odxtools/parameters/valueparameter.py +20 -20
  64. odxtools/parentref.py +6 -7
  65. odxtools/physicaldimension.py +11 -11
  66. odxtools/physicaltype.py +9 -14
  67. odxtools/preconditionstateref.py +85 -0
  68. odxtools/progcode.py +1 -2
  69. odxtools/protstack.py +4 -4
  70. odxtools/relateddoc.py +3 -4
  71. odxtools/scaleconstr.py +0 -1
  72. odxtools/singleecujob.py +8 -4
  73. odxtools/specialdata.py +10 -9
  74. odxtools/specialdatagroup.py +1 -0
  75. odxtools/standardlengthtype.py +10 -10
  76. odxtools/statechart.py +10 -6
  77. odxtools/statemachine.py +186 -0
  78. odxtools/statetransitionref.py +231 -0
  79. odxtools/structure.py +4 -4
  80. odxtools/subcomponent.py +72 -8
  81. odxtools/table.py +23 -13
  82. odxtools/tablerow.py +86 -69
  83. odxtools/teammember.py +4 -4
  84. odxtools/templates/macros/printCompanyData.xml.jinja2 +2 -2
  85. odxtools/templates/macros/printComparam.xml.jinja2 +3 -5
  86. odxtools/templates/macros/printDOP.xml.jinja2 +4 -1
  87. odxtools/templates/macros/printDiagComm.xml.jinja2 +6 -5
  88. odxtools/templates/macros/printParam.xml.jinja2 +5 -5
  89. odxtools/templates/macros/printPreConditionStateRef.xml.jinja2 +18 -0
  90. odxtools/templates/macros/printStateTransitionRef.xml.jinja2 +18 -0
  91. odxtools/templates/macros/printTable.xml.jinja2 +13 -9
  92. odxtools/text.py +35 -0
  93. odxtools/unit.py +1 -3
  94. odxtools/unitgroup.py +6 -8
  95. odxtools/utils.py +0 -4
  96. odxtools/version.py +2 -2
  97. {odxtools-9.5.0.dist-info → odxtools-9.6.0.dist-info}/METADATA +3 -2
  98. {odxtools-9.5.0.dist-info → odxtools-9.6.0.dist-info}/RECORD +102 -96
  99. {odxtools-9.5.0.dist-info → odxtools-9.6.0.dist-info}/WHEEL +1 -1
  100. {odxtools-9.5.0.dist-info → odxtools-9.6.0.dist-info}/entry_points.txt +0 -0
  101. {odxtools-9.5.0.dist-info → odxtools-9.6.0.dist-info/licenses}/LICENSE +0 -0
  102. {odxtools-9.5.0.dist-info → odxtools-9.6.0.dist-info}/top_level.txt +0 -0
@@ -22,12 +22,16 @@ if TYPE_CHECKING:
22
22
 
23
23
  @dataclass
24
24
  class DiagLayerContainer(OdxCategory):
25
- ecu_shared_datas: NamedItemList[EcuSharedData]
26
25
  protocols: NamedItemList[Protocol]
27
26
  functional_groups: NamedItemList[FunctionalGroup]
27
+ ecu_shared_datas: NamedItemList[EcuSharedData]
28
28
  base_variants: NamedItemList[BaseVariant]
29
29
  ecu_variants: NamedItemList[EcuVariant]
30
30
 
31
+ @property
32
+ def diag_layers(self) -> NamedItemList[DiagLayer]:
33
+ return self._diag_layers
34
+
31
35
  @property
32
36
  def ecus(self) -> NamedItemList[EcuVariant]:
33
37
  """ECU variants defined in the container
@@ -35,15 +39,6 @@ class DiagLayerContainer(OdxCategory):
35
39
  This property is an alias for `.ecu_variants`"""
36
40
  return self.ecu_variants
37
41
 
38
- def __post_init__(self) -> None:
39
- self._diag_layers = NamedItemList[DiagLayer](chain(
40
- self.ecu_shared_datas,
41
- self.protocols,
42
- self.functional_groups,
43
- self.base_variants,
44
- self.ecu_variants,
45
- ),)
46
-
47
42
  @staticmethod
48
43
  def from_et(et_element: ElementTree.Element,
49
44
  doc_frags: List[OdxDocFragment]) -> "DiagLayerContainer":
@@ -52,10 +47,6 @@ class DiagLayerContainer(OdxCategory):
52
47
  doc_frags = cat.odx_id.doc_fragments
53
48
  kwargs = dataclass_fields_asdict(cat)
54
49
 
55
- ecu_shared_datas = NamedItemList([
56
- EcuSharedData.from_et(dl_element, doc_frags)
57
- for dl_element in et_element.iterfind("ECU-SHARED-DATAS/ECU-SHARED-DATA")
58
- ])
59
50
  protocols = NamedItemList([
60
51
  Protocol.from_et(dl_element, doc_frags)
61
52
  for dl_element in et_element.iterfind("PROTOCOLS/PROTOCOL")
@@ -64,6 +55,10 @@ class DiagLayerContainer(OdxCategory):
64
55
  FunctionalGroup.from_et(dl_element, doc_frags)
65
56
  for dl_element in et_element.iterfind("FUNCTIONAL-GROUPS/FUNCTIONAL-GROUP")
66
57
  ])
58
+ ecu_shared_datas = NamedItemList([
59
+ EcuSharedData.from_et(dl_element, doc_frags)
60
+ for dl_element in et_element.iterfind("ECU-SHARED-DATAS/ECU-SHARED-DATA")
61
+ ])
67
62
  base_variants = NamedItemList([
68
63
  BaseVariant.from_et(dl_element, doc_frags)
69
64
  for dl_element in et_element.iterfind("BASE-VARIANTS/BASE-VARIANT")
@@ -74,22 +69,31 @@ class DiagLayerContainer(OdxCategory):
74
69
  ])
75
70
 
76
71
  return DiagLayerContainer(
77
- ecu_shared_datas=ecu_shared_datas,
78
72
  protocols=protocols,
79
73
  functional_groups=functional_groups,
74
+ ecu_shared_datas=ecu_shared_datas,
80
75
  base_variants=base_variants,
81
76
  ecu_variants=ecu_variants,
82
77
  **kwargs)
83
78
 
79
+ def __post_init__(self) -> None:
80
+ self._diag_layers = NamedItemList[DiagLayer](chain(
81
+ self.protocols,
82
+ self.functional_groups,
83
+ self.ecu_shared_datas,
84
+ self.base_variants,
85
+ self.ecu_variants,
86
+ ),)
87
+
84
88
  def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
85
89
  result = super()._build_odxlinks()
86
90
 
87
- for ecu_shared_data in self.ecu_shared_datas:
88
- result.update(ecu_shared_data._build_odxlinks())
89
91
  for protocol in self.protocols:
90
92
  result.update(protocol._build_odxlinks())
91
93
  for functional_group in self.functional_groups:
92
94
  result.update(functional_group._build_odxlinks())
95
+ for ecu_shared_data in self.ecu_shared_datas:
96
+ result.update(ecu_shared_data._build_odxlinks())
93
97
  for base_variant in self.base_variants:
94
98
  result.update(base_variant._build_odxlinks())
95
99
  for ecu_variant in self.ecu_variants:
@@ -100,12 +104,12 @@ class DiagLayerContainer(OdxCategory):
100
104
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
101
105
  super()._resolve_odxlinks(odxlinks)
102
106
 
103
- for ecu_shared_data in self.ecu_shared_datas:
104
- ecu_shared_data._resolve_odxlinks(odxlinks)
105
107
  for protocol in self.protocols:
106
108
  protocol._resolve_odxlinks(odxlinks)
107
109
  for functional_group in self.functional_groups:
108
110
  functional_group._resolve_odxlinks(odxlinks)
111
+ for ecu_shared_data in self.ecu_shared_datas:
112
+ ecu_shared_data._resolve_odxlinks(odxlinks)
109
113
  for base_variant in self.base_variants:
110
114
  base_variant._resolve_odxlinks(odxlinks)
111
115
  for ecu_variant in self.ecu_variants:
@@ -114,12 +118,12 @@ class DiagLayerContainer(OdxCategory):
114
118
  def _finalize_init(self, database: "Database", odxlinks: OdxLinkDatabase) -> None:
115
119
  super()._finalize_init(database, odxlinks)
116
120
 
117
- for ecu_shared_data in self.ecu_shared_datas:
118
- ecu_shared_data._finalize_init(database, odxlinks)
119
121
  for protocol in self.protocols:
120
122
  protocol._finalize_init(database, odxlinks)
121
123
  for functional_group in self.functional_groups:
122
124
  functional_group._finalize_init(database, odxlinks)
125
+ for ecu_shared_data in self.ecu_shared_datas:
126
+ ecu_shared_data._finalize_init(database, odxlinks)
123
127
  for base_variant in self.base_variants:
124
128
  base_variant._finalize_init(database, odxlinks)
125
129
  for ecu_variant in self.ecu_variants:
@@ -128,9 +132,5 @@ class DiagLayerContainer(OdxCategory):
128
132
  def _resolve_snrefs(self, context: SnRefContext) -> None:
129
133
  super()._resolve_snrefs(context)
130
134
 
131
- @property
132
- def diag_layers(self) -> NamedItemList[DiagLayer]:
133
- return self._diag_layers
134
-
135
135
  def __getitem__(self, key: Union[int, str]) -> DiagLayer:
136
136
  return self.diag_layers[key]
@@ -88,15 +88,15 @@ class DiagLayerRaw(IdentifiableElement):
88
88
  if (admin_data_elem := et_element.find("ADMIN-DATA")) is not None:
89
89
  admin_data = AdminData.from_et(admin_data_elem, doc_frags)
90
90
 
91
- company_datas = [
91
+ company_datas = NamedItemList([
92
92
  CompanyData.from_et(cd_el, doc_frags)
93
93
  for cd_el in et_element.iterfind("COMPANY-DATAS/COMPANY-DATA")
94
- ]
94
+ ])
95
95
 
96
- functional_classes = [
96
+ functional_classes = NamedItemList([
97
97
  FunctionalClass.from_et(fc_el, doc_frags)
98
98
  for fc_el in et_element.iterfind("FUNCT-CLASSS/FUNCT-CLASS")
99
- ]
99
+ ])
100
100
 
101
101
  diag_data_dictionary_spec = None
102
102
  if (ddds_elem := et_element.find("DIAG-DATA-DICTIONARY-SPEC")) is not None:
@@ -141,24 +141,23 @@ class DiagLayerRaw(IdentifiableElement):
141
141
  for el in et_element.iterfind("IMPORT-REFS/IMPORT-REF")
142
142
  ]
143
143
 
144
- state_charts = [
144
+ state_charts = NamedItemList([
145
145
  StateChart.from_et(el, doc_frags)
146
146
  for el in et_element.iterfind("STATE-CHARTS/STATE-CHART")
147
- ]
147
+ ])
148
148
 
149
- additional_audiences = [
149
+ additional_audiences = NamedItemList([
150
150
  AdditionalAudience.from_et(el, doc_frags)
151
151
  for el in et_element.iterfind("ADDITIONAL-AUDIENCES/ADDITIONAL-AUDIENCE")
152
- ]
153
-
154
- libraries = [
155
- Library.from_et(el, doc_frags) for el in et_element.iterfind("LIBRARYS/LIBRARY")
156
- ]
152
+ ])
157
153
 
158
- sub_components = [
154
+ sub_components = NamedItemList([
159
155
  SubComponent.from_et(el, doc_frags)
160
156
  for el in et_element.iterfind("SUB-COMPONENTS/SUB-COMPONENT")
161
- ]
157
+ ])
158
+
159
+ libraries = NamedItemList(
160
+ [Library.from_et(el, doc_frags) for el in et_element.iterfind("LIBRARYS/LIBRARY")])
162
161
 
163
162
  sdgs = [
164
163
  SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
@@ -168,19 +167,19 @@ class DiagLayerRaw(IdentifiableElement):
168
167
  return DiagLayerRaw(
169
168
  variant_type=variant_type,
170
169
  admin_data=admin_data,
171
- company_datas=NamedItemList(company_datas),
172
- functional_classes=NamedItemList(functional_classes),
170
+ company_datas=company_datas,
171
+ functional_classes=functional_classes,
173
172
  diag_data_dictionary_spec=diag_data_dictionary_spec,
174
173
  diag_comms_raw=diag_comms_raw,
175
174
  requests=requests,
176
175
  positive_responses=positive_responses,
177
176
  negative_responses=negative_responses,
178
- global_negative_responses=NamedItemList(global_negative_responses),
177
+ global_negative_responses=global_negative_responses,
179
178
  import_refs=import_refs,
180
- state_charts=NamedItemList(state_charts),
181
- additional_audiences=NamedItemList(additional_audiences),
182
- libraries=NamedItemList(libraries),
183
- sub_components=NamedItemList(sub_components),
179
+ state_charts=state_charts,
180
+ additional_audiences=additional_audiences,
181
+ sub_components=sub_components,
182
+ libraries=libraries,
184
183
  sdgs=sdgs,
185
184
  **kwargs)
186
185
 
@@ -213,10 +212,10 @@ class DiagLayerRaw(IdentifiableElement):
213
212
  odxlinks.update(state_chart._build_odxlinks())
214
213
  for additional_audience in self.additional_audiences:
215
214
  odxlinks.update(additional_audience._build_odxlinks())
216
- for library in self.libraries:
217
- odxlinks.update(library._build_odxlinks())
218
215
  for sub_comp in self.sub_components:
219
216
  odxlinks.update(sub_comp._build_odxlinks())
217
+ for library in self.libraries:
218
+ odxlinks.update(library._build_odxlinks())
220
219
  for sdg in self.sdgs:
221
220
  odxlinks.update(sdg._build_odxlinks())
222
221
 
@@ -269,10 +268,10 @@ class DiagLayerRaw(IdentifiableElement):
269
268
  state_chart._resolve_odxlinks(odxlinks)
270
269
  for additional_audience in self.additional_audiences:
271
270
  additional_audience._resolve_odxlinks(odxlinks)
272
- for library in self.libraries:
273
- library._resolve_odxlinks(odxlinks)
274
271
  for sub_component in self.sub_components:
275
272
  sub_component._resolve_odxlinks(odxlinks)
273
+ for library in self.libraries:
274
+ library._resolve_odxlinks(odxlinks)
276
275
  for sdg in self.sdgs:
277
276
  sdg._resolve_odxlinks(odxlinks)
278
277
 
@@ -303,9 +302,9 @@ class DiagLayerRaw(IdentifiableElement):
303
302
  state_chart._resolve_snrefs(context)
304
303
  for additional_audience in self.additional_audiences:
305
304
  additional_audience._resolve_snrefs(context)
306
- for library in self.libraries:
307
- library._resolve_snrefs(context)
308
305
  for sub_component in self.sub_components:
309
306
  sub_component._resolve_snrefs(context)
307
+ for library in self.libraries:
308
+ library._resolve_snrefs(context)
310
309
  for sdg in self.sdgs:
311
310
  sdg._resolve_snrefs(context)
@@ -9,18 +9,20 @@ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
9
9
  from .odxtypes import odxstr_to_bool
10
10
  from .snrefcontext import SnRefContext
11
11
  from .specialdatagroup import SpecialDataGroup
12
+ from .text import Text
12
13
  from .utils import dataclass_fields_asdict
13
14
 
14
15
 
15
16
  @dataclass
16
17
  class DiagnosticTroubleCode(IdentifiableElement):
17
18
  trouble_code: int
18
- text: str
19
19
  display_trouble_code: Optional[str]
20
+ text: Text
20
21
  level: Optional[int]
21
- is_temporary_raw: Optional[bool]
22
22
  sdgs: List[SpecialDataGroup]
23
23
 
24
+ is_temporary_raw: Optional[bool]
25
+
24
26
  @property
25
27
  def is_temporary(self) -> bool:
26
28
  return self.is_temporary_raw is True
@@ -29,31 +31,32 @@ class DiagnosticTroubleCode(IdentifiableElement):
29
31
  def from_et(et_element: ElementTree.Element,
30
32
  doc_frags: List[OdxDocFragment]) -> "DiagnosticTroubleCode":
31
33
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
32
- display_trouble_code = et_element.findtext("DISPLAY-TROUBLE-CODE")
33
34
 
35
+ trouble_code = int(odxrequire(et_element.findtext("TROUBLE-CODE")))
36
+ display_trouble_code = et_element.findtext("DISPLAY-TROUBLE-CODE")
37
+ text = Text.from_et(odxrequire(et_element.find("TEXT")), doc_frags)
34
38
  level = None
35
39
  if (level_str := et_element.findtext("LEVEL")) is not None:
36
40
  level = int(level_str)
37
-
38
- is_temporary_raw = odxstr_to_bool(et_element.get("IS-TEMPORARY"))
39
41
  sdgs = [
40
42
  SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
41
43
  ]
42
44
 
45
+ is_temporary_raw = odxstr_to_bool(et_element.attrib.get("IS-TEMPORARY"))
46
+
43
47
  return DiagnosticTroubleCode(
44
- trouble_code=int(odxrequire(et_element.findtext("TROUBLE-CODE"))),
45
- text=odxrequire(et_element.findtext("TEXT")),
48
+ trouble_code=trouble_code,
49
+ text=text,
46
50
  display_trouble_code=display_trouble_code,
47
51
  level=level,
48
- is_temporary_raw=is_temporary_raw,
49
52
  sdgs=sdgs,
53
+ is_temporary_raw=is_temporary_raw,
50
54
  **kwargs)
51
55
 
52
56
  def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
53
57
  result: Dict[OdxLinkId, Any] = {}
54
58
 
55
- if self.odx_id is not None:
56
- result[self.odx_id] = self
59
+ result[self.odx_id] = self
57
60
 
58
61
  for sdg in self.sdgs:
59
62
  result.update(sdg._build_odxlinks())
odxtools/diagservice.py CHANGED
@@ -102,11 +102,9 @@ class DiagService(DiagComm):
102
102
  """
103
103
 
104
104
  comparam_refs: List[ComparamInstance]
105
-
106
105
  request_ref: OdxLinkRef
107
106
  pos_response_refs: List[OdxLinkRef]
108
107
  neg_response_refs: List[OdxLinkRef]
109
-
110
108
  pos_response_suppressible: Optional[PosResponseSuppressible]
111
109
 
112
110
  is_cyclic_raw: Optional[bool]
@@ -114,6 +112,45 @@ class DiagService(DiagComm):
114
112
  addressing_raw: Optional[Addressing]
115
113
  transmission_mode_raw: Optional[TransMode]
116
114
 
115
+ @property
116
+ def comparams(self) -> NamedItemList[ComparamInstance]:
117
+ return self._comparams
118
+
119
+ @property
120
+ def request(self) -> Optional[Request]:
121
+ return self._request
122
+
123
+ @property
124
+ def positive_responses(self) -> NamedItemList[Response]:
125
+ return self._positive_responses
126
+
127
+ @property
128
+ def negative_responses(self) -> NamedItemList[Response]:
129
+ return self._negative_responses
130
+
131
+ @property
132
+ def is_cyclic(self) -> bool:
133
+ return self.is_cyclic_raw is True
134
+
135
+ @property
136
+ def is_multiple(self) -> bool:
137
+ return self.is_multiple_raw is True
138
+
139
+ @property
140
+ def addressing(self) -> Addressing:
141
+ return self.addressing_raw or Addressing.PHYSICAL
142
+
143
+ @property
144
+ def transmission_mode(self) -> TransMode:
145
+ return self.transmission_mode_raw or TransMode.SEND_AND_RECEIVE
146
+
147
+ @property
148
+ def free_parameters(self) -> List[Parameter]:
149
+ """Return the list of parameters which can be freely specified by
150
+ the user when encoding the service's request.
151
+ """
152
+ return self.request.free_parameters if self.request is not None else []
153
+
117
154
  @staticmethod
118
155
  def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "DiagService":
119
156
 
@@ -171,54 +208,6 @@ class DiagService(DiagComm):
171
208
  transmission_mode_raw=transmission_mode_raw,
172
209
  **kwargs)
173
210
 
174
- @property
175
- def request(self) -> Optional[Request]:
176
- return self._request
177
-
178
- @property
179
- def free_parameters(self) -> List[Parameter]:
180
- """Return the list of parameters which can be freely specified by
181
- the user when encoding the service's request.
182
- """
183
- return self.request.free_parameters if self.request is not None else []
184
-
185
- def print_free_parameters_info(self) -> None:
186
- """Return a human readable description of the service's
187
- request's free parameters.
188
- """
189
- if self.request is None:
190
- return
191
-
192
- self.request.print_free_parameters_info()
193
-
194
- @property
195
- def positive_responses(self) -> NamedItemList[Response]:
196
- return self._positive_responses
197
-
198
- @property
199
- def negative_responses(self) -> NamedItemList[Response]:
200
- return self._negative_responses
201
-
202
- @property
203
- def comparams(self) -> NamedItemList[ComparamInstance]:
204
- return self._comparams
205
-
206
- @property
207
- def addressing(self) -> Addressing:
208
- return self.addressing_raw or Addressing.PHYSICAL
209
-
210
- @property
211
- def transmission_mode(self) -> TransMode:
212
- return self.transmission_mode_raw or TransMode.SEND_AND_RECEIVE
213
-
214
- @property
215
- def is_cyclic(self) -> bool:
216
- return self.is_cyclic_raw is True
217
-
218
- @property
219
- def is_multiple(self) -> bool:
220
- return self.is_multiple_raw is True
221
-
222
211
  def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
223
212
  result = super()._build_odxlinks()
224
213
 
@@ -256,6 +245,15 @@ class DiagService(DiagComm):
256
245
 
257
246
  context.diag_service = None
258
247
 
248
+ def print_free_parameters_info(self) -> None:
249
+ """Return a human readable description of the service's
250
+ request's free parameters.
251
+ """
252
+ if self.request is None:
253
+ return
254
+
255
+ self.request.print_free_parameters_info()
256
+
259
257
  def decode_message(self, raw_message: bytes) -> Message:
260
258
  request_prefix = b''
261
259
  candidate_coding_objects: List[Union[Request, Response]] = [
odxtools/diagvariable.py CHANGED
@@ -46,6 +46,7 @@ class DiagVariable(IdentifiableElement):
46
46
  table_row_snref: Optional[str]
47
47
 
48
48
  sdgs: List[SpecialDataGroup]
49
+
49
50
  is_read_before_write_raw: Optional[bool]
50
51
 
51
52
  @property
@@ -91,6 +92,7 @@ class DiagVariable(IdentifiableElement):
91
92
  sdgs = [
92
93
  SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
93
94
  ]
95
+
94
96
  is_read_before_write_raw = odxstr_to_bool(et_element.get("IS-READ-BEFORE-WRITE"))
95
97
 
96
98
  return DiagVariable(
@@ -119,26 +121,23 @@ class DiagVariable(IdentifiableElement):
119
121
  return result
120
122
 
121
123
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
124
+ if self.admin_data is not None:
125
+ self.admin_data._resolve_odxlinks(odxlinks)
126
+
122
127
  self._variable_group = None
123
128
  if self.variable_group_ref is not None:
124
129
  self._variable_group = odxlinks.resolve(self.variable_group_ref, VariableGroup)
125
130
 
126
- if self.admin_data is not None:
127
- self.admin_data._resolve_odxlinks(odxlinks)
131
+ for cr in self.comm_relations:
132
+ cr._resolve_odxlinks(odxlinks)
128
133
 
129
134
  for sdg in self.sdgs:
130
135
  sdg._resolve_odxlinks(odxlinks)
131
136
 
132
- for cr in self.comm_relations:
133
- cr._resolve_odxlinks(odxlinks)
134
-
135
137
  def _resolve_snrefs(self, context: SnRefContext) -> None:
136
138
  if self.admin_data is not None:
137
139
  self.admin_data._resolve_snrefs(context)
138
140
 
139
- for sdg in self.sdgs:
140
- sdg._resolve_snrefs(context)
141
-
142
141
  for cr in self.comm_relations:
143
142
  cr._resolve_snrefs(context)
144
143
 
@@ -149,3 +148,6 @@ class DiagVariable(IdentifiableElement):
149
148
  self._table = resolve_snref(self.table_snref, ddds.tables, Table)
150
149
  self._table_row = resolve_snref(
151
150
  odxrequire(self.table_row_snref), self._table.table_rows, TableRow)
151
+
152
+ for sdg in self.sdgs:
153
+ sdg._resolve_snrefs(context)
odxtools/docrevision.py CHANGED
@@ -17,10 +17,10 @@ class DocRevision:
17
17
  Representation of a single revision of the relevant object.
18
18
  """
19
19
 
20
- date: str
21
20
  team_member_ref: Optional[OdxLinkRef]
22
21
  revision_label: Optional[str]
23
22
  state: Optional[str]
23
+ date: str
24
24
  tool: Optional[str]
25
25
  company_revision_infos: List[CompanyRevisionInfo]
26
26
  modifications: List[Modification]
@@ -38,13 +38,13 @@ class DocRevision:
38
38
  date = odxrequire(et_element.findtext("DATE"))
39
39
  tool = et_element.findtext("TOOL")
40
40
 
41
- crilist = [
41
+ company_revision_infos = [
42
42
  CompanyRevisionInfo.from_et(cri_elem, doc_frags)
43
43
  for cri_elem in et_element.iterfind("COMPANY-REVISION-INFOS/"
44
44
  "COMPANY-REVISION-INFO")
45
45
  ]
46
46
 
47
- modlist = [
47
+ modifications = [
48
48
  Modification.from_et(mod_elem, doc_frags)
49
49
  for mod_elem in et_element.iterfind("MODIFICATIONS/MODIFICATION")
50
50
  ]
@@ -55,8 +55,8 @@ class DocRevision:
55
55
  state=state,
56
56
  date=date,
57
57
  tool=tool,
58
- company_revision_infos=crilist,
59
- modifications=modlist,
58
+ company_revision_infos=company_revision_infos,
59
+ modifications=modifications,
60
60
  )
61
61
 
62
62
  def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
odxtools/dtcdop.py CHANGED
@@ -27,6 +27,10 @@ class LinkedDtcDop:
27
27
  not_inherited_dtc_snrefs: List[str]
28
28
  dtc_dop_ref: OdxLinkRef
29
29
 
30
+ @property
31
+ def not_inherited_dtcs(self) -> NamedItemList[DiagnosticTroubleCode]:
32
+ return self._not_inherited_dtcs
33
+
30
34
  @property
31
35
  def dtc_dop(self) -> "DtcDop":
32
36
  return self._dtc_dop
@@ -35,10 +39,6 @@ class LinkedDtcDop:
35
39
  def short_name(self) -> str:
36
40
  return self._dtc_dop.short_name
37
41
 
38
- @property
39
- def not_inherited_dtcs(self) -> NamedItemList[DiagnosticTroubleCode]:
40
- return self._not_inherited_dtcs
41
-
42
42
  @staticmethod
43
43
  def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "LinkedDtcDop":
44
44
  not_inherited_dtc_snrefs = [
@@ -79,8 +79,17 @@ class DtcDop(DopBase):
79
79
  linked_dtc_dops_raw: List[LinkedDtcDop]
80
80
  is_visible_raw: Optional[bool]
81
81
 
82
- def __post_init__(self) -> None:
83
- self._init_finished = False
82
+ @property
83
+ def dtcs(self) -> NamedItemList[DiagnosticTroubleCode]:
84
+ return self._dtcs
85
+
86
+ @property
87
+ def linked_dtc_dops(self) -> NamedItemList[LinkedDtcDop]:
88
+ return self._linked_dtc_dops
89
+
90
+ @property
91
+ def is_visible(self) -> bool:
92
+ return self.is_visible_raw is True
84
93
 
85
94
  @staticmethod
86
95
  def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "DtcDop":
@@ -121,17 +130,8 @@ class DtcDop(DopBase):
121
130
  is_visible_raw=is_visible_raw,
122
131
  **kwargs)
123
132
 
124
- @property
125
- def dtcs(self) -> NamedItemList[DiagnosticTroubleCode]:
126
- return self._dtcs
127
-
128
- @property
129
- def linked_dtc_dops(self) -> NamedItemList[LinkedDtcDop]:
130
- return self._linked_dtc_dops
131
-
132
- @property
133
- def is_visible(self) -> bool:
134
- return self.is_visible_raw is True
133
+ def __post_init__(self) -> None:
134
+ self._init_finished = False
135
135
 
136
136
  @override
137
137
  def decode_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
@@ -23,6 +23,14 @@ class DynamicEndmarkerField(Field):
23
23
 
24
24
  dyn_end_dop_ref: DynEndDopRef
25
25
 
26
+ @property
27
+ def dyn_end_dop(self) -> DataObjectProperty:
28
+ return self._dyn_end_dop
29
+
30
+ @property
31
+ def termination_value(self) -> AtomicOdxType:
32
+ return self._termination_value
33
+
26
34
  @staticmethod
27
35
  def from_et(et_element: ElementTree.Element,
28
36
  doc_frags: List[OdxDocFragment]) -> "DynamicEndmarkerField":
@@ -52,14 +60,6 @@ class DynamicEndmarkerField(Field):
52
60
  def _resolve_snrefs(self, context: SnRefContext) -> None:
53
61
  super()._resolve_snrefs(context)
54
62
 
55
- @property
56
- def dyn_end_dop(self) -> DataObjectProperty:
57
- return self._dyn_end_dop
58
-
59
- @property
60
- def termination_value(self) -> AtomicOdxType:
61
- return self._termination_value
62
-
63
63
  @override
64
64
  def encode_into_pdu(self, physical_value: ParameterValue, encode_state: EncodeState) -> None:
65
65
 
@@ -26,11 +26,13 @@ class DynamicLengthField(Field):
26
26
  def from_et(et_element: ElementTree.Element,
27
27
  doc_frags: List[OdxDocFragment]) -> "DynamicLengthField":
28
28
  kwargs = dataclass_fields_asdict(Field.from_et(et_element, doc_frags))
29
+
29
30
  offset = int(odxrequire(et_element.findtext('OFFSET')))
30
31
  determine_number_of_items = DetermineNumberOfItems.from_et(
31
32
  odxrequire(et_element.find('DETERMINE-NUMBER-OF-ITEMS')),
32
33
  doc_frags,
33
34
  )
35
+
34
36
  return DynamicLengthField(
35
37
  offset=offset, determine_number_of_items=determine_number_of_items, **kwargs)
36
38