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,17 +1,35 @@
1
+ """Registry and predicate logic for ABI encoders and decoders.
2
+
3
+ Implements registration, lookup, and matching of encoders and decoders for ABI type strings.
4
+ """
1
5
  import abc
2
- import copy
6
+ from copy import (
7
+ copy,
8
+ )
3
9
  import functools
4
10
  from typing import (
5
11
  Any,
6
12
  Callable,
13
+ Dict,
14
+ Final,
15
+ Generic,
16
+ Iterator,
7
17
  Optional,
8
18
  Type,
19
+ TypeVar,
9
20
  Union,
21
+ cast,
22
+ final,
10
23
  )
11
24
 
12
25
  from eth_typing import (
13
26
  TypeStr,
14
27
  )
28
+ from typing_extensions import (
29
+ Concatenate,
30
+ ParamSpec,
31
+ Self,
32
+ )
15
33
 
16
34
  from . import (
17
35
  decoding,
@@ -30,6 +48,9 @@ from .io import (
30
48
  ContextFramesBytesIO,
31
49
  )
32
50
 
51
+ T = TypeVar("T")
52
+ P = ParamSpec("P")
53
+
33
54
  Lookup = Union[TypeStr, Callable[[TypeStr], bool]]
34
55
 
35
56
  EncoderCallable = Callable[[Any], bytes]
@@ -41,44 +62,45 @@ Decoder = Union[DecoderCallable, Type[decoding.BaseDecoder]]
41
62
 
42
63
  class Copyable(abc.ABC):
43
64
  @abc.abstractmethod
44
- def copy(self):
65
+ def copy(self) -> Self:
45
66
  pass
46
67
 
47
- def __copy__(self):
68
+ def __copy__(self) -> Self:
48
69
  return self.copy()
49
70
 
50
- def __deepcopy__(self, *args):
71
+ def __deepcopy__(self, *args: Any) -> Self:
51
72
  return self.copy()
52
73
 
53
74
 
54
- class PredicateMapping(Copyable):
75
+ class PredicateMapping(Copyable, Generic[T]):
55
76
  """
56
77
  Acts as a mapping from predicate functions to values. Values are retrieved
57
78
  when their corresponding predicate matches a given input. Predicates can
58
79
  also be labeled to facilitate removal from the mapping.
59
80
  """
60
81
 
61
- def __init__(self, name):
62
- self._name = name
63
- self._values = {}
64
- self._labeled_predicates = {}
82
+ def __init__(self, name: str):
83
+ self._name: Final = name
84
+ self._values: Dict[Lookup, T] = {}
85
+ self._labeled_predicates: Dict[str, Lookup] = {}
65
86
 
66
- def add(self, predicate, value, label=None):
87
+ def add(self, predicate: Lookup, value: T, label: Optional[str] = None) -> None:
67
88
  if predicate in self._values:
68
89
  raise ValueError(f"Matcher {predicate!r} already exists in {self._name}")
69
90
 
70
91
  if label is not None:
71
- if label in self._labeled_predicates:
92
+ labeled_predicates = self._labeled_predicates
93
+ if label in labeled_predicates:
72
94
  raise ValueError(
73
95
  f"Matcher {predicate!r} with label '{label}' "
74
96
  f"already exists in {self._name}"
75
97
  )
76
98
 
77
- self._labeled_predicates[label] = predicate
99
+ labeled_predicates[label] = predicate
78
100
 
79
101
  self._values[predicate] = value
80
102
 
81
- def find(self, type_str):
103
+ def find(self, type_str: TypeStr) -> T:
82
104
  results = tuple(
83
105
  (predicate, value)
84
106
  for predicate, value in self._values.items()
@@ -103,9 +125,9 @@ class PredicateMapping(Copyable):
103
125
  "documentation for more information."
104
126
  )
105
127
 
106
- return values[0]
128
+ return values[0] # type: ignore [no-any-return]
107
129
 
108
- def remove_by_equality(self, predicate):
130
+ def remove_by_equality(self, predicate: Lookup) -> None:
109
131
  # Delete the predicate mapping to the previously stored value
110
132
  try:
111
133
  del self._values[predicate]
@@ -120,7 +142,7 @@ class PredicateMapping(Copyable):
120
142
  else:
121
143
  del self._labeled_predicates[label]
122
144
 
123
- def _label_for_predicate(self, predicate):
145
+ def _label_for_predicate(self, predicate: Lookup) -> str:
124
146
  # Both keys and values in `_labeled_predicates` are unique since the
125
147
  # `add` method enforces this
126
148
  for key, value in self._labeled_predicates.items():
@@ -131,16 +153,17 @@ class PredicateMapping(Copyable):
131
153
  f"Matcher {predicate!r} not referred to by any label in {self._name}"
132
154
  )
