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,389 @@
1
+ """
2
+ Private helpers for ABI type string grammar and parsing, intended for C compilation.
3
+
4
+ This file exists because the original grammar.py is not ready to be fully compiled to C.
5
+ This module contains functions and logic that we do wish to compile.
6
+ """
7
+ import re
8
+ from typing import (
9
+ Any,
10
+ Final,
11
+ Generic,
12
+ Literal,
13
+ NewType,
14
+ NoReturn,
15
+ Optional,
16
+ Tuple,
17
+ TypeAlias,
18
+ TypeVar,
19
+ Union,
20
+ cast,
21
+ final,
22
+ )
23
+
24
+ from eth_typing.abi import (
25
+ TypeStr,
26
+ )
27
+ from parsimonious.nodes import (
28
+ Node,
29
+ )
30
+ from typing_extensions import (
31
+ Self,
32
+ )
33
+
34
+ from faster_eth_abi.exceptions import (
35
+ ABITypeError,
36
+ )
37
+
38
+ TYPE_ALIASES: Final = {
39
+ "int": "int256",
40
+ "uint": "uint256",
41
+ "fixed": "fixed128x18",
42
+ "ufixed": "ufixed128x18",
43
+ "function": "bytes24",
44
+ "byte": "bytes1",
45
+ }
46
+
47
+ TYPE_ALIAS_RE: Final = re.compile(
48
+ rf"\b({'|'.join(map(re.escape, TYPE_ALIASES.keys()))})\b"
49
+ )
50
+
51
+
52
+ Arrlist = Tuple[Union[int, Tuple[int, ...]], ...]
53
+ IntSubtype = NewType("IntSubtype", int)
54
+ FixedSubtype = NewType("FixedSubtype", Tuple[int, int])
55
+ Subtype = Union[IntSubtype, FixedSubtype]
56
+ TSub = TypeVar("TSub", IntSubtype, FixedSubtype, Literal[None])
57
+
58
+
59
+ class ABIType:
60
+ """
61
+ Base class for results of type string parsing operations.
62
+
63
+ Notes
64
+ -----
65
+ Users are unable to subclass this class. If your use case requires subclassing,
66
+ you will need to stick to the original `eth-abi`.
67
+
68
+ """
69
+
70
+ arrlist: Final[Optional[Arrlist]]
71
+ node: Final[Optional[Node]]
72
+
73
+ __slots__ = ("arrlist", "node")
74
+
75
+ def __init__(
76
+ self, arrlist: Optional[Arrlist] = None, node: Optional[Node] = None
77
+ ) -> None:
78
+ self.arrlist = arrlist
79
+ """
80
+ The list of array dimensions for a parsed type. Equal to ``None`` if
81
+ type string has no array dimensions.
82
+ """
83
+
84
+ self.node = node
85
+ """
86
+ The parsimonious ``Node`` instance associated with this parsed type.
87
+ Used to generate error messages for invalid types.
88
+ """
89
+
90
+ def __repr__(self) -> str: # pragma: no cover
91
+ return f"<{type(self).__qualname__} {self.to_type_str()!r}>"
92
+
93
+ def __eq__(self, other: Any) -> bool:
94
+ # Two ABI types are equal if their string representations are equal
95
+ return type(self) is type(other) and self.to_type_str() == other.to_type_str()
96
+
97
+ def to_type_str(self) -> TypeStr: # pragma: no cover
98
+ """
99
+ Returns the string representation of an ABI type. This will be equal to
100
+ the type string from which it was created.
101
+ """
102
+ raise NotImplementedError("Must implement `to_type_str`")
103
+
104
+ @property
105
+ def item_type(self) -> Self:
106
+ """
107
+ If this type is an array type, equal to an appropriate
108
+ :class:`~faster_eth_abi.grammar.ABIType` instance for the array's items.
109
+ """
110
+ raise NotImplementedError("Must implement `item_type`")
111
+
112
+ def validate(self) -> None: # pragma: no cover
113
+ """
114
+ Validates the properties of an ABI type against the solidity ABI spec:
115
+
116
+ https://solidity.readthedocs.io/en/develop/abi-spec.html
117
+
118
+ Raises :class:`~faster_eth_abi.exceptions.ABITypeError` if validation fails.
119
+ """
120
+ raise NotImplementedError("Must implement `validate`")
121
+
122
+ @final
123
+ def invalidate(self, error_msg: str) -> NoReturn:
124
+ # Invalidates an ABI type with the given error message. Expects that a
125
+ # parsimonious node was provided from the original parsing operation
126
+ # that yielded this type.
127
+ node = self.node
128
+
129
+ raise ABITypeError(
130
+ f"For '{node.text}' type at column {node.start + 1} "
131
+ f"in '{node.full_text}': {error_msg}"
132
+ )
133
+
134
+ @final
135
+ @property
136
+ def is_array(self) -> bool:
137
+ """
138
+ Equal to ``True`` if a type is an array type (i.e. if it has an array
139
+ dimension list). Otherwise, equal to ``False``.
140
+ """
141
+ return self.arrlist is not None
142
+
143
+ @property
144
+ def is_dynamic(self) -> bool:
145
+ """
146
+ Equal to ``True`` if a type has a dynamically sized encoding.
147
+ Otherwise, equal to ``False``.
148
+ """
149
+ raise NotImplementedError("Must implement `is_dynamic`")
150
+
151
+ @final
152
+ @property
153
+ def _has_dynamic_arrlist(self) -> bool:
154
+ return self.is_array and any(len(dim) == 0 for dim in self.arrlist)
155
+
156
+
157
+ TComp = TypeVar("TComp", bound=ABIType)
158
+
159
+
160
+ class TupleType(ABIType):
161
+ """
162
+ Represents the result of parsing a tuple type string e.g. "(int,bool)".
163
+
164
+ Notes
165
+ -----
166
+ Users are unable to subclass this class. If your use case requires subclassing,
167
+ you will need to stick to the original `eth-abi`.
168
+
169
+ """
170
+
171
+ __slots__ = ("components",)
172
+
173
+ def __init__(
174
+ self,
175
+ components: Tuple[TComp, ...],
176
+ arrlist: Optional[Arrlist] = None,
177
+ *,
178
+ node: Optional[Node] = None,
179
+ ) -> None:
180
+ super().__init__(arrlist, node)
181
+
182
+ self.components: Final = components
183
+ """
184
+ A tuple of :class:`~faster_eth_abi.grammar.ABIType` instances for each of the
185
+ tuple type's components.
186
+ """
187
+
188
+ def to_type_str(self) -> TypeStr:
189
+ components = f"({','.join(c.to_type_str() for c in self.components)})"
190
+
191
+ if isinstance(arrlist := self.arrlist, tuple):
192
+ return components + "".join(map(repr, map(list, arrlist)))
193
+ else:
194
+ return components
195
+
196
+ @property
197
+ def item_type(self) -> Self:
198
+ if not self.is_array:
199
+ raise ValueError(
200
+ f"Cannot determine item type for non-array type '{self.to_type_str()}'"
201
+ )
202
+
203
+ arrlist = cast(Arrlist, self.arrlist)[:-1] or None
204
+ cls = type(self)
205
+ if cls is TupleType:
206
+ return cast(Self, TupleType(self.components, arrlist, node=self.node))
207
+ else:
208
+ return cls(self.components, arrlist, node=self.node)
209
+
210
+ def validate(self) -> None:
211
+ for c in self.components:
212
+ c.validate()
213
+
214
+ @property
215
+ def is_dynamic(self) -> bool:
216
+ if self._has_dynamic_arrlist:
217
+ return True
218
+
219
+ return any(c.is_dynamic for c in self.components)
220
+
221
+
222
+ class BasicType(ABIType, Generic[TSub]):
223
+ """
224
+ Represents the result of parsing a basic type string e.g. "uint", "address",
225
+ "ufixed128x19[][2]".
226
+
227
+ Notes
228
+ -----
229
+ Users are unable to subclass this class. If your use case requires subclassing,
230
+ you will need to stick to the original `eth-abi`.
231
+
232
+ """
233
+
234
+ __slots__ = ("base", "sub")
235
+
236
+ def __init__(
237
+ self,
238
+ base: str,
239
+ sub: Optional[TSub] = None,
240
+ arrlist: Optional[Arrlist] = None,
241
+ *,
242
+ node: Optional[Node] = None,
243
+ ) -> None:
244
+ super().__init__(arrlist, node)
245
+
246
+ self.base: Final = base
247
+ """The base of a basic type e.g. "uint" for "uint256" etc."""
248
+
249
+ self.sub: Final = sub
250
+ """
251
+ The sub type of a basic type e.g. ``256`` for "uint256" or ``(128, 18)``
252
+ for "ufixed128x18" etc. Equal to ``None`` if type string has no sub
253
+ type.
254
+ """
255
+
256
+ def to_type_str(self) -> TypeStr:
257
+ sub, arrlist = self.sub, self.arrlist
258
+
259
+ if isinstance(sub, int):
260
+ substr = str(sub)
261
+ elif isinstance(sub, tuple):
262
+ substr = "x".join(map(str, sub))
263
+ else:
264
+ substr = ""
265
+
266
+ if isinstance(arrlist, tuple):
267
+ return self.base + substr + "".join(map(repr, map(list, arrlist)))
268
+ else:
269
+ return self.base + substr
270
+
271
+ @property
272
+ def item_type(self) -> Self:
273
+ if not self.is_array:
274
+ raise ValueError(
275
+ f"Cannot determine item type for non-array type '{self.to_type_str()}'"
276
+ )
277
+
278
+ cls = type(self)
279
+ arrlist = cast(Arrlist, self.arrlist)[:-1] or None
280
+ if cls is BasicType:
281
+ return cast(Self, BasicType(self.base, self.sub, arrlist, node=self.node))
282
+ else:
283
+ return cls(self.base, self.sub, arrlist, node=self.node)
284
+
285
+ @property
286
+ def is_dynamic(self) -> bool:
287
+ if self._has_dynamic_arrlist:
288
+ return True
289
+
290
+ base = self.base
291
+ if base == "string":
292
+ return True
293
+
294
+ if base == "bytes" and self.sub is None:
295
+ return True
296
+
297
+ return False
298
+
299
+ def validate(self) -> None:
300
+ base, sub = self.base, self.sub
301
+
302
+ # Check validity of string type
303
+ if base == "string":
304
+ if sub is not None:
305
+ self.invalidate("string type cannot have suffix")
306
+
307
+ # Check validity of bytes type
308
+ elif base == "bytes":
309
+ if not (sub is None or isinstance(sub, int)):
310
+ self.invalidate(
311
+ "bytes type must have either no suffix or a numerical suffix"
312
+ )
313
+
314
+ if isinstance(sub, int) and sub > 32:
315
+ self.invalidate("maximum 32 bytes for fixed-length bytes")
316
+
317
+ # Check validity of integer type
318
+ elif base in ("int", "uint"):
319
+ if not isinstance(sub, int):
320
+ self.invalidate("integer type must have numerical suffix")
321
+
322
+ if sub < 8 or sub > 256:
323
+ self.invalidate("integer size out of bounds (max 256 bits)")
324
+
325
+ if sub % 8 != 0:
326
+ self.invalidate("integer size must be multiple of 8")
327
+
328
+ # Check validity of fixed type
329
+ elif base in ("fixed", "ufixed"):
330
+ if not isinstance(sub, tuple):
331
+ self.invalidate(
332
+ "fixed type must have suffix of form <bits>x<exponent>, "
333
+ "e.g. 128x19",
334
+ )
335
+
336
+ bits, minus_e = sub
337
+
338
+ if bits < 8 or bits > 256:
339
+ self.invalidate("fixed size out of bounds (max 256 bits)")
340
+
341
+ if bits % 8 != 0:
342
+ self.invalidate("fixed size must be multiple of 8")
343
+
344
+ if minus_e < 1 or minus_e > 80:
345
+ self.invalidate(
346
+ f"fixed exponent size out of bounds, {minus_e} must be in 1-80"
347
+ )
348
+
349
+ # Check validity of hash type
350
+ elif base == "hash":
351
+ if not isinstance(sub, int):
352
+ self.invalidate("hash type must have numerical suffix")
353
+
354
+ # Check validity of address type
355
+ elif base == "address":
356
+ if sub is not None:
357
+ self.invalidate("address cannot have suffix")
358
+
359
+
360
+ BytesType: TypeAlias = BasicType[IntSubtype]
361
+ FixedType: TypeAlias = BasicType[FixedSubtype]
362
+
363
+ _NORMALIZED_TYPE_STR_CACHE: Final[dict[TypeStr, TypeStr]] = {}
364
+
365
+
366
+ def normalize(type_str: TypeStr) -> TypeStr:
367
+ """
368
+ Normalizes a type string into its canonical version e.g. the type string
369
+ 'int' becomes 'int256', etc.
370
+
371
+ :param type_str: The type string to be normalized.
372
+ :returns: The canonical version of the input type string.
373
+ """
374
+ cached = _NORMALIZED_TYPE_STR_CACHE.get(type_str)
375
+ if cached is not None:
376
+ return cached
377
+
378
+ if TYPE_ALIAS_RE.search(type_str) is None:
379
+ normalized = type_str
380
+ else:
381
+ normalized = TYPE_ALIAS_RE.sub(__normalize, type_str)
382
+
383
+ _NORMALIZED_TYPE_STR_CACHE[type_str] = normalized
384
+
385
+ return normalized
386
+
387
+
388
+ def __normalize(match: "re.Match[str]") -> str:
389
+ return TYPE_ALIASES[match.group(0)]
faster_eth_abi/abi.py ADDED
@@ -0,0 +1,17 @@
1
+ from typing import (
2
+ Final,
3
+ )
4
+
5
+ from faster_eth_abi.codec import (
6
+ ABICodec,
7
+ )
8
+ from faster_eth_abi.registry import (
9
+ registry,
10
+ )
11
+
12
+ default_codec: Final = ABICodec(registry)
13
+
14
+ encode: Final = default_codec.encode
15
+ decode: Final = default_codec.decode
16
+ is_encodable: Final = default_codec.is_encodable
17
+ is_encodable_type: Final = default_codec.is_encodable_type
faster_eth_abi/base.py ADDED
@@ -0,0 +1,45 @@
1
+ """Base classes for encoder and decoder implementations.
2
+
3
+ Defines the foundational interface and validation logic for all coder classes.
4
+ """
5
+ from typing import (
6
+ Any,
7
+ )
8
+
9
+
10
+ class BaseCoder:
11
+ """
12
+ Base class for all encoder and decoder classes.
13
+ """
14
+
15
+ is_dynamic = False
16
+
17
+ def __init__(self, **kwargs: Any) -> None:
18
+ cls = type(self)
19
+
20
+ # Ensure no unrecognized kwargs were given
21
+ for key, value in kwargs.items():
22
+ if not hasattr(cls, key):
23
+ raise AttributeError(
24
+ "Property {key} not found on {cls_name} class. "
25
+ "`{cls_name}.__init__` only accepts keyword arguments which are "
26
+ "present on the {cls_name} class.".format(
27
+ key=key,
28
+ cls_name=cls.__name__,
29
+ )
30
+ )
31
+ setattr(self, key, value)
32
+
33
+ # Validate given combination of kwargs
34
+ self.validate()
35
+
36
+ def validate(self) -> None:
37
+ pass
38
+
39
+ @classmethod
40
+ def from_type_str(cls, type_str, registry): # pragma: no cover
41
+ """
42
+ Used by :any:`ABIRegistry` to get an appropriate encoder or decoder
43
+ instance for the given type string and type registry.
44
+ """
45
+ raise NotImplementedError("Must implement `from_type_str`")