faster-eth-abi 5.2.8__cp314-cp314t-win_amd64.whl → 5.2.19__cp314-cp314t-win_amd64.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 (41) hide show
  1. faster_eth_abi/_codec.cp314t-win_amd64.pyd +0 -0
  2. faster_eth_abi/_codec.py +7 -5
  3. faster_eth_abi/_decoding.cp314t-win_amd64.pyd +0 -0
  4. faster_eth_abi/_decoding.py +212 -30
  5. faster_eth_abi/_encoding.cp314t-win_amd64.pyd +0 -0
  6. faster_eth_abi/_encoding.py +159 -11
  7. faster_eth_abi/_grammar.cp314t-win_amd64.pyd +0 -0
  8. faster_eth_abi/_grammar.py +375 -0
  9. faster_eth_abi/abi.cp314t-win_amd64.pyd +0 -0
  10. faster_eth_abi/base.py +5 -1
  11. faster_eth_abi/codec.py +2675 -9
  12. faster_eth_abi/constants.cp314t-win_amd64.pyd +0 -0
  13. faster_eth_abi/decoding.py +214 -176
  14. faster_eth_abi/encoding.py +112 -38
  15. faster_eth_abi/exceptions.py +26 -14
  16. faster_eth_abi/from_type_str.cp314t-win_amd64.pyd +0 -0
  17. faster_eth_abi/from_type_str.py +7 -1
  18. faster_eth_abi/grammar.py +30 -326
  19. faster_eth_abi/io.py +5 -1
  20. faster_eth_abi/packed.cp314t-win_amd64.pyd +0 -0
  21. faster_eth_abi/packed.py +4 -0
  22. faster_eth_abi/registry.py +186 -91
  23. faster_eth_abi/tools/__init__.cp314t-win_amd64.pyd +0 -0
  24. faster_eth_abi/tools/_strategies.cp314t-win_amd64.pyd +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__.cp314t-win_amd64.pyd +0 -0
  28. faster_eth_abi/utils/numeric.cp314t-win_amd64.pyd +0 -0
  29. faster_eth_abi/utils/numeric.py +51 -20
  30. faster_eth_abi/utils/padding.cp314t-win_amd64.pyd +0 -0
  31. faster_eth_abi/utils/string.cp314t-win_amd64.pyd +0 -0
  32. faster_eth_abi/utils/validation.cp314t-win_amd64.pyd +0 -0
  33. {faster_eth_abi-5.2.8.dist-info → faster_eth_abi-5.2.19.dist-info}/METADATA +38 -14
  34. faster_eth_abi-5.2.19.dist-info/RECORD +46 -0
  35. faster_eth_abi-5.2.19.dist-info/top_level.txt +2 -0
  36. faster_eth_abi__mypyc.cp314t-win_amd64.pyd +0 -0
  37. 76f9a3652d4d2667c55c__mypyc.cp314t-win_amd64.pyd +0 -0
  38. faster_eth_abi-5.2.8.dist-info/RECORD +0 -44
  39. faster_eth_abi-5.2.8.dist-info/licenses/LICENSE +0 -21
  40. faster_eth_abi-5.2.8.dist-info/top_level.txt +0 -2
  41. {faster_eth_abi-5.2.8.dist-info → faster_eth_abi-5.2.19.dist-info}/WHEEL +0 -0
@@ -1,15 +1,29 @@
1
+ """Classes for ABI encoding logic.
2
+
3
+ Implements classes and functions for serializing Python values into binary data
4
+ according to ABI type specifications.
5
+ """
1
6
  import abc
2
7
  import codecs
3
8
  import decimal
9
+ from functools import (
10
+ cached_property,
11
+ lru_cache,
12
+ )
13
+ from types import (
14
+ MethodType,
15
+ )
4
16
  from typing import (
5
17
  Any,
6
18
  Callable,
7
19
  ClassVar,
20
+ Final,
8
21
  NoReturn,
9
22
  Optional,
10
23
  Sequence,
11
24
  Tuple,
12
25
  Type,
26
+ final,
13
27
  )