133
155
 
134
- def remove_by_label(self, label):
156
+ def remove_by_label(self, label: str) -> None:
157
+ labeled_predicates = self._labeled_predicates
135
158
  try:
136
- predicate = self._labeled_predicates[label]
159
+ predicate = labeled_predicates[label]
137
160
  except KeyError:
138
161
  raise KeyError(f"Label '{label}' not found in {self._name}")
139
162
 
140
- del self._labeled_predicates[label]
163
+ del labeled_predicates[label]
141
164
  del self._values[predicate]
142
165
 
143
- def remove(self, predicate_or_label):
166
+ def remove(self, predicate_or_label: Union[Lookup, str]) -> None:
144
167
  if callable(predicate_or_label):
145
168
  self.remove_by_equality(predicate_or_label)
146
169
  elif isinstance(predicate_or_label, str):
@@ -151,61 +174,79 @@ class PredicateMapping(Copyable):
151
174
  f"{type(predicate_or_label)}"
152
175
  )
153
176
 
154
- def copy(self):
177
+ def copy(self) -> Self:
155
178
  cpy = type(self)(self._name)
156
179
 
157
- cpy._values = copy.copy(self._values)
158
- cpy._labeled_predicates = copy.copy(self._labeled_predicates)
180
+ cpy._values = copy(self._values)
181
+ cpy._labeled_predicates = copy(self._labeled_predicates)
159
182
 
160
183
  return cpy
161
184
 
162
185
 
163
- class Predicate:
186
+ class Predicate(Generic[T]):
164
187
  """
165
188
  Represents a predicate function to be used for type matching in
166
189
  ``ABIRegistry``.
167
190
  """
168
191
 
169
- __slots__ = tuple()
192
+ __slots__ = ("_string", "__hash")
193
+
194
+ _string: Optional[str]
195
+
196
+ def __init__(self) -> None:
197
+ self._string = None
198
+ self.__hash = None
170
199
 
171
- def __call__(self, *args, **kwargs): # pragma: no cover
200
+ def __call__(self, arg: TypeStr) -> None:
172
201
  raise NotImplementedError("Must implement `__call__`")
173
202
 
174
- def __str__(self): # pragma: no cover
203
+ def __str__(self) -> str:
175
204
  raise NotImplementedError("Must implement `__str__`")
176
205
 
177
- def __repr__(self):
206
+ def __repr__(self) -> str:
178
207
  return f"<{type(self).__name__} {self}>"
179
208
 
180
- def __iter__(self):
181
- for attr in self.__slots__:
182
- yield getattr(self, attr)
209
+ def __iter__(self) -> Iterator[T]:
210
+ raise NotImplementedError("must be implemented by subclass")
183
211
 
184
- def __hash__(self):
185
- return hash(tuple(self))
212
+ def __hash__(self) -> int:
213
+ hashval = self.__hash
214
+ if hashval is None:
215
+ self.__hash = hashval = hash(tuple(self))
216
+ return hashval
186
217
 
187
- def __eq__(self, other):
218
+ def __eq__(self, other: "Predicate") -> bool:
188
219
  return type(self) is type(other) and tuple(self) == tuple(other)
189
220
 
190
221
 
191
- class Equals(Predicate):
222
+ @final
223
+ class Equals(Predicate[str]):
192
224
  """
193
225
  A predicate that matches any input equal to `value`.
194
226
  """
195
227
 
196
228
  __slots__ = ("value",)
197
229
 
198
- def __init__(self, value):
199
- self.value = value
230
+ def __init__(self, value: str) -> None:
231
+ super().__init__()
232
+ self.value: Final = value
200
233
 
