faster-eth-abi 5.2.13__cp39-cp39-macosx_11_0_arm64.whl → 5.2.14__cp39-cp39-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 (27) hide show
  1. benchmarks/test_registry_benchmarks.py +7 -4
  2. faster_eth_abi/_codec.cpython-39-darwin.so +0 -0
  3. faster_eth_abi/_codec.py +1 -1
  4. faster_eth_abi/_decoding.cpython-39-darwin.so +0 -0
  5. faster_eth_abi/_encoding.cpython-39-darwin.so +0 -0
  6. faster_eth_abi/_encoding.py +141 -6
  7. faster_eth_abi/_grammar.cpython-39-darwin.so +0 -0
  8. faster_eth_abi/abi.cpython-39-darwin.so +0 -0
  9. faster_eth_abi/constants.cpython-39-darwin.so +0 -0
  10. faster_eth_abi/decoding.py +41 -16
  11. faster_eth_abi/encoding.py +55 -27
  12. faster_eth_abi/from_type_str.cpython-39-darwin.so +0 -0
  13. faster_eth_abi/packed.cpython-39-darwin.so +0 -0
  14. faster_eth_abi/registry.py +47 -31
  15. faster_eth_abi/tools/__init__.cpython-39-darwin.so +0 -0
  16. faster_eth_abi/tools/_strategies.cpython-39-darwin.so +0 -0
  17. faster_eth_abi/utils/__init__.cpython-39-darwin.so +0 -0
  18. faster_eth_abi/utils/numeric.cpython-39-darwin.so +0 -0
  19. faster_eth_abi/utils/padding.cpython-39-darwin.so +0 -0
  20. faster_eth_abi/utils/string.cpython-39-darwin.so +0 -0
  21. faster_eth_abi/utils/validation.cpython-39-darwin.so +0 -0
  22. {faster_eth_abi-5.2.13.dist-info → faster_eth_abi-5.2.14.dist-info}/METADATA +1 -1
  23. {faster_eth_abi-5.2.13.dist-info → faster_eth_abi-5.2.14.dist-info}/RECORD +27 -27
  24. faster_eth_abi__mypyc.cpython-39-darwin.so +0 -0
  25. {faster_eth_abi-5.2.13.dist-info → faster_eth_abi-5.2.14.dist-info}/WHEEL +0 -0
  26. {faster_eth_abi-5.2.13.dist-info → faster_eth_abi-5.2.14.dist-info}/licenses/LICENSE +0 -0
  27. {faster_eth_abi-5.2.13.dist-info → faster_eth_abi-5.2.14.dist-info}/top_level.txt +0 -0
@@ -18,25 +18,28 @@ from faster_eth_abi.registry import (
18
18
  )
19
19
 
20
20
 
21
+ ITERATIONS = 50_000
22
+
23
+
21
24
  @pytest.mark.benchmark(group="RegistryGetEncoder")
22
25
  @pytest.mark.parametrize("type_str", type_strings)
23
26
  def test_get_encoder(benchmark: BenchmarkFixture, type_str):
24
- benchmark(batch, 1000, registry.get_encoder, type_str)
27
+ benchmark(batch, ITERATIONS, registry.get_encoder, type_str)
25
28
 
26
29
 
27
30
  @pytest.mark.benchmark(group="RegistryGetEncoder")
28
31
  @pytest.mark.parametrize("type_str", type_strings)
29
32
  def test_faster_get_encoder(benchmark: BenchmarkFixture, type_str):
30
- benchmark(batch, 1000, faster_registry.get_encoder, type_str)
33
+ benchmark(batch, ITERATIONS, faster_registry.get_encoder, type_str)
31
34
 
32
35
 
33
36
  @pytest.mark.benchmark(group="RegistryGetDecoder")
34
37
  @pytest.mark.parametrize("type_str", type_strings)
35
38
  def test_get_decoder(benchmark: BenchmarkFixture, type_str):
36
- benchmark(batch, 1000, registry.get_decoder, type_str)
39
+ benchmark(batch, ITERATIONS, registry.get_decoder, type_str)
37
40
 
38
41
 
39
42
  @pytest.mark.benchmark(group="RegistryGetDecoder")
40
43
  @pytest.mark.parametrize("type_str", type_strings)
41
44
  def test_faster_get_decoder(benchmark: BenchmarkFixture, type_str):