14
28
 
15
29
  from faster_eth_utils import (
@@ -32,7 +46,11 @@ from faster_eth_abi._encoding import (
32
46
  encode_fixed,
33
47
  encode_signed,
34
48
  encode_tuple,
49
+ encode_tuple_all_dynamic,
50
+ encode_tuple_no_dynamic,
51
+ encode_tuple_no_dynamic_funcs,
35
52
  int_to_big_endian,
53
+ validate_tuple,
36
54
  )
37
55
  from faster_eth_abi.base import (
38
56
  BaseCoder,
@@ -78,7 +96,7 @@ class BaseEncoder(BaseCoder, metaclass=abc.ABCMeta):
78
96
  """
79
97
 
80
98
  @abc.abstractmethod
81
- def validate_value(self, value: Any) -> None: # pragma: no cover
99
+ def validate_value(self, value: Any) -> None:
82
100
  """
83
101
  Checks whether or not the given value can be encoded by this encoder.
84
102
  If the given value cannot be encoded, must raise
@@ -111,7 +129,35 @@ class TupleEncoder(BaseEncoder):
111
129
  def __init__(self, encoders: Tuple[BaseEncoder, ...], **kwargs: Any) -> None:
112
130
  super().__init__(encoders=encoders, **kwargs)
113
131
 
114
- self.is_dynamic = any(getattr(e, "is_dynamic", False) for e in self.encoders)
132
+ self._is_dynamic: Final = tuple(
133
+ getattr(e, "is_dynamic", False) for e in self.encoders
134
+ )
135
+ self.is_dynamic = any(self._is_dynamic)
136
+
137
+ validators = []
138
+ for encoder in self.encoders:
139
+ try:
140
+ validator = encoder.validate_value
141
+ except AttributeError:
142
+ validators.append(encoder)
143
+ else:
144
+ validators.append(validator)
145
+
146
+ self.validators: Final[Callable[[Any], None]] = tuple(validators)
147
+
148
+ if type(self).encode is TupleEncoder.encode:
149
+ encode_func = (
150
+ encode_tuple_all_dynamic
151
+ if all(self._is_dynamic)
152
+ else encode_tuple_no_dynamic_funcs.get(
153
+ len(self.encoders),
154
+ encode_tuple_no_dynamic,
155
+ )
156
+ if not self.is_dynamic
157
+ else encode_tuple
158
+ )
159
+
160
+ self.encode = MethodType(encode_func, self)
115
161
 
116
162
  def validate(self) -> None:
117
163
  super().validate()
@@ -119,33 +165,15 @@ class TupleEncoder(BaseEncoder):
119
165
  if self.encoders is None:
120
166
  raise ValueError("`encoders` may not be none")
121
167
 
168
+ @final
122
169
  def validate_value(self, value: Sequence[Any]) -> None:
123
- if not is_list_like(value):
124
- self.invalidate_value(
125
- value,
126
- msg="must be list-like object such as array or tuple",
127
- )
128
-
129
- encoders = self.encoders
130
- if len(value) != len(encoders):
131
- self.invalidate_value(
132
- value,
133
- exc=ValueOutOfBounds,
134
- msg=f"value has {len(value)} items when {len(encoders)} "
135
- "were expected",
136
- )
137
-
138
- for item, encoder in zip(value, encoders):
139
- try:
140
- encoder.validate_value(item)
141
- except AttributeError:
142
- encoder(item)
170
+ validate_tuple(self, value)
143
171
 
144
172
  def encode(self, values: Sequence[Any]) -> bytes:
145
- self.validate_value(values)
146
- return encode_tuple(values, self.encoders)
173
+ return encode_tuple(self, values)
147
174
 
148
- __call__: Callable[[Self, Sequence[Any]], bytes] = encode
175
+ def __call__(self, values: Sequence[Any]) -> bytes:
176
+ return self.encode(values)
149
177
 
150
178
  @parse_tuple_type_str
151
179
  def from_type_str(cls, abi_type, registry):
@@ -185,7 +213,7 @@ class FixedSizeEncoder(BaseEncoder):
185
213
  if value_bit_size > data_byte_size * 8:
186
214
  raise ValueError("Value byte size exceeds data size")
187
215
 
188
- def validate_value(self, value):
216
+ def validate_value(self, value: Any) -> None:
189
217
  raise NotImplementedError("Must be implemented by subclasses")
190
218
 
191
219
  def encode(self, value: Any) -> bytes:
@@ -243,7 +271,7 @@ class NumberEncoder(Fixed32ByteSizeEncoder):
243
271
  if self.type_check_fn is None:
244
272
  raise ValueError("`type_check_fn` cannot be null")
245
273
 
246
- def validate_value(self, value):
274
+ def validate_value(self, value: Any) -> None:
247
275
  type_check_fn = self.type_check_fn
248
276
  if type_check_fn is None:
249
277
  raise AssertionError("`type_check_fn` is None")
@@ -275,6 +303,16 @@ class UnsignedIntegerEncoder(NumberEncoder):
275
303
  return cls(value_bit_size=abi_type.sub)
276
304
 
277
305
 
306
+ class UnsignedIntegerEncoderCached(UnsignedIntegerEncoder):
307
+ encode: Final[Callable[[int], bytes]]
308
+ maxsize: Final[Optional[int]]
309
+
310
+ def __init__(self, maxsize: Optional[int] = None, **kwargs: Any) -> None:
311
+ super().__init__(**kwargs)
312
+ self.maxsize = maxsize
313
+ self.encode = lru_cache(maxsize=maxsize)(self.encode)
314
+
315
+
278
316
  encode_uint_256 = UnsignedIntegerEncoder(value_bit_size=256, data_byte_size=32)
279
317
 
280
318
 
@@ -287,6 +325,16 @@ class PackedUnsignedIntegerEncoder(UnsignedIntegerEncoder):
287
325
  )
288
326
 
289
327
 
328
+ class PackedUnsignedIntegerEncoderCached(PackedUnsignedIntegerEncoder):
329
+ encode: Final[Callable[[int], bytes]]
330
+ maxsize: Final[Optional[int]]
331
+
332
+ def __init__(self, maxsize: Optional[int] = None, **kwargs: Any) -> None:
333
+ super().__init__(**kwargs)
334
+ self.maxsize = maxsize
335
+ self.encode = lru_cache(maxsize=maxsize)(self.encode)
336
+
337
+
290
338
  class SignedIntegerEncoder(NumberEncoder):
291
339
  bounds_fn = staticmethod(compute_signed_integer_bounds)
292
340
  type_check_fn = staticmethod(is_integer)
@@ -305,6 +353,16 @@ class SignedIntegerEncoder(NumberEncoder):
305
353
  return cls(value_bit_size=abi_type.sub)
306
354
 
307
355
 
356
+ class SignedIntegerEncoderCached(SignedIntegerEncoder):
357
+ encode: Final[Callable[[int], bytes]]
358
+ maxsize: Final[Optional[int]]
359
+
360
+ def __init__(self, maxsize: Optional[int] = None, **kwargs: Any) -> None:
361
+ super().__init__(**kwargs)
362
+ self.maxsize = maxsize
363
+ self.encode = lru_cache(maxsize=maxsize)(self.encode)
364
+
365
+
308
366
  class PackedSignedIntegerEncoder(SignedIntegerEncoder):
309
367
  @parse_type_str("int")
310
368
  def from_type_str(cls, abi_type, registry):
@@ -314,6 +372,16 @@ class PackedSignedIntegerEncoder(SignedIntegerEncoder):
314
372
  )
