faster-eth-abi 5.2.7__cp38-cp38-win_amd64.whl → 5.2.8__cp38-cp38-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.

Binary file
faster_eth_abi/_codec.py CHANGED
@@ -3,7 +3,6 @@ from typing import (
3
3
  Any,
4
4
  Iterable,
5
5
  Tuple,
6
- cast,
7
6
  )
8
7
 
9
8
  from eth_typing import (
@@ -79,4 +78,4 @@ def decode_c(
79
78
  decoder = self._registry.get_tuple_decoder(*types, strict=strict)
80
79
  stream = self.stream_class(data)
81
80
 
82
- return cast(Tuple[Any, ...], decoder(stream))
81
+ return decoder(stream)
@@ -0,0 +1,117 @@
1
+ from typing import (
2
+ TYPE_CHECKING,
3
+ Any,
4
+ Optional,
5
+ Tuple,
6
+ )
7
+
8
+ from faster_eth_abi.exceptions import (
9
+ InsufficientDataBytes,
10
+ )
11
+ from faster_eth_abi.io import (
12
+ BytesIO,
13
+ ContextFramesBytesIO,
14
+ )
15
+
16
+ if TYPE_CHECKING:
17
+ from .decoding import (
18
+ DynamicArrayDecoder,
19
+ FixedByteSizeDecoder,
20
+ HeadTailDecoder,
21
+ SizedArrayDecoder,
22
+ TupleDecoder,
23
+ UnsignedIntegerDecoder,
24
+ )
25
+
26
+
27
+ _UINT256_DECODER: Optional["UnsignedIntegerDecoder"] = None
28
+
29
+
30
+ def __set_uint256_decoder() -> "UnsignedIntegerDecoder":
31
+ # this helper breaks a circular dependency on the non-compiled decoding module
32
+ from . import (
33
+ decoding,
34
+ )
35
+
36
+ global _UINT256_DECODER
37
+ _UINT256_DECODER = decoding.decode_uint_256
38
+
39
+ return _UINT256_DECODER
40
+
41
+
42
+ def decode_uint_256(stream: ContextFramesBytesIO) -> int:
43
+ decoder = _UINT256_DECODER
44
+ if decoder is None:
45
+ decoder = __set_uint256_decoder()
46
+ decoded: int = decoder(stream)
47
+ return decoded
48
+
49
+
50
+ # HeadTailDecoder
51
+ def decode_head_tail(self: "HeadTailDecoder", stream: ContextFramesBytesIO) -> Any:
52
+ # Decode the offset and move the stream cursor forward 32 bytes
53
+ start_pos = decode_uint_256(stream)
54
+ # Jump ahead to the start of the value
55
+ stream.push_frame(start_pos)
56
+
57
+ # assertion check for mypy
58
+ tail_decoder = self.tail_decoder
59
+ if tail_decoder is None:
60
+ raise AssertionError("`tail_decoder` is None")
61
+ # Decode the value
62
+ value = tail_decoder(stream)
63
+ # Return the cursor
64
+ stream.pop_frame()
65
+
66
+ return value
67
+
68
+
69
+ # TupleDecoder
70
+ def decode_tuple(self: "TupleDecoder", stream: ContextFramesBytesIO) -> Tuple[Any, ...]:
71
+ self.validate_pointers(stream)
72
+ return tuple(decoder(stream) for decoder in self.decoders)
73
+
74
+
75
+ # SizedArrayDecoder
76
+ def decode_sized_array(
77
+ self: "SizedArrayDecoder", stream: ContextFramesBytesIO
78
+ ) -> Tuple[Any, ...]:
79
+ item_decoder = self.item_decoder
80
+ if item_decoder is None:
81
+ raise AssertionError("`item_decoder` is None")
82
+
83
+ array_size = self.array_size
84
+ self.validate_pointers(stream, array_size)
85
+ return tuple(item_decoder(stream) for _ in range(array_size))
86
+
87
+
88
+ # DynamicArrayDecoder
89
+ def decode_dynamic_array(
90
+ self: "DynamicArrayDecoder", stream: ContextFramesBytesIO
91
+ ) -> Tuple[Any, ...]:
92
+ array_size = decode_uint_256(stream)
93
+ stream.push_frame(32)
94
+ if self.item_decoder is None:
95
+ raise AssertionError("`item_decoder` is None")
96
+
97
+ self.validate_pointers(stream, array_size)
98
+ item_decoder = self.item_decoder
99
+ try:
100
+ return tuple(item_decoder(stream) for _ in range(array_size))
101
+ finally:
102
+ stream.pop_frame()
103
+
104
+
105
+ # FixedByteSizeDecoder
106
+ def read_fixed_byte_size_data_from_stream(
107
+ self: "FixedByteSizeDecoder",
108
+ # NOTE: use BytesIO here so mypyc doesn't type-check
109
+ # `stream` once we compile ContextFramesBytesIO.
110
+ stream: BytesIO,
111
+ ) -> bytes:
112
+ data_byte_size = self.data_byte_size
113
+ if len(data := stream.read(data_byte_size)) == data_byte_size:
114
+ return data
115
+ raise InsufficientDataBytes(
116
+ f"Tried to read {data_byte_size} bytes, only got {len(data)} bytes."
117
+ )
Binary file
Binary file
Binary file
@@ -2,16 +2,25 @@ import abc
2
2
  import decimal
3
3
  from typing import (
4
4
  Any,
5
- Generator,
5
+ Callable,
6
+ Final,
7
+ Optional,
6
8
  Tuple,
9
+ Union,
7
10
  )
8
11
 
9
12
  from faster_eth_utils import (
10
13
  big_endian_to_int,
11
14
  to_normalized_address,
12
- to_tuple,
13
15
  )
14
16
 
17
+ from faster_eth_abi._decoding import (
18
+ decode_dynamic_array,
19
+ decode_head_tail,
20
+ decode_sized_array,
21
+ decode_tuple,
22
+ read_fixed_byte_size_data_from_stream,
23
+ )
15
24
  from faster_eth_abi.base import (
16
25
  BaseCoder,
17
26
  )
@@ -33,6 +42,10 @@ from faster_eth_abi.utils.numeric import (
33
42
  ceil32,
34
43
  )
35
44
 
45
+ DynamicDecoder = Union[
46
+ "HeadTailDecoder", "SizedArrayDecoder", "DynamicArrayDecoder", "ByteStringDecoder"
47
+ ]
48
+
36
49
 
37
50
  class BaseDecoder(BaseCoder, metaclass=abc.ABCMeta):
38
51
  """
@@ -65,29 +78,18 @@ class HeadTailDecoder(BaseDecoder):
65
78
 
66
79
  is_dynamic = True
67
80
 
68
- tail_decoder = None
81
+ tail_decoder: Optional[DynamicDecoder] = None
69
82
 
70
- def validate(self):
83
+ def validate(self) -> None:
71
84
  super().validate()
72
85
 
73
86
  if self.tail_decoder is None:
74
87
  raise ValueError("No `tail_decoder` set")
75
88
 
76
89
  def decode(self, stream: ContextFramesBytesIO) -> Any:
77
- # Decode the offset and move the stream cursor forward 32 bytes
78
- start_pos = decode_uint_256(stream)
79
- # Jump ahead to the start of the value
80
- stream.push_frame(start_pos)
90
+ return decode_head_tail(self, stream)
81
91
 
82
- # assertion check for mypy
83
- if self.tail_decoder is None:
84
- raise AssertionError("`tail_decoder` is None")
85
- # Decode the value
86
- value = self.tail_decoder(stream)
87
- # Return the cursor
88
- stream.pop_frame()
89
-
90
- return value
92
+ __call__ = decode
91
93
 
92
94
 
93
95
  class TupleDecoder(BaseDecoder):
@@ -102,8 +104,11 @@ class TupleDecoder(BaseDecoder):
102
104
  )
103
105
 
104
106
  self.is_dynamic = any(getattr(d, "is_dynamic", False) for d in self.decoders)
107
+ self.len_of_head = sum(
108
+ getattr(decoder, "array_size", 1) for decoder in self.decoders
109
+ )
105
110
 
106
- def validate(self):
111
+ def validate(self) -> None:
107
112
  super().validate()
108
113
 
109
114
  if self.decoders is None:
@@ -114,11 +119,7 @@ class TupleDecoder(BaseDecoder):
114
119
  Verify that all pointers point to a valid location in the stream.
115
120
  """
116
121
  current_location = stream.tell()
117
- len_of_head = sum(
118
- decoder.array_size if hasattr(decoder, "array_size") else 1
119
- for decoder in self.decoders
120
- )
121
- end_of_offsets = current_location + 32 * len_of_head
122
+ end_of_offsets = current_location + 32 * self.len_of_head
122
123
  total_stream_length = len(stream.getbuffer())
123
124
  for decoder in self.decoders:
124
125
  if isinstance(decoder, HeadTailDecoder):
@@ -143,11 +144,10 @@ class TupleDecoder(BaseDecoder):
143
144
  # return the stream to its original location for actual decoding
144
145
  stream.seek(current_location)
145
146
 
146
- @to_tuple # type: ignore [misc]
147
- def decode(self, stream: ContextFramesBytesIO) -> Generator[Any, None, None]:
148
- self.validate_pointers(stream)
149
- for decoder in self.decoders:
150
- yield decoder(stream)
147
+ def decode(self, stream: ContextFramesBytesIO) -> Tuple[Any, ...]:
148
+ return decode_tuple(self, stream)
149
+
150
+ __call__ = decode
151
151
 
152
152
  @parse_tuple_type_str
153
153
  def from_type_str(cls, abi_type, registry):
@@ -161,7 +161,7 @@ class TupleDecoder(BaseDecoder):
161
161
  class SingleDecoder(BaseDecoder):
162
162
  decoder_fn = None
163
163
 
164
- def validate(self):
164
+ def validate(self) -> None:
165
165
  super().validate()
166
166
 
167
167
  if self.decoder_fn is None:
@@ -180,17 +180,19 @@ class SingleDecoder(BaseDecoder):
180
180
 
181
181
  return value
182
182
 
183
- def read_data_from_stream(self, stream):
183
+ __call__ = decode
184
+
185
+ def read_data_from_stream(self, stream: ContextFramesBytesIO) -> bytes:
184
186
  raise NotImplementedError("Must be implemented by subclasses")
185
187
 
186
- def split_data_and_padding(self, raw_data):
188
+ def split_data_and_padding(self, raw_data: bytes) -> Tuple[bytes, bytes]:
187
189
  return raw_data, b""
188
190
 
189
191
 
190
192
  class BaseArrayDecoder(BaseDecoder):
191
193
  item_decoder = None
192
194
 
193
- def __init__(self, **kwargs):
195
+ def __init__(self, **kwargs: Any) -> None:
194
196
  super().__init__(**kwargs)
195
197
 
196
198
  # Use a head-tail decoder to decode dynamic elements
@@ -199,7 +201,7 @@ class BaseArrayDecoder(BaseDecoder):
199
201
  tail_decoder=self.item_decoder,
200
202
  )
201
203
 
202
- def validate(self):
204
+ def validate(self) -> None:
203
205
  super().validate()
204
206
 
205
207
  if self.item_decoder is None:
@@ -246,47 +248,36 @@ class BaseArrayDecoder(BaseDecoder):
246
248
 
247
249
 
248
250
  class SizedArrayDecoder(BaseArrayDecoder):
249
- array_size = None
251
+ array_size: int = None
250
252
 
251
253
  def __init__(self, **kwargs):
252
254
  super().__init__(**kwargs)
253
255
 
254
256
  self.is_dynamic = self.item_decoder.is_dynamic
255
257
 
256
- @to_tuple
257
258
  def decode(self, stream):
258
- if self.item_decoder is None:
259
- raise AssertionError("`item_decoder` is None")
259
+ return decode_sized_array(self, stream)
260
260
 
261
- self.validate_pointers(stream, self.array_size)
262
- for _ in range(self.array_size):
263
- yield self.item_decoder(stream)
261
+ __call__ = decode
264
262
 
265
263
 
266
264
  class DynamicArrayDecoder(BaseArrayDecoder):
267
265
  # Dynamic arrays are always dynamic, regardless of their elements
268
266
  is_dynamic = True
269
267
 
270
- @to_tuple
271
- def decode(self, stream):
272
- array_size = decode_uint_256(stream)
273
- stream.push_frame(32)
274
- if self.item_decoder is None:
275
- raise AssertionError("`item_decoder` is None")
268
+ def decode(self, stream: ContextFramesBytesIO) -> Tuple[Any, ...]:
269
+ return decode_dynamic_array(self, stream)
276
270
 
277
- self.validate_pointers(stream, array_size)
278
- for _ in range(array_size):
279
- yield self.item_decoder(stream)
280
- stream.pop_frame()
271
+ __call__ = decode
281
272
 
282
273
 
283
274
  class FixedByteSizeDecoder(SingleDecoder):
284
- decoder_fn = None
285
- value_bit_size = None
286
- data_byte_size = None
287
- is_big_endian = None
275
+ decoder_fn: Callable[[bytes], Any] = None
276
+ value_bit_size: int = None
277
+ data_byte_size: int = None
278
+ is_big_endian: bool = None
288
279
 
289
- def validate(self):
280
+ def validate(self) -> None:
290
281
  super().validate()
291
282
 
292
283
  if self.value_bit_size is None:
@@ -306,18 +297,10 @@ class FixedByteSizeDecoder(SingleDecoder):
306
297
  if self.value_bit_size > self.data_byte_size * 8:
307
298
  raise ValueError("Value byte size exceeds data size")
308
299
 
309
- def read_data_from_stream(self, stream):
310
- data = stream.read(self.data_byte_size)
311
-
312
- if len(data) != self.data_byte_size:
313
- raise InsufficientDataBytes(
314
- f"Tried to read {self.data_byte_size} bytes, "
315
- f"only got {len(data)} bytes."
316
- )
300
+ def read_data_from_stream(self, stream: ContextFramesBytesIO) -> bytes:
301
+ return read_fixed_byte_size_data_from_stream(self, stream)
317
302
 
318
- return data
319
-
320
- def split_data_and_padding(self, raw_data):
303
+ def split_data_and_padding(self, raw_data: bytes) -> Tuple[bytes, bytes]:
321
304
  value_byte_size = self._get_value_byte_size()
322
305
  padding_size = self.data_byte_size - value_byte_size
323
306
 
@@ -330,7 +313,7 @@ class FixedByteSizeDecoder(SingleDecoder):
330
313
 
331
314
  return data, padding_bytes
332
315
 
333
- def validate_padding_bytes(self, value, padding_bytes):
316
+ def validate_padding_bytes(self, value: Any, padding_bytes: bytes) -> None:
334
317
  value_byte_size = self._get_value_byte_size()
335
318
  padding_size = self.data_byte_size - value_byte_size
336
319
 
@@ -406,7 +389,7 @@ class SignedIntegerDecoder(Fixed32ByteSizeDecoder):
406
389
  else:
407
390
  return value
408
391
 
409
- def validate_padding_bytes(self, value, padding_bytes):
392
+ def validate_padding_bytes(self, value: Any, padding_bytes: bytes) -> None:
410
393
  value_byte_size = self._get_value_byte_size()
411
394
  padding_size = self.data_byte_size - value_byte_size
412
395
 
@@ -444,7 +427,7 @@ class BaseFixedDecoder(Fixed32ByteSizeDecoder):
444
427
  frac_places = None
445
428
  is_big_endian = True
446
429
 
447
- def validate(self):
430
+ def validate(self) -> None:
448
431
  super().validate()
449
432
 
450
433
  if self.frac_places is None:
@@ -483,7 +466,7 @@ class SignedFixedDecoder(BaseFixedDecoder):
483
466
 
484
467
  return decimal_value
485
468
 
486
- def validate_padding_bytes(self, value, padding_bytes):
469
+ def validate_padding_bytes(self, value: Any, padding_bytes: bytes) -> None:
487
470
  value_byte_size = self._get_value_byte_size()
488
471
  padding_size = self.data_byte_size - value_byte_size
489
472
 
@@ -514,7 +497,7 @@ class ByteStringDecoder(SingleDecoder):
514
497
  def decoder_fn(data):
515
498
  return data
516
499
 
517
- def read_data_from_stream(self, stream):
500
+ def read_data_from_stream(self, stream: ContextFramesBytesIO) -> bytes:
518
501
  data_length = decode_uint_256(stream)
519
502
  padded_length = ceil32(data_length)
520
503
 
@@ -534,7 +517,7 @@ class ByteStringDecoder(SingleDecoder):
534
517
 
535
518
  return data[:data_length]
536
519
 
537
- def validate_padding_bytes(self, value, padding_bytes):
520
+ def validate_padding_bytes(self, value: Any, padding_bytes: bytes) -> None:
538
521
  pass
539
522
 
540
523
  @parse_type_str("bytes")
@@ -543,21 +526,21 @@ class ByteStringDecoder(SingleDecoder):
543
526
 
544
527
 
545
528
  class StringDecoder(ByteStringDecoder):
546
- def __init__(self, handle_string_errors="strict"):
547
- self.bytes_errors = handle_string_errors
529
+ def __init__(self, handle_string_errors: str = "strict") -> None:
530
+ self.bytes_errors: Final = handle_string_errors
548
531
  super().__init__()
549
532
 
550
533
  @parse_type_str("string")
551
534
  def from_type_str(cls, abi_type, registry):
552
535
  return cls()
553
536
 
554
- def decode(self, stream):
537
+ def decode(self, stream: ContextFramesBytesIO) -> str:
555
538
  raw_data = self.read_data_from_stream(stream)
556
539
  data, padding_bytes = self.split_data_and_padding(raw_data)
557
- value = self.decoder_fn(data, self.bytes_errors)
558
- self.validate_padding_bytes(value, padding_bytes)
559
- return value
540
+ return self.decoder_fn(data, self.bytes_errors)
541
+
542
+ __call__ = decode
560
543
 
561
544
  @staticmethod
562
- def decoder_fn(data, handle_string_errors="strict"):
545
+ def decoder_fn(data: bytes, handle_string_errors: str = "strict") -> str:
563
546
  return data.decode("utf-8", errors=handle_string_errors)
@@ -3,6 +3,8 @@ import codecs
3
3
  import decimal
4
4
  from typing import (
5
5
  Any,
6
+ Callable,
7
+ ClassVar,
6
8
  NoReturn,
7
9
  Optional,
8
10
  Sequence,
@@ -20,6 +22,9 @@ from faster_eth_utils import (
20
22
  is_text,
21
23
  to_canonical_address,
22
24
  )
25
+ from typing_extensions import (
26
+ Self,
27
+ )
23
28
 
24
29
  from faster_eth_abi._encoding import (
25
30
  encode_elements,
@@ -108,37 +113,40 @@ class TupleEncoder(BaseEncoder):
108
113
 
109
114
  self.is_dynamic = any(getattr(e, "is_dynamic", False) for e in self.encoders)
110
115
 
111
- def validate(self):
116
+ def validate(self) -> None:
112
117
  super().validate()
113
118
 
114
119
  if self.encoders is None:
115
120
  raise ValueError("`encoders` may not be none")
116
121
 
117
- def validate_value(self, value):
122
+ def validate_value(self, value: Sequence[Any]) -> None:
118
123
  if not is_list_like(value):
119
124
  self.invalidate_value(
120
125
  value,
121
126
  msg="must be list-like object such as array or tuple",
122
127
  )
123
128
 
124
- if len(value) != len(self.encoders):
129
+ encoders = self.encoders
130
+ if len(value) != len(encoders):
125
131
  self.invalidate_value(
126
132
  value,
127
133
  exc=ValueOutOfBounds,
128
- msg=f"value has {len(value)} items when {len(self.encoders)} "
134
+ msg=f"value has {len(value)} items when {len(encoders)} "
129
135
  "were expected",
130
136
  )
131
137
 
132
- for item, encoder in zip(value, self.encoders):
138
+ for item, encoder in zip(value, encoders):
133
139
  try:
134
140
  encoder.validate_value(item)
135
141
  except AttributeError:
136
142
  encoder(item)
137
143
 
138
- def encode(self, values):
144
+ def encode(self, values: Sequence[Any]) -> bytes:
139
145
  self.validate_value(values)
140
146
  return encode_tuple(values, self.encoders)
141
147
 
148
+ __call__: Callable[[Self, Sequence[Any]], bytes] = encode
149
+
142
150
  @parse_tuple_type_str
143
151
  def from_type_str(cls, abi_type, registry):
144
152
  encoders = tuple(
@@ -155,25 +163,26 @@ class FixedSizeEncoder(BaseEncoder):
155
163
  type_check_fn = None
156
164
  is_big_endian = None
157
165
 
158
- def validate(self):
166
+ def validate(self) -> None:
159
167
  super().validate()
160
168
 
161
- if self.value_bit_size is None:
169
+ value_bit_size = self.value_bit_size
170
+ if value_bit_size is None:
162
171
  raise ValueError("`value_bit_size` may not be none")
163
- if self.data_byte_size is None:
172
+ data_byte_size = self.data_byte_size
173
+ if data_byte_size is None:
164
174
  raise ValueError("`data_byte_size` may not be none")
165
175
  if self.encode_fn is None:
166
176
  raise ValueError("`encode_fn` may not be none")
167
177
  if self.is_big_endian is None:
168
178
  raise ValueError("`is_big_endian` may not be none")
169
179
 
170
- if self.value_bit_size % 8 != 0:
180
+ if value_bit_size % 8 != 0:
171
181
  raise ValueError(
172
- f"Invalid value bit size: {self.value_bit_size}. "
173
- "Must be a multiple of 8"
182
+ f"Invalid value bit size: {value_bit_size}. Must be a multiple of 8"
174
183
  )
175
184
 
176
- if self.value_bit_size > self.data_byte_size * 8:
185
+ if value_bit_size > data_byte_size * 8:
177
186
  raise ValueError("Value byte size exceeds data size")
178
187
 
179
188
  def validate_value(self, value):
@@ -181,11 +190,12 @@ class FixedSizeEncoder(BaseEncoder):
181
190
 
182
191
  def encode(self, value: Any) -> bytes:
183
192
  self.validate_value(value)
184
- if self.encode_fn is None:
193
+ encode_fn = self.encode_fn
194
+ if encode_fn is None:
185
195
  raise AssertionError("`encode_fn` is None")
186
- return encode_fixed(
187
- value, self.encode_fn, self.is_big_endian, self.data_byte_size
188
- )
196
+ return encode_fixed(value, encode_fn, self.is_big_endian, self.data_byte_size)
197
+
198
+ __call__ = encode
189
199
 
190
200
 
191
201
  class Fixed32ByteSizeEncoder(FixedSizeEncoder):
@@ -202,7 +212,7 @@ class BooleanEncoder(Fixed32ByteSizeEncoder):
202
212
  cls.invalidate_value(value)
203
213
 
204
214
  @classmethod
205
- def encode_fn(cls, value):
215
+ def encode_fn(cls, value: bool) -> bytes:
206
216
  if value is True:
207
217
  return b"\x01"
208
218
  elif value is False:
@@ -225,7 +235,7 @@ class NumberEncoder(Fixed32ByteSizeEncoder):
225
235
  illegal_value_fn = None
226
236
  type_check_fn = None
227
237
 
228
- def validate(self):
238
+ def validate(self) -> None:
229
239
  super().validate()
230
240
 
231
241
  if self.bounds_fn is None:
@@ -234,14 +244,14 @@ class NumberEncoder(Fixed32ByteSizeEncoder):
234
244
  raise ValueError("`type_check_fn` cannot be null")
235
245
 
236
246
  def validate_value(self, value):
237
- if self.type_check_fn is None:
247
+ type_check_fn = self.type_check_fn
248
+ if type_check_fn is None:
238
249
  raise AssertionError("`type_check_fn` is None")
239
- if not self.type_check_fn(value):
250
+ if not type_check_fn(value):
240
251
  self.invalidate_value(value)
241
252
 
242
- illegal_value = self.illegal_value_fn is not None and self.illegal_value_fn(
243
- value
244
- )
253
+ illegal_value_fn = self.illegal_value_fn
254
+ illegal_value = illegal_value_fn is not None and illegal_value_fn(value)
245
255
  if illegal_value:
246
256
  self.invalidate_value(value, exc=IllegalValue)
247
257
 
@@ -284,10 +294,12 @@ class SignedIntegerEncoder(NumberEncoder):
284
294
  def encode_fn(self, value: int) -> bytes:
285
295
  return int_to_big_endian(value % (2**self.value_bit_size))
286
296
 
287
- def encode(self, value):
297
+ def encode(self, value: int) -> bytes:
288
298
  self.validate_value(value)
289
299
  return encode_signed(value, self.encode_fn, self.data_byte_size)
290
300
 
301
+ __call__ = encode
302
+
291
303
  @parse_type_str("int")
292
304
  def from_type_str(cls, abi_type, registry):
293
305
  return cls(value_bit_size=abi_type.sub)
@@ -330,13 +342,14 @@ class BaseFixedEncoder(NumberEncoder):
330
342
  f"{self.frac_places}",
331
343
  )
332
344
 
333
- def validate(self):
345
+ def validate(self) -> None:
334
346
  super().validate()
335
347
 
336
- if self.frac_places is None:
348
+ frac_places = self.frac_places
349
+ if frac_places is None:
337
350
  raise ValueError("must specify `frac_places`")
338
351
 
339
- if self.frac_places <= 0 or self.frac_places > 80:
352
+ if frac_places <= 0 or frac_places > 80:
340
353
  raise ValueError("`frac_places` must be in range (0, 80]")
341
354
 
342
355
 
@@ -390,6 +403,8 @@ class SignedFixedEncoder(BaseFixedEncoder):
390
403
  self.validate_value(value)
391
404
  return encode_signed(value, self.encode_fn, self.data_byte_size)
392
405
 
406
+ __call__ = encode
407
+
393
408
  @parse_type_str("fixed")
394
409
  def from_type_str(cls, abi_type, registry):
395
410
  value_bit_size, frac_places = abi_type.sub
@@ -422,7 +437,7 @@ class AddressEncoder(Fixed32ByteSizeEncoder):
422
437
  if not is_address(value):
423
438
  cls.invalidate_value(value)
424
439
 
425
- def validate(self):
440
+ def validate(self) -> None:
426
441
  super().validate()
427
442
 
428
443
  if self.value_bit_size != 20 * 8:
@@ -479,7 +494,7 @@ class ByteStringEncoder(BaseEncoder):
479
494
  cls.invalidate_value(value)
480
495
 
481
496
  @classmethod
482
- def encode(cls, value):
497
+ def encode(cls, value: bytes) -> bytes:
483
498
  cls.validate_value(value)
484
499
  value_length = len(value)
485
500
 
@@ -488,9 +503,11 @@ class ByteStringEncoder(BaseEncoder):
488
503
 
489
504
  return encoded_size + padded_value
490
505
 
506
+ __call__: ClassVar[Callable[[Type[Self], bytes], bytes]] = encode
507
+
491
508
  @parse_type_str("bytes")
492
509
  def from_type_str(cls, abi_type, registry):
493
- return cls()
510
+ return cls() # type: ignore [misc]
494
511
 
495
512
 
496
513
  class PackedByteStringEncoder(ByteStringEncoder):
@@ -501,6 +518,8 @@ class PackedByteStringEncoder(ByteStringEncoder):
501
518
  cls.validate_value(value)
502
519
  return value
503
520
 
521
+ __call__ = encode
522
+
504
523
 
505
524
  class TextStringEncoder(BaseEncoder):
506
525
  is_dynamic = True
@@ -511,7 +530,7 @@ class TextStringEncoder(BaseEncoder):
511
530
  cls.invalidate_value(value)
512
531
 
513
532
  @classmethod
514
- def encode(cls, value):
533
+ def encode(cls, value: str) -> bytes:
515
534
  cls.validate_value(value)
516
535
 
517
536
  value_as_bytes = codecs.encode(value, "utf8")
@@ -522,24 +541,28 @@ class TextStringEncoder(BaseEncoder):
522
541
 
523
542
  return encoded_size + padded_value
524
543
 
544
+ __call__: ClassVar[Callable[[Type[Self], str], bytes]] = encode
545
+
525
546
  @parse_type_str("string")
526
547
  def from_type_str(cls, abi_type, registry):
527
- return cls()
548
+ return cls() # type: ignore [misc]
528
549
 
529
550
 
530
551
  class PackedTextStringEncoder(TextStringEncoder):
531
552
  is_dynamic = False
532
553
 
533
554
  @classmethod
534
- def encode(cls, value):
555
+ def encode(cls, value: str) -> bytes:
535
556
  cls.validate_value(value)
536
557
  return codecs.encode(value, "utf8")
537
558
 
559
+ __call__ = encode
560
+
538
561
 
539
562
  class BaseArrayEncoder(BaseEncoder):
540
- item_encoder = None
563
+ item_encoder: BaseEncoder = None
541
564
 
542
- def validate(self):
565
+ def validate(self) -> None:
543
566
  super().validate()
544
567
 
545
568
  if self.item_encoder is None:
@@ -552,8 +575,9 @@ class BaseArrayEncoder(BaseEncoder):
552
575
  msg="must be list-like such as array or tuple",
553
576
  )
554
577
 
578
+ item_encoder = self.item_encoder
555
579
  for item in value:
556
- self.item_encoder.validate_value(item)
580
+ item_encoder.validate_value(item)
557
581
 
558
582
  def encode_elements(self, value: Sequence[Any]) -> bytes:
559
583
  self.validate_value(value)
@@ -581,17 +605,19 @@ class PackedArrayEncoder(BaseArrayEncoder):
581
605
  def validate_value(self, value: Any) -> None:
582
606
  super().validate_value(value)
583
607
 
584
- if self.array_size is not None and len(value) != self.array_size:
608
+ array_size = self.array_size
609
+ if array_size is not None and len(value) != array_size:
585
610
  self.invalidate_value(
586
611
  value,
587
612
  exc=ValueOutOfBounds,
588
- msg=f"value has {len(value)} items when {self.array_size} were "
589
- "expected",
613
+ msg=f"value has {len(value)} items when {array_size} were expected",
590
614
  )
591
615
 
592
616
  def encode(self, value: Sequence[Any]) -> bytes:
593
617
  return encode_elements(self.item_encoder, value)
594
618
 
619
+ __call__ = encode
620
+
595
621
  @parse_type_str(with_arrlist=True)
596
622
  def from_type_str(cls, abi_type, registry):
597
623
  item_encoder = registry.get_encoder(abi_type.item_type.to_type_str())
@@ -614,7 +640,7 @@ class SizedArrayEncoder(BaseArrayEncoder):
614
640
 
615
641
  self.is_dynamic = self.item_encoder.is_dynamic
616
642
 
617
- def validate(self):
643
+ def validate(self) -> None:
618
644
  super().validate()
619
645
 
620
646
  if self.array_size is None:
@@ -634,9 +660,13 @@ class SizedArrayEncoder(BaseArrayEncoder):
634
660
  def encode(self, value: Sequence[Any]) -> bytes:
635
661
  return encode_elements(self.item_encoder, value)
636
662
 
663
+ __call__ = encode
664
+
637
665
 
638
666
  class DynamicArrayEncoder(BaseArrayEncoder):
639
667
  is_dynamic = True
640
668
 
641
669
  def encode(self, value: Sequence[Any]) -> bytes:
642
670
  return encode_elements_dynamic(self.item_encoder, value)
671
+
672
+ __call__ = encode
Binary file
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: faster_eth_abi
3
- Version: 5.2.7
4
- Summary: A aster fork of eth_abi: Python utilities for working with Ethereum ABI definitions, especially encoding and decoding. Implemented in C.
3
+ Version: 5.2.8
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
7
7
  Author-email: snakecharmers@ethereum.org
@@ -0,0 +1,44 @@
1
+ 76f9a3652d4d2667c55c__mypyc.cp38-win_amd64.pyd,sha256=q4OWcbGDcAvt6tEq6H4JmF2sD2wZGQQDmb8Z08zyoBo,150528
2
+ faster_eth_abi/__init__.py,sha256=JpTfPTiusUGMmX8sEsGAxvILxFbvhh3MEyfiKOd5o9g,217
3
+ faster_eth_abi/_codec.cp38-win_amd64.pyd,sha256=ov2tFCp3g4DpZMjiTNVKE4KG6D_kLHVoQCqDKd-m3fs,10752
4
+ faster_eth_abi/_codec.py,sha256=fLRvqvrD8F38U4m1wZztvx-7JJbZaPikwXS5u9BzY14,2509
5
+ faster_eth_abi/_decoding.cp38-win_amd64.pyd,sha256=e1D0PXNjPWPArQCTTGz8S4L-JNnbxtFRTMerZn7Hvd0,10752
6
+ faster_eth_abi/_decoding.py,sha256=uhteNEJzs873MqIOxc68XuFnKOhsUH0CJcQFLbL0Q18,3264
7
+ faster_eth_abi/_encoding.cp38-win_amd64.pyd,sha256=eB1NvWF884YxLwfAaFpO-peOjdwXavNR8D7sSU6N_Q0,10752
8
+ faster_eth_abi/_encoding.py,sha256=157A_MltVLCEwBmD7SB8UaKXkAOtIKC5MVupk6dk_yA,3217
9
+ faster_eth_abi/abi.cp38-win_amd64.pyd,sha256=g_ZjR_KtG0AdhsXupKMyB3cI1a7IcmHoM1yum_yvAvc,10752
10
+ faster_eth_abi/abi.py,sha256=-t9OVBSCxy6SuWpCu3cxHrCqkx8_svPIRb0MSFXEl5Q,383
11
+ faster_eth_abi/base.py,sha256=y4IXpQJWGfUISl3xjCO420Grxido3tE2ebPV2rK-DvM,1229
12
+ faster_eth_abi/codec.py,sha256=e1uO8BJrXRn0Ih70eUa5qipD2wcg2aZSR4fyVuGpFoY,4580
13
+ faster_eth_abi/constants.cp38-win_amd64.pyd,sha256=hDd5QdYIRSHnIsFYvOTs6HS5sNpCkbPcqF0wvUZs1ZA,10752
14
+ faster_eth_abi/constants.py,sha256=q3FGynS-Eb78cnrL6mBoAvTDz16PF3tW2OylTMd6ajs,114
15
+ faster_eth_abi/decoding.py,sha256=-2P8kAaHM1HFYS5b8QKstStO6PkWlugEaDUoujX1Uf0,17447
16
+ faster_eth_abi/encoding.py,sha256=bKw8wCqpfv8U83I2xsmiI37wn2lQUIhn4bn1xS_l1Zc,19704
17
+ faster_eth_abi/exceptions.py,sha256=KzNYRc9t0CvlkveozWvLeo1WC_GarcBkwzV67aY_5yI,3067
18
+ faster_eth_abi/from_type_str.cp38-win_amd64.pyd,sha256=arpdYW6yEWJV-thinlDbcau9zVXLE1vQbHE1N-_t9Sc,10752
19
+ faster_eth_abi/from_type_str.py,sha256=WLRP3OIyrJORgloX-7V0x2KdrZj0kLay-J9I8f-H36s,4446
20
+ faster_eth_abi/grammar.py,sha256=lhEmp3ZwMTzm1-jJiMUVD4zrBgU4MEZCRiND4WxfOes,13839
21
+ faster_eth_abi/io.py,sha256=E_QX7aYAjGYnkNAZmJMmSmx1lqvl_FDNmMFruTi9UX4,3831
22
+ faster_eth_abi/packed.cp38-win_amd64.pyd,sha256=S4BxBMQ5iKxx-EuX9NLs01BtDJ_ZTMr7t5XTshs9CYA,10752
23
+ faster_eth_abi/packed.py,sha256=RZ2chvsx9_AL9OxY1ixHTsaUJHaR_tmrNdViOIp-xSg,316
24
+ faster_eth_abi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ faster_eth_abi/registry.py,sha256=gU5-k_1eYUjs7-NAKoH9nncCJ36tZZHM5ZXvwmXt0cw,21192
26
+ faster_eth_abi/tools/__init__.cp38-win_amd64.pyd,sha256=y9qVkZkQBq4cHlak6AxTd8vgyZjqgzO5Gi0hdHYfMgU,10752
27
+ faster_eth_abi/tools/__init__.py,sha256=jxyQnb34ldRjCTYi3Ajb5h5QlFQ6ODfKQNhOCVwR7Ao,54
28
+ faster_eth_abi/tools/_strategies.cp38-win_amd64.pyd,sha256=hqimZqHOpkEx4y9wwzxUb1aiTq3ba6JKf77ciDr1uOg,10752
29
+ faster_eth_abi/tools/_strategies.py,sha256=HCFdQFLa84SMf7Deui2-szTH34hxTfc0Rog_kmpTg_w,6197
30
+ faster_eth_abi/utils/__init__.cp38-win_amd64.pyd,sha256=mNvFnTB_cDtCph7BYWTyqYBdZWYigaX5A0tsigibdQA,10752
31
+ faster_eth_abi/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ faster_eth_abi/utils/numeric.cp38-win_amd64.pyd,sha256=7tKEMfWQe04RNnhtGrVt1hPgHdNIc99PmHbTSd69ERI,10752
33
+ faster_eth_abi/utils/numeric.py,sha256=hNGble1NA99_5hrAOnH0ZakCuHc6PFMC1p0olmpo_vM,2232
34
+ faster_eth_abi/utils/padding.cp38-win_amd64.pyd,sha256=hGtYY27LEgjZRn8ILVr96XPiL_zr7ccMt10YcBJhF6A,10752
35
+ faster_eth_abi/utils/padding.py,sha256=k6dkOiQ3k0OhQUZ6blCiL1VOQVYGyynucafbySjcFfY,515
36
+ faster_eth_abi/utils/string.cp38-win_amd64.pyd,sha256=CsEnZWyDRCU_8DR6WGoVvETY5ufvEdNkvBmcLatJky8,10752
37
+ faster_eth_abi/utils/string.py,sha256=wYcvWof4kuitrGGSe_NOduQaxE4HHYmpraCPXKcZxMs,455
38
+ faster_eth_abi/utils/validation.cp38-win_amd64.pyd,sha256=uK55JUrpdE2odEoakg24S_gi_XGubIbg3BltGoiEss4,10752
39
+ faster_eth_abi/utils/validation.py,sha256=9veO7wyQsmcFgeaGrsKdSifjV1gaXfTDDKAt1EbKHYY,539
40
+ faster_eth_abi-5.2.8.dist-info/LICENSE,sha256=Q1lDDWXR057JL2Y7HTAwclCF32_LCloN4sGUkXO1YeI,1127
41
+ faster_eth_abi-5.2.8.dist-info/METADATA,sha256=yOnTAF2c2n9t-pBL2rjLtx82TLs9NscD8mV7UV2ZEnw,5207
42
+ faster_eth_abi-5.2.8.dist-info/WHEEL,sha256=2M046GvC9RLU1f1TWyM-2sB7cRKLhAC7ucAFK8l8f24,99
43
+ faster_eth_abi-5.2.8.dist-info/top_level.txt,sha256=CO2FQwf61aFzjYze7Wywa5KQdJ6bbLkzDoGEjDF2g9o,43
44
+ faster_eth_abi-5.2.8.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ 76f9a3652d4d2667c55c__mypyc
2
+ faster_eth_abi
@@ -1,42 +0,0 @@
1
- c42f5c78bc058f310136__mypyc.cp38-win_amd64.pyd,sha256=R7Ly2lhWHIOJR2kyUFv3I4zPgmJRzMsk5EAyYG6elaM,141824
2
- faster_eth_abi/__init__.py,sha256=JpTfPTiusUGMmX8sEsGAxvILxFbvhh3MEyfiKOd5o9g,217
3
- faster_eth_abi/_codec.cp38-win_amd64.pyd,sha256=oPffSO17VA43_MQO3h9ThqPtFZ423hhRZnafTDXyh8s,10752
4
- faster_eth_abi/_codec.py,sha256=mEjPRDPbpT67gc3HlzM8xAQ7uDOLwVRqQq5-dbwXZ1g,2543
5
- faster_eth_abi/_encoding.cp38-win_amd64.pyd,sha256=cbAFl0WY9r1KVIQ56R0IbGrcFXcBbJSua16VOzStoTs,10752
6
- faster_eth_abi/_encoding.py,sha256=157A_MltVLCEwBmD7SB8UaKXkAOtIKC5MVupk6dk_yA,3217
7
- faster_eth_abi/abi.cp38-win_amd64.pyd,sha256=VW5W6HoorMQtlCkSBusYQu6W35knXvJvqB5s8Mp-L0g,10752
8
- faster_eth_abi/abi.py,sha256=-t9OVBSCxy6SuWpCu3cxHrCqkx8_svPIRb0MSFXEl5Q,383
9
- faster_eth_abi/base.py,sha256=y4IXpQJWGfUISl3xjCO420Grxido3tE2ebPV2rK-DvM,1229
10
- faster_eth_abi/codec.py,sha256=e1uO8BJrXRn0Ih70eUa5qipD2wcg2aZSR4fyVuGpFoY,4580
11
- faster_eth_abi/constants.cp38-win_amd64.pyd,sha256=HCruOVtC5tKpp7tNM4hYIjnWacofEbT4ViGVpPRhfc0,10752
12
- faster_eth_abi/constants.py,sha256=q3FGynS-Eb78cnrL6mBoAvTDz16PF3tW2OylTMd6ajs,114
13
- faster_eth_abi/decoding.py,sha256=w98AsF5cq5DXE9OVflfkVLpMeCRbxzZuIj0hFPJcJNc,17910
14
- faster_eth_abi/encoding.py,sha256=vlFlvohYCUCGtvxhIih3apDuCA5FPu-D_qH7UiaiFTQ,18805
15
- faster_eth_abi/exceptions.py,sha256=KzNYRc9t0CvlkveozWvLeo1WC_GarcBkwzV67aY_5yI,3067
16
- faster_eth_abi/from_type_str.cp38-win_amd64.pyd,sha256=Wm5jsFmqZqYG0vojORMVUgChjMmZuI6jE1kC1Dh6bEo,10752
17
- faster_eth_abi/from_type_str.py,sha256=WLRP3OIyrJORgloX-7V0x2KdrZj0kLay-J9I8f-H36s,4446
18
- faster_eth_abi/grammar.py,sha256=lhEmp3ZwMTzm1-jJiMUVD4zrBgU4MEZCRiND4WxfOes,13839
19
- faster_eth_abi/io.py,sha256=E_QX7aYAjGYnkNAZmJMmSmx1lqvl_FDNmMFruTi9UX4,3831
20
- faster_eth_abi/packed.cp38-win_amd64.pyd,sha256=UtGWVJE1fntLKvPNG0mASXmIP0vc2HlxoMsHgfK_3Lc,10752
21
- faster_eth_abi/packed.py,sha256=RZ2chvsx9_AL9OxY1ixHTsaUJHaR_tmrNdViOIp-xSg,316
22
- faster_eth_abi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
- faster_eth_abi/registry.py,sha256=gU5-k_1eYUjs7-NAKoH9nncCJ36tZZHM5ZXvwmXt0cw,21192
24
- faster_eth_abi/tools/__init__.cp38-win_amd64.pyd,sha256=eEZWZEsTiNiNrOui9MU952CSxzZ-THwIv170mFCleFQ,10752
25
- faster_eth_abi/tools/__init__.py,sha256=jxyQnb34ldRjCTYi3Ajb5h5QlFQ6ODfKQNhOCVwR7Ao,54
26
- faster_eth_abi/tools/_strategies.cp38-win_amd64.pyd,sha256=ZY3F44p_mji7aQPrZtqpqZBARBJlM00bAa1hsHmU_y0,10752
27
- faster_eth_abi/tools/_strategies.py,sha256=HCFdQFLa84SMf7Deui2-szTH34hxTfc0Rog_kmpTg_w,6197
28
- faster_eth_abi/utils/__init__.cp38-win_amd64.pyd,sha256=GYusZ5fV9qana6ismMUcBgzOl54YXCT-CWcDi9opjjE,10752
29
- faster_eth_abi/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
- faster_eth_abi/utils/numeric.cp38-win_amd64.pyd,sha256=5vy5SpnVlbmr8ZnzRed8uBPH3JvrI9BLBPO5ftYeNks,10752
31
- faster_eth_abi/utils/numeric.py,sha256=hNGble1NA99_5hrAOnH0ZakCuHc6PFMC1p0olmpo_vM,2232
32
- faster_eth_abi/utils/padding.cp38-win_amd64.pyd,sha256=8XE4-hP6RrUqX2ERs7rwGU5bU5bc5xGKO2bUdyDomKQ,10752
33
- faster_eth_abi/utils/padding.py,sha256=k6dkOiQ3k0OhQUZ6blCiL1VOQVYGyynucafbySjcFfY,515
34
- faster_eth_abi/utils/string.cp38-win_amd64.pyd,sha256=BrAFt8HqTChSMh8M7Ds0kf387sQZNfAVz8RRgelsa2c,10752
35
- faster_eth_abi/utils/string.py,sha256=wYcvWof4kuitrGGSe_NOduQaxE4HHYmpraCPXKcZxMs,455
36
- faster_eth_abi/utils/validation.cp38-win_amd64.pyd,sha256=KeA99IaYPqEXXXanh5I7Zu2pdqq80rLkjHcQbNwRlbU,10752
37
- faster_eth_abi/utils/validation.py,sha256=9veO7wyQsmcFgeaGrsKdSifjV1gaXfTDDKAt1EbKHYY,539
38
- faster_eth_abi-5.2.7.dist-info/LICENSE,sha256=Q1lDDWXR057JL2Y7HTAwclCF32_LCloN4sGUkXO1YeI,1127
39
- faster_eth_abi-5.2.7.dist-info/METADATA,sha256=kQzDvvRInVqFBhsPk0aeqgABHsOt6zucNW1MqXA0Ggc,5206
40
- faster_eth_abi-5.2.7.dist-info/WHEEL,sha256=2M046GvC9RLU1f1TWyM-2sB7cRKLhAC7ucAFK8l8f24,99
41
- faster_eth_abi-5.2.7.dist-info/top_level.txt,sha256=5cP87jVHTOdG5bgQZ3ws5MGsnIwm_yX-WalM08iynHc,51
42
- faster_eth_abi-5.2.7.dist-info/RECORD,,
@@ -1,3 +0,0 @@
1
- c42f5c78bc058f310136__mypyc
2
- eth_abi
3
- faster_eth_abi