201
- def __call__(self, other):
234
+ def __call__(self, other: TypeStr) -> bool:
202
235
  return self.value == other
203
236
 
204
- def __str__(self):
205
- return f"(== {self.value!r})"
237
+ def __str__(self) -> str:
238
+ # NOTE should this just be done at init time? is it always called?
239
+ string = self._string
240
+ if string is None:
241
+ self._string = string = f"(== {self.value!r})"
242
+ return string
206
243
 
244
+ def __iter__(self) -> Iterator[str]:
245
+ yield self.value
207
246
 
208
- class BaseEquals(Predicate):
247
+
248
+ @final
249
+ class BaseEquals(Predicate[Union[str, bool, None]]):
209
250
  """
210
251
  A predicate that matches a basic type string with a base component equal to
211
252
  `value` and no array component. If `with_sub` is `True`, the type string
@@ -216,11 +257,12 @@ class BaseEquals(Predicate):
216
257
 
217
258
  __slots__ = ("base", "with_sub")
218
259
 
219
- def __init__(self, base, *, with_sub=None):
220
- self.base = base
221
- self.with_sub = with_sub
260
+ def __init__(self, base: TypeStr, *, with_sub: Optional[bool] = None):
261
+ super().__init__()
262
+ self.base: Final = base
263
+ self.with_sub: Final = with_sub
222
264
 
223
- def __call__(self, type_str):
265
+ def __call__(self, type_str: TypeStr) -> bool:
224
266
  try:
225
267
  abi_type = grammar.parse(type_str)
226
268
  except (exceptions.ParseError, ValueError):
@@ -230,10 +272,12 @@ class BaseEquals(Predicate):
230
272
  if abi_type.arrlist is not None:
231
273
  return False
232
274
 
233
- if self.with_sub is not None:
234
- if self.with_sub and abi_type.sub is None:
275
+ with_sub = self.with_sub
276
+ if with_sub is not None:
277
+ abi_subtype = abi_type.sub
278
+ if with_sub and abi_subtype is None:
235
279
  return False
236
- if not self.with_sub and abi_type.sub is not None:
280
+ if not with_sub and abi_subtype is not None:
237
281
  return False
238
282
 
239
283
  return abi_type.base == self.base
@@ -242,19 +286,25 @@ class BaseEquals(Predicate):
242
286
  # e.g. if it contained a tuple type
243
287
  return False
244
288
 
245
- def __str__(self):
246
- return (
247
- f"(base == {self.base!r}"
248
- + (
249
- ""
250
- if self.with_sub is None
251
- else (" and sub is not None" if self.with_sub else " and sub is None")
252
- )
253
- + ")"
254
- )
255
-
256
-
257
- def has_arrlist(type_str):
289
+ def __str__(self) -> str:
290
+ # NOTE should this just be done at init time? is it always called?
291
+ string = self._string
292
+ if string is None:
293
+ if self.with_sub is None:
294
+ string = f"(base == {self.base!r})"
295
+ elif self.with_sub:
296
+ string = f"(base == {self.base!r} and sub is not None)"
297
+ else:
298
+ string = f"(base == {self.base!r} and sub is None)"
299
+ self._string = string
300
+ return string
301
+
302
+ def __iter__(self) -> Iterator[Union[str, bool, None]]:
303
+ yield self.base
304
+ yield self.with_sub
305
+
306
+
307
+ def has_arrlist(type_str: TypeStr) -> bool:
258
308
  """
259
309
  A predicate that matches a type string with an array dimension list.
260
310
  """
@@ -266,7 +316,7 @@ def has_arrlist(type_str):
266
316
  return abi_type.arrlist is not None
267
317
 
268
318
 
269
- def is_base_tuple(type_str):
319
+ def is_base_tuple(type_str: TypeStr) -> bool:
270
320
  """
271
321
  A predicate that matches a tuple type with no array dimension list.