315
373
 
316
374
 
375
+ class PackedSignedIntegerEncoderCached(PackedSignedIntegerEncoder):
376
+ encode: Final[Callable[[int], bytes]]
377
+ maxsize: Final[Optional[int]]
378
+
379
+ def __init__(self, maxsize: Optional[int] = None, **kwargs: Any) -> None:
380
+ super().__init__(**kwargs)
381
+ self.maxsize = maxsize
382
+ self.encode = lru_cache(maxsize=maxsize)(self.encode)
383
+
384
+
317
385
  class BaseFixedEncoder(NumberEncoder):
318
386
  frac_places = None
319
387
 
@@ -328,11 +396,19 @@ class BaseFixedEncoder(NumberEncoder):
328
396
 
329
397
  return False
330
398
 
399
+ @cached_property
400
+ def denominator(self) -> decimal.Decimal:
401
+ return TEN**self.frac_places
402
+
403
+ @cached_property
404
+ def precision(self) -> int:
405
+ return TEN**-self.frac_places
406
+
331
407
  def validate_value(self, value):
332
408
  super().validate_value(value)
333
409
 
334
410
  with decimal.localcontext(abi_decimal_context):
335
- residue = value % (TEN**-self.frac_places)
411
+ residue = value % self.precision
336
412
 
