faster-eth-abi 5.2.1__cp313-cp313-macosx_11_0_arm64.whl → 5.2.20__cp313-cp313-macosx_11_0_arm64.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 (43) hide show
  1. faster_eth_abi/_codec.cpython-313-darwin.so +0 -0
  2. faster_eth_abi/_codec.py +83 -0
  3. faster_eth_abi/_decoding.cpython-313-darwin.so +0 -0
  4. faster_eth_abi/_decoding.py +299 -0
  5. faster_eth_abi/_encoding.cpython-313-darwin.so +0 -0
  6. faster_eth_abi/_encoding.py +251 -0
  7. faster_eth_abi/_grammar.cpython-313-darwin.so +0 -0
  8. faster_eth_abi/_grammar.py +375 -0
  9. faster_eth_abi/abi.cpython-313-darwin.so +0 -0
  10. faster_eth_abi/base.py +5 -1
  11. faster_eth_abi/codec.py +2694 -52
  12. faster_eth_abi/constants.cpython-313-darwin.so +0 -0
  13. faster_eth_abi/decoding.py +263 -242
  14. faster_eth_abi/encoding.py +201 -154
  15. faster_eth_abi/exceptions.py +26 -14
  16. faster_eth_abi/from_type_str.cpython-313-darwin.so +0 -0
  17. faster_eth_abi/from_type_str.py +7 -1
  18. faster_eth_abi/grammar.py +30 -325
  19. faster_eth_abi/io.py +5 -1
  20. faster_eth_abi/packed.cpython-313-darwin.so +0 -0
  21. faster_eth_abi/packed.py +4 -0
  22. faster_eth_abi/registry.py +201 -83
  23. faster_eth_abi/tools/__init__.cpython-313-darwin.so +0 -0
  24. faster_eth_abi/tools/_strategies.cpython-313-darwin.so +0 -0
  25. faster_eth_abi/tools/_strategies.py +12 -6
  26. faster_eth_abi/typing.py +4627 -0
  27. faster_eth_abi/utils/__init__.cpython-313-darwin.so +0 -0
  28. faster_eth_abi/utils/numeric.cpython-313-darwin.so +0 -0
  29. faster_eth_abi/utils/numeric.py +51 -20
  30. faster_eth_abi/utils/padding.cpython-313-darwin.so +0 -0
  31. faster_eth_abi/utils/string.cpython-313-darwin.so +0 -0
  32. faster_eth_abi/utils/validation.cpython-313-darwin.so +0 -0
  33. faster_eth_abi/utils/validation.py +1 -5
  34. faster_eth_abi-5.2.20.dist-info/METADATA +136 -0
  35. faster_eth_abi-5.2.20.dist-info/RECORD +46 -0
  36. faster_eth_abi-5.2.20.dist-info/top_level.txt +2 -0
  37. faster_eth_abi__mypyc.cpython-313-darwin.so +0 -0
  38. a1f8aa123fabc88e2b56__mypyc.cpython-313-darwin.so +0 -0
  39. faster_eth_abi-5.2.1.dist-info/METADATA +0 -95
  40. faster_eth_abi-5.2.1.dist-info/RECORD +0 -38
  41. faster_eth_abi-5.2.1.dist-info/licenses/LICENSE +0 -21
  42. faster_eth_abi-5.2.1.dist-info/top_level.txt +0 -3
  43. {faster_eth_abi-5.2.1.dist-info → faster_eth_abi-5.2.20.dist-info}/WHEEL +0 -0
@@ -1,20 +1,30 @@
1
- import parsimonious
1
+ # mypy: disable-error-code="misc"
2
+ # cannot subclass `Any`
2
3
 
4
+ """
5
+ Exception classes for error handling during ABI encoding and decoding operations.
3
6
 
4
- class EncodingError(Exception):
7
+ faster-eth-abi exceptions always inherit from eth-abi exceptions, so porting to faster-eth-abi
8
+ does not require any change to your existing exception handlers. They will continue to work.
9
+ """
10
+
11
+ import eth_abi.exceptions
12
+
13
+
14
+ class EncodingError(eth_abi.exceptions.EncodingError):
5
15
  """
6
16
  Base exception for any error that occurs during encoding.
7
17
  """
