faster-eth-abi 5.2.23__cp314-cp314-musllinux_1_2_x86_64.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.
Files changed (48) hide show
  1. faster_eth_abi/__init__.py +12 -0
  2. faster_eth_abi/_codec.cpython-314-x86_64-linux-musl.so +0 -0
  3. faster_eth_abi/_codec.py +83 -0
  4. faster_eth_abi/_decoding.cpython-314-x86_64-linux-musl.so +0 -0
  5. faster_eth_abi/_decoding.py +356 -0
  6. faster_eth_abi/_encoding.cpython-314-x86_64-linux-musl.so +0 -0
  7. faster_eth_abi/_encoding.py +480 -0
  8. faster_eth_abi/_grammar.cpython-314-x86_64-linux-musl.so +0 -0
  9. faster_eth_abi/_grammar.py +375 -0
  10. faster_eth_abi/abi.cpython-314-x86_64-linux-musl.so +0 -0
  11. faster_eth_abi/abi.py +17 -0
  12. faster_eth_abi/base.py +45 -0
  13. faster_eth_abi/codec.py +2809 -0
  14. faster_eth_abi/constants.cpython-314-x86_64-linux-musl.so +0 -0
  15. faster_eth_abi/constants.py +7 -0
  16. faster_eth_abi/decoding.py +556 -0
  17. faster_eth_abi/encoding.py +721 -0
  18. faster_eth_abi/exceptions.py +127 -0
  19. faster_eth_abi/from_type_str.cpython-314-x86_64-linux-musl.so +0 -0
  20. faster_eth_abi/from_type_str.py +141 -0
  21. faster_eth_abi/grammar.py +172 -0
  22. faster_eth_abi/io.py +107 -0
  23. faster_eth_abi/packed.cpython-314-x86_64-linux-musl.so +0 -0
  24. faster_eth_abi/packed.py +19 -0
  25. faster_eth_abi/py.typed +0 -0
  26. faster_eth_abi/registry.py +758 -0
  27. faster_eth_abi/tools/__init__.cpython-314-x86_64-linux-musl.so +0 -0
  28. faster_eth_abi/tools/__init__.py +3 -0
  29. faster_eth_abi/tools/_strategies.cpython-314-x86_64-linux-musl.so +0 -0
  30. faster_eth_abi/tools/_strategies.py +243 -0
  31. faster_eth_abi/typing.py +4627 -0
  32. faster_eth_abi/utils/__init__.cpython-314-x86_64-linux-musl.so +0 -0
  33. faster_eth_abi/utils/__init__.py +0 -0
  34. faster_eth_abi/utils/localcontext.cpython-314-x86_64-linux-musl.so +0 -0
  35. faster_eth_abi/utils/localcontext.py +49 -0
  36. faster_eth_abi/utils/numeric.cpython-314-x86_64-linux-musl.so +0 -0
  37. faster_eth_abi/utils/numeric.py +117 -0
  38. faster_eth_abi/utils/padding.cpython-314-x86_64-linux-musl.so +0 -0
  39. faster_eth_abi/utils/padding.py +22 -0
  40. faster_eth_abi/utils/string.cpython-314-x86_64-linux-musl.so +0 -0
  41. faster_eth_abi/utils/string.py +19 -0
  42. faster_eth_abi/utils/validation.cpython-314-x86_64-linux-musl.so +0 -0
  43. faster_eth_abi/utils/validation.py +18 -0
  44. faster_eth_abi-5.2.23.dist-info/METADATA +136 -0
  45. faster_eth_abi-5.2.23.dist-info/RECORD +48 -0
  46. faster_eth_abi-5.2.23.dist-info/WHEEL +5 -0
  47. faster_eth_abi-5.2.23.dist-info/top_level.txt +2 -0
  48. faster_eth_abi__mypyc.cpython-314-x86_64-linux-musl.so +0 -0
