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