faster-eth-abi 5.2.9__cp314-cp314t-musllinux_1_2_x86_64.whl → 5.2.11__cp314-cp314t-musllinux_1_2_x86_64.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.

Potentially problematic release.


This version of faster-eth-abi might be problematic. Click here for more details.

Files changed (35) hide show
  1. 29859a9e7da9d19bb98c__mypyc.cpython-314t-x86_64-linux-musl.so +0 -0
  2. faster_eth_abi/_codec.cpython-314t-x86_64-linux-musl.so +0 -0
  3. faster_eth_abi/_codec.py +0 -4
  4. faster_eth_abi/_decoding.cpython-314t-x86_64-linux-musl.so +0 -0
  5. faster_eth_abi/_decoding.py +46 -0
  6. faster_eth_abi/_encoding.cpython-314t-x86_64-linux-musl.so +0 -0
  7. faster_eth_abi/_encoding.py +12 -5
  8. faster_eth_abi/_grammar.cpython-314t-x86_64-linux-musl.so +0 -0
  9. faster_eth_abi/_grammar.py +349 -0
  10. faster_eth_abi/abi.cpython-314t-x86_64-linux-musl.so +0 -0
  11. faster_eth_abi/codec.py +8 -9
  12. faster_eth_abi/constants.cpython-314t-x86_64-linux-musl.so +0 -0
  13. faster_eth_abi/decoding.py +11 -31
  14. faster_eth_abi/from_type_str.cpython-314t-x86_64-linux-musl.so +0 -0
  15. faster_eth_abi/from_type_str.py +3 -1
  16. faster_eth_abi/grammar.py +10 -308
  17. faster_eth_abi/packed.cpython-314t-x86_64-linux-musl.so +0 -0
  18. faster_eth_abi/registry.py +37 -24
  19. faster_eth_abi/tools/__init__.cpython-314t-x86_64-linux-musl.so +0 -0
  20. faster_eth_abi/tools/_strategies.cpython-314t-x86_64-linux-musl.so +0 -0
  21. faster_eth_abi/tools/_strategies.py +9 -5
  22. faster_eth_abi/utils/__init__.cpython-314t-x86_64-linux-musl.so +0 -0
  23. faster_eth_abi/utils/numeric.cpython-314t-x86_64-linux-musl.so +0 -0
  24. faster_eth_abi/utils/numeric.py +51 -20
  25. faster_eth_abi/utils/padding.cpython-314t-x86_64-linux-musl.so +0 -0
  26. faster_eth_abi/utils/string.cpython-314t-x86_64-linux-musl.so +0 -0
  27. faster_eth_abi/utils/validation.cpython-314t-x86_64-linux-musl.so +0 -0
  28. {faster_eth_abi-5.2.9.dist-info → faster_eth_abi-5.2.11.dist-info}/METADATA +1 -1
  29. faster_eth_abi-5.2.11.dist-info/RECORD +46 -0
  30. faster_eth_abi-5.2.11.dist-info/top_level.txt +2 -0
  31. 76f9a3652d4d2667c55c__mypyc.cpython-314t-x86_64-linux-musl.so +0 -0
  32. faster_eth_abi-5.2.9.dist-info/RECORD +0 -44
  33. faster_eth_abi-5.2.9.dist-info/top_level.txt +0 -2
  34. {faster_eth_abi-5.2.9.dist-info → faster_eth_abi-5.2.11.dist-info}/WHEEL +0 -0
  35. {faster_eth_abi-5.2.9.dist-info → faster_eth_abi-5.2.11.dist-info}/licenses/LICENSE +0 -0
