faster-eth-abi 5.2.22__cp313-cp313-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- faster_eth_abi/__init__.py +12 -0
- faster_eth_abi/_codec.cpython-313-darwin.so +0 -0
- faster_eth_abi/_codec.py +83 -0
- faster_eth_abi/_decoding.cpython-313-darwin.so +0 -0
- faster_eth_abi/_decoding.py +299 -0
- faster_eth_abi/_encoding.cpython-313-darwin.so +0 -0
- faster_eth_abi/_encoding.py +354 -0
- faster_eth_abi/_grammar.cpython-313-darwin.so +0 -0
- faster_eth_abi/_grammar.py +375 -0
- faster_eth_abi/abi.cpython-313-darwin.so +0 -0
- faster_eth_abi/abi.py +17 -0
- faster_eth_abi/base.py +45 -0
- faster_eth_abi/codec.py +2809 -0
- faster_eth_abi/constants.cpython-313-darwin.so +0 -0
- faster_eth_abi/constants.py +7 -0
- faster_eth_abi/decoding.py +584 -0
- faster_eth_abi/encoding.py +746 -0
- faster_eth_abi/exceptions.py +127 -0
- faster_eth_abi/from_type_str.cpython-313-darwin.so +0 -0
- faster_eth_abi/from_type_str.py +141 -0
- faster_eth_abi/grammar.py +172 -0
- faster_eth_abi/io.py +107 -0
- faster_eth_abi/packed.cpython-313-darwin.so +0 -0
- faster_eth_abi/packed.py +19 -0
- faster_eth_abi/py.typed +0 -0
- faster_eth_abi/registry.py +758 -0
- faster_eth_abi/tools/__init__.cpython-313-darwin.so +0 -0
- faster_eth_abi/tools/__init__.py +3 -0
- faster_eth_abi/tools/_strategies.cpython-313-darwin.so +0 -0
- faster_eth_abi/tools/_strategies.py +243 -0
- faster_eth_abi/typing.py +4627 -0
- faster_eth_abi/utils/__init__.cpython-313-darwin.so +0 -0
- faster_eth_abi/utils/__init__.py +0 -0
- faster_eth_abi/utils/numeric.cpython-313-darwin.so +0 -0
- faster_eth_abi/utils/numeric.py +117 -0
- faster_eth_abi/utils/padding.cpython-313-darwin.so +0 -0
- faster_eth_abi/utils/padding.py +22 -0
- faster_eth_abi/utils/string.cpython-313-darwin.so +0 -0
- faster_eth_abi/utils/string.py +19 -0
- faster_eth_abi/utils/validation.cpython-313-darwin.so +0 -0
- faster_eth_abi/utils/validation.py +18 -0
- faster_eth_abi-5.2.22.dist-info/METADATA +136 -0
- faster_eth_abi-5.2.22.dist-info/RECORD +46 -0
- faster_eth_abi-5.2.22.dist-info/WHEEL +6 -0
- faster_eth_abi-5.2.22.dist-info/top_level.txt +2 -0
- faster_eth_abi__mypyc.cpython-313-darwin.so +0 -0
|
@@ -0,0 +1,354 @@
|
|
|
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
|
+
from typing import (
|
|
7
|
+
TYPE_CHECKING,
|
|
8
|
+
Any,
|
|
9
|
+
Callable,
|
|
10
|
+
Dict,
|
|
11
|
+
List,
|
|
12
|
+
Optional,
|
|
13
|
+
Sequence,
|
|
14
|
+
Tuple,
|
|
15
|
+
TypeVar,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
from faster_eth_utils import (
|
|
19
|
+
is_list_like,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
from faster_eth_abi.exceptions import (
|
|
23
|
+
ValueOutOfBounds,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from faster_eth_abi.encoding import (
|
|
28
|
+
BaseEncoder,
|
|
29
|
+
TupleEncoder,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
T = TypeVar("T")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# TupleEncoder
|
|
37
|
+
def validate_tuple(self: "TupleEncoder", value: Sequence[Any]) -> None:
|
|
38
|
+
# if we check list and tuple first it compiles to much quicker C code
|
|
39
|
+
if not isinstance(value, (list, tuple)) and not is_list_like(value):
|
|
40
|
+
self.invalidate_value(
|
|
41
|
+
value,
|
|
42
|
+
msg="must be list-like object such as array or tuple",
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
validators = self.validators
|
|
46
|
+
if len(value) != len(validators):
|
|
47
|
+
self.invalidate_value(
|
|
48
|
+
value,
|
|
49
|
+
exc=ValueOutOfBounds,
|
|
50
|
+
msg=f"value has {len(value)} items when {len(validators)} " "were expected",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
for item, validator in zip(value, validators):
|
|
54
|
+
validator(item)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def encode_tuple(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
|
|
58
|
+
validate_tuple(self, values)
|
|
59
|
+
raw_head_chunks: List[Optional[bytes]] = []
|
|
60
|
+
tail_chunks: List[bytes] = []
|
|
61
|
+
|
|
62
|
+
# we can make more optimized C code if we split this block by `values` type
|
|
63
|
+
if isinstance(values, tuple):
|
|
64
|
+
for value, encoder, is_dynamic in zip(values, self.encoders, self._is_dynamic):
|
|
65
|
+
if is_dynamic:
|
|
66
|
+
raw_head_chunks.append(None)
|
|
67
|
+
tail_chunks.append(encoder(value))
|
|
68
|
+
else:
|
|
69
|
+
raw_head_chunks.append(encoder(value))
|
|
70
|
+
tail_chunks.append(b"")
|
|
71
|
+
elif isinstance(values, list):
|
|
72
|
+
for value, encoder, is_dynamic in zip(values, self.encoders, self._is_dynamic):
|
|
73
|
+
if is_dynamic:
|
|
74
|
+
raw_head_chunks.append(None)
|
|
75
|
+
tail_chunks.append(encoder(value))
|
|
76
|
+
else:
|
|
77
|
+
raw_head_chunks.append(encoder(value))
|
|
78
|
+
tail_chunks.append(b"")
|
|
79
|
+
else:
|
|
80
|
+
for value, encoder, is_dynamic in zip(values, self.encoders, self._is_dynamic):
|
|
81
|
+
if is_dynamic:
|
|
82
|
+
raw_head_chunks.append(None)
|
|
83
|
+
tail_chunks.append(encoder(value))
|
|
84
|
+
else:
|
|
85
|
+
raw_head_chunks.append(encoder(value))
|
|
86
|
+
tail_chunks.append(b"")
|
|
87
|
+
|
|
88
|
+
head_length = sum(32 if item is None else len(item) for item in raw_head_chunks)
|
|
89
|
+
tail_offsets = [0]
|
|
90
|
+
total_offset = 0
|
|
91
|
+
for item in tail_chunks[:-1]:
|
|
92
|
+
total_offset += len(item)
|
|
93
|
+
tail_offsets.append(total_offset)
|
|
94
|
+
|
|
95
|
+
head_chunks = tuple(
|
|
96
|
+
encode_uint_256(head_length + offset) if chunk is None else chunk
|
|
97
|
+
for chunk, offset in zip(raw_head_chunks, tail_offsets)
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
return b"".join(head_chunks) + b"".join(tail_chunks)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def encode_tuple_all_dynamic(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
|
|
104
|
+
validate_tuple(self, values)
|
|
105
|
+
encoders = self.encoders
|
|
106
|
+
|
|
107
|
+
# we can make more optimized C code if we split this line by `values` type
|
|
108
|
+
if isinstance(values, tuple):
|
|
109
|
+
tail_chunks = [encoder(value) for encoder, value in zip(encoders, values)]
|
|
110
|
+
elif isinstance(values, list):
|
|
111
|
+
tail_chunks = [encoder(value) for encoder, value in zip(encoders, values)]
|
|
112
|
+
else:
|
|
113
|
+
tail_chunks = [encoder(value) for encoder, value in zip(encoders, values)]
|
|
114
|
+
|
|
115
|
+
total_offset = 0
|
|
116
|
+
head_length = 32 * len(encoders)
|
|
117
|
+
head_chunks = [encode_uint_256(head_length)]
|
|
118
|
+
for item in tail_chunks[:-1]:
|
|
119
|
+
total_offset += len(item)
|
|
120
|
+
head_chunks.append(encode_uint_256(head_length + total_offset))
|
|
121
|
+
|
|
122
|
+
return b"".join(head_chunks) + b"".join(tail_chunks)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def encode_tuple_no_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
|
+
return b"".join(encoders[i](values[i]) for i in range(len(encoders)))
|
|
132
|
+
elif isinstance(values, list):
|
|
133
|
+
return b"".join(encoders[i](values[i]) for i in range(len(encoders)))
|
|
134
|
+
else:
|
|
135
|
+
return b"".join(encoders[i](values[i]) for i in range(len(encoders)))
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def encode_tuple_no_dynamic1(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
|
|
139
|
+
validate_tuple(self, values)
|
|
140
|
+
encoders: Tuple["BaseEncoder"] = self.encoders
|
|
141
|
+
|
|
142
|
+
# we can make more optimized C code if we split this line by `values` type
|
|
143
|
+
if isinstance(values, tuple):
|
|
144
|
+
return encoders[0](values[0])
|
|
145
|
+
elif isinstance(values, list):
|
|
146
|
+
return encoders[0](values[0])
|
|
147
|
+
else:
|
|
148
|
+
return encoders[0](values[0])
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def encode_tuple_no_dynamic2(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
|
|
152
|
+
validate_tuple(self, values)
|
|
153
|
+
encoders = self.encoders
|
|
154
|
+
# encoders: Tuple["BaseEncoder", "BaseEncoder"] = self.encoders
|
|
155
|
+
|
|
156
|
+
# we can make more optimized C code if we split this line by `values` type
|
|
157
|
+
if isinstance(values, tuple):
|
|
158
|
+
return encoders[0](values[0]) + encoders[1](values[1])
|
|
159
|
+
elif isinstance(values, list):
|
|
160
|
+
return encoders[0](values[0]) + encoders[1](values[1])
|
|
161
|
+
else:
|
|
162
|
+
return encoders[0](values[0]) + encoders[1](values[1])
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def encode_tuple_no_dynamic3(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
|
|
166
|
+
validate_tuple(self, values)
|
|
167
|
+
encoders = self.encoders
|
|
168
|
+
# encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
|
|
169
|
+
|
|
170
|
+
# we can make more optimized C code if we split this line by `values` type
|
|
171
|
+
if isinstance(values, tuple):
|
|
172
|
+
return b"".join(encoders[i](values[i]) for i in range(3))
|
|
173
|
+
elif isinstance(values, list):
|
|
174
|
+
return b"".join(encoders[i](values[i]) for i in range(3))
|
|
175
|
+
else:
|
|
176
|
+
return b"".join(encoders[i](values[i]) for i in range(3))
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def encode_tuple_no_dynamic4(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
|
|
180
|
+
validate_tuple(self, values)
|
|
181
|
+
encoders = self.encoders
|
|
182
|
+
# encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
|
|
183
|
+
|
|
184
|
+
# we can make more optimized C code if we split this line by `values` type
|
|
185
|
+
if isinstance(values, tuple):
|
|
186
|
+
return b"".join(encoders[i](values[i]) for i in range(4))
|
|
187
|
+
elif isinstance(values, list):
|
|
188
|
+
return b"".join(encoders[i](values[i]) for i in range(4))
|
|
189
|
+
else:
|
|
190
|
+
return b"".join(encoders[i](values[i]) for i in range(4))
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def encode_tuple_no_dynamic5(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
|
|
194
|
+
validate_tuple(self, values)
|
|
195
|
+
encoders = self.encoders
|
|
196
|
+
# encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
|
|
197
|
+
|
|
198
|
+
# we can make more optimized C code if we split this line by `values` type
|
|
199
|
+
if isinstance(values, tuple):
|
|
200
|
+
return b"".join(encoders[i](values[i]) for i in range(5))
|
|
201
|
+
elif isinstance(values, list):
|
|
202
|
+
return b"".join(encoders[i](values[i]) for i in range(5))
|
|
203
|
+
else:
|
|
204
|
+
return b"".join(encoders[i](values[i]) for i in range(5))
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def encode_tuple_no_dynamic6(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
|
|
208
|
+
validate_tuple(self, values)
|
|
209
|
+
encoders = self.encoders
|
|
210
|
+
# encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
|
|
211
|
+
|
|
212
|
+
# we can make more optimized C code if we split this line by `values` type
|
|
213
|
+
if isinstance(values, tuple):
|
|
214
|
+
return b"".join(encoders[i](values[i]) for i in range(6))
|
|
215
|
+
elif isinstance(values, list):
|
|
216
|
+
return b"".join(encoders[i](values[i]) for i in range(6))
|
|
217
|
+
else:
|
|
218
|
+
return b"".join(encoders[i](values[i]) for i in range(6))
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def encode_tuple_no_dynamic7(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
|
|
222
|
+
validate_tuple(self, values)
|
|
223
|
+
encoders = self.encoders
|
|
224
|
+
# encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
|
|
225
|
+
|
|
226
|
+
# we can make more optimized C code if we split this line by `values` type
|
|
227
|
+
if isinstance(values, tuple):
|
|
228
|
+
return b"".join(encoders[i](values[i]) for i in range(7))
|
|
229
|
+
elif isinstance(values, list):
|
|
230
|
+
return b"".join(encoders[i](values[i]) for i in range(7))
|
|
231
|
+
else:
|
|
232
|
+
return b"".join(encoders[i](values[i]) for i in range(7))
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def encode_tuple_no_dynamic8(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
|
|
236
|
+
validate_tuple(self, values)
|
|
237
|
+
encoders = self.encoders
|
|
238
|
+
# encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
|
|
239
|
+
|
|
240
|
+
# we can make more optimized C code if we split this line by `values` type
|
|
241
|
+
if isinstance(values, tuple):
|
|
242
|
+
return b"".join(encoders[i](values[i]) for i in range(8))
|
|
243
|
+
elif isinstance(values, list):
|
|
244
|
+
return b"".join(encoders[i](values[i]) for i in range(8))
|
|
245
|
+
else:
|
|
246
|
+
return b"".join(encoders[i](values[i]) for i in range(8))
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def encode_tuple_no_dynamic9(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
|
|
250
|
+
validate_tuple(self, values)
|
|
251
|
+
encoders = self.encoders
|
|
252
|
+
# encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
|
|
253
|
+
|
|
254
|
+
# we can make more optimized C code if we split this line by `values` type
|
|
255
|
+
if isinstance(values, tuple):
|
|
256
|
+
return b"".join(encoders[i](values[i]) for i in range(9))
|
|
257
|
+
elif isinstance(values, list):
|
|
258
|
+
return b"".join(encoders[i](values[i]) for i in range(9))
|
|
259
|
+
else:
|
|
260
|
+
return b"".join(encoders[i](values[i]) for i in range(9))
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def encode_tuple_no_dynamic10(self: "TupleEncoder", values: Sequence[Any]) -> bytes:
|
|
264
|
+
validate_tuple(self, values)
|
|
265
|
+
encoders = self.encoders
|
|
266
|
+
# encoders: Tuple["BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder", "BaseEncoder"] = self.encoders
|
|
267
|
+
|
|
268
|
+
# we can make more optimized C code if we split this line by `values` type
|
|
269
|
+
if isinstance(values, tuple):
|
|
270
|
+
return b"".join(encoders[i](values[i]) for i in range(10))
|
|
271
|
+
elif isinstance(values, list):
|
|
272
|
+
return b"".join(encoders[i](values[i]) for i in range(10))
|
|
273
|
+
else:
|
|
274
|
+
return b"".join(encoders[i](values[i]) for i in range(10))
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
encode_tuple_no_dynamic_funcs: Dict[
|
|
278
|
+
int, Callable[["TupleEncoder", Sequence[Any]], bytes]
|
|
279
|
+
] = {
|
|
280
|
+
1: encode_tuple_no_dynamic1,
|
|
281
|
+
2: encode_tuple_no_dynamic2,
|
|
282
|
+
3: encode_tuple_no_dynamic3,
|
|
283
|
+
4: encode_tuple_no_dynamic4,
|
|
284
|
+
5: encode_tuple_no_dynamic5,
|
|
285
|
+
6: encode_tuple_no_dynamic6,
|
|
286
|
+
7: encode_tuple_no_dynamic7,
|
|
287
|
+
8: encode_tuple_no_dynamic8,
|
|
288
|
+
9: encode_tuple_no_dynamic9,
|
|
289
|
+
10: encode_tuple_no_dynamic10,
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def encode_fixed(
|
|
294
|
+
value: Any,
|
|
295
|
+
encode_fn: Callable[[Any], bytes],
|
|
296
|
+
is_big_endian: bool,
|
|
297
|
+
data_byte_size: int,
|
|
298
|
+
) -> bytes:
|
|
299
|
+
base_encoded_value = encode_fn(value)
|
|
300
|
+
if is_big_endian:
|
|
301
|
+
return base_encoded_value.rjust(data_byte_size, b"\x00")
|
|
302
|
+
else:
|
|
303
|
+
return base_encoded_value.ljust(data_byte_size, b"\x00")
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
def encode_signed(
|
|
307
|
+
value: T,
|
|
308
|
+
encode_fn: Callable[[T], bytes],
|
|
309
|
+
data_byte_size: int,
|
|
310
|
+
) -> bytes:
|
|
311
|
+
base_encoded_value = encode_fn(value)
|
|
312
|
+
if value >= 0:
|
|
313
|
+
return base_encoded_value.rjust(data_byte_size, b"\x00")
|
|
314
|
+
else:
|
|
315
|
+
return base_encoded_value.rjust(data_byte_size, b"\xff")
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
def encode_elements(item_encoder: "BaseEncoder", value: Sequence[Any]) -> bytes:
|
|
319
|
+
tail_chunks = tuple(item_encoder(i) for i in value)
|
|
320
|
+
|
|
321
|
+
items_are_dynamic: bool = getattr(item_encoder, "is_dynamic", False)
|
|
322
|
+
if not items_are_dynamic or len(value) == 0:
|
|
323
|
+
return b"".join(tail_chunks)
|
|
324
|
+
|
|
325
|
+
head_length = 32 * len(value)
|
|
326
|
+
tail_offsets = [0]
|
|
327
|
+
total_offset = 0
|
|
328
|
+
for item in tail_chunks[:-1]:
|
|
329
|
+
total_offset += len(item)
|
|
330
|
+
tail_offsets.append(total_offset)
|
|
331
|
+
|
|
332
|
+
head_chunks = tuple(
|
|
333
|
+
encode_uint_256(head_length + offset) for offset in tail_offsets
|
|
334
|
+
)
|
|
335
|
+
return b"".join(head_chunks) + b"".join(tail_chunks)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def encode_elements_dynamic(item_encoder: "BaseEncoder", value: Sequence[Any]) -> bytes:
|
|
339
|
+
encoded_size = encode_uint_256(len(value))
|
|
340
|
+
encoded_elements = encode_elements(item_encoder, value)
|
|
341
|
+
return encoded_size + encoded_elements
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def encode_uint_256(i: int) -> bytes:
|
|
345
|
+
# An optimized version of the `encode_uint_256` in `encoding.py` which
|
|
346
|
+
# does not perform any validation. We should not have any issues here
|
|
347
|
+
# unless you're encoding really really massive iterables.
|
|
348
|
+
big_endian = int_to_big_endian(i)
|
|
349
|
+
return big_endian.rjust(32, b"\x00")
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def int_to_big_endian(value: int) -> bytes:
|
|
353
|
+
# vendored from eth-utils so it can compile nicely into faster-eth-abi's binary
|
|
354
|
+
return value.to_bytes((value.bit_length() + 7) // 8 or 1, "big")
|
|
Binary file
|