337
413
  if residue > 0:
338
414
  self.invalidate_value(
@@ -357,9 +433,9 @@ class UnsignedFixedEncoder(BaseFixedEncoder):
357
433
  def bounds_fn(self, value_bit_size):
358
434
  return compute_unsigned_fixed_bounds(self.value_bit_size, self.frac_places)
359
435
 
360
- def encode_fn(self, value):
436
+ def encode_fn(self, value: decimal.Decimal) -> bytes:
361
437
  with decimal.localcontext(abi_decimal_context):
362
- scaled_value = value * TEN**self.frac_places
438
+ scaled_value = value * self.denominator
363
439
  integer_value = int(scaled_value)
364
440
 
365
441
  return int_to_big_endian(integer_value)
@@ -390,16 +466,16 @@ class SignedFixedEncoder(BaseFixedEncoder):
390
466
  def bounds_fn(self, value_bit_size):
391
467
  return compute_signed_fixed_bounds(self.value_bit_size, self.frac_places)
392
468
 
393
- def encode_fn(self, value):
469
+ def encode_fn(self, value: decimal.Decimal) -> bytes:
394
470
  with decimal.localcontext(abi_decimal_context):
395
- scaled_value = value * TEN**self.frac_places
471
+ scaled_value = value * self.denominator
396
472
  integer_value = int(scaled_value)
397
473
 
398
474
  unsigned_integer_value = integer_value % (2**self.value_bit_size)
399
475
 
400
476
  return int_to_big_endian(unsigned_integer_value)
401
477
 
402
- def encode(self, value):
478
+ def encode(self, value: decimal.Decimal) -> bytes:
403
479
  self.validate_value(value)
404
480
  return encode_signed(value, self.encode_fn, self.data_byte_size)
405
481
 
@@ -468,7 +544,7 @@ class BytesEncoder(Fixed32ByteSizeEncoder):
468
544
  )
469
545
 
470
546
  @staticmethod
471
- def encode_fn(value):
547
+ def encode_fn(value: bytes) -> bytes:
472
548
  return value
473
549
 
474
550
  @parse_type_str("bytes")
@@ -514,7 +590,7 @@ class PackedByteStringEncoder(ByteStringEncoder):
514
590
  is_dynamic = False
515
591
 
516
592
  @classmethod
517
- def encode(cls, value):
593
+ def encode(cls, value: bytes) -> bytes:
518
594
  cls.validate_value(value)
519
595
  return value
520
596
 
@@ -635,7 +711,7 @@ class PackedArrayEncoder(BaseArrayEncoder):
635
711
  class SizedArrayEncoder(BaseArrayEncoder):
636
712
  array_size = None
637
713
 
638
- def __init__(self, **kwargs):
714
+ def __init__(self, **kwargs: Any) -> None:
639
715
  super().__init__(**kwargs)
640
716
 
641
717
  self.is_dynamic = self.item_encoder.is_dynamic
@@ -668,5 +744,3 @@ class DynamicArrayEncoder(BaseArrayEncoder):
668
744
 
669
745
  def encode(self, value: Sequence[Any]) -> bytes:
670
746
  return encode_elements_dynamic(self.item_encoder, value)
671
-
672
- __call__ = encode
@@ -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