272
322
  """
@@ -278,19 +328,25 @@ def is_base_tuple(type_str):
278
328
  return isinstance(abi_type, grammar.TupleType) and abi_type.arrlist is None
279
329
 
280
330
 
281
- def _clear_encoder_cache(old_method: Callable[..., None]) -> Callable[..., None]:
331
+ def _clear_encoder_cache(
332
+ old_method: Callable[Concatenate["ABIRegistry", P], T]
333
+ ) -> Callable[Concatenate["ABIRegistry", P], T]:
282
334
  @functools.wraps(old_method)
283
- def new_method(self: "ABIRegistry", *args: Any, **kwargs: Any) -> None:
335
+ def new_method(self: "ABIRegistry", *args: P.args, **kwargs: P.kwargs) -> T:
284
336
  self.get_encoder.cache_clear()
337
+ self.get_tuple_encoder.cache_clear()
285
338
  return old_method(self, *args, **kwargs)
286
339
 
287
340
  return new_method
288
341
 
289
342
 
290
- def _clear_decoder_cache(old_method: Callable[..., None]) -> Callable[..., None]:
343
+ def _clear_decoder_cache(
344
+ old_method: Callable[Concatenate["ABIRegistry", P], T]
345
+ ) -> Callable[Concatenate["ABIRegistry", P], T]:
291
346
  @functools.wraps(old_method)
292
- def new_method(self: "ABIRegistry", *args: Any, **kwargs: Any) -> None:
347
+ def new_method(self: "ABIRegistry", *args: P.args, **kwargs: P.kwargs) -> T:
293
348
  self.get_decoder.cache_clear()
349
+ self.get_tuple_decoder.cache_clear()
294
350
  return old_method(self, *args, **kwargs)
295
351
 
296
352
  return new_method
@@ -298,7 +354,12 @@ def _clear_decoder_cache(old_method: Callable[..., None]) -> Callable[..., None]
298
354
 
299
355
  class BaseRegistry:
300
356
  @staticmethod
301
- def _register(mapping, lookup, value, label=None):
357
+ def _register(
358
+ mapping: PredicateMapping[T],
359
+ lookup: Lookup,
360
+ value: T,
361
+ label: Optional[str] = None,
362
+ ) -> None:
302
363
  if callable(lookup):
303
364
  mapping.add(lookup, value, label)
304
365
  return
@@ -312,7 +373,7 @@ class BaseRegistry:
312
373
  )
313
374
 
314
375
  @staticmethod
315
- def _unregister(mapping, lookup_or_label):
376
+ def _unregister(mapping: PredicateMapping[Any], lookup_or_label: Lookup) -> None:
316
377
  if callable(lookup_or_label):
317
378
  mapping.remove_by_equality(lookup_or_label)
318
379
  return
@@ -327,7 +388,7 @@ class BaseRegistry:
327
388
  )
328
389
 
329
390
  @staticmethod
330
- def _get_registration(mapping, type_str):
391
+ def _get_registration(mapping: PredicateMapping[T], type_str: TypeStr) -> T:
331
392
  try:
332
393
  value = mapping.find(type_str)
333
394
  except ValueError as e:
@@ -342,19 +403,25 @@ class BaseRegistry:
342
403
 
343
404
 
344
405
  class ABIRegistry(Copyable, BaseRegistry):
345
- def __init__(self):
346
- self._encoders = PredicateMapping("encoder registry")
347
- self._decoders = PredicateMapping("decoder registry")
406
+ def __init__(self) -> None:
407
+ self._encoders: PredicateMapping[Encoder] = PredicateMapping("encoder registry")
408
+ self._decoders: PredicateMapping[Decoder] = PredicateMapping("decoder registry")
348
409
  self.get_encoder = functools.lru_cache(maxsize=None)(self._get_encoder_uncached)
349
410
  self.get_decoder = functools.lru_cache(maxsize=None)(self._get_decoder_uncached)
411
+ self.get_tuple_encoder = functools.lru_cache(maxsize=None)(
412
+ self._get_tuple_encoder_uncached
413
+ )
414
+ self.get_tuple_decoder = functools.lru_cache(maxsize=None)(
415
+ self._get_tuple_decoder_uncached
416
+ )
350
417
 
351
- def _get_registration(self, mapping, type_str):
418
+ def _get_registration(self, mapping: PredicateMapping[T], type_str: TypeStr) -> T:
352
419
  coder = super()._get_registration(mapping, type_str)
353
420
 
354
421
  if isinstance(coder, type) and issubclass(coder, BaseCoder):
355
422
  return coder.from_type_str(type_str, self)
356
423
 
357
- return coder
424
+ return cast(T, coder)
358
425
 
359
426
  @_clear_encoder_cache
360
427
  def register_encoder(
@@ -454,9 +521,16 @@ class ABIRegistry(Copyable, BaseRegistry):
454
521
  self.unregister_encoder(label)
455
522
  self.unregister_decoder(label)
456
523
 
457
- def _get_encoder_uncached(self, type_str):
524
+ def _get_encoder_uncached(self, type_str: TypeStr) -> Encoder:
458
525
  return self._get_registration(self._encoders, type_str)
459
526
 
527
+ def _get_tuple_encoder_uncached(
528
+ self,
529
+ *type_strs: TypeStr,
530
+ ) -> encoding.TupleEncoder:
531
+ encoders = tuple(map(self.get_encoder, type_strs))
532
+ return encoding.TupleEncoder(encoders=encoders)
533
+
460
534
  def has_encoder(self, type_str: TypeStr) -> bool:
461
535
  """