8
18
 
9
19
 
10
- class EncodingTypeError(EncodingError):
20
+ class EncodingTypeError(EncodingError, eth_abi.exceptions.EncodingTypeError):
11
21
  """
12
22
  Raised when trying to encode a python value whose type is not supported for
13
23
  the output ABI type.
14
24
  """
15
25
 
16
26
 
17
- class IllegalValue(EncodingError):
27
+ class IllegalValue(EncodingError, eth_abi.exceptions.IllegalValue):
18
28
  """
19
29
  Raised when trying to encode a python value with the correct type but with
20
30
  a value that is not considered legal for the output ABI type.
@@ -26,7 +36,7 @@ class IllegalValue(EncodingError):
26
36
  """
27
37
 
28
38
 
29
- class ValueOutOfBounds(IllegalValue):
39
+ class ValueOutOfBounds(IllegalValue, eth_abi.exceptions.ValueOutOfBounds):
30
40
  """
31
41
  Raised when trying to encode a python value with the correct type but with
32
42
  a value that appears outside the range of valid values for the output ABI
@@ -39,31 +49,31 @@ class ValueOutOfBounds(IllegalValue):
39
49
  """
40
50
 
41
51
 
42
- class DecodingError(Exception):
52
+ class DecodingError(eth_abi.exceptions.DecodingError):
43
53
  """
44
54
  Base exception for any error that occurs during decoding.
45
55
  """
46
56
 
47
57
 
48
- class InsufficientDataBytes(DecodingError):
58
+ class InsufficientDataBytes(DecodingError, eth_abi.exceptions.InsufficientDataBytes):
49
59
  """
50
60
  Raised when there are insufficient data to decode a value for a given ABI type.
51
61
  """
52
62
 
53
63
 
54
- class NonEmptyPaddingBytes(DecodingError):
64
+ class NonEmptyPaddingBytes(DecodingError, eth_abi.exceptions.NonEmptyPaddingBytes):
55
65
  """
56
66
  Raised when the padding bytes of an ABI value are malformed.
57
67
  """
58
68
 
59
69
 
60
- class InvalidPointer(DecodingError):
70
+ class InvalidPointer(DecodingError, eth_abi.exceptions.InvalidPointer):
61
71
  """
62
72
  Raised when the pointer to a value in the ABI encoding is invalid.
63
73
  """
64
74
 
65
75
 
66
- class ParseError(parsimonious.ParseError): # type: ignore[misc] # subclasses Any
76
+ class ParseError(eth_abi.exceptions.ParseError):
67
77
  """
68
78
  Raised when an ABI type string cannot be parsed.
69
79
  """
@@ -75,7 +85,7 @@ class ParseError(parsimonious.ParseError): # type: ignore[misc] # subclasses An
75
85
  )
76
86
 
77
87
 
78
- class ABITypeError(ValueError):
88
+ class ABITypeError(eth_abi.exceptions.ABITypeError):
79
89
  """
80
90
  Raised when a parsed ABI type has inconsistent properties; for example,
81
91
  when trying to parse the type string ``'uint7'`` (which has a bit-width
@@ -83,13 +93,13 @@ class ABITypeError(ValueError):
83
93
  """
84
94
 
85
95
 
86
- class PredicateMappingError(Exception):
96
+ class PredicateMappingError(eth_abi.exceptions.PredicateMappingError):
87
97
  """
88
98
  Raised when an error occurs in a registry's internal mapping.
89
99
  """
90
100
 
91
101
 
92
- class NoEntriesFound(ValueError, PredicateMappingError):
102
+ class NoEntriesFound(PredicateMappingError, eth_abi.exceptions.NoEntriesFound):
93
103
  """
94
104
  Raised when no registration is found for a type string in a registry's
95
105
  internal mapping.
@@ -101,7 +111,9 @@ class NoEntriesFound(ValueError, PredicateMappingError):
101
111
  """