42
- benchmark(batch, 1000, faster_registry.get_decoder, type_str)
45
+ benchmark(batch, ITERATIONS, faster_registry.get_decoder, type_str)
Binary file
faster_eth_abi/_codec.py CHANGED
@@ -43,7 +43,7 @@ def encode_c(
43
43
 
44
44
  encoder = self._registry.get_tuple_encoder(*types)
45
45
 
46
- return encoder(args)
46
+ return encoder.encode(args)
47
47
 
48
48
 
49
49
  def decode_c(
@@ -2,29 +2,59 @@ from typing import (
2
2
  TYPE_CHECKING,
3
3
  Any,
4
4
  Callable,
5
+ Dict,
5
6
  List,
6
7
  Optional,
7
8
  Sequence,
9
+ Tuple,
8
10
  TypeVar,
9
11
  )
10
12
 
13
+ from faster_eth_utils import (
14
+ is_list_like,
15
+ )
16
+
17
+ from faster_eth_abi.exceptions import (
18
+ ValueOutOfBounds,
19
+ )
20
+
11
21
  if TYPE_CHECKING:
12
22
  from faster_eth_abi.encoding import (
13
23
  BaseEncoder,
24
+ TupleEncoder,
14
25
  )
15
26
 
16
27
 
17
28
  T = TypeVar("T")
18
29
 
19
30
 
20
- def encode_tuple(
21
- values: Sequence[Any],
22
- encoders: Sequence["BaseEncoder"],
23
- ) -> bytes:
31
+ # TupleEncoder
32
+ def validate_tuple(self: "TupleEncoder", value: Sequence[Any]) -> None:
33
+ # if we check list and tuple first it compiles to much quicker C code
34
+ if not isinstance(value, (list, tuple)) and not is_list_like(value):
35
+ self.invalidate_value(
36
+ value,
37
+ msg="must be list-like object such as array or tuple",
38
+ )
39
+
40
+ validators = self.validators
41
+ if len(value) != len(validators):
42
+ self.invalidate_value(
43
+ value,
44
+ exc=ValueOutOfBounds,
45
+ msg=f"value has {len(value)} items when {len(validators)} " "were expected",
46
+ )
47
+
48
+ for item, validator in zip(value, validators):
49
+ validator(item)
50
+
51
+
52
+ def encode_tuple(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
53
+ validate_tuple(self, values)
24
54
  raw_head_chunks: List[Optional[bytes]] = []
25
55
  tail_chunks: List[bytes] = []
26
- for value, encoder in zip(values, encoders):
27
- if getattr(encoder, "is_dynamic", False):
56
+ for value, encoder, is_dynamic in zip(values, self.encoders, self._is_dynamic):
57
+ if is_dynamic:
28
58
  raw_head_chunks.append(None)
29
59
  tail_chunks.append(encoder(value))
30
60
  else:
@@ -46,6 +76,111 @@ def encode_tuple(
46
76
  return b"".join(head_chunks) + b"".join(tail_chunks)
47
77
 
48
78
 
79
+ def encode_tuple_all_dynamic(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
80
+ validate_tuple(self, values)
81
+ encoders = self.encoders
82
+ tail_chunks = [encoder(value) for encoder, value in zip(encoders, values)]
83
+
84
+ total_offset = 0
85
+ head_length = 32 * len(encoders)
86
+ head_chunks = [encode_uint_256(head_length)]
87
+ for item in tail_chunks[:-1]:
88
+ total_offset += len(item)
89
+ head_chunks.append(encode_uint_256(head_length + total_offset))
90
+
91
+ return b"".join(head_chunks) + b"".join(tail_chunks)
92
+
93
+
94
+ def encode_tuple_no_dynamic(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
95
+ validate_tuple(self, values)
96
+ encoders = self.encoders
97
+ return b"".join(encoders[i](values[i]) for i in range(len(encoders)))
98
+
99
+
100
+ def encode_tuple_no_dynamic1(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
101
+ validate_tuple(self, values)
102
+ encoders: Tuple["BaseEncoder"] = self.encoders
103
+ return encoders[0](values[0])
104
+
105
+
106
+ def encode_tuple_no_dynamic2(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
107
+ validate_tuple(self, values)
108
+ encoders = self.encoders
109
+ # encoders: Tuple["BaseEncoder", "BaseEncoder"] = self.encoders
110
+ return encoders[0](values[0]) + encoders[1](values[1])
111
+
112
+
113
+ def encode_tuple_no_dynamic3(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
114
+ validate_tuple(self, values)
115
+ encoders = self.encoders
116
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
117
+ return b"".join(encoders[i](values[i]) for i in range(3))
118
+
119
+
120
+ def encode_tuple_no_dynamic4(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
121
+ validate_tuple(self, values)
122
+ encoders = self.encoders
123
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
124
+ return b"".join(encoders[i](values[i]) for i in range(4))
125
+
126
+
127
+ def encode_tuple_no_dynamic5(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
128
+ validate_tuple(self, values)
129
+ encoders = self.encoders
130
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
131
+ return b"".join(encoders[i](values[i]) for i in range(5))
132
+
133
+
134
+ def encode_tuple_no_dynamic6(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
135
+ validate_tuple(self, values)
136
+ encoders = self.encoders
137
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
138
+ return b"".join(encoders[i](values[i]) for i in range(6))
139
+
140
+
141
+ def encode_tuple_no_dynamic7(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
142
+ validate_tuple(self, values)
143
+ encoders = self.encoders
144
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
145
+ return b"".join(encoders[i](values[i]) for i in range(7))
146
+
147
+
148
+ def encode_tuple_no_dynamic8(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
149
+ validate_tuple(self, values)
150
+ encoders = self.encoders
151
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
152
+ return b"".join(encoders[i](values[i]) for i in range(8))
153
+
154
+
155
+ def encode_tuple_no_dynamic9(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
156
+ validate_tuple(self, values)
157
+ encoders = self.encoders
158
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
159
+ return b"".join(encoders[i](values[i]) for i in range(9))
160
+
161
+
162
+ def encode_tuple_no_dynamic10(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
163
+ validate_tuple(self, values)
164
+ encoders = self.encoders
165
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
166
+ return b"".join(encoders[i](values[i]) for i in range(10))
167
+
168
+ encode_tuple_no_dynamic_funcs: Dict[
169
+ int, Callable[["TupleEncoder", Sequence[Any]], bytes]
170
+ ] = {
171
+ 1: encode_tuple_no_dynamic1,
172
+ 2: encode_tuple_no_dynamic2,
173
+ 3: encode_tuple_no_dynamic3,
174
+ 4: encode_tuple_no_dynamic4,
175
+ 5: encode_tuple_no_dynamic5,
176
+ 6: encode_tuple_no_dynamic6,
177
+ 7: encode_tuple_no_dynamic7,
178
+ 8: encode_tuple_no_dynamic8,
179
+ 9: encode_tuple_no_dynamic9,
180
+ 10: encode_tuple_no_dynamic10,
181
+ }
182
+
183
+
49
184
  def encode_fixed(
50
185
  value: Any,
51
186
  encode_fn: Callable[[Any], bytes],
Binary file
@@ -163,10 +163,7 @@ class SingleDecoder(BaseDecoder):
163
163
  def decode(self, stream: ContextFramesBytesIO) -> Any:
164
164
  raw_data = self.read_data_from_stream(stream)
165
165
  data, padding_bytes = self.split_data_and_padding(raw_data)
166
- decoder_fn = self.decoder_fn
167
- if decoder_fn is None:
168
- raise AssertionError("`decoder_fn` is None")
169
- value = decoder_fn(data)
166
+ value = self.decoder_fn(data) # type: ignore [misc]
170
167
  self.validate_padding_bytes(value, padding_bytes)
171
168
 
172
169
  return value
@@ -190,6 +187,7 @@ class BaseArrayDecoder(BaseDecoder):
190
187
  item_decoder = self.item_decoder
191
188
  if item_decoder.is_dynamic:
192
189
  self.item_decoder = HeadTailDecoder(tail_decoder=item_decoder)
190
+ self.validate_pointers = MethodType(validate_pointers_array, self)
193
191
  else:
194
192
 
195
193
  def noop(stream: ContextFramesBytesIO, array_size: int) -> None:
@@ -354,6 +352,13 @@ decode_uint_256 = UnsignedIntegerDecoder(value_bit_size=256)
354
352
  class SignedIntegerDecoder(Fixed32ByteSizeDecoder):
355
353
  is_big_endian = True
356
354
 
355
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
356
+ super().__init__(*args, **kwargs)
357
+
358
+ # Only assign validate_padding_bytes if not overridden in subclass
359
+ if type(self).validate_padding_bytes is SignedIntegerDecoder.validate_padding_bytes:
360
+ self.validate_padding_bytes = MethodType(validate_padding_bytes_signed_integer, self)
361
+
357
362
  @cached_property
358
363
  def neg_threshold(self) -> int:
359
364
  return int(2 ** (self.value_bit_size - 1))
@@ -394,6 +399,10 @@ class BytesDecoder(Fixed32ByteSizeDecoder):
394
399
  class BaseFixedDecoder(Fixed32ByteSizeDecoder):
395
400
  frac_places: int = None
396
401
  is_big_endian = True
402
+
403
+ @cached_property
404
+ def denominator(self) -> decimal.Decimal:
405
+ return TEN**self.frac_places
397
406
 
398
407
  def validate(self) -> None:
399
408
  super().validate()
@@ -407,11 +416,12 @@ class BaseFixedDecoder(Fixed32ByteSizeDecoder):
407
416
 
408
417
 
409
418
  class UnsignedFixedDecoder(BaseFixedDecoder):
419
+
410
420
  def decoder_fn(self, data: bytes) -> decimal.Decimal:
411
421
  value = big_endian_to_int(data)
412
422
 
413
423
  with decimal.localcontext(abi_decimal_context):
414
- decimal_value = decimal.Decimal(value) / TEN**self.frac_places
424
+ decimal_value = decimal.Decimal(value) / self.denominator
415
425
 
416
426
  return decimal_value
417
427
 
@@ -423,27 +433,42 @@ class UnsignedFixedDecoder(BaseFixedDecoder):
423
433
 
424
434
 
425
435
  class SignedFixedDecoder(BaseFixedDecoder):
436
+
437
+ @cached_property
438
+ def neg_threshold(self) -> int:
439
+ return int(2 ** (self.value_bit_size - 1))
440
+
441
+ @cached_property
442
+ def neg_offset(self) -> int:
443
+ return int(2**self.value_bit_size)
444
+
445
+ @cached_property
446
+ def expected_padding_pos(self) -> bytes:
447
+ value_byte_size = get_value_byte_size(self)
448
+ padding_size = self.data_byte_size - value_byte_size
449
+ return b"\x00" * padding_size
450
+
451
+ @cached_property
452
+ def expected_padding_neg(self) -> bytes:
453
+ value_byte_size = get_value_byte_size(self)
454
+ padding_size = self.data_byte_size - value_byte_size
455
+ return b"\xff" * padding_size
456
+
426
457
  def decoder_fn(self, data: bytes) -> decimal.Decimal:
427
458
  value = big_endian_to_int(data)
428
- value_bit_size = self.value_bit_size
429
- if value >= 2 ** (value_bit_size - 1):
430
- signed_value = value - 2**value_bit_size
431
- else:
432
- signed_value = value
459
+ if value >= self.neg_threshold:
460
+ value -= self.neg_offset
433
461
 
434
462
  with decimal.localcontext(abi_decimal_context):
435
- decimal_value = decimal.Decimal(signed_value) / TEN**self.frac_places
463
+ decimal_value = decimal.Decimal(value) / self.denominator
436
464
 
437
465
  return decimal_value
438
466
 
439
467
  def validate_padding_bytes(self, value: Any, padding_bytes: bytes) -> None:
440
- value_byte_size = get_value_byte_size(self)
441
- padding_size = self.data_byte_size - value_byte_size
442
-
443
468
  if value >= 0:
444
- expected_padding_bytes = b"\x00" * padding_size
469
+ expected_padding_bytes = self.expected_padding_pos
445
470
  else:
446
- expected_padding_bytes = b"\xff" * padding_size
471
+ expected_padding_bytes = self.expected_padding_neg
447
472
 
448
473
  if padding_bytes != expected_padding_bytes:
449
474
  raise NonEmptyPaddingBytes(
@@ -1,15 +1,23 @@
1
1
  import abc
2
2
  import codecs
3
3
  import decimal
4
+ from functools import (
5
+ cached_property,
6
+ )
7
+ from types import (
8
+ MethodType,
9
+ )
4
10
  from typing import (
5
11
  Any,
6
12
  Callable,
7
13
  ClassVar,
14
+ Final,
8
15
  NoReturn,
9
16
  Optional,
10
17
  Sequence,
11
18
  Tuple,
12
19
  Type,
20
+ final,
13
21
  )
14
22
 
15
23
  from faster_eth_utils import (
@@ -32,7 +40,11 @@ from faster_eth_abi._encoding import (
32
40
  encode_fixed,
33
41
  encode_signed,
34
42
  encode_tuple,
43
+ encode_tuple_all_dynamic,
44
+ encode_tuple_no_dynamic,
45
+ encode_tuple_no_dynamic_funcs,
35
46
  int_to_big_endian,
47
+ validate_tuple,
36
48
  )
37
49
  from faster_eth_abi.base import (
38
50
  BaseCoder,
@@ -111,7 +123,33 @@ class TupleEncoder(BaseEncoder):
111
123
  def __init__(self, encoders: Tuple[BaseEncoder, ...], **kwargs: Any) -> None:
112
124
  super().__init__(encoders=encoders, **kwargs)
113
125
 
114
- self.is_dynamic = any(getattr(e, "is_dynamic", False) for e in self.encoders)
126
+ self._is_dynamic: Final = tuple(getattr(e, "is_dynamic", False) for e in self.encoders)
127
+ self.is_dynamic = any(self._is_dynamic)
128
+
129
+ validators = []
130
+ for encoder in self.encoders:
131
+ try:
132
+ validator = encoder.validate_value
133
+ except AttributeError:
134
+ validators.append(encoder)
135
+ else:
136
+ validators.append(validator)
137
+
138
+ self.validators: Final[Callable[[Any], None]] = tuple(validators)
139
+
140
+ if type(self).encode is TupleEncoder.encode:
141
+ encode_func = (
142
+ encode_tuple_all_dynamic
143
+ if all(self._is_dynamic)
144
+ else encode_tuple_no_dynamic_funcs.get(
145
+ len(self.encoders),
146
+ encode_tuple_no_dynamic,
147
+ )
148
+ if not self.is_dynamic
149
+ else encode_tuple
150
+ )
151
+
152
+ self.encode = MethodType(encode_func, self)
115
153
 
116
154
  def validate(self) -> None:
117
155
  super().validate()
@@ -119,33 +157,15 @@ class TupleEncoder(BaseEncoder):
119
157
  if self.encoders is None:
120
158
  raise ValueError("`encoders` may not be none")
121
159
 
160
+ @final
122
161
  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)
162
+ validate_tuple(self, value)
143
163
 
144
164
  def encode(self, values: Sequence[Any]) -> bytes:
145
- self.validate_value(values)
146
- return encode_tuple(values, self.encoders)
165
+ return encode_tuple(self, values)
147
166
 
148
- __call__: Callable[[Self, Sequence[Any]], bytes] = encode
167
+ def __call__(self, values: Sequence[Any]) -> bytes:
168
+ return self.encode(values)
149
169
 
150
170
  @parse_tuple_type_str
151
171
  def from_type_str(cls, abi_type, registry):
@@ -328,11 +348,19 @@ class BaseFixedEncoder(NumberEncoder):
328
348
 
329
349
  return False
330
350
 
351
+ @cached_property
352
+ def denominator(self) -> decimal.Decimal:
353
+ return TEN**self.frac_places
354
+
355
+ @cached_property
356
+ def precision(self) -> int:
357
+ return TEN**-self.frac_places
358
+
331
359
  def validate_value(self, value):
332
360
  super().validate_value(value)
333
361
 
334
362
  with decimal.localcontext(abi_decimal_context):
335
- residue = value % (TEN**-self.frac_places)
363
+ residue = value % self.precision
336
364
 
337
365
  if residue > 0:
338
366
  self.invalidate_value(
@@ -359,7 +387,7 @@ class UnsignedFixedEncoder(BaseFixedEncoder):
359
387
 
360
388
  def encode_fn(self, value):
361
389
  with decimal.localcontext(abi_decimal_context):
362
- scaled_value = value * TEN**self.frac_places
390
+ scaled_value = value * self.denominator
363
391
  integer_value = int(scaled_value)
364
392
 
365
393
  return int_to_big_endian(integer_value)
@@ -392,7 +420,7 @@ class SignedFixedEncoder(BaseFixedEncoder):
392
420
 
393
421
  def encode_fn(self, value):
394
422
  with decimal.localcontext(abi_decimal_context):
395
- scaled_value = value * TEN**self.frac_places
423
+ scaled_value = value * self.denominator
396
424
  integer_value = int(scaled_value)
397
425
 
398
426
  unsigned_integer_value = integer_value % (2**self.value_bit_size)
Binary file
@@ -1,12 +1,15 @@
1
1
  import abc
2
+ from copy import (
3
+ copy,
4
+ )
2
5
  import functools
3
- from copy import copy
4
6
  from typing import (
5
7
  Any,
6
8
  Callable,
7
9
  Dict,
8
10
  Final,
9
11
  Generic,
12
+ Iterator,
10
13
  Optional,
11
14
  Type,
12
15
  TypeVar,
@@ -17,6 +20,8 @@ from eth_typing import (
17
20
  TypeStr,
18
21
  )
19
22
  from typing_extensions import (
23
+ Concatenate,
24
+ ParamSpec,
20
25
  Self,
21
26
  )
22
27
 
@@ -38,6 +43,7 @@ from .io import (
38
43
  )
39
44
 
40
45
  T = TypeVar("T")
46
+ P = ParamSpec("P")
41
47
 
42
48
  Lookup = Union[TypeStr, Callable[[TypeStr], bool]]
43
49
 
@@ -177,25 +183,25 @@ class Predicate:
177
183
  ``ABIRegistry``.
178
184
  """
179
185
 
180
- __slots__ = tuple()
186
+ __slots__ = ()
181
187
 
182
188
  def __call__(self, *args, **kwargs): # pragma: no cover
183
189
  raise NotImplementedError("Must implement `__call__`")
184
190
 
185
- def __str__(self): # pragma: no cover
191
+ def __str__(self) -> str:
186
192
  raise NotImplementedError("Must implement `__str__`")
187
193
 
188
- def __repr__(self):
194
+ def __repr__(self) -> str:
189
195
  return f"<{type(self).__name__} {self}>"
190
196
 
191
- def __iter__(self):
197
+ def __iter__(self) -> Iterator[Any]:
192
198
  for attr in self.__slots__:
193
199
  yield getattr(self, attr)
194
200
 
195
- def __hash__(self):
201
+ def __hash__(self) -> int:
196
202
  return hash(tuple(self))
197
203
 
198
- def __eq__(self, other):
204
+ def __eq__(self, other: Any) -> bool:
199
205
  return type(self) is type(other) and tuple(self) == tuple(other)
200
206
 
201
207
 
@@ -209,10 +215,10 @@ class Equals(Predicate):
209
215
  def __init__(self, value):
210
216
  self.value = value
211
217
 
212
- def __call__(self, other):
218
+ def __call__(self, other: Any) -> bool:
213
219
  return self.value == other
214
220
 
215
- def __str__(self):
221
+ def __str__(self) -> str:
216
222
  return f"(== {self.value!r})"
217
223
 
218
224
 
@@ -231,7 +237,7 @@ class BaseEquals(Predicate):
231
237
  self.base = base
232
238
  self.with_sub = with_sub
233
239
 
234
- def __call__(self, type_str):
240
+ def __call__(self, type_str: TypeStr) -> bool:
235
241
  try:
236
242
  abi_type = grammar.parse(type_str)
237
243
  except (exceptions.ParseError, ValueError):
@@ -253,7 +259,7 @@ class BaseEquals(Predicate):
253
259
  # e.g. if it contained a tuple type
254
260
  return False
255
261
 
256
- def __str__(self):
262
+ def __str__(self) -> str:
257
263
  return (
258
264
  f"(base == {self.base!r}"
259
265
  + (
@@ -265,7 +271,7 @@ class BaseEquals(Predicate):
265
271
  )
266
272
 
267
273
 
268
- def has_arrlist(type_str):
274
+ def has_arrlist(type_str: TypeStr) -> bool:
269
275
  """
270
276
  A predicate that matches a type string with an array dimension list.
271
277
  """
@@ -277,7 +283,7 @@ def has_arrlist(type_str):
277
283
  return abi_type.arrlist is not None
278
284
 
279
285
 
280
- def is_base_tuple(type_str):
286
+ def is_base_tuple(type_str: TypeStr) -> bool:
281
287
  """
282
288
  A predicate that matches a tuple type with no array dimension list.
283
289
  """
@@ -289,9 +295,11 @@ def is_base_tuple(type_str):
289
295
  return isinstance(abi_type, grammar.TupleType) and abi_type.arrlist is None
290
296
 
291
297
 
292
- def _clear_encoder_cache(old_method: Callable[..., None]) -> Callable[..., None]:
298
+ def _clear_encoder_cache(
299
+ old_method: Callable[Concatenate["ABIRegistry", P], T]
300
+ ) -> Callable[Concatenate["ABIRegistry", P], T]:
293
301
  @functools.wraps(old_method)
294
- def new_method(self: "ABIRegistry", *args: Any, **kwargs: Any) -> None:
302
+ def new_method(self: "ABIRegistry", *args: P.args, **kwargs: P.kwargs) -> T:
295
303
  self.get_encoder.cache_clear()
296
304
  self.get_tuple_encoder.cache_clear()
297
305
  return old_method(self, *args, **kwargs)
@@ -299,9 +307,11 @@ def _clear_encoder_cache(old_method: Callable[..., None]) -> Callable[..., None]
299
307
  return new_method
300
308
 
301
309
 
302
- def _clear_decoder_cache(old_method: Callable[..., None]) -> Callable[..., None]:
310
+ def _clear_decoder_cache(
311
+ old_method: Callable[Concatenate["ABIRegistry", P], T]
312
+ ) -> Callable[Concatenate["ABIRegistry", P], T]:
303
313
  @functools.wraps(old_method)
304
- def new_method(self: "ABIRegistry", *args: Any, **kwargs: Any) -> None:
314
+ def new_method(self: "ABIRegistry", *args: P.args, **kwargs: P.kwargs) -> T:
305
315
  self.get_decoder.cache_clear()
306
316
  self.get_tuple_decoder.cache_clear()
307
317
  return old_method(self, *args, **kwargs)
@@ -311,7 +321,12 @@ def _clear_decoder_cache(old_method: Callable[..., None]) -> Callable[..., None]
311
321
 
312
322
  class BaseRegistry:
313
323
  @staticmethod
314
- def _register(mapping, lookup, value, label=None):
324
+ def _register(
325
+ mapping: PredicateMapping[T],
326
+ lookup: Lookup,
327
+ value: T,
328
+ label: Optional[str] = None,
329
+ ) -> None:
315
330
  if callable(lookup):
316
331
  mapping.add(lookup, value, label)
317
332
  return
@@ -325,7 +340,7 @@ class BaseRegistry:
325
340
  )
326
341
 
327
342
  @staticmethod
328
- def _unregister(mapping, lookup_or_label):
343
+ def _unregister(mapping: PredicateMapping[Any], lookup_or_label: Lookup) -> None:
329
344
  if callable(lookup_or_label):
330
345
  mapping.remove_by_equality(lookup_or_label)
331
346
  return
@@ -340,7 +355,7 @@ class BaseRegistry:
340
355
  )
341
356
 
342
357
  @staticmethod
343
- def _get_registration(mapping, type_str):
358
+ def _get_registration(mapping: PredicateMapping[T], type_str: TypeStr) -> T:
344
359
  try:
345
360
  value = mapping.find(type_str)
346
361
  except ValueError as e:
@@ -473,16 +488,15 @@ class ABIRegistry(Copyable, BaseRegistry):
473
488
  self.unregister_encoder(label)
474
489
  self.unregister_decoder(label)
475
490
 
476
- def _get_encoder_uncached(self, type_str: TypeStr): # type: ignore [no-untyped-def]
491
+ def _get_encoder_uncached(self, type_str: TypeStr) -> Encoder:
477
492
  return self._get_registration(self._encoders, type_str)
478
493
 
479
494
  def _get_tuple_encoder_uncached(
480
- self,
495
+ self,
481
496
  *type_strs: TypeStr,
482
497
  ) -> encoding.TupleEncoder:
483
- return encoding.TupleEncoder(
484
- encoders=tuple(self.get_encoder(type_str) for type_str in type_strs)
485
- )
498
+ encoders = tuple(map(self.get_encoder, type_strs))
499
+ return encoding.TupleEncoder(encoders=encoders)
486
500
 
487
501
  def has_encoder(self, type_str: TypeStr) -> bool:
488
502
  """
@@ -500,7 +514,7 @@ class ABIRegistry(Copyable, BaseRegistry):
500
514
 
501
515
  return True
502
516
 
503
- def _get_decoder_uncached(self, type_str: TypeStr, strict: bool = True): # type: ignore [no-untyped-def]
517
+ def _get_decoder_uncached(self, type_str: TypeStr, strict: bool = True) -> Decoder:
504
518
  decoder = self._get_registration(self._decoders, type_str)
505
519
 
506
520
  if hasattr(decoder, "is_dynamic") and decoder.is_dynamic:
@@ -512,15 +526,17 @@ class ABIRegistry(Copyable, BaseRegistry):
512
526
  return decoder
513
527
 
514
528
  def _get_tuple_decoder_uncached(
515
- self,
516
- *type_strs: TypeStr,
529
+ self,
530
+ *type_strs: TypeStr,
517
531
  strict: bool = True,
518
532
  ) -> decoding.TupleDecoder:
519
- return decoding.TupleDecoder(
520
- decoders=tuple(self.get_decoder(type_str, strict) for type_str in type_strs)
533
+ decoders = tuple(
534
+ self.get_decoder(type_str, strict) # type: ignore [misc]
535
+ for type_str in type_strs
521
536
  )
537
+ return decoding.TupleDecoder(decoders=decoders)
522
538
 
523
- def copy(self):
539
+ def copy(self) -> Self:
524
540
  """
525
541
  Copies a registry such that new registrations can be made or existing
526
542
  registrations can be unregistered without affecting any instance from
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: faster_eth_abi
3
- Version: 5.2.13
3
+ Version: 5.2.14
4
4
  Summary: A faster fork of eth_abi: Python utilities for working with Ethereum ABI definitions, especially encoding and decoding. Implemented in C.
5
5
  Home-page: https://github.com/BobTheBuidler/faster-eth-abi
6
6
  Author: The Ethereum Foundation
@@ -1,45 +1,50 @@
1
- faster_eth_abi__mypyc.cpython-39-darwin.so,sha256=huSn2poUCKwNvXlGWy9_NU_XRQapup6p6Xmg6kfKQO0,631912
2
- faster_eth_abi/_encoding.py,sha256=nBIqwHbvT7loTmiYlcl7Z8HhnOGEY-jr-cpCZEU-1X8,3230
1
+ faster_eth_abi__mypyc.cpython-39-darwin.so,sha256=KT3djdqKL3NjeRzGQ6vCBLrqUWLbWAlhUdgJUEARcWo,695112
2
+ faster_eth_abi/_encoding.py,sha256=n3POAR1IAjQObaDTY_GyqgQPwmTIC2CT7VuAf5vBvyg,8540
3
3
  faster_eth_abi/packed.py,sha256=qDPBjish_0h26O7xGWopnlD4pRkphFuFq4izgIqT600,301
4
- faster_eth_abi/encoding.py,sha256=lH6t_8rokfmg8M4JBjmIO3a3l9jGu_rbwoskb0PcH7M,19009
5
- faster_eth_abi/registry.py,sha256=RqHQNDLzvQ6embdnOSxlpvPw7dn-jqUU9MshLe5JuuM,21082
4
+ faster_eth_abi/encoding.py,sha256=3-MNnZ7PUNZXUbu-HrmM_PDSVfAEZcdmrbMu8GHqYMQ,19685
5
+ faster_eth_abi/registry.py,sha256=HmspZBvwUrkeVjecCOQJUjXkYP5aDAGbkCx1CzASppk,21554
6
6
  faster_eth_abi/_decoding.py,sha256=WbFy1GxPYGHduUNCjiTz4gLbNuDffbbJ6MFujjINTpw,9613
7
- faster_eth_abi/_codec.cpython-39-darwin.so,sha256=n6UP7b7L-r4o2rHJUH_O6pUzQlJvYxGSa7ADxicd0Yo,50632
7
+ faster_eth_abi/_codec.cpython-39-darwin.so,sha256=8eRdMo_ZID0pRdeURhGN0WQuzIntPk0dzO79zzHXo9c,50632
8
8
  faster_eth_abi/constants.py,sha256=uJbuND1rFs_Pexuz58TKd-BJPuoA6hLqFEX6kkDS-dE,107
9
9
  faster_eth_abi/io.py,sha256=PjOnBChWh_-6ADkpJQONnxHVwsAfC_4bRiT6YQhlP6c,3728
10
10
  faster_eth_abi/__init__.py,sha256=55jGpiVbsTGNu-c_rr-wwyH3eqEv9MELSTWa4AMiKvU,205
11
11
  faster_eth_abi/_grammar.py,sha256=6REsztEP6kJvWSB3DoLRGbl1whc-pLj5aEWrT6GxaN0,10142
12
- faster_eth_abi/packed.cpython-39-darwin.so,sha256=awzvwPh1-gUMkxyQNxfpV0KRtJ7VEQstFKWab_ZeXW4,50632
13
- faster_eth_abi/abi.cpython-39-darwin.so,sha256=UifpiNfv7uBdba-5lcnEqfrT8Ui54NzUqKfENo5wZDs,50632
14
- faster_eth_abi/from_type_str.cpython-39-darwin.so,sha256=00S5OAB9wOTIJEE97odFF4XCqan5ukT4t8LllE8ev-M,50672
15
- faster_eth_abi/decoding.py,sha256=MYddNAyi3cUKnkV0KYSvff8SeJe3oXaw0GH--iujLzY,15350
12
+ faster_eth_abi/packed.cpython-39-darwin.so,sha256=tEBrqs9ApOVDDHGFGRKwawrugpdO-2ZQ-85WuZa-0QY,50632
13
+ faster_eth_abi/abi.cpython-39-darwin.so,sha256=mOh5DejFuGgItVILGDW9aniDqaNCo0a0mqkFfCZHDEg,50632
14
+ faster_eth_abi/from_type_str.cpython-39-darwin.so,sha256=HmUhCENW1owjS8fT6QFVM7IF_NzqjXKHWcuHsFo9NwQ,50672
15
+ faster_eth_abi/decoding.py,sha256=vBrGAol7NC_7iA3j4V_rwtLwo2hzK1b60-o559iuHls,16227
16
16
  faster_eth_abi/grammar.py,sha256=JJ7QLGJVKmoWwx3J8O-5snrza-Si4NdCweUummqzjlo,4511
17
- faster_eth_abi/_encoding.cpython-39-darwin.so,sha256=1yj5Paf90_G2srbVrhXt0QfeV5QKjmNyEGAHCxxCJAk,50656
17
+ faster_eth_abi/_encoding.cpython-39-darwin.so,sha256=rKbIpCR3AQrmSMehIHwWL3LhpwvsmbLn6f_oDlzcp7s,50656
18
18
  faster_eth_abi/from_type_str.py,sha256=C3QNACXS-5lTtOx1kNAqfZLvky37wV7gqY3Cf9QoEkk,4337
19
- faster_eth_abi/_grammar.cpython-39-darwin.so,sha256=F5q3iL_0AiLwu_Awz500meyowy-3RkG5o1rhfSYC7Ps,50656
20
- faster_eth_abi/constants.cpython-39-darwin.so,sha256=uUPbIbif0ciYwLRn0jlhV1aQ9VaUbSdxKlRo4yX0du8,50656
19
+ faster_eth_abi/_grammar.cpython-39-darwin.so,sha256=SIPhwYnBJlF8oCd-F8UO0O9h6SegSCDvi-hi0ILrGb0,50656
20
+ faster_eth_abi/constants.cpython-39-darwin.so,sha256=lKGj90TMS7t0bvNBvIkFopD4vjiRq_Y1JB-ENP9xLe4,50656
21
21
  faster_eth_abi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  faster_eth_abi/abi.py,sha256=HzkXy0EjHraNbbC5l-EhVqVcx5vy8tcykiKIO4Fp1xw,366
23
23
  faster_eth_abi/exceptions.py,sha256=pbwvH_WeAlSlwqA8w79e_RCt8_uaasLcGtRY7yT9LTQ,3577
24
- faster_eth_abi/_codec.py,sha256=7TfO2ij2jBuUK54LuMdhC0YX8NEui3rnN2ZG1NnP3dA,2264
24
+ faster_eth_abi/_codec.py,sha256=qcK1Mfy_6tO48srobl-WyBBIkEFzwpMQrdGQ8H5TH-o,2271
25
25
  faster_eth_abi/codec.py,sha256=2CtGd3SdNCF5mLqTrZ2FpMAyBtFt83IGu81T--Gevyc,4415
26
26
  faster_eth_abi/base.py,sha256=eMpUM78FhJg5wHPj6glvJRpS1AmvQ_1ks9ENwyu68hc,1188
27
- faster_eth_abi/_decoding.cpython-39-darwin.so,sha256=BaIl-55QMZXW4iZfk6AZ-F7yPpQ9VlXnicy68VugdhM,50656
27
+ faster_eth_abi/_decoding.cpython-39-darwin.so,sha256=rm-FvOJjertsekewwmTW14XDt315mQCnZt5EpeN9IZA,50656
28
28
  faster_eth_abi/tools/_strategies.py,sha256=XQhK8eG87W7LB5v6ibzEAB0BkhTr-oc7dIzPvZu6AE0,6089
29
29
  faster_eth_abi/tools/__init__.py,sha256=trtATEmgu4ctg04qkejbODDzvDSofgcVJ3rkzMP_hQE,51
30
- faster_eth_abi/tools/__init__.cpython-39-darwin.so,sha256=-hdvztdSxmImzuCqb9GFGJmlNypl4Iu3NmqdoBeDfrM,50640
31
- faster_eth_abi/tools/_strategies.cpython-39-darwin.so,sha256=QoxWn3vAQC_sO2agLJ7npCuMqPI4rB9N7hIX_PA9zpc,50672
30
+ faster_eth_abi/tools/__init__.cpython-39-darwin.so,sha256=ToJaEIptQwzDFE_BnbVIHlKz4omS66Xa5heYIxjib7g,50640
31
+ faster_eth_abi/tools/_strategies.cpython-39-darwin.so,sha256=-NwvUYXHBxsor0sklAvyeoC6-Eok-9dAi6itP4ruIfc,50672
32
32
  faster_eth_abi/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- faster_eth_abi/utils/validation.cpython-39-darwin.so,sha256=CM6WNz5aHKoIHKKMK0uoOSMvg9PWJNluyZ-r8n5ofrw,50672
34
- faster_eth_abi/utils/__init__.cpython-39-darwin.so,sha256=jm_0szKPmWh3dB1H-WtdT_rUmxwa1ZTL2Gd2MeB0Vts,50640
35
- faster_eth_abi/utils/string.cpython-39-darwin.so,sha256=tUsM_c9VMqAut2vctoZuiXOgxGSbCJj3Qw1FlfNP5Yo,50648
36
- faster_eth_abi/utils/numeric.cpython-39-darwin.so,sha256=zV1-9ViLK3mZ8QFULItxn1hyHgrLt4BRzjH04eGdt5U,50656
33
+ faster_eth_abi/utils/validation.cpython-39-darwin.so,sha256=XBgELw1ZWFb4uQi6GxEOnHOzjLdpItqyryY_xajhY2g,50672
34
+ faster_eth_abi/utils/__init__.cpython-39-darwin.so,sha256=1LPf4NdcGOrgU2cqJYejOeanhejnkqI2T66-75kBXQU,50640
35
+ faster_eth_abi/utils/string.cpython-39-darwin.so,sha256=epvySWV16R1QdMZiEPowGrLYH8hDBWYhKeTLjL2a760,50648
36
+ faster_eth_abi/utils/numeric.cpython-39-darwin.so,sha256=K92jVUL9PZvTaWojLRXrpMqwqM9mOQ2RAtHm7BsR6_4,50656
37
37
  faster_eth_abi/utils/numeric.py,sha256=fkdazLcgd7FN0JGSSyb6Jsx555QdgRf2N0mxrm6rGB4,3278
38
38
  faster_eth_abi/utils/string.py,sha256=fjsAR2C7Xlu5bHomxx5l4rlADFtByzGTQfugMTo8TQk,436
39
- faster_eth_abi/utils/padding.cpython-39-darwin.so,sha256=-Tk67l5wbblUsidEEqj9KQIQ2M26AAugQ27oPmolkFI,50656
39
+ faster_eth_abi/utils/padding.cpython-39-darwin.so,sha256=QO_41oapDBTN72vc5C340TPUQFJvYFx4bCE_4iDL6vw,50656
40
40
  faster_eth_abi/utils/padding.py,sha256=JBuFhdrvKWLrmmJBZ-a6pqbHWydAuiUBt2aBjCwVcVE,493
41
41
  faster_eth_abi/utils/validation.py,sha256=NA2wRacYEBdkpQnZfmeDvzF-sHyy6NT2QzCFuBnYJVI,521
42
- benchmarks/test_registry_benchmarks.py,sha256=76bFMgx0o4YxWfMszWJdmancPtywNJBN38nehhXeMRM,1216
42
+ faster_eth_abi-5.2.14.dist-info/RECORD,,
43
+ faster_eth_abi-5.2.14.dist-info/WHEEL,sha256=bDWaFWigpG5bEpqw9IoRiyYs8MvmSFh0OhUAOoi_-KA,134
44
+ faster_eth_abi-5.2.14.dist-info/top_level.txt,sha256=z3gorxabz8D2eg5A3YX2M3p3JMFRLLX3DRp0jAwNZOY,48
45
+ faster_eth_abi-5.2.14.dist-info/METADATA,sha256=9Y3LCTA4ytM8PUoj2EoYJ1QTfGfyli9EY-HQCu2ugx8,6978
46
+ faster_eth_abi-5.2.14.dist-info/licenses/LICENSE,sha256=P_zrhVa0OXK-_XuA0RF3d3gwMLXRSBkn2fWraC4CFLo,1106
47
+ benchmarks/test_registry_benchmarks.py,sha256=RQTkFsOk9pIDPd84bZqm3mfBuKSYhuQCCmSblYDzFOE,1262
43
48
  benchmarks/type_strings.py,sha256=tC12IvA5TbJFQDvydi1lCxnCHUxWurBW69xLG9Xjywc,566
44
49
  benchmarks/batch.py,sha256=8MkG1hAxZerEnPTtrESUAWXB6C-iNnCMQ5yJMz3HDIM,199
45
50
  benchmarks/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
@@ -50,8 +55,3 @@ benchmarks/test_io_benchmarks.py,sha256=SkBGL0FijyVefSlL1VTQIaD1b2oruWjdo6WAck8r
50
55
  benchmarks/test_encoding_benchmarks.py,sha256=sfVncm7BGIV0k_byD8HCjuwc8oGx4-KLnx8Jk8_9uD0,3212
51
56
  benchmarks/data.py,sha256=YeU6gxSF2_XFVnwy7N2CuEiqiS8AFrc4ZQ4B3Z0HRw4,9205
52
57
  benchmarks/test_decoding_benchmarks.py,sha256=MVZ4lN1V8OTvO-957joBBOgkHnsfSghF3d_GiBeEh1E,3904
53
- faster_eth_abi-5.2.13.dist-info/RECORD,,
54
- faster_eth_abi-5.2.13.dist-info/WHEEL,sha256=bDWaFWigpG5bEpqw9IoRiyYs8MvmSFh0OhUAOoi_-KA,134
55
- faster_eth_abi-5.2.13.dist-info/top_level.txt,sha256=z3gorxabz8D2eg5A3YX2M3p3JMFRLLX3DRp0jAwNZOY,48
56
- faster_eth_abi-5.2.13.dist-info/METADATA,sha256=xmxMq_V5kqGXUFQQWEQB33b7JhiezKLg--TTfjkK60s,6978
57
- faster_eth_abi-5.2.13.dist-info/licenses/LICENSE,sha256=P_zrhVa0OXK-_XuA0RF3d3gwMLXRSBkn2fWraC4CFLo,1106
Binary file