@@ -0,0 +1,480 @@
1
+ """Private helpers for encoding logic, intended for C compilation.
2
+
3
+ This file exists because the original encoding.py is not ready to be fully compiled to C.
4
+ This module contains functions and logic that we do wish to compile.
5
+ """
6
+ import codecs
7
+ import decimal
8
+ from typing import (
9
+ TYPE_CHECKING,
10
+ Any,
11
+ Callable,
12
+ Dict,
13
+ Final,
14
+ List,
15
+ Optional,
16
+ Sequence,
17
+ Tuple,
18
+ TypeVar,
19
+ )
20
+
21
+ from faster_eth_utils import (
22
+ is_list_like,
23
+ )
24
+
25
+ from faster_eth_abi.exceptions import (
26
+ IllegalValue,
27
+ ValueOutOfBounds,
28
+ )
29
+ from faster_eth_abi.utils.localcontext import (
30
+ DECIMAL_CONTEXT,
31
+ )
32
+ from faster_eth_abi.utils.numeric import (
33
+ ceil32,
34
+ )
35
+ from faster_eth_abi.utils.padding import (
36
+ zpad_right,
37
+ )
38
+
39
+ if TYPE_CHECKING:
40
+ from faster_eth_abi.encoding import (
41
+ BaseArrayEncoder,
42
+ BaseEncoder,
43
+ BaseFixedEncoder,
44
+ PackedArrayEncoder,
45
+ SizedArrayEncoder,
46
+ SignedFixedEncoder,
47
+ TupleEncoder,
48
+ UnsignedFixedEncoder,
49
+ )
50
+
51
+
52
+ T = TypeVar("T")
53
+
54
+ __encode: Final = codecs.encode
55
+
56
+
57
+ # TupleEncoder
58
+ def validate_tuple(self: "TupleEncoder", value: Sequence[Any]) -> None:
59
+ # TODO: optimize this with fast paths like we do in encode_array
60
+ # if we check list and tuple first it compiles to much quicker C code
61
+ if not isinstance(value, (list, tuple)) and not is_list_like(value):
62
+ self.invalidate_value(
63
+ value,
64
+ msg="must be list-like object such as array or tuple",
65
+ )
66
+
67
+ validators = self.validators
68
+ if len(value) != len(validators):
69
+ self.invalidate_value(
70
+ value,
71
+ exc=ValueOutOfBounds,
72
+ msg=f"value has {len(value)} items when {len(validators)} " "were expected",
73
+ )
74
+
75
+ for item, validator in zip(value, validators):
76
+ validator(item)
77
+
78
+
79
+ def encode_tuple(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
80
+ validate_tuple(self, values)
81
+ raw_head_chunks: List[Optional[bytes]] = []
82
+ tail_chunks: List[bytes] = []
83
+
84
+ # we can make more optimized C code if we split this block by `values` type
85
+ if isinstance(values, tuple):
86
+ for value, encoder, is_dynamic in zip(values, self.encoders, self._is_dynamic):
87
+ if is_dynamic:
88
+ raw_head_chunks.append(None)
89
+ tail_chunks.append(encoder(value))
90
+ else:
91
+ raw_head_chunks.append(encoder(value))
92
+ tail_chunks.append(b"")
93
+ elif isinstance(values, list):
94
+ for value, encoder, is_dynamic in zip(values, self.encoders, self._is_dynamic):
95
+ if is_dynamic:
96
+ raw_head_chunks.append(None)
97
+ tail_chunks.append(encoder(value))
98
+ else:
99
+ raw_head_chunks.append(encoder(value))
100
+ tail_chunks.append(b"")
101
+ else:
102
+ for value, encoder, is_dynamic in zip(values, self.encoders, self._is_dynamic):
103
+ if is_dynamic:
104
+ raw_head_chunks.append(None)
105
+ tail_chunks.append(encoder(value))
106
+ else:
107
+ raw_head_chunks.append(encoder(value))
108
+ tail_chunks.append(b"")
109
+
110
+ head_length = sum(32 if item is None else len(item) for item in raw_head_chunks)
111
+ tail_offsets = [0]
112
+ total_offset = 0
113
+ for item in tail_chunks[:-1]:
114
+ total_offset += len(item)
115
+ tail_offsets.append(total_offset)
116
+
117
+ head_chunks = tuple(
118
+ encode_uint_256(head_length + offset) if chunk is None else chunk
119
+ for chunk, offset in zip(raw_head_chunks, tail_offsets)
120
+ )
121
+
122
+ return b"".join(head_chunks) + b"".join(tail_chunks)
123
+
124
+
125
+ def encode_tuple_all_dynamic(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
126
+ validate_tuple(self, values)
127
+ encoders = self.encoders
128
+
129
+ # we can make more optimized C code if we split this line by `values` type
130
+ if isinstance(values, tuple):
131
+ tail_chunks = [encoder(value) for encoder, value in zip(encoders, values)]
132
+ elif isinstance(values, list):
133
+ tail_chunks = [encoder(value) for encoder, value in zip(encoders, values)]
134
+ else:
135
+ tail_chunks = [encoder(value) for encoder, value in zip(encoders, values)]
136
+
137
+ total_offset = 0
138
+ head_length = 32 * len(encoders)
139
+ head_chunks = [encode_uint_256(head_length)]
140
+ for item in tail_chunks[:-1]:
141
+ total_offset += len(item)
142
+ head_chunks.append(encode_uint_256(head_length + total_offset))
143
+
144
+ return b"".join(head_chunks) + b"".join(tail_chunks)
145
+
146
+
147
+ def encode_tuple_no_dynamic(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
148
+ validate_tuple(self, values)
149
+ encoders = self.encoders
150
+
151
+ # we can make more optimized C code if we split this line by `values` type
152
+ if isinstance(values, tuple):
153
+ return b"".join(encoders[i](values[i]) for i in range(len(encoders)))
154
+ elif isinstance(values, list):
155
+ return b"".join(encoders[i](values[i]) for i in range(len(encoders)))
156
+ else:
157
+ return b"".join(encoders[i](values[i]) for i in range(len(encoders)))
158
+
159
+
160
+ def encode_tuple_no_dynamic1(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
161
+ validate_tuple(self, values)
162
+ encoders: Tuple["BaseEncoder"] = self.encoders
163
+
164
+ # we can make more optimized C code if we split this line by `values` type
165
+ if isinstance(values, tuple):
166
+ return encoders[0](values[0])
167
+ elif isinstance(values, list):
168
+ return encoders[0](values[0])
169
+ else:
170
+ return encoders[0](values[0])
171
+
172
+
173
+ def encode_tuple_no_dynamic2(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
174
+ validate_tuple(self, values)
175
+ encoders = self.encoders
176
+ # encoders: Tuple["BaseEncoder", "BaseEncoder"] = self.encoders
177
+
178
+ # we can make more optimized C code if we split this line by `values` type
179
+ if isinstance(values, tuple):
180
+ return encoders[0](values[0]) + encoders[1](values[1])
181
+ elif isinstance(values, list):
182
+ return encoders[0](values[0]) + encoders[1](values[1])
183
+ else:
184
+ return encoders[0](values[0]) + encoders[1](values[1])
185
+
186
+
187
+ def encode_tuple_no_dynamic3(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
188
+ validate_tuple(self, values)
189
+ encoders = self.encoders
190
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
191
+
192
+ # we can make more optimized C code if we split this line by `values` type
193
+ if isinstance(values, tuple):
194
+ return b"".join(encoders[i](values[i]) for i in range(3))
195
+ elif isinstance(values, list):
196
+ return b"".join(encoders[i](values[i]) for i in range(3))
197
+ else:
198
+ return b"".join(encoders[i](values[i]) for i in range(3))
199
+
200
+
201
+ def encode_tuple_no_dynamic4(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
202
+ validate_tuple(self, values)
203
+ encoders = self.encoders
204
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
205
+
206
+ # we can make more optimized C code if we split this line by `values` type
207
+ if isinstance(values, tuple):
208
+ return b"".join(encoders[i](values[i]) for i in range(4))
209
+ elif isinstance(values, list):
210
+ return b"".join(encoders[i](values[i]) for i in range(4))
211
+ else:
212
+ return b"".join(encoders[i](values[i]) for i in range(4))
213
+
214
+
215
+ def encode_tuple_no_dynamic5(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
216
+ validate_tuple(self, values)
217
+ encoders = self.encoders
218
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
219
+
220
+ # we can make more optimized C code if we split this line by `values` type
221
+ if isinstance(values, tuple):
222
+ return b"".join(encoders[i](values[i]) for i in range(5))
223
+ elif isinstance(values, list):
224
+ return b"".join(encoders[i](values[i]) for i in range(5))
225
+ else:
226
+ return b"".join(encoders[i](values[i]) for i in range(5))
227
+
228
+
229
+ def encode_tuple_no_dynamic6(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
230
+ validate_tuple(self, values)
231
+ encoders = self.encoders
232
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
233
+
234
+ # we can make more optimized C code if we split this line by `values` type
235
+ if isinstance(values, tuple):
236
+ return b"".join(encoders[i](values[i]) for i in range(6))
237
+ elif isinstance(values, list):
238
+ return b"".join(encoders[i](values[i]) for i in range(6))
239
+ else:
240
+ return b"".join(encoders[i](values[i]) for i in range(6))
241
+
242
+
243
+ def encode_tuple_no_dynamic7(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
244
+ validate_tuple(self, values)
245
+ encoders = self.encoders
246
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
247
+
248
+ # we can make more optimized C code if we split this line by `values` type
249
+ if isinstance(values, tuple):
250
+ return b"".join(encoders[i](values[i]) for i in range(7))
251
+ elif isinstance(values, list):
252
+ return b"".join(encoders[i](values[i]) for i in range(7))
253
+ else:
254
+ return b"".join(encoders[i](values[i]) for i in range(7))
255
+
256
+
257
+ def encode_tuple_no_dynamic8(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
258
+ validate_tuple(self, values)
259
+ encoders = self.encoders
260
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
261
+
262
+ # we can make more optimized C code if we split this line by `values` type
263
+ if isinstance(values, tuple):
264
+ return b"".join(encoders[i](values[i]) for i in range(8))
265
+ elif isinstance(values, list):
266
+ return b"".join(encoders[i](values[i]) for i in range(8))
267
+ else:
268
+ return b"".join(encoders[i](values[i]) for i in range(8))
269
+
270
+
271
+ def encode_tuple_no_dynamic9(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
272
+ validate_tuple(self, values)
273
+ encoders = self.encoders
274
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
275
+
276
+ # we can make more optimized C code if we split this line by `values` type
277
+ if isinstance(values, tuple):
278
+ return b"".join(encoders[i](values[i]) for i in range(9))
279
+ elif isinstance(values, list):
280
+ return b"".join(encoders[i](values[i]) for i in range(9))
281
+ else:
282
+ return b"".join(encoders[i](values[i]) for i in range(9))
283
+
284
+
285
+ def encode_tuple_no_dynamic10(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
286
+ validate_tuple(self, values)
287
+ encoders = self.encoders
288
+ # encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
289
+
290
+ # we can make more optimized C code if we split this line by `values` type
291
+ if isinstance(values, tuple):
292
+ return b"".join(encoders[i](values[i]) for i in range(10))
293
+ elif isinstance(values, list):
294
+ return b"".join(encoders[i](values[i]) for i in range(10))
295
+ else:
296
+ return b"".join(encoders[i](values[i]) for i in range(10))
297
+
298
+
299
+ encode_tuple_no_dynamic_funcs: Dict[
300
+ int, Callable[["TupleEncoder", Sequence[Any]], bytes]
301
+ ] = {
302
+ 1: encode_tuple_no_dynamic1,
303
+ 2: encode_tuple_no_dynamic2,
304
+ 3: encode_tuple_no_dynamic3,
305
+ 4: encode_tuple_no_dynamic4,
306
+ 5: encode_tuple_no_dynamic5,
307
+ 6: encode_tuple_no_dynamic6,
308
+ 7: encode_tuple_no_dynamic7,
309
+ 8: encode_tuple_no_dynamic8,
310
+ 9: encode_tuple_no_dynamic9,
311
+ 10: encode_tuple_no_dynamic10,
312
+ }
313
+
314
+
315
+ # BaseFixedEncoder
316
+ def validate_fixed(self: "BaseFixedEncoder", value: decimal.Decimal) -> None:
317
+ with DECIMAL_CONTEXT:
318
+ residue = value % self.precision
319
+
320
+ if residue > 0:
321
+ self.invalidate_value(
322
+ value,
323
+ exc=IllegalValue,
324
+ msg=f"residue {residue!r} outside allowed fractional precision of "
325
+ f"{self.frac_places}",
326
+ )
327
+
328
+
329
+ def encode_fixed(
330
+ value: Any,
331
+ encode_fn: Callable[[Any], bytes],
332
+ is_big_endian: bool,
333
+ data_byte_size: int,
334
+ ) -> bytes:
335
+ base_encoded_value = encode_fn(value)
336
+ if is_big_endian:
337
+ return base_encoded_value.rjust(data_byte_size, b"\x00")
338
+ else:
339
+ return base_encoded_value.ljust(data_byte_size, b"\x00")
340
+
341
+
342
+ # UnsignedFixedEncoder
343
+
344
+ def encode_unsigned_fixed(self: "UnsignedFixedEncoder", value: decimal.Decimal) -> bytes:
345
+ with DECIMAL_CONTEXT:
346
+ scaled_value = value * self.denominator
347
+ integer_value = int(scaled_value)
348
+
349
+ return int_to_big_endian(integer_value)
350
+
351
+
352
+ # SignedFixedEncoder
353
+
354
+ def encode_signed_fixed(self: "SignedFixedEncoder", value: decimal.Decimal) -> bytes:
355
+ with DECIMAL_CONTEXT:
356
+ scaled_value = value * self.denominator
357
+ integer_value = int(scaled_value)
358
+
359
+ unsigned_integer_value = integer_value % self.modulus
360
+
361
+ return int_to_big_endian(unsigned_integer_value)
362
+
363
+
364
+ def encode_signed(
365
+ value: T,
366
+ encode_fn: Callable[[T], bytes],
367
+ data_byte_size: int,
368
+ ) -> bytes:
369
+ base_encoded_value = encode_fn(value)
370
+ if value >= 0:
371
+ return base_encoded_value.rjust(data_byte_size, b"\x00")
372
+ else:
373
+ return base_encoded_value.rjust(data_byte_size, b"\xff")
374
+
375
+
376
+ def encode_bytestring(value: bytes) -> bytes:
377
+ value_length = len(value)
378
+ encoded_size = encode_uint_256(value_length)
379
+ padded_value = zpad_right(value, ceil32(value_length))
380
+ return encoded_size + padded_value
381
+
382
+
383
+ def encode_text(value: str) -> bytes:
384
+ value_as_bytes = __encode(value, "utf8")
385
+ value_length = len(value_as_bytes)
386
+
387
+ encoded_size = encode_uint_256(value_length)
388
+ padded_value = zpad_right(value_as_bytes, ceil32(value_length))
389
+
390
+ return encoded_size + padded_value
391
+
392
+
393
+ def validate_array(array_encoder: "BaseArrayEncoder", value: Sequence[Any]) -> None:
394
+ # sourcery skip: merge-duplicate-blocks
395
+ # TODO: specialize this func so we can call validate_item at the C level
396
+
397
+ validate_item = array_encoder.item_encoder.validate_value
398
+
399
+ # fast path for lists
400
+ if isinstance(value, list):
401
+ for item in value:
402
+ validate_item(item)
403
+
404
+ # fast path for tuples
405
+ elif isinstance(value, tuple):
406
+ for item in value:
407
+ validate_item(item)
408
+
409
+ # slow path for generic sequences
410
+ elif is_list_like(value):
411
+ for item in value:
412
+ validate_item(item)
413
+
414
+ # failure path
415
+ else:
416
+ array_encoder.invalidate_value(
417
+ value,
418
+ msg="must be list-like such as array or tuple",
419
+ )
420
+
421
+
422
+ def encode_elements(item_encoder: "BaseEncoder", value: Sequence[Any]) -> bytes:
423
+ tail_chunks = tuple(item_encoder(i) for i in value)
424
+
425
+ items_are_dynamic: bool = getattr(item_encoder, "is_dynamic", False)
426
+ if not items_are_dynamic or len(value) == 0:
427
+ return b"".join(tail_chunks)
428
+
429
+ head_length = 32 * len(value)
430
+ tail_offsets = [0]
431
+ total_offset = 0
432
+ for item in tail_chunks[:-1]:
433
+ total_offset += len(item)
434
+ tail_offsets.append(total_offset)
435
+
436
+ head_chunks = tuple(
437
+ encode_uint_256(head_length + offset) for offset in tail_offsets
438
+ )
439
+ return b"".join(head_chunks) + b"".join(tail_chunks)
440
+
441
+
442
+ def validate_packed_array(array_encoder: "PackedArrayEncoder", value: Sequence[Any]) -> None:
443
+ validate_array(array_encoder, value)
444
+ array_size = array_encoder.array_size
445
+ if array_size is not None and len(value) != array_size:
446
+ array_encoder.invalidate_value(
447
+ value,
448
+ exc=ValueOutOfBounds,
449
+ msg=f"value has {len(value)} items when {array_size} were expected",
450
+ )
451
+
452
+
453
+ def validate_sized_array(array_encoder: "SizedArrayEncoder", value: Sequence[Any]) -> None:
454
+ validate_array(array_encoder, value)
455
+ if len(value) != array_encoder.array_size:
456
+ array_encoder.invalidate_value(
457
+ value,
458
+ exc=ValueOutOfBounds,
459
+ msg=f"value has {len(value)} items when {array_encoder.array_size} were "
460
+ "expected",
461
+ )
462
+
463
+
464
+ def encode_elements_dynamic(item_encoder: "BaseEncoder", value: Sequence[Any]) -> bytes:
465
+ encoded_size = encode_uint_256(len(value))
466
+ encoded_elements = encode_elements(item_encoder, value)
467
+ return encoded_size + encoded_elements
468
+
469
+
470
+ def encode_uint_256(i: int) -> bytes:
471
+ # An optimized version of the `encode_uint_256` in `encoding.py` which
472
+ # does not perform any validation. We should not have any issues here
473
+ # unless you're encoding really really massive iterables.
474
+ big_endian = int_to_big_endian(i)
475
+ return big_endian.rjust(32, b"\x00")
476
+
477
+
478
+ def int_to_big_endian(value: int) -> bytes:
479
+ # vendored from eth-utils so it can compile nicely into faster-eth-abi's binary
480
+ return value.to_bytes((value.bit_length() + 7) // 8 or 1, "big")