102
112
 
103
113
 
104
- class MultipleEntriesFound(ValueError, PredicateMappingError):
114
+ class MultipleEntriesFound(
115
+ PredicateMappingError, eth_abi.exceptions.MultipleEntriesFound
116
+ ):
105
117
  """
106
118
  Raised when multiple registrations are found for a type string in a
107
119
  registry's internal mapping. This error is non-recoverable and indicates
@@ -1,3 +1,7 @@
1
+ """Helpers for parsing and normalizing ABI type strings.
2
+
3
+ Provides decorators and utilities for implementing from_type_str methods on coder classes.
4
+ """
1
5
  import functools
2
6
  from typing import (
3
7
  TYPE_CHECKING,
@@ -12,11 +16,13 @@ from eth_typing import (
12
16
  TypeStr,
13
17
  )
14
18
 
15
- from .grammar import (
19
+ from ._grammar import (
16
20
  ABIType,
17
21
  BasicType,
18
22
  TupleType,
19
23
  normalize,
24
+ )
25
+ from .grammar import (
20
26
  parse,
21
27
  )
22
28
 
faster_eth_abi/grammar.py CHANGED
@@ -1,32 +1,31 @@
1
+ """Parsing and normalization logic for ABI type strings.
2
+
3
+ Implements grammar, parsing, and type validation for ABI type strings.
4
+ """
1
5
  import functools
2
- import re
3
6
  from typing import (
4
7
  Any,
5
8
  Final,
6
- NoReturn,
7
- Optional,
8
- Sequence,
9
- Tuple,
10
- TypeVar,
11
9
  final,
12
10
  )
13
11
 
12
+ import parsimonious
14
13
  from eth_typing import (
15
14
  TypeStr,
16
15
  )
17
- import parsimonious
18
16
  from parsimonious import (
19
17
  expressions,
20
18
  )
21
- from parsimonious.nodes import (
22
- Node,
23
- )
24
- from typing_extensions import (
25
- Self,
26
- )
27
19
 
20
+ from faster_eth_abi._grammar import (
21
+ TYPE_ALIAS_RE,
22
+ TYPE_ALIASES,
23
+ ABIType,
24
+ BasicType,
25
+ TupleType,
26
+ normalize,
27
+ )
28
28
  from faster_eth_abi.exceptions import (
29
- ABITypeError,
30
29
  ParseError,
31
30
  )
32
31
 
@@ -58,14 +57,14 @@ grammar: Final = parsimonious.Grammar(
58
57
 
59
58
 
60
59
  @final
61
- class NodeVisitor(parsimonious.NodeVisitor): # type: ignore [misc]
60
+ class NodeVisitor(parsimonious.NodeVisitor):
62
61
  """
63
62
  Parsimonious node visitor which performs both parsing of type strings and
64
63
  post-processing of parse trees. Parsing operations are cached.
65
64
  """
66
65
 
67
- def __init__(self):
68
- self.parse = functools.lru_cache(maxsize=None)(self._parse_uncached)
66
+ def __init__(self) -> None:
67
+ self.parse: Final = functools.lru_cache(maxsize=None)(self._parse_uncached)
69
68
 
70
69
  grammar = grammar
71
70
 
@@ -127,7 +126,7 @@ class NodeVisitor(parsimonious.NodeVisitor): # type: ignore [misc]
127
126
 
128
127
  return tuple(visited_children)
129
128
 
130
- def _parse_uncached(self, type_str, **kwargs):
129
+ def _parse_uncached(self, type_str: TypeStr, **kwargs: Any) -> ABIType:
131
130
  """
132
131
  Parses a type string into an appropriate instance of
133
132
  :class:`~faster_eth_abi.grammar.ABIType`. If a type string cannot be parsed,