faster_eth_abi/_codec.py CHANGED
@@ -39,8 +39,6 @@ def encode_c(
39
39
  :returns: The head-tail encoded binary representation of the python
40
40
  values in ``args`` as values of the ABI types in ``types``.
41
41
  """
42
- # validate encode types and args
43
- validate_list_like_param(types, "types")
44
42
  validate_list_like_param(args, "args")
45
43
 
46
44
  encoder = self._registry.get_tuple_encoder(*types)
@@ -71,8 +69,6 @@ def decode_c(
71
69
  :returns: A tuple of equivalent python values for the ABI values
72
70
  represented in ``data``.
73
71
  """
74
- # validate decode types and data
75
- validate_list_like_param(types, "types")
76
72
  validate_bytes_param(data, "data")
77
73
 
78
74
  decoder = self._registry.get_tuple_decoder(*types, strict=strict)
@@ -10,6 +10,7 @@ from faster_eth_utils import (
10
10
 
11
11
  from faster_eth_abi.exceptions import (
12
12
  InsufficientDataBytes,
13
+ NonEmptyPaddingBytes,
13
14
  )
14
15
  from faster_eth_abi.io import (
15
16
  BytesIO,
@@ -26,6 +27,7 @@ if TYPE_CHECKING:
26
27
  )
27
28
 
28
29
 
30
+ # Helpers
29
31
  def decode_uint_256(stream: ContextFramesBytesIO) -> int:
30
32
  """
31
33
  This function is a faster version of decode_uint_256 in decoding.py.
@@ -39,6 +41,10 @@ def decode_uint_256(stream: ContextFramesBytesIO) -> int:
39
41
  raise InsufficientDataBytes(f"Tried to read 32 bytes, only got {len(data)} bytes.")
40
42
 
41
43
 
44
+ def get_value_byte_size(decoder: "FixedByteSizeDecoder") -> int:
45
+ return decoder.value_bit_size // 8
46
+
47
+
42
48
  # HeadTailDecoder
43
49
  def decode_head_tail(self: "HeadTailDecoder", stream: ContextFramesBytesIO) -> Any:
44
50
  # Decode the offset and move the stream cursor forward 32 bytes
@@ -107,3 +113,43 @@ def read_fixed_byte_size_data_from_stream(
107
113
  raise InsufficientDataBytes(
108
114
  f"Tried to read {data_byte_size} bytes, only got {len(data)} bytes."
109
115
  )
116
+
117
+
118
+ def split_data_and_padding_fixed_byte_size(
119
+ self: "FixedByteSizeDecoder",
120
+ raw_data: bytes,
121
+ ) -> Tuple[bytes, bytes]:
122
+ value_byte_size = get_value_byte_size(self)
123
+ padding_size = self.data_byte_size - value_byte_size
124
+
125
+ if self.is_big_endian:
126
+ if padding_size == 0:
127
+ return raw_data, b""
128
+ padding_bytes = raw_data[:padding_size]
129
+ data = raw_data[padding_size:]
130
+ else:
131
+ data = raw_data[:value_byte_size]
132
+ padding_bytes = raw_data[value_byte_size:]
133
+
134
+ return data, padding_bytes
135
+
136
+
137
+ def validate_padding_bytes_fixed_byte_size(
138
+ self: "FixedByteSizeDecoder",
139
+ value: Any,
140
+ padding_bytes: bytes,
141
+ ) -> None:
142
+ value_byte_size = get_value_byte_size(self)
143
+ padding_size = self.data_byte_size - value_byte_size
144
+
145
+ if padding_bytes != b"\x00" * padding_size:
146
+ raise NonEmptyPaddingBytes(f"Padding bytes were not empty: {padding_bytes!r}")
147
+
148
+
149
+ # BooleanDecoder
150
+ def decoder_fn_boolean(data: bytes) -> bool:
151
+ if data == b"\x00":
152
+ return False
153
+ elif data == b"\x01":
154
+ return True
155
+ raise NonEmptyPaddingBytes(f"Boolean must be either 0x0 or 0x1. Got: {data!r}")
@@ -1,6 +1,3 @@
1
- from itertools import (
2
- accumulate,
3
- )
4
1
  from typing import (
5
2
  TYPE_CHECKING,
6
3
  Any,
@@ -35,7 +32,12 @@ def encode_tuple(
35
32
  tail_chunks.append(b"")
36
33
 
37
34
  head_length = sum(32 if item is None else len(item) for item in raw_head_chunks)
38
- tail_offsets = (0, *accumulate(len(item) for item in tail_chunks[:-1]))
35
+ tail_offsets = [0]
36
+ total_offset = 0
37
+ for item in tail_chunks[:-1]:
38
+ total_offset += len(item)
39
+ tail_offsets.append(total_offset)
40
+
39
41
  head_chunks = tuple(
40
42
  encode_uint_256(head_length + offset) if chunk is None else chunk
41
43
  for chunk, offset in zip(raw_head_chunks, tail_offsets)
@@ -77,7 +79,12 @@ def encode_elements(item_encoder: "BaseEncoder", value: Sequence[Any]) -> bytes:
77
79
  return b"".join(tail_chunks)
78
80
 
79
81
  head_length = 32 * len(value)
80
- tail_offsets = (0, *accumulate(len(item) for item in tail_chunks[:-1]))
82
+ tail_offsets = [0]
83
+ total_offset = 0
84
+ for item in tail_chunks[:-1]:
85
+ total_offset += len(item)
86
+ tail_offsets.append(total_offset)
87
+
81
88
  head_chunks = tuple(
82
89
  encode_uint_256(head_length + offset) for offset in tail_offsets
83
90
  )
@@ -0,0 +1,349 @@
1
+ import re
2
+ from typing import (
3
+ Any,
4
+ Final,
5
+ NewType,
6
+ NoReturn,
7
+ Optional,
8
+ Sequence,
9
+ Tuple,
10
+ TypeVar,
11
+ Union,
12
+ final,
13
+ )
14
+
15
+ from eth_typing.abi import (
16
+ TypeStr,
17
+ )
18
+ from mypy_extensions import (
19
+ mypyc_attr,
20
+ )
21
+ from parsimonious.nodes import (
22
+ Node,
23
+ )
24
+ from typing_extensions import (
25
+ Self,
26
+ )
27
+
28
+ from faster_eth_abi.exceptions import (
29
+ ABITypeError,
30
+ )
31
+
32
+
33
+ TYPE_ALIASES: Final = {
34
+ "int": "int256",
35
+ "uint": "uint256",
36
+ "fixed": "fixed128x18",
37
+ "ufixed": "ufixed128x18",
38
+ "function": "bytes24",
39
+ "byte": "bytes1",
40
+ }
41
+
42
+ TYPE_ALIAS_RE: Final = re.compile(
43
+ rf"\b({'|'.join(map(re.escape, TYPE_ALIASES.keys()))})\b"
44
+ )
45
+
46
+
47
+ IntSubtype = NewType("IntSubtype", int)
48
+ FixedSubtype = NewType("FixedSubtype", Tuple[int, int])
49
+ Subtype = Union[IntSubtype, FixedSubtype]
50
+
51
+
52
+ @mypyc_attr(allow_interpreted_subclasses=True)
53
+ class ABIType:
54
+ """
55
+ Base class for results of type string parsing operations.
56
+ """
57
+
58
+ __slots__ = ("arrlist", "node")
59
+
60
+ def __init__(
61
+ self, arrlist: Optional[Sequence[str]] = None, node: Optional[Node] = None
62
+ ) -> None:
63
+ self.arrlist: Final = arrlist
64
+ """
65
+ The list of array dimensions for a parsed type. Equal to ``None`` if
66
+ type string has no array dimensions.
67
+ """
68
+
69
+ self.node: Final = node
70
+ """
71
+ The parsimonious ``Node`` instance associated with this parsed type.
72
+ Used to generate error messages for invalid types.
73
+ """
74
+
75
+ def __repr__(self) -> str: # pragma: no cover
76
+ return f"<{type(self).__qualname__} {self.to_type_str()!r}>"
77
+
78
+ def __eq__(self, other: Any) -> bool:
79
+ # Two ABI types are equal if their string representations are equal
80
+ return type(self) is type(other) and self.to_type_str() == other.to_type_str()
81
+
82
+ def to_type_str(self) -> TypeStr: # pragma: no cover
83
+ """
84
+ Returns the string representation of an ABI type. This will be equal to
85
+ the type string from which it was created.
86
+ """
87
+ raise NotImplementedError("Must implement `to_type_str`")
88
+
89
+ @property
90
+ def item_type(self) -> Self:
91
+ """
92
+ If this type is an array type, equal to an appropriate
93
+ :class:`~faster_eth_abi.grammar.ABIType` instance for the array's items.
94
+ """
95
+ raise NotImplementedError("Must implement `item_type`")
96
+
97
+ def validate(self) -> None: # pragma: no cover
98
+ """
99
+ Validates the properties of an ABI type against the solidity ABI spec:
100
+
101
+ https://solidity.readthedocs.io/en/develop/abi-spec.html
102
+
103
+ Raises :class:`~faster_eth_abi.exceptions.ABITypeError` if validation fails.
104
+ """
105
+ raise NotImplementedError("Must implement `validate`")
106
+
107
+ @final
108
+ def invalidate(self, error_msg: str) -> NoReturn:
109
+ # Invalidates an ABI type with the given error message. Expects that a
110
+ # parsimonious node was provided from the original parsing operation
111
+ # that yielded this type.
112
+ node = self.node
113
+
114
+ raise ABITypeError(
115
+ f"For '{node.text}' type at column {node.start + 1} "
116
+ f"in '{node.full_text}': {error_msg}"
117
+ )
118
+
119
+ @final
120
+ @property
121
+ def is_array(self) -> bool:
122
+ """
123
+ Equal to ``True`` if a type is an array type (i.e. if it has an array
124
+ dimension list). Otherwise, equal to ``False``.
125
+ """
126
+ return self.arrlist is not None
127
+
128
+ @property
129
+ def is_dynamic(self) -> bool:
130
+ """
131
+ Equal to ``True`` if a type has a dynamically sized encoding.
132
+ Otherwise, equal to ``False``.
133
+ """
134
+ raise NotImplementedError("Must implement `is_dynamic`")
135
+
136
+ @final
137
+ @property
138
+ def _has_dynamic_arrlist(self) -> bool:
139
+ return self.is_array and any(len(dim) == 0 for dim in self.arrlist)
140
+
141
+
142
+ TComp = TypeVar("TComp", bound=ABIType)
143
+
144
+
145
+ @mypyc_attr(allow_interpreted_subclasses=True)
146
+ class TupleType(ABIType):
147
+ """
148
+ Represents the result of parsing a tuple type string e.g. "(int,bool)".
149
+ """
150
+
151
+ __slots__ = ("components",)
152
+
153
+ def __init__(
154
+ self,
155
+ components: Tuple[TComp, ...],
156
+ arrlist: Optional[Sequence[str]] = None,
157
+ *,
158
+ node: Optional[Node] = None,
159
+ ) -> None:
160
+ super().__init__(arrlist, node)
161
+
162
+ self.components: Final = components
163
+ """
164
+ A tuple of :class:`~faster_eth_abi.grammar.ABIType` instances for each of the
165
+ tuple type's components.
166
+ """
167
+
168
+ def to_type_str(self) -> TypeStr:
169
+ arrlist = self.arrlist
170
+
171
+ if isinstance(arrlist, tuple):
172
+ arrlist = "".join(map(repr, map(list, arrlist)))
173
+ else:
174
+ arrlist = ""
175
+
176
+ return f"({','.join(c.to_type_str() for c in self.components)}){arrlist}"
177
+
178
+ @property
179
+ def item_type(self) -> Self:
180
+ if not self.is_array:
181
+ raise ValueError(
182
+ f"Cannot determine item type for non-array type '{self.to_type_str()}'"
183
+ )
184
+
185
+ arrlist = self.arrlist[:-1] or None # type: ignore [index]
186
+ cls = type(self)
187
+ if cls is TupleType:
188
+ return TupleType(self.components, arrlist, node=self.node) # type: ignore [return-value]
189
+ else:
190
+ return cls(self.components, arrlist, node=self.node)
191
+
192
+ def validate(self) -> None:
193
+ for c in self.components:
194
+ c.validate()
195
+
196
+ @property
197
+ def is_dynamic(self) -> bool:
198
+ if self._has_dynamic_arrlist:
199
+ return True
200
+
201
+ return any(c.is_dynamic for c in self.components)
202
+
203
+
204
+ @mypyc_attr(allow_interpreted_subclasses=True)
205
+ class BasicType(ABIType):
206
+ """
207
+ Represents the result of parsing a basic type string e.g. "uint", "address",
208
+ "ufixed128x19[][2]".
209
+ """
210
+
211
+ __slots__ = ("base", "sub")
212
+
213
+ def __init__(
214
+ self,
215
+ base: str,
216
+ sub: Optional[Subtype] = None,
217
+ arrlist: Optional[Sequence] = None,
218
+ *,
219
+ node: Optional[Node] = None,
220
+ ) -> None:
221
+ super().__init__(arrlist, node)
222
+
223
+ self.base: Final = base
224
+ """The base of a basic type e.g. "uint" for "uint256" etc."""
225
+
226
+ self.sub: Final = sub
227
+ """
228
+ The sub type of a basic type e.g. ``256`` for "uint256" or ``(128, 18)``
229
+ for "ufixed128x18" etc. Equal to ``None`` if type string has no sub
230
+ type.
231
+ """
232
+
233
+ def to_type_str(self) -> TypeStr:
234
+ sub, arrlist = self.sub, self.arrlist
235
+
236
+ if isinstance(sub, int):
237
+ substr = str(sub)
238
+ elif isinstance(sub, tuple):
239
+ substr = "x".join(map(str, sub))
240
+ else:
241
+ substr = ""
242
+
243
+ if isinstance(arrlist, tuple):
244
+ return self.base + substr + "".join(map(repr, map(list, arrlist)))
245
+ else:
246
+ return self.base + substr
247
+
248
+ @property
249
+ def item_type(self) -> Self:
250
+ if not self.is_array:
251
+ raise ValueError(
252
+ f"Cannot determine item type for non-array type '{self.to_type_str()}'"
253
+ )
254
+
255
+ cls = type(self)
256
+ arrlist = self.arrlist[:-1] or None # type: ignore [index]
257
+ if cls is BasicType:
258
+ return BasicType(self.base, self.sub, arrlist, node=self.node) # type: ignore [return-value]
259
+ else:
260
+ return cls(self.base, self.sub, arrlist, node=self.node)
261
+
262
+ @property
263
+ def is_dynamic(self) -> bool:
264
+ if self._has_dynamic_arrlist:
265
+ return True
266
+
267
+ base = self.base
268
+ if base == "string":
269
+ return True
270
+
271
+ if base == "bytes" and self.sub is None:
272
+ return True
273
+
274
+ return False
275
+
276
+ def validate(self) -> None:
277
+ base, sub = self.base, self.sub
278
+
279
+ # Check validity of string type
280
+ if base == "string":
281
+ if sub is not None:
282
+ self.invalidate("string type cannot have suffix")
283
+
284
+ # Check validity of bytes type
285
+ elif base == "bytes":
286
+ if not (sub is None or isinstance(sub, int)):
287
+ self.invalidate(
288
+ "bytes type must have either no suffix or a numerical suffix"
289
+ )
290
+
291
+ if isinstance(sub, int) and sub > 32:
292
+ self.invalidate("maximum 32 bytes for fixed-length bytes")
293
+
294
+ # Check validity of integer type
295
+ elif base in ("int", "uint"):
296
+ if not isinstance(sub, int):
297
+ self.invalidate("integer type must have numerical suffix")
298
+
299
+ if sub < 8 or sub > 256:
300
+ self.invalidate("integer size out of bounds (max 256 bits)")
301
+
302
+ if sub % 8 != 0:
303
+ self.invalidate("integer size must be multiple of 8")
304
+
305
+ # Check validity of fixed type
306
+ elif base in ("fixed", "ufixed"):
307
+ if not isinstance(sub, tuple):
308
+ self.invalidate(
309
+ "fixed type must have suffix of form <bits>x<exponent>, "
310
+ "e.g. 128x19",
311
+ )
312
+
313
+ bits, minus_e = sub
314
+
315
+ if bits < 8 or bits > 256:
316
+ self.invalidate("fixed size out of bounds (max 256 bits)")
317
+
318
+ if bits % 8 != 0:
319
+ self.invalidate("fixed size must be multiple of 8")
320
+
321
+ if minus_e < 1 or minus_e > 80:
322
+ self.invalidate(
323
+ f"fixed exponent size out of bounds, {minus_e} must be in 1-80"
324
+ )
325
+
326
+ # Check validity of hash type
327
+ elif base == "hash":
328
+ if not isinstance(sub, int):
329
+ self.invalidate("hash type must have numerical suffix")
330
+
331
+ # Check validity of address type
332
+ elif base == "address":
333
+ if sub is not None:
334
+ self.invalidate("address cannot have suffix")
335
+
336
+
337
+ def normalize(type_str: TypeStr) -> TypeStr:
338
+ """
339
+ Normalizes a type string into its canonical version e.g. the type string
340
+ 'int' becomes 'int256', etc.
341
+
342
+ :param type_str: The type string to be normalized.
343
+ :returns: The canonical version of the input type string.
344
+ """
345
+ return TYPE_ALIAS_RE.sub(__normalize, type_str)
346
+
347
+
348
+ def __normalize(match: "re.Match[str]") -> str:
349
+ return TYPE_ALIASES[match.group(0)]
faster_eth_abi/codec.py CHANGED
@@ -18,6 +18,7 @@ from faster_eth_abi.decoding import (
18
18
  )
19
19
  from faster_eth_abi.exceptions import (
20
20
  EncodingError,
21
+ MultipleEntriesFound,
21
22
  )
22
23
  from faster_eth_abi.registry import (
23
24
  ABIRegistry,
@@ -74,20 +75,18 @@ class ABIEncoder(BaseABICoder):
74
75
  :returns: ``True`` if ``arg`` is encodable as a value of the ABI type
75
76
  ``typ``. Otherwise, ``False``.
76
77
  """
77
- if not self.is_encodable_type(typ):
78
+ try:
79
+ encoder = self._registry.get_encoder(typ)
80
+ except MultipleEntriesFound:
81
+ raise
82
+ except:
78
83
  return False
79
84
 
80
- encoder = self._registry.get_encoder(typ)
81
-
85
+ validate = getattr(encoder, "validate_value", encoder)
82
86
  try:
83
- encoder.validate_value(arg)
87
+ validate(arg)
84
88
  except EncodingError:
85
89
  return False
86
- except AttributeError:
87
- try:
88
- encoder(arg)
89
- except EncodingError:
90
- return False
91
90
 
92
91
  return True
93
92
 
@@ -19,7 +19,11 @@ from faster_eth_abi._decoding import (
19
19
  decode_head_tail,
20
20
  decode_sized_array,
21
21
  decode_tuple,
22
+ decoder_fn_boolean,
23
+ get_value_byte_size,
22
24
  read_fixed_byte_size_data_from_stream,
25
+ split_data_and_padding_fixed_byte_size,
26
+ validate_padding_bytes_fixed_byte_size,
23
27
  )
24
28
  from faster_eth_abi.base import (
25
29
  BaseCoder,
@@ -303,29 +307,14 @@ class FixedByteSizeDecoder(SingleDecoder):
303
307
  return read_fixed_byte_size_data_from_stream(self, stream)
304
308
 
305
309
  def split_data_and_padding(self, raw_data: bytes) -> Tuple[bytes, bytes]:
306
- value_byte_size = self._get_value_byte_size()
307
- padding_size = self.data_byte_size - value_byte_size
308
-
309
- if self.is_big_endian:
310
- padding_bytes = raw_data[:padding_size]
311
- data = raw_data[padding_size:]
312
- else:
313
- data = raw_data[:value_byte_size]
314
- padding_bytes = raw_data[value_byte_size:]
315
-
316
- return data, padding_bytes
310
+ return split_data_and_padding_fixed_byte_size(self, raw_data)
317
311
 
318
312
  def validate_padding_bytes(self, value: Any, padding_bytes: bytes) -> None:
319
- value_byte_size = self._get_value_byte_size()
320
- padding_size = self.data_byte_size - value_byte_size
321
-
322
- if padding_bytes != b"\x00" * padding_size:
323
- raise NonEmptyPaddingBytes(
324
- f"Padding bytes were not empty: {padding_bytes!r}"
325
- )
313
+ validate_padding_bytes_fixed_byte_size(self, value, padding_bytes)
326
314
 
327
315
  def _get_value_byte_size(self) -> int:
328
- return self.value_bit_size // 8
316
+ # This is unused, but it is kept in to preserve the eth-abi api
317
+ return get_value_byte_size(self)
329
318
 
330
319
 
331
320
  class Fixed32ByteSizeDecoder(FixedByteSizeDecoder):
@@ -336,16 +325,7 @@ class BooleanDecoder(Fixed32ByteSizeDecoder):
336
325
  value_bit_size = 8
337
326
  is_big_endian = True
338
327
 
339
- @staticmethod
340
- def decoder_fn(data: bytes) -> bool:
341
- if data == b"\x00":
342
- return False
343
- elif data == b"\x01":
344
- return True
345
- else:
346
- raise NonEmptyPaddingBytes(
347
- f"Boolean must be either 0x0 or 0x1. Got: {data!r}"
348
- )
328
+ decoder_fn = staticmethod(decoder_fn_boolean)
349
329
 
350
330
  @parse_type_str("bool")
351
331
  def from_type_str(cls, abi_type, registry):
@@ -392,7 +372,7 @@ class SignedIntegerDecoder(Fixed32ByteSizeDecoder):
392
372
  return value
393
373
 
394
374
  def validate_padding_bytes(self, value: Any, padding_bytes: bytes) -> None:
395
- value_byte_size = self._get_value_byte_size()
375
+ value_byte_size = get_value_byte_size(self)
396
376
  padding_size = self.data_byte_size - value_byte_size
397
377
 
398
378
  if value >= 0:
@@ -471,7 +451,7 @@ class SignedFixedDecoder(BaseFixedDecoder):
471
451
  return decimal_value
472
452
 
473
453
  def validate_padding_bytes(self, value: Any, padding_bytes: bytes) -> None:
474
- value_byte_size = self._get_value_byte_size()
454
+ value_byte_size = get_value_byte_size(self)
475
455
  padding_size = self.data_byte_size - value_byte_size
476
456
 
477
457
  if value >= 0:
@@ -12,11 +12,13 @@ from eth_typing import (
12
12
  TypeStr,
13
13
  )
14
14
 
15
- from .grammar import (
15
+ from ._grammar import (
16
16
  ABIType,
17
17
  BasicType,
18
18
  TupleType,
19
19
  normalize,
20
+ )
21
+ from .grammar import (
20
22
  parse,
21
23
  )
22
24