462
536
  Returns ``True`` if an encoder is found for the given type string
@@ -473,7 +547,7 @@ class ABIRegistry(Copyable, BaseRegistry):
473
547
 
474
548
  return True
475
549
 
476
- def _get_decoder_uncached(self, type_str, strict=True):
550
+ def _get_decoder_uncached(self, type_str: TypeStr, strict: bool = True) -> Decoder:
477
551
  decoder = self._get_registration(self._decoders, type_str)
478
552
 
479
553
  if hasattr(decoder, "is_dynamic") and decoder.is_dynamic:
@@ -484,7 +558,18 @@ class ABIRegistry(Copyable, BaseRegistry):
484
558
 
485
559
  return decoder
486
560
 
487
- def copy(self):
561
+ def _get_tuple_decoder_uncached(
562
+ self,
563
+ *type_strs: TypeStr,
564
+ strict: bool = True,
565
+ ) -> decoding.TupleDecoder:
566
+ decoders = tuple(
567
+ self.get_decoder(type_str, strict)
568
+ for type_str in type_strs
569
+ )
570
+ return decoding.TupleDecoder(decoders=decoders)
571
+
572
+ def copy(self) -> Self:
488
573
  """
489
574
  Copies a registry such that new registrations can be made or existing
490
575
  registrations can be unregistered without affecting any instance from
@@ -495,22 +580,43 @@ class ABIRegistry(Copyable, BaseRegistry):
495
580
  """
496
581
  cpy = type(self)()
497
582
 
498
- cpy._encoders = copy.copy(self._encoders)
499
- cpy._decoders = copy.copy(self._decoders)
583
+ cpy._encoders = copy(self._encoders)
584
+ cpy._decoders = copy(self._decoders)
500
585
 
501
586
  return cpy
502
587
 
503
588
 
504
589
  registry = ABIRegistry()
505
590
 
591
+ is_int = BaseEquals("int")
592
+ is_int8 = Equals("int8")
593
+ is_int16 = Equals("int16")
594
+ is_uint = BaseEquals("uint")
595
+ is_uint8 = Equals("uint8")
596
+ is_uint16 = Equals("uint16")
597
+
598
+ for size in (8, 16):
599
+ registry.register(
600
+ Equals(f"uint{size}"),
601
+ encoding.UnsignedIntegerEncoder,
602
+ decoding.UnsignedIntegerDecoder,
603
+ label=f"uint{size}",
604
+ )
605
+ registry.register(
606
+ Equals(f"int{size}"),
607
+ encoding.SignedIntegerEncoder,
608
+ decoding.SignedIntegerDecoder,
609
+ label=f"int{size}",
610
+ )
611
+
506
612
  registry.register(
507
- BaseEquals("uint"),
613
+ lambda s: is_uint(s) and not is_uint8(s) and not is_uint16(s),
508
614
  encoding.UnsignedIntegerEncoder,
509
615
  decoding.UnsignedIntegerDecoder,
510
616
  label="uint",
511
617
  )