@@ -156,312 +155,18 @@ class NodeVisitor(parsimonious.NodeVisitor): # type: ignore [misc]
156
155
 
157
156
  visitor: Final = NodeVisitor()
158
157
 
159
-
160
- class ABIType:
161
- """
162
- Base class for results of type string parsing operations.
163
- """
164
-
165
- __slots__ = ("arrlist", "node")
166
-
167
- def __init__(
168
- self, arrlist: Optional[Sequence] = None, node: Optional[Node] = None
169
- ) -> None:
170
- self.arrlist: Final = arrlist
171
- """
172
- The list of array dimensions for a parsed type. Equal to ``None`` if
173
- type string has no array dimensions.
174
- """
175
-
176
- self.node: Final = node
177
- """
178
- The parsimonious ``Node`` instance associated with this parsed type.
179
- Used to generate error messages for invalid types.
180
- """
181
-
182
- def __repr__(self) -> str: # pragma: no cover
183
- return f"<{type(self).__qualname__} {self.to_type_str()!r}>"
184
-
185
- def __eq__(self, other: Any) -> bool:
186
- # Two ABI types are equal if their string representations are equal
187
- return type(self) is type(other) and self.to_type_str() == other.to_type_str()
188
-
189
- def to_type_str(self) -> TypeStr: # pragma: no cover
190
- """
191
- Returns the string representation of an ABI type. This will be equal to
192
- the type string from which it was created.
193
- """
194
- raise NotImplementedError("Must implement `to_type_str`")
195
-
196
- @property
197
- def item_type(self) -> Self:
198
- """
199
- If this type is an array type, equal to an appropriate
200
- :class:`~faster_eth_abi.grammar.ABIType` instance for the array's items.
201
- """
202
- raise NotImplementedError("Must implement `item_type`")
203
-
204
- def validate(self) -> None: # pragma: no cover
205
- """
206
- Validates the properties of an ABI type against the solidity ABI spec:
207
-
208
- https://solidity.readthedocs.io/en/develop/abi-spec.html
209
-
210
- Raises :class:`~faster_eth_abi.exceptions.ABITypeError` if validation fails.
211
- """
212
- raise NotImplementedError("Must implement `validate`")
213
-
214
- def invalidate(self, error_msg: str) -> NoReturn:
215
- # Invalidates an ABI type with the given error message. Expects that a
216
- # parsimonious node was provided from the original parsing operation
217
- # that yielded this type.
218
- node = self.node
219
-
220
- raise ABITypeError(
221
- f"For '{node.text}' type at column {node.start + 1} "
222
- f"in '{node.full_text}': {error_msg}"
223
- )
224
-
225
- @property
226
- def is_array(self) -> bool:
227
- """
228
- Equal to ``True`` if a type is an array type (i.e. if it has an array
229
- dimension list). Otherwise, equal to ``False``.
230
- """
231
- return self.arrlist is not None
232
-
233
- @property
234
- def is_dynamic(self) -> bool:
235
- """
236
- Equal to ``True`` if a type has a dynamically sized encoding.
237
- Otherwise, equal to ``False``.
238
- """
239
- raise NotImplementedError("Must implement `is_dynamic`")
240
-
241
- @property
242
- def _has_dynamic_arrlist(self) -> bool:
243
- return self.is_array and any(len(dim) == 0 for dim in self.arrlist)
244
-
245
-
246
- TComp = TypeVar("TComp", bound=ABIType)
247
-
248
-
249
- @final
250
- class TupleType(ABIType):
251
- """
252
- Represents the result of parsing a tuple type string e.g. "(int,bool)".
253
- """
254
-
255
- __slots__ = ("components",)
256
-
257
- def __init__(
258
- self,
259
- components: Tuple[TComp, ...],
260
- arrlist: Optional[Sequence] = None,
261
- *,
262
- node: Optional[Node] = None,
263
- ) -> None:
264
- super().__init__(arrlist, node)
265
-
266
- self.components: Final = components
267
- """
268
- A tuple of :class:`~faster_eth_abi.grammar.ABIType` instances for each of the
269
- tuple type's components.
270
- """
271
-
272
- def to_type_str(self) -> TypeStr:
273
- arrlist = self.arrlist
274
-
275
- if isinstance(arrlist, tuple):
276
- arrlist = "".join(repr(list(a)) for a in arrlist)
277
- else:
278
- arrlist = ""
279
-
280
- return f"({','.join(c.to_type_str() for c in self.components)}){arrlist}"
281
-
282
- @property
283
- def item_type(self) -> Self:
284
- if not self.is_array:
285
- raise ValueError(
286
- f"Cannot determine item type for non-array type '{self.to_type_str()}'"
287
- )
288
-
289
- return type(self)(
290
- self.components,
291
- self.arrlist[:-1] or None, # type: ignore [index]
292
- node=self.node,
293
- )
294
-
295
- def validate(self) -> None:
296
- for c in self.components:
297
- c.validate()
298
-
299
- @property
300
- def is_dynamic(self) -> bool:
301
- if self._has_dynamic_arrlist:
302
- return True
303
-
304
- return any(c.is_dynamic for c in self.components)
305
-
306
-
307
- @final
308
- class BasicType(ABIType):
309
- """
310
- Represents the result of parsing a basic type string e.g. "uint", "address",
311
- "ufixed128x19[][2]".
312
- """
313
-
314
- __slots__ = ("base", "sub")
315
-
316
- def __init__(
317
- self,
318
- base: str,
319
- sub: Any = None,
320
- arrlist: Optional[Sequence] = None,
321
- *,
322
- node: Optional[Node] = None,
323
- ) -> None:
324
- super().__init__(arrlist, node)
325
-
326
- self.base: Final = base
327
- """The base of a basic type e.g. "uint" for "uint256" etc."""
328
-
329
- self.sub: Final = sub
330
- """
331
- The sub type of a basic type e.g. ``256`` for "uint256" or ``(128, 18)``
332
- for "ufixed128x18" etc. Equal to ``None`` if type string has no sub
333
- type.
334
- """
335
-
336
- def to_type_str(self) -> TypeStr:
337
- sub, arrlist = self.sub, self.arrlist
338
-
339
- if isinstance(sub, int):
340
- substr = str(sub)
341
- elif isinstance(sub, tuple):
342
- substr = "x".join(str(s) for s in sub)
343
- else:
344
- substr = ""
345
-
346
- if isinstance(arrlist, tuple):
347
- return self.base + substr + "".join(repr(list(a)) for a in arrlist)
348
- else:
349
- return self.base + substr
350
-
351
- @property
352
- def item_type(self) -> Self:
353
- if not self.is_array:
354
- raise ValueError(
355
- f"Cannot determine item type for non-array type '{self.to_type_str()}'"
356
- )
357
-
358
- return type(self)(
359
- self.base,
360
- self.sub,
361
- self.arrlist[:-1] or None, # type: ignore [index]
362
- node=self.node,
363
- )
364
-
365
- @property
366
- def is_dynamic(self) -> bool:
367
- if self._has_dynamic_arrlist:
368
- return True
369
-
370
- if self.base == "string":
371
- return True
372
-
373
- if self.base == "bytes" and self.sub is None:
374
- return True
375
-
376
- return False
377
-
378
- def validate(self) -> None:
379
- base, sub = self.base, self.sub
380
-
381
- # Check validity of string type
382
- if base == "string":
383
- if sub is not None:
384
- self.invalidate("string type cannot have suffix")
385
-
386
- # Check validity of bytes type
387
- elif base == "bytes":
388
- if not (sub is None or isinstance(sub, int)):
389
- self.invalidate(
390
- "bytes type must have either no suffix or a numerical suffix"
391
- )
392
-
393
- if isinstance(sub, int) and sub > 32:
394
- self.invalidate("maximum 32 bytes for fixed-length bytes")
395
-
396
- # Check validity of integer type
397
- elif base in ("int", "uint"):
398
- if not isinstance(sub, int):
399
- self.invalidate("integer type must have numerical suffix")
400
-
401
- if sub < 8 or sub > 256:
402
- self.invalidate("integer size out of bounds (max 256 bits)")
403
-
404
- if sub % 8 != 0:
405
- self.invalidate("integer size must be multiple of 8")
406
-
407
- # Check validity of fixed type
408
- elif base in ("fixed", "ufixed"):
409
- if not isinstance(sub, tuple):
410
- self.invalidate(
411
- "fixed type must have suffix of form <bits>x<exponent>, "
412
- "e.g. 128x19",
413
- )
414
-
415
- bits, minus_e = sub
416
-
417
- if bits < 8 or bits > 256:
418
- self.invalidate("fixed size out of bounds (max 256 bits)")
419
-
420
- if bits % 8 != 0:
421
- self.invalidate("fixed size must be multiple of 8")
422
-
423
- if minus_e < 1 or minus_e > 80:
424
- self.invalidate(
425
- f"fixed exponent size out of bounds, {minus_e} must be in 1-80"
426
- )
427
-
428
- # Check validity of hash type
429
- elif base == "hash":
430
- if not isinstance(sub, int):
431
- self.invalidate("hash type must have numerical suffix")
432
-
433
- # Check validity of address type
434
- elif base == "address":
435
- if sub is not None:
436
- self.invalidate("address cannot have suffix")
437
-
438
-
439
- TYPE_ALIASES: Final = {
440
- "int": "int256",
441
- "uint": "uint256",
442
- "fixed": "fixed128x18",
443
- "ufixed": "ufixed128x18",
444
- "function": "bytes24",
445
- "byte": "bytes1",
446
- }
447
-
448
- TYPE_ALIAS_RE: Final = re.compile(
449
- rf"\b({'|'.join(re.escape(a) for a in TYPE_ALIASES.keys())})\b"
450
- )
451
-
452
-
453
- def normalize(type_str: TypeStr) -> TypeStr:
454
- """
455
- Normalizes a type string into its canonical version e.g. the type string
456
- 'int' becomes 'int256', etc.
457
-
458
- :param type_str: The type string to be normalized.
459
- :returns: The canonical version of the input type string.
460
- """
461
- return TYPE_ALIAS_RE.sub(
462
- lambda match: TYPE_ALIASES[match.group(0)],
463
- type_str,
464
- )
158
+ parse: Final = visitor.parse
465
159
 
