odxtools 5.3.1__py3-none-any.whl → 6.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. odxtools/__init__.py +1 -1
  2. odxtools/basicstructure.py +76 -91
  3. odxtools/cli/_parser_utils.py +12 -9
  4. odxtools/cli/_print_utils.py +7 -7
  5. odxtools/cli/browse.py +94 -73
  6. odxtools/cli/find.py +42 -59
  7. odxtools/cli/list.py +21 -17
  8. odxtools/cli/snoop.py +19 -18
  9. odxtools/communicationparameterref.py +6 -3
  10. odxtools/companydocinfo.py +2 -2
  11. odxtools/companyrevisioninfo.py +1 -1
  12. odxtools/comparamsubset.py +6 -6
  13. odxtools/complexcomparam.py +1 -1
  14. odxtools/compumethods/compumethod.py +6 -9
  15. odxtools/compumethods/createanycompumethod.py +11 -9
  16. odxtools/compumethods/identicalcompumethod.py +5 -4
  17. odxtools/compumethods/limit.py +9 -9
  18. odxtools/compumethods/linearcompumethod.py +25 -17
  19. odxtools/compumethods/scalelinearcompumethod.py +6 -5
  20. odxtools/compumethods/tabintpcompumethod.py +30 -9
  21. odxtools/compumethods/texttablecompumethod.py +22 -24
  22. odxtools/database.py +5 -5
  23. odxtools/dataobjectproperty.py +10 -23
  24. odxtools/decodestate.py +1 -1
  25. odxtools/determinenumberofitems.py +37 -8
  26. odxtools/diagcodedtype.py +14 -9
  27. odxtools/diagdatadictionaryspec.py +60 -37
  28. odxtools/diaglayer.py +30 -21
  29. odxtools/diaglayercontainer.py +40 -40
  30. odxtools/diaglayerraw.py +92 -63
  31. odxtools/diagnostictroublecode.py +2 -2
  32. odxtools/diagservice.py +53 -35
  33. odxtools/docrevision.py +1 -1
  34. odxtools/dopbase.py +14 -3
  35. odxtools/dtcdop.py +15 -9
  36. odxtools/dynamiclengthfield.py +6 -4
  37. odxtools/endofpdufield.py +22 -23
  38. odxtools/environmentdata.py +2 -5
  39. odxtools/environmentdatadescription.py +6 -4
  40. odxtools/field.py +3 -8
  41. odxtools/isotp_state_machine.py +52 -38
  42. odxtools/leadinglengthinfotype.py +9 -7
  43. odxtools/load_file.py +2 -1
  44. odxtools/load_odx_d_file.py +2 -5
  45. odxtools/load_pdx_file.py +2 -6
  46. odxtools/message.py +11 -3
  47. odxtools/minmaxlengthtype.py +107 -78
  48. odxtools/modification.py +2 -2
  49. odxtools/multiplexer.py +23 -21
  50. odxtools/multiplexerswitchkey.py +37 -8
  51. odxtools/nameditemlist.py +59 -58
  52. odxtools/odxlink.py +4 -2
  53. odxtools/odxtypes.py +4 -3
  54. odxtools/parameterinfo.py +6 -6
  55. odxtools/parameters/codedconstparameter.py +15 -25
  56. odxtools/parameters/createanyparameter.py +1 -1
  57. odxtools/parameters/dynamicparameter.py +6 -5
  58. odxtools/parameters/lengthkeyparameter.py +2 -1
  59. odxtools/parameters/matchingrequestparameter.py +8 -11
  60. odxtools/parameters/nrcconstparameter.py +11 -21
  61. odxtools/parameters/parameter.py +4 -18
  62. odxtools/parameters/parameterwithdop.py +14 -29
  63. odxtools/parameters/physicalconstantparameter.py +7 -9
  64. odxtools/parameters/reservedparameter.py +17 -38
  65. odxtools/parameters/systemparameter.py +6 -5
  66. odxtools/parameters/tableentryparameter.py +6 -5
  67. odxtools/parameters/tablekeyparameter.py +8 -15
  68. odxtools/parameters/tablestructparameter.py +11 -12
  69. odxtools/parameters/valueparameter.py +9 -24
  70. odxtools/paramlengthinfotype.py +11 -9
  71. odxtools/physicaldimension.py +1 -1
  72. odxtools/physicaltype.py +2 -2
  73. odxtools/response.py +7 -3
  74. odxtools/singleecujob.py +48 -22
  75. odxtools/standardlengthtype.py +11 -6
  76. odxtools/uds.py +1 -1
  77. odxtools/unit.py +5 -5
  78. odxtools/unitgroup.py +1 -1
  79. odxtools/unitspec.py +2 -2
  80. odxtools/version.py +13 -3
  81. odxtools/write_pdx_file.py +7 -4
  82. {odxtools-5.3.1.dist-info → odxtools-6.0.1.dist-info}/METADATA +7 -5
  83. {odxtools-5.3.1.dist-info → odxtools-6.0.1.dist-info}/RECORD +87 -88
  84. odxtools/positioneddataobjectproperty.py +0 -74
  85. {odxtools-5.3.1.dist-info → odxtools-6.0.1.dist-info}/LICENSE +0 -0
  86. {odxtools-5.3.1.dist-info → odxtools-6.0.1.dist-info}/WHEEL +0 -0
  87. {odxtools-5.3.1.dist-info → odxtools-6.0.1.dist-info}/entry_points.txt +0 -0
  88. {odxtools-5.3.1.dist-info → odxtools-6.0.1.dist-info}/top_level.txt +0 -0