512
618
  registry.register(
513
- BaseEquals("int"),
619
+ lambda s: is_int(s) and not is_int8(s) and not is_int16(s),
514
620
  encoding.SignedIntegerEncoder,
515
621
  decoding.SignedIntegerDecoder,
516
622
  label="int",
@@ -578,13 +684,25 @@ registry.register(
578
684
 
579
685
  registry_packed = ABIRegistry()
580
686
 
687
+ for size in (8, 16):
688
+ registry_packed.register_encoder(
689
+ Equals(f"uint{size}"),
690
+ encoding.PackedUnsignedIntegerEncoderCached,
691
+ label=f"uint{size}",
692
+ )
693
+ registry_packed.register_encoder(
694
+ Equals(f"int{size}"),
695
+ encoding.PackedSignedIntegerEncoderCached,
696
+ label=f"int{size}",
697
+ )
698
+
581
699
  registry_packed.register_encoder(
582
- BaseEquals("uint"),
700
+ lambda s: is_uint(s) and not is_uint8(s) and not is_uint16(s),
583
701
  encoding.PackedUnsignedIntegerEncoder,
584
702
  label="uint",
585
703
  )
586
704
  registry_packed.register_encoder(
587
- BaseEquals("int"),
705
+ lambda s: is_int(s) and not is_int8(s) and not is_int16(s),
588
706
  encoding.PackedSignedIntegerEncoder,
589
707
  label="int",
590
708
  )
@@ -2,7 +2,9 @@ from typing import (
2
2
  Callable,
3
3
  Final,
4
4
  Optional,
5
+ Tuple,
5
6
  Union,
7
+ cast,
6
8
  )
7
9
 
8
10
  from cchecksum import (
@@ -15,11 +17,14 @@ from hypothesis import (
15
17
  strategies as st,
16
18
  )
17
19
 
18
- from faster_eth_abi.grammar import (
20
+ from faster_eth_abi._grammar import (
19
21
  ABIType,
22
+ Arrlist,
20
23
  BasicType,
21
24
  TupleType,
22
25
  normalize,
26
+ )
27
+ from faster_eth_abi.grammar import (
23
28
  parse,
24
29
  )
25
30
  from faster_eth_abi.registry import (
@@ -81,7 +86,7 @@ class StrategyRegistry(BaseRegistry):
81
86
  def get_uint_strategy(
82
87
  abi_type: BasicType, registry: StrategyRegistry
83
88
  ) -> st.SearchStrategy:
84
- bits = abi_type.sub
89
+ bits = cast(int, abi_type.sub)
85
90
 
86
91
  return st.integers(
87
92
  min_value=0,
@@ -92,7 +97,7 @@ def get_uint_strategy(
92
97
  def get_int_strategy(
93
98
  abi_type: BasicType, registry: StrategyRegistry
94
99
  ) -> st.SearchStrategy:
95
- bits = abi_type.sub
100
+ bits = cast(int, abi_type.sub)
96
101
 
97
102
  return st.integers(
98
103
  min_value=-(2 ** (bits - 1)),
@@ -107,7 +112,7 @@ bool_strategy: Final = st.booleans()
107
112
  def get_ufixed_strategy(
108
113
  abi_type: BasicType, registry: StrategyRegistry
109
114
  ) -> st.SearchStrategy:
110
- bits, places = abi_type.sub
115
+ bits, places = cast(Tuple[int, int], abi_type.sub)
111
116
 
112
117
  return st.decimals(
113
118
  min_value=0,
@@ -119,7 +124,7 @@ def get_ufixed_strategy(
119
124
  def get_fixed_strategy(
120
125
  abi_type: BasicType, registry: StrategyRegistry
121
126
  ) -> st.SearchStrategy:
122
- bits, places = abi_type.sub
127
+ bits, places = cast(Tuple[int, int], abi_type.sub)
123
128
 
124
129
  return st.decimals(
125
130
  min_value=-(2 ** (bits - 1)),
@@ -150,7 +155,8 @@ def get_array_strategy(
150
155
  item_type_str = item_type.to_type_str()
151
156
  item_strategy = registry.get_strategy(item_type_str)
152
157
 
153
- last_dim = abi_type.arrlist[-1] # type: ignore [index]
158
+ arrlist = cast(Arrlist, abi_type.arrlist)
159
+ last_dim = cast(Tuple[int, ...], arrlist[-1])
154
160
  if len(last_dim) == 0:
155
161
  # Is dynamic list. Don't restrict length.
156
162
  return st.lists(item_strategy)