466
160
 
467
- parse: Final = visitor.parse
161
+ __all__ = [
162
+ "NodeVisitor",
163
+ "ABIType",
164
+ "TupleType",
165
+ "BasicType",
166
+ "grammar",
167
+ "parse",
168
+ "normalize",
169
+ "visitor",
170
+ "TYPE_ALIASES",
171
+ "TYPE_ALIAS_RE",
172
+ ]
faster_eth_abi/io.py CHANGED
@@ -1,3 +1,7 @@
1
+ """Context-aware byte stream for ABI decoding.
2
+
3
+ Implements a BytesIO subclass that supports contextual frame management for nested ABI decoding.
4
+ """
1
5
  from io import (
2
6
  BytesIO,
3
7
  )
@@ -89,7 +93,7 @@ class ContextFramesBytesIO(BytesIO):
89
93
 
90
94
  self.seek_in_frame(0)
91
95
 
92
- def pop_frame(self):
96
+ def pop_frame(self) -> None:
93
97
  """
94
98
  Pops the current contextual frame off of the stack and returns the
95
99
  cursor to the frame's return position.
Binary file
faster_eth_abi/packed.py CHANGED
@@ -1,3 +1,7 @@
1
+ """Helpers for packed ABI encoding.
2
+
3
+ Defines functions and registry for packed encoding and encodability checks.
4
+ """
1
5
  from typing import (
2
6
  Final,
3
7
  )