@@ -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 TYPE_CHECKING, Any, Dict, List, Optional, Tuple
4
4
  from xml.etree import ElementTree
5
5
 
6
6
  from .createsdgs import create_sdgs_from_et
@@ -11,7 +11,7 @@ from .encodestate import EncodeState
11
11
  from .environmentdata import EnvironmentData
12
12
  from .exceptions import DecodeError, EncodeError, odxrequire
13
13
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
14
- from .odxtypes import odxstr_to_bool
14
+ from .odxtypes import ParameterValue, odxstr_to_bool
15
15
  from .utils import dataclass_fields_asdict
16
16
 
17
17
  if TYPE_CHECKING:
@@ -93,7 +93,7 @@ class EnvironmentDataDescription(DopBase):
93
93
  for ed in self.env_datas:
94
94
  ed._resolve_snrefs(diag_layer)
95
95
 
96
- def convert_physical_to_bytes(self, physical_value, encode_state: EncodeState,
96
+ def convert_physical_to_bytes(self, physical_value: ParameterValue, encode_state: EncodeState,
97
97
  bit_position: int) -> bytes:
98
98
  """Convert the physical value into bytes.
99
99
 
@@ -102,7 +102,9 @@ class EnvironmentDataDescription(DopBase):
102
102
  """
103
103
  raise EncodeError("EnvironmentDataDescription DOPs cannot be encoded or decoded")
104
104
 
105
- def convert_bytes_to_physical(self, decode_state: DecodeState, bit_position: int = 0):
105
+ def convert_bytes_to_physical(self,
106
+ decode_state: DecodeState,
107
+ bit_position: int = 0) -> Tuple[ParameterValue, int]:
106
108
  """Extract the bytes from the PDU and convert them to the physical value.
107
109
 
108
110
  Since environmental data is supposed to never appear on the
odxtools/field.py CHANGED
@@ -2,11 +2,10 @@ from dataclasses import dataclass
2
2
  from typing import TYPE_CHECKING, List, Optional
3
3
  from xml.etree import ElementTree
4
4
 
5
- from .environmentdatadescription import EnvironmentDataDescription
6
5
  from .basicstructure import BasicStructure
7
6
  from .createsdgs import create_sdgs_from_et
8
7
  from .dopbase import DopBase
9
- from .element import IdentifiableElement
8
+ from .environmentdatadescription import EnvironmentDataDescription
10
9
  from .exceptions import odxassert, odxrequire
11
10
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkRef
12
11
  from .odxtypes import odxstr_to_bool
@@ -67,12 +66,8 @@ class Field(DopBase):
67
66
  """may be a Structure or a env-data-desc"""
68
67
  return odxrequire(self._structure, "EnvironmentDataDescription is not supported")
69
68
 
70
- @property
71
- def bit_length(self):
72
- return self.structure.bit_length
73
-
74
- def convert_physical_to_internal(self, physical_value):
75
- return self.structure.convert_physical_to_internal(physical_value)
69
+ def get_static_bit_length(self) -> Optional[int]:
70
+ return None
76
71
 
77
72
  def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
78
73
  """Recursively resolve any odxlinks references"""
@@ -5,7 +5,8 @@ import asyncio
5
5
  import re
6
6
  import sys
7
7
  from enum import IntEnum
8
- from typing import Iterable, List, Optional, Tuple, Union
8
+ from io import TextIOBase
9
+ from typing import AsyncGenerator, Iterable, List, Optional, TextIO, Tuple, Union
9
10
 
10
11
  import bitstruct
11
12
  import can
@@ -26,8 +27,10 @@ class IsoTp(IntEnum):
26
27
 
27
28
  class IsoTpStateMachine:
28
29
  can_normal_frame_re = re.compile(
29
- "([a-zA-Z0-9_-]*) *([0-9A-Fa-f ]*) *\[[0-9]*\] *([ 0-9A-Fa-f]*)")
30
- can_log_frame_re = re.compile("\([0-9.]*\) *([a-zA-Z0-9_-]*) ([0-9A-Fa-f]*)#([0-9A-Fa-f]*)")
30
+ "([a-zA-Z0-9_-]*) *([0-9A-Fa-f ]*) *\\[[0-9]+\\] *([ 0-9A-Fa-f]+)")
31
+ can_log_frame_re = re.compile("\\([0-9.]*\\) *([a-zA-Z0-9_-]*) ([0-9A-Fa-f]+)#([0-9A-Fa-f]+)")
32
+ can_fd_log_frame_re = re.compile(
33
+ "\\([0-9.]*\\) *([a-zA-Z0-9_-]*) ([0-9A-Fa-f]+)##[0-9A-Fa-f]([0-9A-Fa-f]+)")
31
34
 
32
35
  def __init__(self, can_rx_ids: Union[int, List[int]]):
33
36
  if isinstance(can_rx_ids, int):
@@ -103,7 +106,8 @@ class IsoTpStateMachine:
103
106
  else:
104
107
  self.on_frame_type_error(telegram_idx, frame_type)
105
108
 
106
- async def read_telegrams(self, bus):
109
+ async def read_telegrams(self, bus: Union[can.Bus,
110
+ TextIO]) -> AsyncGenerator[Tuple[int, bytes], None]:
107
111
  """This is equivalent to the :py:meth:`file.readlines()` method, but
108
112
  it yields ISO-TP telegrams instead of lines.
109
113
 
@@ -112,12 +116,8 @@ class IsoTpStateMachine:
112
116
  :param bus: Input file or socket of can bus to read the can frames
113
117
  """
114
118
 
115
- if hasattr(bus, "set_filters"):
116
- # this is a bit of a hack: passing any object which
117
- # exhibits a set_filters() method is assumed to be a can
118
- # bus object.
119
-
120
- # creat an "on receive" event for the can bus
119
+ if isinstance(bus, can.Bus):
120
+ # create an "on receive" event for the can bus
121
121
  rx_event = asyncio.Event()
122
122
  loop = asyncio.get_running_loop()
123
123
  loop.add_reader(bus, rx_event.set)
@@ -126,11 +126,13 @@ class IsoTpStateMachine:
126
126
  await rx_event.wait()
127
127
 
128
128
  msg = bus.recv()
129
+ if msg is None:
130
+ continue
129
131
  for tmp in self.decode_rx_frame(msg.arbitration_id, msg.data):
130
132
  yield tmp
131
133
  else:
134
+ assert isinstance(bus, TextIOBase)
132
135
  # input is a file
133
-
134
136
  while bus:
135
137
  cur_line = bus.readline()
136
138
  if cur_line == "":
@@ -141,13 +143,14 @@ class IsoTpStateMachine:
141
143
  frame_id = int(m.group(2), 16)
142
144
 
143
145
  frame_data_formatted = m.group(3).strip()
144
- frame_data = bytearray(
145
- map(lambda x: int(x, 16), frame_data_formatted.split(" ")))
146
+ frame_data = bytearray([int(x, 16) for x in frame_data_formatted.split(" ")])
146
147
 
147
148
  for tmp in self.decode_rx_frame(frame_id, frame_data):
148
149
  yield tmp
149
150
 
150
- elif m := self.can_log_frame_re.match(cur_line.strip()):
151
+ elif (m := self.can_log_frame_re.match(
152
+ cur_line.strip())) or (m := self.can_fd_log_frame_re.match(
153
+ cur_line.strip())):
151
154
  #frame_interface = m.group(2)
152
155
  frame_id = int(m.group(2), 16)
153
156
 
@@ -156,7 +159,7 @@ class IsoTpStateMachine:
156
159
  frame_data_formatted[i:i + 2]
157
160
  for i in range(0, len(frame_data_formatted), 2)
158
161
  ]
159
- frame_data = bytearray(map(lambda x: int(x, 16), frame_data_list))
162
+ frame_data = bytearray([int(x, 16) for x in frame_data_list])
160
163
 
161
164
  for tmp in self.decode_rx_frame(frame_id, frame_data):
162
165
  yield tmp
@@ -166,14 +169,14 @@ class IsoTpStateMachine:
166
169
  f"Warning: unrecognized frame format: '{cur_line.strip()}'",
167
170
  file=sys.stderr)
168
171
 
169
- def can_rx_id(self, telegram_idx):
172
+ def can_rx_id(self, telegram_idx: int) -> int:
170
173
  """Given a Telegram index, returns the CAN ID for receiving data.
171
174
 
172
175
  :raises IndexError: The telegram index is invalid.
173
176
  """
174
177
  return self._can_rx_ids[telegram_idx]
175
178
 
176
- def telegram_data(self, telegram_idx):
179
+ def telegram_data(self, telegram_idx: int) -> Optional[bytes]:
177
180
  """Given a Telegram index, returns the data received for this telegram
178
181
  so far.
179
182
 
@@ -184,31 +187,32 @@ class IsoTpStateMachine:
184
187
  ##############
185
188
  # Callbacks
186
189
  ##############
187
- def on_single_frame(self, telegram_idx, frame_payload):
188
- """Method called when an ISO-TP message of type "single frame" has been received"""
190
+ def on_single_frame(self, telegram_idx: int, frame_payload: bytes) -> None:
191
+ """Callback method for when an ISO-TP message of type "single frame" has been received"""
189
192
  pass
190
193
 
191
- def on_first_frame(self, telegram_idx, frame_payload):
192
- """Method called when an ISO-TP message of type "first frame" has been received"""
194
+ def on_first_frame(self, telegram_idx: int, frame_payload: bytes) -> None:
195
+ """Callback method for when an ISO-TP message of type "first frame" has been received"""
193
196
  pass
194
197
 
195
- def on_consecutive_frame(self, telegram_idx, segment_idx, frame_payload):
196
- """Method called when an ISO-TP message of type "consecutive frame" has been received"""
198
+ def on_consecutive_frame(self, telegram_idx: int, segment_idx: int,
199
+ frame_payload: bytes) -> None:
200
+ """Callback method for when an ISO-TP message of type "consecutive frame" has been received"""
197
201
  pass
198
202
 
199
- def on_flow_control_frame(self, telegram_idx, flow_control_flag):
203
+ def on_flow_control_frame(self, telegram_idx: int, flow_control_flag: int) -> None:
200
204
  """Method called when an ISO-TP message of type "flow control frame" has been received"""
201
205
  pass
202
206
 
203
- def on_sequence_error(self, telegram_idx, expected_idx, rx_idx):
207
+ def on_sequence_error(self, telegram_idx: int, expected_idx: int, rx_idx: int) -> None:
204
208
  """Method called when a frame with an unexpected sequence index has been received"""
205
209
  pass
206
210
 
207
- def on_frame_type_error(self, telegram_idx, frame_type):
211
+ def on_frame_type_error(self, telegram_idx: int, frame_type: int) -> None:
208
212
  """Method called when a frame exhibiting an unknown frame type has been received"""
209
213
  pass
210
214
 
211
- def on_telegram_complete(self, telegram_idx, telegram_payload):
215
+ def on_telegram_complete(self, telegram_idx: int, telegram_payload: bytes) -> None:
212
216
  """Method called when an ISO-TP telegram has been fully received"""
213
217
  pass
214
218
 
@@ -219,7 +223,12 @@ class IsoTpActiveDecoder(IsoTpStateMachine):
219
223
  receive ISO-TP messages actively instead of just snooping in on
220
224
  other people's conversations."""
221
225
 
222
- def __init__(self, can_bus, can_rx_ids, can_tx_ids, padding_size=0, padding_value=0xAA):
226
+ def __init__(self,
227
+ can_bus: can.Bus,
228
+ can_rx_ids: List[int],
229
+ can_tx_ids: List[int],
230
+ padding_size: int = 0,
231
+ padding_value: int = 0xAA):
223
232
  self._can_bus = can_bus
224
233
 
225
234
  if isinstance(can_tx_ids, int):
@@ -231,14 +240,13 @@ class IsoTpActiveDecoder(IsoTpStateMachine):
231
240
 
232
241
  super().__init__(can_rx_ids)
233
242
 
234
- assert isinstance(self._can_tx_ids, list)
235
243
  assert len(self._can_rx_ids) == len(self._can_tx_ids)
236
244
  assert set(self._can_rx_ids).isdisjoint(set(self._can_tx_ids)) # correct?
237
245
 
238
- self._block_size = [None] * len(self._can_rx_ids)
239
- self._frames_received = [None] * len(self._can_rx_ids)
246
+ self._block_size: List[Optional[int]] = [None] * len(self._can_rx_ids)
247
+ self._frames_received: List[Optional[int]] = [None] * len(self._can_rx_ids)
240
248
 
241
- def can_tx_id(self, telegram_idx):
249
+ def can_tx_id(self, telegram_idx: int) -> int:
242
250
  """Given a Telegram index, returns the CAN ID for sending data.
243
251
 
244
252
  :raises TypeError: No transmission IDs specified (e.g.,
@@ -247,7 +255,7 @@ class IsoTpActiveDecoder(IsoTpStateMachine):
247
255
  """
248
256
  return self._can_tx_ids[telegram_idx]
249
257
 
250
- def on_single_frame(self, telegram_idx, frame_payload):
258
+ def on_single_frame(self, telegram_idx: int, frame_payload: bytes) -> None:
251
259
  # send ACK
252
260
  #rx_id = self.can_rx_id(telegram_idx)
253
261
  tx_id = self.can_tx_id(telegram_idx)
@@ -266,7 +274,7 @@ class IsoTpActiveDecoder(IsoTpStateMachine):
266
274
 
267
275
  super().on_first_frame(telegram_idx, frame_payload)
268
276
 
269
- def on_first_frame(self, telegram_idx, frame_payload):
277
+ def on_first_frame(self, telegram_idx: int, frame_payload: bytes) -> None:
270
278
  # send ACK
271
279
  #rx_id = self.can_rx_id(telegram_idx)
272
280
  tx_id = self.can_tx_id(telegram_idx)
@@ -288,12 +296,18 @@ class IsoTpActiveDecoder(IsoTpStateMachine):
288
296
 
289
297
  super().on_first_frame(telegram_idx, frame_payload)
290
298
 
291
- def on_consecutive_frame(self, telegram_idx, segment_idx, frame_payload):
292
- self._frames_received[telegram_idx] += 1
299
+ def on_consecutive_frame(self, telegram_idx: int, segment_idx: int,
300
+ frame_payload: bytes) -> None:
301
+ num_received = self._frames_received[telegram_idx]
302
+ if num_received is None:
303
+ # consequtive frame received before a first frame.
304
+ # TODO (?): throw an exception
305
+ return
306
+ self._frames_received[telegram_idx] = num_received + 1
293
307
 
294
308
  # send new ACK if necessary
295
309
  block_size = self._block_size[telegram_idx]
296
- if self._frames_received[telegram_idx] >= block_size:
310
+ if block_size is not None and num_received >= block_size:
297
311
  #rx_id = self.can_rx_id(telegram_idx)
298
312
  tx_id = self.can_tx_id(telegram_idx)
299
313
  min_separation_time = 0 # ms
@@ -310,7 +324,7 @@ class IsoTpActiveDecoder(IsoTpStateMachine):
310
324
 
311
325
  super().on_consecutive_frame(telegram_idx, segment_idx, frame_payload)
312
326
 
313
- def _send_can_message(self, can_tx_id, payload):
327
+ def _send_can_message(self, can_tx_id: int, payload: bytes) -> None:
314
328
  if len(payload) < self._padding_size:
315
329
  payload = bytes(payload) + bytes([self._padding_value] *
316
330
  (self._padding_size - len(payload)))
@@ -1,19 +1,19 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any
3
+ from typing import Any, Tuple
4
4
 
5
5
  from .decodestate import DecodeState
6
6
  from .diagcodedtype import DctType, DiagCodedType
7
7
  from .encodestate import EncodeState
8
8
  from .exceptions import odxassert, odxraise
9
- from .odxtypes import DataType
9
+ from .odxtypes import AtomicOdxType, DataType
10
10
 
11
11
 
12
12
  @dataclass
13
13
  class LeadingLengthInfoType(DiagCodedType):
14
14
  bit_length: int
15
15
 
16
- def __post_init__(self):
16
+ def __post_init__(self) -> None:
17
17
  odxassert(self.bit_length > 0,
18
18
  "A Leading length info type with bit length == 0 does not make sense.")
19
19
  odxassert(
@@ -53,13 +53,15 @@ class LeadingLengthInfoType(DiagCodedType):
53
53
 
54
54
  return length_byte + value_byte
55
55
 
56
- def convert_bytes_to_internal(self, decode_state: DecodeState, bit_position: int = 0):
56
+ def convert_bytes_to_internal(self,
57
+ decode_state: DecodeState,
58
+ bit_position: int = 0) -> Tuple[AtomicOdxType, int]:
57
59
  coded_message = decode_state.coded_message
58
60
 
59
61
  # Extract length of the parameter value
60
62
  byte_length, byte_position = self._extract_internal(
61
63
  coded_message=coded_message,
62
- byte_position=decode_state.next_byte_position,
64
+ byte_position=decode_state.cursor_position,
63
65
  bit_position=bit_position,
64
66
  bit_length=self.bit_length,
65
67
  base_data_type=DataType.A_UINT32, # length is an integer
@@ -72,7 +74,7 @@ class LeadingLengthInfoType(DiagCodedType):
72
74
  # Extract actual value
73
75
  # TODO: The returned value is None if the byte_length is 0. Maybe change it
74
76
  # to some default value like an empty bytearray() or 0?
75
- value, next_byte_position = self._extract_internal(
77
+ value, cursor_position = self._extract_internal(
76
78
  coded_message=coded_message,
77
79
  byte_position=byte_position,
78
80
  bit_position=0,
@@ -81,4 +83,4 @@ class LeadingLengthInfoType(DiagCodedType):
81
83
  is_highlow_byte_order=self.is_highlow_byte_order,
82
84
  )
83
85
 
84
- return value, next_byte_position
86
+ return value, cursor_position
odxtools/load_file.py CHANGED
@@ -1,9 +1,10 @@
1
1
  # SPDX-License-Identifier: MIT
2
+ from .database import Database
2
3
  from .load_odx_d_file import load_odx_d_file
3
4
  from .load_pdx_file import load_pdx_file
4
5
 
5
6
 
6
- def load_file(file_name: str):
7
+ def load_file(file_name: str) -> Database:
7
8
  if file_name.lower().endswith(".pdx"):
8
9
  return load_pdx_file(file_name)
9
10
  elif file_name.lower().endswith(".odx-d"):
@@ -1,9 +1,6 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from .database import Database
3
- from .globals import logger
4
3
 
5
4
 
6
- def load_odx_d_file(odx_d_file_name: str):
7
- container = Database(odx_d_file_name=odx_d_file_name)
8
- logger.info(f"--- --- --- Done with parsing --- --- ---")
9
- return container
5
+ def load_odx_d_file(odx_d_file_name: str) -> Database:
6
+ return Database(odx_d_file_name=odx_d_file_name)
odxtools/load_pdx_file.py CHANGED
@@ -2,11 +2,7 @@
2
2
  from zipfile import ZipFile
3
3
 
4
4
  from .database import Database
5
- from .globals import logger
6
5
 
7
6
 
8
- def load_pdx_file(pdx_file: str):
9
- u = ZipFile(pdx_file)
10
- container = Database(pdx_zip=u)
11
- logger.info(f"--- --- --- Done with parsing --- --- ---")
12
- return container
7
+ def load_pdx_file(pdx_file: str) -> Database:
8
+ return Database(pdx_zip=ZipFile(pdx_file))
odxtools/message.py CHANGED
@@ -1,12 +1,15 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import TYPE_CHECKING
3
+ from typing import TYPE_CHECKING, Union
4
+
5
+ from deprecation import deprecated
4
6
 
5
7
  from .odxtypes import ParameterValue, ParameterValueDict
6
8
 
7
9
  if TYPE_CHECKING:
8
10
  from .diagservice import DiagService
9
- from .structure import Structure
11
+ from .request import Request
12
+ from .response import Response
10
13
 
11
14
 
12
15
  @dataclass
@@ -21,8 +24,13 @@ class Message:
21
24
 
22
25
  coded_message: bytes
23
26
  service: "DiagService"
24
- structure: "Structure"
27
+ coding_object: Union["Request", "Response"]
25
28
  param_dict: ParameterValueDict
26
29
 
27
30
  def __getitem__(self, key: str) -> ParameterValue:
28
31
  return self.param_dict[key]
32
+
33
+ @property
34
+ @deprecated("use .coding_object")
35
+ def structure(self) -> Union["Request", "Response"]:
36
+ return self.coding_object