faster-eth-abi 5.2.15__cp314-cp314t-win32.whl → 5.2.16__cp314-cp314t-win32.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.
- faster_eth_abi/_codec.cp314t-win32.pyd +0 -0
- faster_eth_abi/_codec.py +6 -0
- faster_eth_abi/_decoding.cp314t-win32.pyd +0 -0
- faster_eth_abi/_decoding.py +28 -15
- faster_eth_abi/_encoding.cp314t-win32.pyd +0 -0
- faster_eth_abi/_encoding.py +7 -1
- faster_eth_abi/_grammar.cp314t-win32.pyd +0 -0
- faster_eth_abi/_grammar.py +5 -0
- faster_eth_abi/abi.cp314t-win32.pyd +0 -0
- faster_eth_abi/base.py +4 -0
- faster_eth_abi/codec.py +1261 -144
- faster_eth_abi/constants.cp314t-win32.pyd +0 -0
- faster_eth_abi/decoding.py +91 -47
- faster_eth_abi/encoding.py +51 -3
- faster_eth_abi/exceptions.py +5 -2
- faster_eth_abi/from_type_str.cp314t-win32.pyd +0 -0
- faster_eth_abi/from_type_str.py +4 -0
- faster_eth_abi/grammar.py +17 -19
- faster_eth_abi/io.py +4 -0
- faster_eth_abi/packed.cp314t-win32.pyd +0 -0
- faster_eth_abi/packed.py +4 -0
- faster_eth_abi/registry.py +98 -33
- faster_eth_abi/tools/__init__.cp314t-win32.pyd +0 -0
- faster_eth_abi/tools/_strategies.cp314t-win32.pyd +0 -0
- faster_eth_abi/typing.py +94 -10
- faster_eth_abi/utils/__init__.cp314t-win32.pyd +0 -0
- faster_eth_abi/utils/numeric.cp314t-win32.pyd +0 -0
- faster_eth_abi/utils/padding.cp314t-win32.pyd +0 -0
- faster_eth_abi/utils/string.cp314t-win32.pyd +0 -0
- faster_eth_abi/utils/validation.cp314t-win32.pyd +0 -0
- {faster_eth_abi-5.2.15.dist-info → faster_eth_abi-5.2.16.dist-info}/METADATA +13 -8
- faster_eth_abi-5.2.16.dist-info/RECORD +47 -0
- {faster_eth_abi-5.2.15.dist-info → faster_eth_abi-5.2.16.dist-info}/top_level.txt +0 -1
- faster_eth_abi__mypyc.cp314t-win32.pyd +0 -0
- benchmarks/__init__.py +0 -1
- benchmarks/batch.py +0 -9
- benchmarks/data.py +0 -313
- benchmarks/test_abi_benchmarks.py +0 -82
- benchmarks/test_decoding_benchmarks.py +0 -109
- benchmarks/test_encoding_benchmarks.py +0 -99
- benchmarks/test_grammar_benchmarks.py +0 -38
- benchmarks/test_io_benchmarks.py +0 -99
- benchmarks/test_packed_benchmarks.py +0 -41
- benchmarks/test_registry_benchmarks.py +0 -45
- benchmarks/type_strings.py +0 -26
- faster_eth_abi-5.2.15.dist-info/RECORD +0 -58
- {faster_eth_abi-5.2.15.dist-info → faster_eth_abi-5.2.16.dist-info}/WHEEL +0 -0
- {faster_eth_abi-5.2.15.dist-info → faster_eth_abi-5.2.16.dist-info}/licenses/LICENSE +0 -0
|
Binary file
|
faster_eth_abi/decoding.py
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
"""Classes for ABI decoding logic.
|
|
2
|
+
|
|
3
|
+
Implements classes and functions for deserializing binary data into Python values
|
|
4
|
+
according to ABI type specifications.
|
|
5
|
+
"""
|
|
1
6
|
import abc
|
|
2
7
|
import decimal
|
|
3
8
|
from functools import (
|
|
4
9
|
cached_property,
|
|
10
|
+
lru_cache,
|
|
5
11
|
)
|
|
6
12
|
from types import (
|
|
7
13
|
MethodType,
|
|
@@ -10,12 +16,17 @@ from typing import (
|
|
|
10
16
|
Any,
|
|
11
17
|
Callable,
|
|
12
18
|
Final,
|
|
19
|
+
Generic,
|
|
13
20
|
Optional,
|
|
14
21
|
Tuple,
|
|
22
|
+
TypeVar,
|
|
15
23
|
Union,
|
|
16
24
|
final,
|
|
17
25
|
)
|
|
18
26
|
|
|
27
|
+
from eth_typing import (
|
|
28
|
+
HexAddress,
|
|
29
|
+
)
|
|
19
30
|
from faster_eth_utils import (
|
|
20
31
|
big_endian_to_int,
|
|
21
32
|
to_normalized_address,
|
|
@@ -48,18 +59,19 @@ from faster_eth_abi.from_type_str import (
|
|
|
48
59
|
from faster_eth_abi.io import (
|
|
49
60
|
ContextFramesBytesIO,
|
|
50
61
|
)
|
|
62
|
+
from faster_eth_abi.typing import (
|
|
63
|
+
T,
|
|
64
|
+
)
|
|
51
65
|
from faster_eth_abi.utils.numeric import (
|
|
52
66
|
TEN,
|
|
53
67
|
abi_decimal_context,
|
|
54
68
|
ceil32,
|
|
55
69
|
)
|
|
56
70
|
|
|
57
|
-
|
|
58
|
-
"HeadTailDecoder", "SizedArrayDecoder", "DynamicArrayDecoder", "ByteStringDecoder"
|
|
59
|
-
]
|
|
71
|
+
TByteStr = TypeVar("TByteStr", bytes, str)
|
|
60
72
|
|
|
61
73
|
|
|
62
|
-
class BaseDecoder(BaseCoder, metaclass=abc.ABCMeta):
|
|
74
|
+
class BaseDecoder(BaseCoder, Generic[T], metaclass=abc.ABCMeta):
|
|
63
75
|
"""
|
|
64
76
|
Base class for all decoder classes. Subclass this if you want to define a
|
|
65
77
|
custom decoder class. Subclasses must also implement
|
|
@@ -69,18 +81,18 @@ class BaseDecoder(BaseCoder, metaclass=abc.ABCMeta):
|
|
|
69
81
|
strict = True
|
|
70
82
|
|
|
71
83
|
@abc.abstractmethod
|
|
72
|
-
def decode(self, stream: ContextFramesBytesIO) ->
|
|
84
|
+
def decode(self, stream: ContextFramesBytesIO) -> T: # pragma: no cover
|
|
73
85
|
"""
|
|
74
86
|
Decodes the given stream of bytes into a python value. Should raise
|
|
75
87
|
:any:`exceptions.DecodingError` if a python value cannot be decoded
|
|
76
88
|
from the given byte stream.
|
|
77
89
|
"""
|
|
78
90
|
|
|
79
|
-
def __call__(self, stream: ContextFramesBytesIO) ->
|
|
91
|
+
def __call__(self, stream: ContextFramesBytesIO) -> T:
|
|
80
92
|
return self.decode(stream)
|
|
81
93
|
|
|
82
94
|
|
|
83
|
-
class HeadTailDecoder(BaseDecoder):
|
|
95
|
+
class HeadTailDecoder(BaseDecoder[T]):
|
|
84
96
|
"""
|
|
85
97
|
Decoder for a dynamic element of a dynamic container (a dynamic array, or a sized
|
|
86
98
|
array or tuple that contains dynamic elements). A dynamic element consists of a
|
|
@@ -90,24 +102,33 @@ class HeadTailDecoder(BaseDecoder):
|
|
|
90
102
|
|
|
91
103
|
is_dynamic = True
|
|
92
104
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
105
|
+
def __init__(
|
|
106
|
+
self,
|
|
107
|
+
tail_decoder: Union[ # type: ignore [type-var]
|
|
108
|
+
"HeadTailDecoder[T]",
|
|
109
|
+
"SizedArrayDecoder[T]",
|
|
110
|
+
"DynamicArrayDecoder[T]",
|
|
111
|
+
"ByteStringDecoder[T]",
|
|
112
|
+
],
|
|
113
|
+
**kwargs: Any,
|
|
114
|
+
) -> None:
|
|
115
|
+
super().__init__(**kwargs)
|
|
97
116
|
|
|
98
|
-
if
|
|
117
|
+
if tail_decoder is None:
|
|
99
118
|
raise ValueError("No `tail_decoder` set")
|
|
100
119
|
|
|
101
|
-
|
|
120
|
+
self.tail_decoder: Final = tail_decoder
|
|
121
|
+
|
|
122
|
+
def decode(self, stream: ContextFramesBytesIO) -> T:
|
|
102
123
|
return decode_head_tail(self, stream)
|
|
103
124
|
|
|
104
125
|
__call__ = decode
|
|
105
126
|
|
|
106
127
|
|
|
107
|
-
class TupleDecoder(BaseDecoder):
|
|
108
|
-
decoders: Tuple[BaseDecoder, ...] = ()
|
|
128
|
+
class TupleDecoder(BaseDecoder[Tuple[T, ...]]):
|
|
129
|
+
decoders: Tuple[BaseDecoder[T], ...] = ()
|
|
109
130
|
|
|
110
|
-
def __init__(self, decoders: Tuple[BaseDecoder, ...], **kwargs: Any) -> None:
|
|
131
|
+
def __init__(self, decoders: Tuple[BaseDecoder[T], ...], **kwargs: Any) -> None:
|
|
111
132
|
super().__init__(**kwargs)
|
|
112
133
|
|
|
113
134
|
self.decoders = decoders = tuple(
|
|
@@ -134,7 +155,7 @@ class TupleDecoder(BaseDecoder):
|
|
|
134
155
|
def validate_pointers(self, stream: ContextFramesBytesIO) -> None:
|
|
135
156
|
raise NotImplementedError("didnt call __init__")
|
|
136
157
|
|
|
137
|
-
def decode(self, stream: ContextFramesBytesIO) -> Tuple[
|
|
158
|
+
def decode(self, stream: ContextFramesBytesIO) -> Tuple[T, ...]:
|
|
138
159
|
return decode_tuple(self, stream)
|
|
139
160
|
|
|
140
161
|
__call__ = decode
|
|
@@ -148,7 +169,7 @@ class TupleDecoder(BaseDecoder):
|
|
|
148
169
|
return cls(decoders=decoders)
|
|
149
170
|
|
|
150
171
|
|
|
151
|
-
class SingleDecoder(BaseDecoder):
|
|
172
|
+
class SingleDecoder(BaseDecoder[T]):
|
|
152
173
|
decoder_fn = None
|
|
153
174
|
|
|
154
175
|
def validate(self) -> None:
|
|
@@ -160,7 +181,7 @@ class SingleDecoder(BaseDecoder):
|
|
|
160
181
|
def validate_padding_bytes(self, value: Any, padding_bytes: bytes) -> None:
|
|
161
182
|
raise NotImplementedError("Must be implemented by subclasses")
|
|
162
183
|
|
|
163
|
-
def decode(self, stream: ContextFramesBytesIO) ->
|
|
184
|
+
def decode(self, stream: ContextFramesBytesIO) -> T:
|
|
164
185
|
raw_data = self.read_data_from_stream(stream)
|
|
165
186
|
data, padding_bytes = self.split_data_and_padding(raw_data)
|
|
166
187
|
value = self.decoder_fn(data) # type: ignore [misc]
|
|
@@ -177,7 +198,7 @@ class SingleDecoder(BaseDecoder):
|
|
|
177
198
|
return raw_data, b""
|
|
178
199
|
|
|
179
200
|
|
|
180
|
-
class BaseArrayDecoder(BaseDecoder):
|
|
201
|
+
class BaseArrayDecoder(BaseDecoder[Tuple[T, ...]]):
|
|
181
202
|
item_decoder: BaseDecoder = None
|
|
182
203
|
|
|
183
204
|
def __init__(self, **kwargs: Any) -> None:
|
|
@@ -195,7 +216,7 @@ class BaseArrayDecoder(BaseDecoder):
|
|
|
195
216
|
|
|
196
217
|
self.validate_pointers = noop
|
|
197
218
|
|
|
198
|
-
def decode(self, stream: ContextFramesBytesIO) -> Tuple[
|
|
219
|
+
def decode(self, stream: ContextFramesBytesIO) -> Tuple[T, ...]:
|
|
199
220
|
raise NotImplementedError # this is a type stub
|
|
200
221
|
|
|
201
222
|
def validate(self) -> None:
|
|
@@ -226,7 +247,7 @@ class BaseArrayDecoder(BaseDecoder):
|
|
|
226
247
|
validate_pointers_array(self, stream, array_size)
|
|
227
248
|
|
|
228
249
|
|
|
229
|
-
class SizedArrayDecoder(BaseArrayDecoder):
|
|
250
|
+
class SizedArrayDecoder(BaseArrayDecoder[T]):
|
|
230
251
|
array_size: int = None
|
|
231
252
|
|
|
232
253
|
def __init__(self, **kwargs):
|
|
@@ -234,30 +255,30 @@ class SizedArrayDecoder(BaseArrayDecoder):
|
|
|
234
255
|
|
|
235
256
|
self.is_dynamic = self.item_decoder.is_dynamic
|
|
236
257
|
|
|
237
|
-
def decode(self, stream):
|
|
258
|
+
def decode(self, stream: ContextFramesBytesIO) -> Tuple[T, ...]:
|
|
238
259
|
return decode_sized_array(self, stream)
|
|
239
260
|
|
|
240
261
|
__call__ = decode
|
|
241
262
|
|
|
242
263
|
|
|
243
|
-
class DynamicArrayDecoder(BaseArrayDecoder):
|
|
264
|
+
class DynamicArrayDecoder(BaseArrayDecoder[T]):
|
|
244
265
|
# Dynamic arrays are always dynamic, regardless of their elements
|
|
245
266
|
is_dynamic = True
|
|
246
267
|
|
|
247
|
-
def decode(self, stream: ContextFramesBytesIO) -> Tuple[
|
|
268
|
+
def decode(self, stream: ContextFramesBytesIO) -> Tuple[T, ...]:
|
|
248
269
|
return decode_dynamic_array(self, stream)
|
|
249
270
|
|
|
250
271
|
__call__ = decode
|
|
251
272
|
|
|
252
273
|
|
|
253
|
-
class FixedByteSizeDecoder(SingleDecoder):
|
|
254
|
-
decoder_fn: Callable[[bytes],
|
|
274
|
+
class FixedByteSizeDecoder(SingleDecoder[T]):
|
|
275
|
+
decoder_fn: Callable[[bytes], T] = None
|
|
255
276
|
value_bit_size: int = None
|
|
256
277
|
data_byte_size: int = None
|
|
257
278
|
is_big_endian: bool = None
|
|
258
279
|
|
|
259
|
-
def __init__(self,
|
|
260
|
-
super().__init__(
|
|
280
|
+
def __init__(self, **kwargs):
|
|
281
|
+
super().__init__(**kwargs)
|
|
261
282
|
|
|
262
283
|
self.read_data_from_stream = MethodType(
|
|
263
284
|
read_fixed_byte_size_data_from_stream, self
|
|
@@ -306,11 +327,11 @@ class FixedByteSizeDecoder(SingleDecoder):
|
|
|
306
327
|
raise NotImplementedError("didnt call __init__")
|
|
307
328
|
|
|
308
329
|
|
|
309
|
-
class Fixed32ByteSizeDecoder(FixedByteSizeDecoder):
|
|
330
|
+
class Fixed32ByteSizeDecoder(FixedByteSizeDecoder[T]):
|
|
310
331
|
data_byte_size = 32
|
|
311
332
|
|
|
312
333
|
|
|
313
|
-
class BooleanDecoder(Fixed32ByteSizeDecoder):
|
|
334
|
+
class BooleanDecoder(Fixed32ByteSizeDecoder[bool]):
|
|
314
335
|
value_bit_size = 8
|
|
315
336
|
is_big_endian = True
|
|
316
337
|
|
|
@@ -321,7 +342,7 @@ class BooleanDecoder(Fixed32ByteSizeDecoder):
|
|
|
321
342
|
return cls()
|
|
322
343
|
|
|
323
344
|
|
|
324
|
-
class AddressDecoder(Fixed32ByteSizeDecoder):
|
|
345
|
+
class AddressDecoder(Fixed32ByteSizeDecoder[HexAddress]):
|
|
325
346
|
value_bit_size = 20 * 8
|
|
326
347
|
is_big_endian = True
|
|
327
348
|
decoder_fn = staticmethod(to_normalized_address)
|
|
@@ -334,8 +355,8 @@ class AddressDecoder(Fixed32ByteSizeDecoder):
|
|
|
334
355
|
#
|
|
335
356
|
# Unsigned Integer Decoders
|
|
336
357
|
#
|
|
337
|
-
class UnsignedIntegerDecoder(Fixed32ByteSizeDecoder):
|
|
338
|
-
decoder_fn = staticmethod(big_endian_to_int)
|
|
358
|
+
class UnsignedIntegerDecoder(Fixed32ByteSizeDecoder[int]):
|
|
359
|
+
decoder_fn: "staticmethod[[bytes], int]" = staticmethod(big_endian_to_int)
|
|
339
360
|
is_big_endian = True
|
|
340
361
|
|
|
341
362
|
@parse_type_str("uint")
|
|
@@ -346,18 +367,33 @@ class UnsignedIntegerDecoder(Fixed32ByteSizeDecoder):
|
|
|
346
367
|
decode_uint_256 = UnsignedIntegerDecoder(value_bit_size=256)
|
|
347
368
|
|
|
348
369
|
|
|
370
|
+
class UnsignedIntegerDecoderCached(UnsignedIntegerDecoder):
|
|
371
|
+
decoder_fn: Callable[[bytes], int]
|
|
372
|
+
maxsize: Final[Optional[int]]
|
|
373
|
+
|
|
374
|
+
def __init__(self, maxsize: Optional[int] = None, **kwargs: Any) -> None:
|
|
375
|
+
super().__init__(**kwargs)
|
|
376
|
+
self.maxsize = maxsize
|
|
377
|
+
self.decoder_fn = lru_cache(maxsize=maxsize)(self.decoder_fn)
|
|
378
|
+
|
|
379
|
+
|
|
349
380
|
#
|
|
350
381
|
# Signed Integer Decoders
|
|
351
382
|
#
|
|
352
|
-
class SignedIntegerDecoder(Fixed32ByteSizeDecoder):
|
|
383
|
+
class SignedIntegerDecoder(Fixed32ByteSizeDecoder[int]):
|
|
353
384
|
is_big_endian = True
|
|
354
385
|
|
|
355
|
-
def __init__(self,
|
|
356
|
-
super().__init__(
|
|
357
|
-
|
|
386
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
387
|
+
super().__init__(**kwargs)
|
|
388
|
+
|
|
358
389
|
# Only assign validate_padding_bytes if not overridden in subclass
|
|
359
|
-
if
|
|
360
|
-
self.validate_padding_bytes
|
|
390
|
+
if (
|
|
391
|
+
type(self).validate_padding_bytes
|
|
392
|
+
is SignedIntegerDecoder.validate_padding_bytes
|
|
393
|
+
):
|
|
394
|
+
self.validate_padding_bytes = MethodType(
|
|
395
|
+
validate_padding_bytes_signed_integer, self
|
|
396
|
+
)
|
|
361
397
|
|
|
362
398
|
@cached_property
|
|
363
399
|
def neg_threshold(self) -> int:
|
|
@@ -381,10 +417,20 @@ class SignedIntegerDecoder(Fixed32ByteSizeDecoder):
|
|
|
381
417
|
return cls(value_bit_size=abi_type.sub)
|
|
382
418
|
|
|
383
419
|
|
|
420
|
+
class SignedIntegerDecoderCached(SignedIntegerDecoder):
|
|
421
|
+
decoder_fn: Callable[[bytes], int]
|
|
422
|
+
maxsize: Final[Optional[int]]
|
|
423
|
+
|
|
424
|
+
def __init__(self, maxsize: Optional[int] = None, **kwargs: Any) -> None:
|
|
425
|
+
super().__init__(**kwargs)
|
|
426
|
+
self.maxsize = maxsize
|
|
427
|
+
self.decoder_fn = lru_cache(maxsize=maxsize)(self.decoder_fn)
|
|
428
|
+
|
|
429
|
+
|
|
384
430
|
#
|
|
385
431
|
# Bytes1..32
|
|
386
432
|
#
|
|
387
|
-
class BytesDecoder(Fixed32ByteSizeDecoder):
|
|
433
|
+
class BytesDecoder(Fixed32ByteSizeDecoder[bytes]):
|
|
388
434
|
is_big_endian = False
|
|
389
435
|
|
|
390
436
|
@staticmethod
|
|
@@ -396,10 +442,10 @@ class BytesDecoder(Fixed32ByteSizeDecoder):
|
|
|
396
442
|
return cls(value_bit_size=abi_type.sub * 8)
|
|
397
443
|
|
|
398
444
|
|
|
399
|
-
class BaseFixedDecoder(Fixed32ByteSizeDecoder):
|
|
445
|
+
class BaseFixedDecoder(Fixed32ByteSizeDecoder[decimal.Decimal]):
|
|
400
446
|
frac_places: int = None
|
|
401
447
|
is_big_endian = True
|
|
402
|
-
|
|
448
|
+
|
|
403
449
|
@cached_property
|
|
404
450
|
def denominator(self) -> decimal.Decimal:
|
|
405
451
|
return TEN**self.frac_places
|
|
@@ -416,7 +462,6 @@ class BaseFixedDecoder(Fixed32ByteSizeDecoder):
|
|
|
416
462
|
|
|
417
463
|
|
|
418
464
|
class UnsignedFixedDecoder(BaseFixedDecoder):
|
|
419
|
-
|
|
420
465
|
def decoder_fn(self, data: bytes) -> decimal.Decimal:
|
|
421
466
|
value = big_endian_to_int(data)
|
|
422
467
|
|
|
@@ -433,7 +478,6 @@ class UnsignedFixedDecoder(BaseFixedDecoder):
|
|
|
433
478
|
|
|
434
479
|
|
|
435
480
|
class SignedFixedDecoder(BaseFixedDecoder):
|
|
436
|
-
|
|
437
481
|
@cached_property
|
|
438
482
|
def neg_threshold(self) -> int:
|
|
439
483
|
return int(2 ** (self.value_bit_size - 1))
|
|
@@ -485,7 +529,7 @@ class SignedFixedDecoder(BaseFixedDecoder):
|
|
|
485
529
|
#
|
|
486
530
|
# String and Bytes
|
|
487
531
|
#
|
|
488
|
-
class ByteStringDecoder(SingleDecoder):
|
|
532
|
+
class ByteStringDecoder(SingleDecoder[TByteStr]):
|
|
489
533
|
is_dynamic = True
|
|
490
534
|
|
|
491
535
|
@staticmethod
|
|
@@ -520,7 +564,7 @@ class ByteStringDecoder(SingleDecoder):
|
|
|
520
564
|
return cls()
|
|
521
565
|
|
|
522
566
|
|
|
523
|
-
class StringDecoder(ByteStringDecoder):
|
|
567
|
+
class StringDecoder(ByteStringDecoder[str]):
|
|
524
568
|
def __init__(self, handle_string_errors: str = "strict") -> None:
|
|
525
569
|
self.bytes_errors: Final = handle_string_errors
|
|
526
570
|
super().__init__()
|
faster_eth_abi/encoding.py
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
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
|
|
4
9
|
from functools import (
|
|
5
10
|
cached_property,
|
|
11
|
+
lru_cache,
|
|
6
12
|
)
|
|
7
13
|
from types import (
|
|
8
14
|
MethodType,
|
|
@@ -123,7 +129,9 @@ class TupleEncoder(BaseEncoder):
|
|
|
123
129
|
def __init__(self, encoders: Tuple[BaseEncoder, ...], **kwargs: Any) -> None:
|
|
124
130
|
super().__init__(encoders=encoders, **kwargs)
|
|
125
131
|
|
|
126
|
-
self._is_dynamic: Final = tuple(
|
|
132
|
+
self._is_dynamic: Final = tuple(
|
|
133
|
+
getattr(e, "is_dynamic", False) for e in self.encoders
|
|
134
|
+
)
|
|
127
135
|
self.is_dynamic = any(self._is_dynamic)
|
|
128
136
|
|
|
129
137
|
validators = []
|
|
@@ -134,7 +142,7 @@ class TupleEncoder(BaseEncoder):
|
|
|
134
142
|
validators.append(encoder)
|
|
135
143
|
else:
|
|
136
144
|
validators.append(validator)
|
|
137
|
-
|
|
145
|
+
|
|
138
146
|
self.validators: Final[Callable[[Any], None]] = tuple(validators)
|
|
139
147
|
|
|
140
148
|
if type(self).encode is TupleEncoder.encode:
|
|
@@ -148,7 +156,7 @@ class TupleEncoder(BaseEncoder):
|
|
|
148
156
|
if not self.is_dynamic
|
|
149
157
|
else encode_tuple
|
|
150
158
|
)
|
|
151
|
-
|
|
159
|
+
|
|
152
160
|
self.encode = MethodType(encode_func, self)
|
|
153
161
|
|
|
154
162
|
def validate(self) -> None:
|
|
@@ -295,6 +303,16 @@ class UnsignedIntegerEncoder(NumberEncoder):
|
|
|
295
303
|
return cls(value_bit_size=abi_type.sub)
|
|
296
304
|
|
|
297
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
|
+
|
|
298
316
|
encode_uint_256 = UnsignedIntegerEncoder(value_bit_size=256, data_byte_size=32)
|
|
299
317
|
|
|
300
318
|
|
|
@@ -307,6 +325,16 @@ class PackedUnsignedIntegerEncoder(UnsignedIntegerEncoder):
|
|
|
307
325
|
)
|
|
308
326
|
|
|
309
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
|
+
|
|
310
338
|
class SignedIntegerEncoder(NumberEncoder):
|
|
311
339
|
bounds_fn = staticmethod(compute_signed_integer_bounds)
|
|
312
340
|
type_check_fn = staticmethod(is_integer)
|
|
@@ -325,6 +353,16 @@ class SignedIntegerEncoder(NumberEncoder):
|
|
|
325
353
|
return cls(value_bit_size=abi_type.sub)
|
|
326
354
|
|
|
327
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
|
+
|
|
328
366
|
class PackedSignedIntegerEncoder(SignedIntegerEncoder):
|
|
329
367
|
@parse_type_str("int")
|
|
330
368
|
def from_type_str(cls, abi_type, registry):
|
|
@@ -334,6 +372,16 @@ class PackedSignedIntegerEncoder(SignedIntegerEncoder):
|
|
|
334
372
|
)
|
|
335
373
|
|
|
336
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
|
+
|
|
337
385
|
class BaseFixedEncoder(NumberEncoder):
|
|
338
386
|
frac_places = None
|
|
339
387
|
|
faster_eth_abi/exceptions.py
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
# cannot subclass `Any`
|
|
3
3
|
|
|
4
4
|
"""
|
|
5
|
+
Exception classes for error handling during ABI encoding and decoding operations.
|
|
6
|
+
|
|
5
7
|
faster-eth-abi exceptions always inherit from eth-abi exceptions, so porting to faster-eth-abi
|
|
6
8
|
does not require any change to your existing exception handlers. They will continue to work.
|
|
7
9
|
"""
|
|
8
10
|
|
|
9
11
|
import eth_abi.exceptions
|
|
10
|
-
import parsimonious
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
class EncodingError(eth_abi.exceptions.EncodingError):
|
|
@@ -110,7 +111,9 @@ class NoEntriesFound(PredicateMappingError, eth_abi.exceptions.NoEntriesFound):
|
|
|
110
111
|
"""
|
|
111
112
|
|
|
112
113
|
|
|
113
|
-
class MultipleEntriesFound(
|
|
114
|
+
class MultipleEntriesFound(
|
|
115
|
+
PredicateMappingError, eth_abi.exceptions.MultipleEntriesFound
|
|
116
|
+
):
|
|
114
117
|
"""
|
|
115
118
|
Raised when multiple registrations are found for a type string in a
|
|
116
119
|
registry's internal mapping. This error is non-recoverable and indicates
|
|
Binary file
|
faster_eth_abi/from_type_str.py
CHANGED
faster_eth_abi/grammar.py
CHANGED
|
@@ -1,40 +1,27 @@
|
|
|
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
|
-
Any,
|
|
5
7
|
Final,
|
|
6
|
-
NoReturn,
|
|
7
|
-
Optional,
|
|
8
|
-
Sequence,
|
|
9
|
-
Tuple,
|
|
10
|
-
TypeVar,
|
|
11
8
|
final,
|
|
12
9
|
)
|
|
13
10
|
|
|
14
|
-
from eth_typing import (
|
|
15
|
-
TypeStr,
|
|
16
|
-
)
|
|
17
11
|
import parsimonious
|
|
18
12
|
from parsimonious import (
|
|
19
13
|
expressions,
|
|
20
14
|
)
|
|
21
|
-
from parsimonious.nodes import (
|
|
22
|
-
Node,
|
|
23
|
-
)
|
|
24
|
-
from typing_extensions import (
|
|
25
|
-
Self,
|
|
26
|
-
)
|
|
27
15
|
|
|
28
16
|
from faster_eth_abi._grammar import (
|
|
29
|
-
TYPE_ALIASES,
|
|
30
17
|
TYPE_ALIAS_RE,
|
|
18
|
+
TYPE_ALIASES,
|
|
31
19
|
ABIType,
|
|
32
20
|
BasicType,
|
|
33
21
|
TupleType,
|
|
34
22
|
normalize,
|
|
35
23
|
)
|
|
36
24
|
from faster_eth_abi.exceptions import (
|
|
37
|
-
ABITypeError,
|
|
38
25
|
ParseError,
|
|
39
26
|
)
|
|
40
27
|
|
|
@@ -167,4 +154,15 @@ visitor: Final = NodeVisitor()
|
|
|
167
154
|
parse: Final = visitor.parse
|
|
168
155
|
|
|
169
156
|
|
|
170
|
-
__all__ = [
|
|
157
|
+
__all__ = [
|
|
158
|
+
"NodeVisitor",
|
|
159
|
+
"ABIType",
|
|
160
|
+
"TupleType",
|
|
161
|
+
"BasicType",
|
|
162
|
+
"grammar",
|
|
163
|
+
"parse",
|
|
164
|
+
"normalize",
|
|
165
|
+
"visitor",
|
|
166
|
+
"TYPE_ALIASES",
|
|
167
|
+
"TYPE_ALIAS_RE",
|
|
168
|
+
]
|
faster_eth_abi/io.py
CHANGED
|
Binary file
|