faster-eth-abi 5.2.10__cp310-cp310-win_amd64.whl → 5.2.12__cp310-cp310-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.

Files changed (32) hide show
  1. faster_eth_abi/_codec.cp310-win_amd64.pyd +0 -0
  2. faster_eth_abi/_codec.py +0 -4
  3. faster_eth_abi/_decoding.cp310-win_amd64.pyd +0 -0
  4. faster_eth_abi/_encoding.cp310-win_amd64.pyd +0 -0
  5. faster_eth_abi/_grammar.cp310-win_amd64.pyd +0 -0
  6. faster_eth_abi/_grammar.py +349 -0
  7. faster_eth_abi/abi.cp310-win_amd64.pyd +0 -0
  8. faster_eth_abi/codec.py +8 -9
  9. faster_eth_abi/constants.cp310-win_amd64.pyd +0 -0
  10. faster_eth_abi/exceptions.py +22 -13
  11. faster_eth_abi/from_type_str.cp310-win_amd64.pyd +0 -0
  12. faster_eth_abi/from_type_str.py +3 -1
  13. faster_eth_abi/grammar.py +10 -308
  14. faster_eth_abi/packed.cp310-win_amd64.pyd +0 -0
  15. faster_eth_abi/registry.py +37 -24
  16. faster_eth_abi/tools/__init__.cp310-win_amd64.pyd +0 -0
  17. faster_eth_abi/tools/_strategies.cp310-win_amd64.pyd +0 -0
  18. faster_eth_abi/tools/_strategies.py +9 -5
  19. faster_eth_abi/utils/__init__.cp310-win_amd64.pyd +0 -0
  20. faster_eth_abi/utils/numeric.cp310-win_amd64.pyd +0 -0
  21. faster_eth_abi/utils/padding.cp310-win_amd64.pyd +0 -0
  22. faster_eth_abi/utils/string.cp310-win_amd64.pyd +0 -0
  23. faster_eth_abi/utils/validation.cp310-win_amd64.pyd +0 -0
  24. {faster_eth_abi-5.2.10.dist-info → faster_eth_abi-5.2.12.dist-info}/METADATA +10 -5
  25. faster_eth_abi-5.2.12.dist-info/RECORD +46 -0
  26. faster_eth_abi-5.2.12.dist-info/top_level.txt +2 -0
  27. faster_eth_abi__mypyc.cp310-win_amd64.pyd +0 -0
  28. 76f9a3652d4d2667c55c__mypyc.cp310-win_amd64.pyd +0 -0
  29. faster_eth_abi-5.2.10.dist-info/RECORD +0 -44
  30. faster_eth_abi-5.2.10.dist-info/top_level.txt +0 -2
  31. {faster_eth_abi-5.2.10.dist-info → faster_eth_abi-5.2.12.dist-info}/WHEEL +0 -0
  32. {faster_eth_abi-5.2.10.dist-info → faster_eth_abi-5.2.12.dist-info}/licenses/LICENSE +0 -0
Binary file
faster_eth_abi/_codec.py CHANGED
@@ -39,8 +39,6 @@ def encode_c(
39
39
  :returns: The head-tail encoded binary representation of the python
40
40
  values in ``args`` as values of the ABI types in ``types``.
41
41
  """
42
- # validate encode types and args
43
- validate_list_like_param(types, "types")
44
42
  validate_list_like_param(args, "args")
45
43
 
46
44
  encoder = self._registry.get_tuple_encoder(*types)
@@ -71,8 +69,6 @@ def decode_c(
71
69
  :returns: A tuple of equivalent python values for the ABI values
72
70
  represented in ``data``.
73
71
  """
74
- # validate decode types and data
75
- validate_list_like_param(types, "types")
76
72
  validate_bytes_param(data, "data")
77
73
 
78
74
  decoder = self._registry.get_tuple_decoder(*types, strict=strict)
@@ -0,0 +1,349 @@
1
+ import re
2
+ from typing import (
3
+ Any,
4
+ Final,
5
+ NewType,
6
+ NoReturn,
7
+ Optional,
8
+ Sequence,
9
+ Tuple,
10
+ TypeVar,
11
+ Union,
12
+ final,
13
+ )
14
+
15
+ from eth_typing.abi import (
16
+ TypeStr,
17
+ )
18
+ from mypy_extensions import (
19
+ mypyc_attr,
20
+ )
21
+ from parsimonious.nodes import (
22
+ Node,
23
+ )
24
+ from typing_extensions import (
25
+ Self,
26
+ )
27
+
28
+ from faster_eth_abi.exceptions import (
29
+ ABITypeError,
30
+ )
31
+
32
+
33
+ TYPE_ALIASES: Final = {
34
+ "int": "int256",
35
+ "uint": "uint256",
36
+ "fixed": "fixed128x18",
37
+ "ufixed": "ufixed128x18",
38
+ "function": "bytes24",
39
+ "byte": "bytes1",
40
+ }
41
+
42
+ TYPE_ALIAS_RE: Final = re.compile(
43
+ rf"\b({'|'.join(map(re.escape, TYPE_ALIASES.keys()))})\b"
44
+ )
45
+
46
+
47
+ IntSubtype = NewType("IntSubtype", int)
48
+ FixedSubtype = NewType("FixedSubtype", Tuple[int, int])
49
+ Subtype = Union[IntSubtype, FixedSubtype]
50
+
51
+
52
+ @mypyc_attr(allow_interpreted_subclasses=True)
53
+ class ABIType:
54
+ """
55
+ Base class for results of type string parsing operations.
56
+ """
57
+
58
+ __slots__ = ("arrlist", "node")
59
+
60
+ def __init__(
61
+ self, arrlist: Optional[Sequence[str]] = None, node: Optional[Node] = None
62
+ ) -> None:
63
+ self.arrlist: Final = arrlist
64
+ """
65
+ The list of array dimensions for a parsed type. Equal to ``None`` if
66
+ type string has no array dimensions.
67
+ """
68
+
69
+ self.node: Final = node
70
+ """
71
+ The parsimonious ``Node`` instance associated with this parsed type.
72
+ Used to generate error messages for invalid types.
73
+ """
74
+
75
+ def __repr__(self) -> str: # pragma: no cover
76
+ return f"<{type(self).__qualname__} {self.to_type_str()!r}>"
77
+
78
+ def __eq__(self, other: Any) -> bool:
79
+ # Two ABI types are equal if their string representations are equal
80
+ return type(self) is type(other) and self.to_type_str() == other.to_type_str()
81
+
82
+ def to_type_str(self) -> TypeStr: # pragma: no cover
83
+ """
84
+ Returns the string representation of an ABI type. This will be equal to
85
+ the type string from which it was created.
86
+ """
87
+ raise NotImplementedError("Must implement `to_type_str`")
88
+
89
+ @property
90
+ def item_type(self) -> Self:
91
+ """
92
+ If this type is an array type, equal to an appropriate
93
+ :class:`~faster_eth_abi.grammar.ABIType` instance for the array's items.
94
+ """
95
+ raise NotImplementedError("Must implement `item_type`")
96
+
97
+ def validate(self) -> None: # pragma: no cover
98
+ """
99
+ Validates the properties of an ABI type against the solidity ABI spec:
100
+
101
+ https://solidity.readthedocs.io/en/develop/abi-spec.html
102
+
103
+ Raises :class:`~faster_eth_abi.exceptions.ABITypeError` if validation fails.
104
+ """
105
+ raise NotImplementedError("Must implement `validate`")
106
+
107
+ @final
108
+ def invalidate(self, error_msg: str) -> NoReturn:
109
+ # Invalidates an ABI type with the given error message. Expects that a
110
+ # parsimonious node was provided from the original parsing operation
111
+ # that yielded this type.
112
+ node = self.node
113
+
114
+ raise ABITypeError(
115
+ f"For '{node.text}' type at column {node.start + 1} "
116
+ f"in '{node.full_text}': {error_msg}"
117
+ )
118
+
119
+ @final
120
+ @property
121
+ def is_array(self) -> bool:
122
+ """
123
+ Equal to ``True`` if a type is an array type (i.e. if it has an array
124
+ dimension list). Otherwise, equal to ``False``.
125
+ """
126
+ return self.arrlist is not None
127
+
128
+ @property
129
+ def is_dynamic(self) -> bool:
130
+ """
131
+ Equal to ``True`` if a type has a dynamically sized encoding.
132
+ Otherwise, equal to ``False``.
133
+ """
134
+ raise NotImplementedError("Must implement `is_dynamic`")
135
+
136
+ @final
137
+ @property
138
+ def _has_dynamic_arrlist(self) -> bool:
139
+ return self.is_array and any(len(dim) == 0 for dim in self.arrlist)
140
+
141
+
142
+ TComp = TypeVar("TComp", bound=ABIType)
143
+
144
+
145
+ @mypyc_attr(allow_interpreted_subclasses=True)
146
+ class TupleType(ABIType):
147
+ """
148
+ Represents the result of parsing a tuple type string e.g. "(int,bool)".
149
+ """
150
+
151
+ __slots__ = ("components",)
152
+
153
+ def __init__(
154
+ self,
155
+ components: Tuple[TComp, ...],
156
+ arrlist: Optional[Sequence[str]] = None,
157
+ *,
158
+ node: Optional[Node] = None,
159
+ ) -> None:
160
+ super().__init__(arrlist, node)
161
+
162
+ self.components: Final = components
163
+ """
164
+ A tuple of :class:`~faster_eth_abi.grammar.ABIType` instances for each of the
165
+ tuple type's components.
166
+ """
167
+
168
+ def to_type_str(self) -> TypeStr:
169
+ arrlist = self.arrlist
170
+
171
+ if isinstance(arrlist, tuple):
172
+ arrlist = "".join(map(repr, map(list, arrlist)))
173
+ else:
174
+ arrlist = ""
175
+
176
+ return f"({','.join(c.to_type_str() for c in self.components)}){arrlist}"
177
+
178
+ @property
179
+ def item_type(self) -> Self:
180
+ if not self.is_array:
181
+ raise ValueError(
182
+ f"Cannot determine item type for non-array type '{self.to_type_str()}'"
183
+ )
184
+
185
+ arrlist = self.arrlist[:-1] or None # type: ignore [index]
186
+ cls = type(self)
187
+ if cls is TupleType:
188
+ return TupleType(self.components, arrlist, node=self.node) # type: ignore [return-value]
189
+ else:
190
+ return cls(self.components, arrlist, node=self.node)
191
+
192
+ def validate(self) -> None:
193
+ for c in self.components:
194
+ c.validate()
195
+
196
+ @property
197
+ def is_dynamic(self) -> bool:
198
+ if self._has_dynamic_arrlist:
199
+ return True
200
+
201
+ return any(c.is_dynamic for c in self.components)
202
+
203
+
204
+ @mypyc_attr(allow_interpreted_subclasses=True)
205
+ class BasicType(ABIType):
206
+ """
207
+ Represents the result of parsing a basic type string e.g. "uint", "address",
208
+ "ufixed128x19[][2]".
209
+ """
210
+
211
+ __slots__ = ("base", "sub")
212
+
213
+ def __init__(
214
+ self,
215
+ base: str,
216
+ sub: Optional[Subtype] = None,
217
+ arrlist: Optional[Sequence] = None,
218
+ *,
219
+ node: Optional[Node] = None,
220
+ ) -> None:
221
+ super().__init__(arrlist, node)
222
+
223
+ self.base: Final = base
224
+ """The base of a basic type e.g. "uint" for "uint256" etc."""
225
+
226
+ self.sub: Final = sub
227
+ """
228
+ The sub type of a basic type e.g. ``256`` for "uint256" or ``(128, 18)``
229
+ for "ufixed128x18" etc. Equal to ``None`` if type string has no sub
230
+ type.
231
+ """
232
+
233
+ def to_type_str(self) -> TypeStr:
234
+ sub, arrlist = self.sub, self.arrlist
235
+
236
+ if isinstance(sub, int):
237
+ substr = str(sub)
238
+ elif isinstance(sub, tuple):
239
+ substr = "x".join(map(str, sub))
240
+ else:
241
+ substr = ""
242
+
243
+ if isinstance(arrlist, tuple):
244
+ return self.base + substr + "".join(map(repr, map(list, arrlist)))
245
+ else:
246
+ return self.base + substr
247
+
248
+ @property
249
+ def item_type(self) -> Self:
250
+ if not self.is_array:
251
+ raise ValueError(
252
+ f"Cannot determine item type for non-array type '{self.to_type_str()}'"
253
+ )
254
+
255
+ cls = type(self)
256
+ arrlist = self.arrlist[:-1] or None # type: ignore [index]
257
+ if cls is BasicType:
258
+ return BasicType(self.base, self.sub, arrlist, node=self.node) # type: ignore [return-value]
259
+ else:
260
+ return cls(self.base, self.sub, arrlist, node=self.node)
261
+
262
+ @property
263
+ def is_dynamic(self) -> bool:
264
+ if self._has_dynamic_arrlist:
265
+ return True
266
+
267
+ base = self.base
268
+ if base == "string":
269
+ return True
270
+
271
+ if base == "bytes" and self.sub is None:
272
+ return True
273
+
274
+ return False
275
+
276
+ def validate(self) -> None:
277
+ base, sub = self.base, self.sub
278
+
279
+ # Check validity of string type
280
+ if base == "string":
281
+ if sub is not None:
282
+ self.invalidate("string type cannot have suffix")
283
+
284
+ # Check validity of bytes type
285
+ elif base == "bytes":
286
+ if not (sub is None or isinstance(sub, int)):
287
+ self.invalidate(
288
+ "bytes type must have either no suffix or a numerical suffix"
289
+ )
290
+
291
+ if isinstance(sub, int) and sub > 32:
292
+ self.invalidate("maximum 32 bytes for fixed-length bytes")
293
+
294
+ # Check validity of integer type
295
+ elif base in ("int", "uint"):
296
+ if not isinstance(sub, int):
297
+ self.invalidate("integer type must have numerical suffix")
298
+
299
+ if sub < 8 or sub > 256:
300
+ self.invalidate("integer size out of bounds (max 256 bits)")
301
+
302
+ if sub % 8 != 0:
303
+ self.invalidate("integer size must be multiple of 8")
304
+
305
+ # Check validity of fixed type
306
+ elif base in ("fixed", "ufixed"):
307
+ if not isinstance(sub, tuple):
308
+ self.invalidate(
309
+ "fixed type must have suffix of form <bits>x<exponent>, "
310
+ "e.g. 128x19",
311
+ )
312
+
313
+ bits, minus_e = sub
314
+
315
+ if bits < 8 or bits > 256:
316
+ self.invalidate("fixed size out of bounds (max 256 bits)")
317
+
318
+ if bits % 8 != 0:
319
+ self.invalidate("fixed size must be multiple of 8")
320
+
321
+ if minus_e < 1 or minus_e > 80:
322
+ self.invalidate(
323
+ f"fixed exponent size out of bounds, {minus_e} must be in 1-80"
324
+ )
325
+
326
+ # Check validity of hash type
327
+ elif base == "hash":
328
+ if not isinstance(sub, int):
329
+ self.invalidate("hash type must have numerical suffix")
330
+
331
+ # Check validity of address type
332
+ elif base == "address":
333
+ if sub is not None:
334
+ self.invalidate("address cannot have suffix")
335
+
336
+
337
+ def normalize(type_str: TypeStr) -> TypeStr:
338
+ """
339
+ Normalizes a type string into its canonical version e.g. the type string
340
+ 'int' becomes 'int256', etc.
341
+
342
+ :param type_str: The type string to be normalized.
343
+ :returns: The canonical version of the input type string.
344
+ """
345
+ return TYPE_ALIAS_RE.sub(__normalize, type_str)
346
+
347
+
348
+ def __normalize(match: "re.Match[str]") -> str:
349
+ return TYPE_ALIASES[match.group(0)]
Binary file
faster_eth_abi/codec.py CHANGED
@@ -18,6 +18,7 @@ from faster_eth_abi.decoding import (
18
18
  )
19
19
  from faster_eth_abi.exceptions import (
20
20
  EncodingError,
21
+ MultipleEntriesFound,
21
22
  )
22
23
  from faster_eth_abi.registry import (
23
24
  ABIRegistry,
@@ -74,20 +75,18 @@ class ABIEncoder(BaseABICoder):
74
75
  :returns: ``True`` if ``arg`` is encodable as a value of the ABI type
75
76
  ``typ``. Otherwise, ``False``.
76
77
  """
77
- if not self.is_encodable_type(typ):
78
+ try:
79
+ encoder = self._registry.get_encoder(typ)
80
+ except MultipleEntriesFound:
81
+ raise
82
+ except:
78
83
  return False
79
84
 
80
- encoder = self._registry.get_encoder(typ)
81
-
85
+ validate = getattr(encoder, "validate_value", encoder)
82
86
  try:
83
- encoder.validate_value(arg)
87
+ validate(arg)
84
88
  except EncodingError:
85
89
  return False
86
- except AttributeError:
87
- try:
88
- encoder(arg)
89
- except EncodingError:
90
- return False
91
90
 
92
91
  return True
93
92
 
@@ -1,20 +1,29 @@
1
+ # mypy: disable-error-code="misc"
2
+ # cannot subclass `Any`
3
+
4
+ """
5
+ faster-eth-abi exceptions always inherit from eth-abi exceptions, so porting to faster-eth-abi
6
+ does not require any change to your existing exception handlers. They will continue to work.
7
+ """
8
+
9
+ import eth_abi.exceptions
1
10
  import parsimonious
2
11
 
3
12
 
4
- class EncodingError(Exception):
13
+ class EncodingError(eth_abi.exceptions.EncodingError):
5
14
  """
6
15
  Base exception for any error that occurs during encoding.
7
16
  """
8
17
 
9
18
 
10
- class EncodingTypeError(EncodingError):
19
+ class EncodingTypeError(EncodingError, eth_abi.exceptions.EncodingTypeError):
11
20
  """
12
21
  Raised when trying to encode a python value whose type is not supported for
13
22
  the output ABI type.
14
23
  """
15
24
 
16
25
 
17
- class IllegalValue(EncodingError):
26
+ class IllegalValue(EncodingError, eth_abi.exceptions.IllegalValue):
18
27
  """
19
28
  Raised when trying to encode a python value with the correct type but with
20
29
  a value that is not considered legal for the output ABI type.
@@ -26,7 +35,7 @@ class IllegalValue(EncodingError):
26
35
  """
27
36
 
28
37
 
29
- class ValueOutOfBounds(IllegalValue):
38
+ class ValueOutOfBounds(IllegalValue, eth_abi.exceptions.ValueOutOfBounds):
30
39
  """
31
40
  Raised when trying to encode a python value with the correct type but with
32
41
  a value that appears outside the range of valid values for the output ABI
@@ -39,31 +48,31 @@ class ValueOutOfBounds(IllegalValue):
39
48
  """
40
49
 
41
50
 
42
- class DecodingError(Exception):
51
+ class DecodingError(eth_abi.exceptions.DecodingError):
43
52
  """
44
53
  Base exception for any error that occurs during decoding.
45
54
  """
46
55
 
47
56
 
48
- class InsufficientDataBytes(DecodingError):
57
+ class InsufficientDataBytes(DecodingError, eth_abi.exceptions.InsufficientDataBytes):
49
58
  """
50
59
  Raised when there are insufficient data to decode a value for a given ABI type.
51
60
  """
52
61
 
53
62
 
54
- class NonEmptyPaddingBytes(DecodingError):
63
+ class NonEmptyPaddingBytes(DecodingError, eth_abi.exceptions.NonEmptyPaddingBytes):
55
64
  """
56
65
  Raised when the padding bytes of an ABI value are malformed.
57
66
  """
58
67
 
59
68
 
60
- class InvalidPointer(DecodingError):
69
+ class InvalidPointer(DecodingError, eth_abi.exceptions.InvalidPointer):
61
70
  """
62
71
  Raised when the pointer to a value in the ABI encoding is invalid.
63
72
  """
64
73
 
65
74
 
66
- class ParseError(parsimonious.ParseError): # type: ignore[misc] # subclasses Any
75
+ class ParseError(eth_abi.exceptions.ParseError):
67
76
  """
68
77
  Raised when an ABI type string cannot be parsed.
69
78
  """
@@ -75,7 +84,7 @@ class ParseError(parsimonious.ParseError): # type: ignore[misc] # subclasses An
75
84
  )
76
85
 
77
86
 
78
- class ABITypeError(ValueError):
87
+ class ABITypeError(eth_abi.exceptions.ABITypeError):
79
88
  """
80
89
  Raised when a parsed ABI type has inconsistent properties; for example,
81
90
  when trying to parse the type string ``'uint7'`` (which has a bit-width
@@ -83,13 +92,13 @@ class ABITypeError(ValueError):
83
92
  """
84
93
 
85
94
 
86
- class PredicateMappingError(Exception):
95
+ class PredicateMappingError(eth_abi.exceptions.PredicateMappingError):
87
96
  """
88
97
  Raised when an error occurs in a registry's internal mapping.
89
98
  """
90
99
 
91
100
 
92
- class NoEntriesFound(ValueError, PredicateMappingError):
101
+ class NoEntriesFound(PredicateMappingError, eth_abi.exceptions.NoEntriesFound):
93
102
  """
94
103
  Raised when no registration is found for a type string in a registry's
95
104
  internal mapping.
@@ -101,7 +110,7 @@ class NoEntriesFound(ValueError, PredicateMappingError):
101
110
  """
102
111
 
103
112
 
104
- class MultipleEntriesFound(ValueError, PredicateMappingError):
113
+ class MultipleEntriesFound(PredicateMappingError, eth_abi.exceptions.MultipleEntriesFound):
105
114
  """
106
115
  Raised when multiple registrations are found for a type string in a
107
116
  registry's internal mapping. This error is non-recoverable and indicates
@@ -12,11 +12,13 @@ from eth_typing import (
12
12
  TypeStr,
13
13
  )
14
14
 
15
- from .grammar import (
15
+ from ._grammar import (
16
16
  ABIType,
17
17
  BasicType,
18
18
  TupleType,
19
19
  normalize,
20
+ )
21
+ from .grammar import (
20
22
  parse,
21
23
  )
22
24
 
faster_eth_abi/grammar.py CHANGED
@@ -25,6 +25,14 @@ from typing_extensions import (
25
25
  Self,
26
26
  )
27
27
 
28
+ from faster_eth_abi._grammar import (
29
+ TYPE_ALIASES,
30
+ TYPE_ALIAS_RE,
31
+ ABIType,
32
+ BasicType,
33
+ TupleType,
34
+ normalize,
35
+ )
28
36
  from faster_eth_abi.exceptions import (
29
37
  ABITypeError,
30
38
  ParseError,
@@ -156,313 +164,7 @@ class NodeVisitor(parsimonious.NodeVisitor): # type: ignore [misc]
156
164
 
157
165
  visitor: Final = NodeVisitor()
158
166
 
159
-
160
- class ABIType:
161
- """
162
- Base class for results of type string parsing operations.
163
- """
164
-
165
- __slots__ = ("arrlist", "node")
166
-
167
- def __init__(
168
- self, arrlist: Optional[Sequence] = None, node: Optional[Node] = None
169
- ) -> None:
170
- self.arrlist: Final = arrlist
171
- """
172
- The list of array dimensions for a parsed type. Equal to ``None`` if
173
- type string has no array dimensions.
174
- """
175
-
176
- self.node: Final = node
177
- """
178
- The parsimonious ``Node`` instance associated with this parsed type.
179
- Used to generate error messages for invalid types.
180
- """
181
-
182
- def __repr__(self) -> str: # pragma: no cover
183
- return f"<{type(self).__qualname__} {self.to_type_str()!r}>"
184
-
185
- def __eq__(self, other: Any) -> bool:
186
- # Two ABI types are equal if their string representations are equal
187
- return type(self) is type(other) and self.to_type_str() == other.to_type_str()
188
-
189
- def to_type_str(self) -> TypeStr: # pragma: no cover
190
- """
191
- Returns the string representation of an ABI type. This will be equal to
192
- the type string from which it was created.
193
- """
194
- raise NotImplementedError("Must implement `to_type_str`")
195
-
196
- @property
197
- def item_type(self) -> Self:
198
- """
199
- If this type is an array type, equal to an appropriate
200
- :class:`~faster_eth_abi.grammar.ABIType` instance for the array's items.
201
- """
202
- raise NotImplementedError("Must implement `item_type`")
203
-
204
- def validate(self) -> None: # pragma: no cover
205
- """
206
- Validates the properties of an ABI type against the solidity ABI spec:
207
-
208
- https://solidity.readthedocs.io/en/develop/abi-spec.html
209
-
210
- Raises :class:`~faster_eth_abi.exceptions.ABITypeError` if validation fails.
211
- """
212
- raise NotImplementedError("Must implement `validate`")
213
-
214
- def invalidate(self, error_msg: str) -> NoReturn:
215
- # Invalidates an ABI type with the given error message. Expects that a
216
- # parsimonious node was provided from the original parsing operation
217
- # that yielded this type.
218
- node = self.node
219
-
220
- raise ABITypeError(
221
- f"For '{node.text}' type at column {node.start + 1} "
222
- f"in '{node.full_text}': {error_msg}"
223
- )
224
-
225
- @property
226
- def is_array(self) -> bool:
227
- """
228
- Equal to ``True`` if a type is an array type (i.e. if it has an array
229
- dimension list). Otherwise, equal to ``False``.
230
- """
231
- return self.arrlist is not None
232
-
233
- @property
234
- def is_dynamic(self) -> bool:
235
- """
236
- Equal to ``True`` if a type has a dynamically sized encoding.
237
- Otherwise, equal to ``False``.
238
- """
239
- raise NotImplementedError("Must implement `is_dynamic`")
240
-
241
- @property
242
- def _has_dynamic_arrlist(self) -> bool:
243
- return self.is_array and any(len(dim) == 0 for dim in self.arrlist)
244
-
245
-
246
- TComp = TypeVar("TComp", bound=ABIType)
247
-
248
-
249
- @final
250
- class TupleType(ABIType):
251
- """
252
- Represents the result of parsing a tuple type string e.g. "(int,bool)".
253
- """
254
-
255
- __slots__ = ("components",)
256
-
257
- def __init__(
258
- self,
259
- components: Tuple[TComp, ...],
260
- arrlist: Optional[Sequence] = None,
261
- *,
262
- node: Optional[Node] = None,
263
- ) -> None:
264
- super().__init__(arrlist, node)
265
-
266
- self.components: Final = components
267
- """
268
- A tuple of :class:`~faster_eth_abi.grammar.ABIType` instances for each of the
269
- tuple type's components.
270
- """
271
-
272
- def to_type_str(self) -> TypeStr:
273
- arrlist = self.arrlist
274
-
275
- if isinstance(arrlist, tuple):
276
- arrlist = "".join(repr(list(a)) for a in arrlist)
277
- else:
278
- arrlist = ""
279
-
280
- return f"({','.join(c.to_type_str() for c in self.components)}){arrlist}"
281
-
282
- @property
283
- def item_type(self) -> Self:
284
- if not self.is_array:
285
- raise ValueError(
286
- f"Cannot determine item type for non-array type '{self.to_type_str()}'"
287
- )
288
-
289
- return type(self)(
290
- self.components,
291
- self.arrlist[:-1] or None, # type: ignore [index]
292
- node=self.node,
293
- )
294
-
295
- def validate(self) -> None:
296
- for c in self.components:
297
- c.validate()
298
-
299
- @property
300
- def is_dynamic(self) -> bool:
301
- if self._has_dynamic_arrlist:
302
- return True
303
-
304
- return any(c.is_dynamic for c in self.components)
305
-
306
-
307
- @final
308
- class BasicType(ABIType):
309
- """
310
- Represents the result of parsing a basic type string e.g. "uint", "address",
311
- "ufixed128x19[][2]".
312
- """
313
-
314
- __slots__ = ("base", "sub")
315
-
316
- def __init__(
317
- self,
318
- base: str,
319
- sub: Any = None,
320
- arrlist: Optional[Sequence] = None,
321
- *,
322
- node: Optional[Node] = None,
323
- ) -> None:
324
- super().__init__(arrlist, node)
325
-
326
- self.base: Final = base
327
- """The base of a basic type e.g. "uint" for "uint256" etc."""
328
-
329
- self.sub: Final = sub
330
- """
331
- The sub type of a basic type e.g. ``256`` for "uint256" or ``(128, 18)``
332
- for "ufixed128x18" etc. Equal to ``None`` if type string has no sub
333
- type.
334
- """
335
-
336
- def to_type_str(self) -> TypeStr:
337
- sub, arrlist = self.sub, self.arrlist
338
-
339
- if isinstance(sub, int):
340
- substr = str(sub)
341
- elif isinstance(sub, tuple):
342
- substr = "x".join(str(s) for s in sub)
343
- else:
344
- substr = ""
345
-
346
- if isinstance(arrlist, tuple):
347
- return self.base + substr + "".join(repr(list(a)) for a in arrlist)
348
- else:
349
- return self.base + substr
350
-
351
- @property
352
- def item_type(self) -> Self:
353
- if not self.is_array:
354
- raise ValueError(
355
- f"Cannot determine item type for non-array type '{self.to_type_str()}'"
356
- )
357
-
358
- return type(self)(
359
- self.base,
360
- self.sub,
361
- self.arrlist[:-1] or None, # type: ignore [index]
362
- node=self.node,
363
- )
364
-
365
- @property
366
- def is_dynamic(self) -> bool:
367
- if self._has_dynamic_arrlist:
368
- return True
369
-
370
- if self.base == "string":
371
- return True
372
-
373
- if self.base == "bytes" and self.sub is None:
374
- return True
375
-
376
- return False
377
-
378
- def validate(self) -> None:
379
- base, sub = self.base, self.sub
380
-
381
- # Check validity of string type
382
- if base == "string":
383
- if sub is not None:
384
- self.invalidate("string type cannot have suffix")
385
-
386
- # Check validity of bytes type
387
- elif base == "bytes":
388
- if not (sub is None or isinstance(sub, int)):
389
- self.invalidate(
390
- "bytes type must have either no suffix or a numerical suffix"
391
- )
392
-
393
- if isinstance(sub, int) and sub > 32:
394
- self.invalidate("maximum 32 bytes for fixed-length bytes")
395
-
396
- # Check validity of integer type
397
- elif base in ("int", "uint"):
398
- if not isinstance(sub, int):
399
- self.invalidate("integer type must have numerical suffix")
400
-
401
- if sub < 8 or sub > 256:
402
- self.invalidate("integer size out of bounds (max 256 bits)")
403
-
404
- if sub % 8 != 0:
405
- self.invalidate("integer size must be multiple of 8")
406
-
407
- # Check validity of fixed type
408
- elif base in ("fixed", "ufixed"):
409
- if not isinstance(sub, tuple):
410
- self.invalidate(
411
- "fixed type must have suffix of form <bits>x<exponent>, "
412
- "e.g. 128x19",
413
- )
414
-
415
- bits, minus_e = sub
416
-
417
- if bits < 8 or bits > 256:
418
- self.invalidate("fixed size out of bounds (max 256 bits)")
419
-
420
- if bits % 8 != 0:
421
- self.invalidate("fixed size must be multiple of 8")
422
-
423
- if minus_e < 1 or minus_e > 80:
424
- self.invalidate(
425
- f"fixed exponent size out of bounds, {minus_e} must be in 1-80"
426
- )
427
-
428
- # Check validity of hash type
429
- elif base == "hash":
430
- if not isinstance(sub, int):
431
- self.invalidate("hash type must have numerical suffix")
432
-
433
- # Check validity of address type
434
- elif base == "address":
435
- if sub is not None:
436
- self.invalidate("address cannot have suffix")
437
-
438
-
439
- TYPE_ALIASES: Final = {
440
- "int": "int256",
441
- "uint": "uint256",
442
- "fixed": "fixed128x18",
443
- "ufixed": "ufixed128x18",
444
- "function": "bytes24",
445
- "byte": "bytes1",
446
- }
447
-
448
- TYPE_ALIAS_RE: Final = re.compile(
449
- rf"\b({'|'.join(re.escape(a) for a in TYPE_ALIASES.keys())})\b"
450
- )
451
-
452
-
453
- def normalize(type_str: TypeStr) -> TypeStr:
454
- """
455
- Normalizes a type string into its canonical version e.g. the type string
456
- 'int' becomes 'int256', etc.
457
-
458
- :param type_str: The type string to be normalized.
459
- :returns: The canonical version of the input type string.
460
- """
461
- return TYPE_ALIAS_RE.sub(__normalize, type_str)
462
-
463
-
464
- def __normalize(match: "re.Match[str]") -> str:
465
- return TYPE_ALIASES[match.group(0)]
167
+ parse: Final = visitor.parse
466
168
 
467
169
 
468
- parse: Final = visitor.parse
170
+ __all__ = ["NodeVisitor", "ABIType", "TupleType", "BasicType", "grammar", "parse", "normalize", "visitor", "TYPE_ALIASES", "TYPE_ALIAS_RE"]
Binary file
@@ -1,17 +1,24 @@
1
1
  import abc
2
- import copy
3
2
  import functools
3
+ from copy import copy
4
4
  from typing import (
5
5
  Any,
6
6
  Callable,
7
+ Dict,
8
+ Final,
9
+ Generic,
7
10
  Optional,
8
11
  Type,
12
+ TypeVar,
9
13
  Union,
10
14
  )
11
15
 
12
16
  from eth_typing import (
13
17
  TypeStr,
14
18
  )
19
+ from typing_extensions import (
20
+ Self,
21
+ )
15
22
 
16
23
  from . import (
17
24
  decoding,
@@ -30,6 +37,8 @@ from .io import (
30
37
  ContextFramesBytesIO,
31
38
  )
32
39
 
40
+ T = TypeVar("T")
41
+
33
42
  Lookup = Union[TypeStr, Callable[[TypeStr], bool]]
34
43
 
35
44
  EncoderCallable = Callable[[Any], bytes]
@@ -51,34 +60,35 @@ class Copyable(abc.ABC):
51
60
  return self.copy()
52
61
 
53
62
 
54
- class PredicateMapping(Copyable):
63
+ class PredicateMapping(Copyable, Generic[T]):
55
64
  """
56
65
  Acts as a mapping from predicate functions to values. Values are retrieved
57
66
  when their corresponding predicate matches a given input. Predicates can
58
67
  also be labeled to facilitate removal from the mapping.
59
68
  """
60
69
 
61
- def __init__(self, name):
62
- self._name = name
63
- self._values = {}
64
- self._labeled_predicates = {}
70
+ def __init__(self, name: str):
71
+ self._name: Final = name
72
+ self._values: Dict[Lookup, T] = {}
73
+ self._labeled_predicates: Dict[str, Lookup] = {}
65
74
 
66
- def add(self, predicate, value, label=None):
75
+ def add(self, predicate: Lookup, value: T, label: Optional[str] = None) -> None:
67
76
  if predicate in self._values:
68
77
  raise ValueError(f"Matcher {predicate!r} already exists in {self._name}")
69
78
 
70
79
  if label is not None:
71
- if label in self._labeled_predicates:
80
+ labeled_predicates = self._labeled_predicates
81
+ if label in labeled_predicates:
72
82
  raise ValueError(
73
83
  f"Matcher {predicate!r} with label '{label}' "
74
84
  f"already exists in {self._name}"
75
85
  )
76
86
 
77
- self._labeled_predicates[label] = predicate
87
+ labeled_predicates[label] = predicate
78
88
 
79
89
  self._values[predicate] = value
80
90
 
81
- def find(self, type_str):
91
+ def find(self, type_str: TypeStr) -> T:
82
92
  results = tuple(
83
93
  (predicate, value)
84
94
  for predicate, value in self._values.items()
@@ -103,9 +113,9 @@ class PredicateMapping(Copyable):
103
113
  "documentation for more information."
104
114
  )
105
115
 
106
- return values[0]
116
+ return values[0] # type: ignore [no-any-return]
107
117
 
108
- def remove_by_equality(self, predicate):
118
+ def remove_by_equality(self, predicate: Lookup) -> None:
109
119
  # Delete the predicate mapping to the previously stored value
110
120
  try:
111
121
  del self._values[predicate]
@@ -120,7 +130,7 @@ class PredicateMapping(Copyable):
120
130
  else:
121
131
  del self._labeled_predicates[label]
122
132
 
123
- def _label_for_predicate(self, predicate):
133
+ def _label_for_predicate(self, predicate: Lookup) -> str:
124
134
  # Both keys and values in `_labeled_predicates` are unique since the
125
135
  # `add` method enforces this
126
136
  for key, value in self._labeled_predicates.items():
@@ -131,16 +141,17 @@ class PredicateMapping(Copyable):
131
141
  f"Matcher {predicate!r} not referred to by any label in {self._name}"
132
142
  )
133
143
 
134
- def remove_by_label(self, label):
144
+ def remove_by_label(self, label: str) -> None:
145
+ labeled_predicates = self._labeled_predicates
135
146
  try:
136
- predicate = self._labeled_predicates[label]
147
+ predicate = labeled_predicates[label]
137
148
  except KeyError:
138
149
  raise KeyError(f"Label '{label}' not found in {self._name}")
139
150
 
140
- del self._labeled_predicates[label]
151
+ del labeled_predicates[label]
141
152
  del self._values[predicate]
142
153
 
143
- def remove(self, predicate_or_label):
154
+ def remove(self, predicate_or_label: Union[Lookup, str]) -> None:
144
155
  if callable(predicate_or_label):
145
156
  self.remove_by_equality(predicate_or_label)
146
157
  elif isinstance(predicate_or_label, str):
@@ -151,11 +162,11 @@ class PredicateMapping(Copyable):
151
162
  f"{type(predicate_or_label)}"
152
163
  )
153
164
 
154
- def copy(self):
165
+ def copy(self) -> Self:
155
166
  cpy = type(self)(self._name)
156
167
 
157
- cpy._values = copy.copy(self._values)
158
- cpy._labeled_predicates = copy.copy(self._labeled_predicates)
168
+ cpy._values = copy(self._values)
169
+ cpy._labeled_predicates = copy(self._labeled_predicates)
159
170
 
160
171
  return cpy
161
172
 
@@ -282,6 +293,7 @@ def _clear_encoder_cache(old_method: Callable[..., None]) -> Callable[..., None]
282
293
  @functools.wraps(old_method)
283
294
  def new_method(self: "ABIRegistry", *args: Any, **kwargs: Any) -> None:
284
295
  self.get_encoder.cache_clear()
296
+ self.get_tuple_encoder.cache_clear()
285
297
  return old_method(self, *args, **kwargs)
286
298
 
287
299
  return new_method
@@ -291,6 +303,7 @@ def _clear_decoder_cache(old_method: Callable[..., None]) -> Callable[..., None]
291
303
  @functools.wraps(old_method)
292
304
  def new_method(self: "ABIRegistry", *args: Any, **kwargs: Any) -> None:
293
305
  self.get_decoder.cache_clear()
306
+ self.get_tuple_decoder.cache_clear()
294
307
  return old_method(self, *args, **kwargs)
295
308
 
296
309
  return new_method
@@ -343,8 +356,8 @@ class BaseRegistry:
343
356
 
344
357
  class ABIRegistry(Copyable, BaseRegistry):
345
358
  def __init__(self):
346
- self._encoders = PredicateMapping("encoder registry")
347
- self._decoders = PredicateMapping("decoder registry")
359
+ self._encoders: PredicateMapping[Encoder] = PredicateMapping("encoder registry")
360
+ self._decoders: PredicateMapping[Decoder] = PredicateMapping("decoder registry")
348
361
  self.get_encoder = functools.lru_cache(maxsize=None)(self._get_encoder_uncached)
349
362
  self.get_decoder = functools.lru_cache(maxsize=None)(self._get_decoder_uncached)
350
363
  self.get_tuple_encoder = functools.lru_cache(maxsize=None)(
@@ -518,8 +531,8 @@ class ABIRegistry(Copyable, BaseRegistry):
518
531
  """
519
532
  cpy = type(self)()
520
533
 
521
- cpy._encoders = copy.copy(self._encoders)
522
- cpy._decoders = copy.copy(self._decoders)
534
+ cpy._encoders = copy(self._encoders)
535
+ cpy._decoders = copy(self._decoders)
523
536
 
524
537
  return cpy
525
538
 
@@ -2,7 +2,9 @@ from typing import (
2
2
  Callable,
3
3
  Final,
4
4
  Optional,
5
+ Tuple,
5
6
  Union,
7
+ cast,
6
8
  )
7
9
 
8
10
  from cchecksum import (
@@ -15,11 +17,13 @@ from hypothesis import (
15
17
  strategies as st,
16
18
  )
17
19
 
18
- from faster_eth_abi.grammar import (
20
+ from faster_eth_abi._grammar import (
19
21
  ABIType,
20
22
  BasicType,
21
23
  TupleType,
22
24
  normalize,
25
+ )
26
+ from faster_eth_abi.grammar import (
23
27
  parse,
24
28
  )
25
29
  from faster_eth_abi.registry import (
@@ -81,7 +85,7 @@ class StrategyRegistry(BaseRegistry):
81
85
  def get_uint_strategy(
82
86
  abi_type: BasicType, registry: StrategyRegistry
83
87
  ) -> st.SearchStrategy:
84
- bits = abi_type.sub
88
+ bits = cast(int, abi_type.sub)
85
89
 
86
90
  return st.integers(
87
91
  min_value=0,
@@ -92,7 +96,7 @@ def get_uint_strategy(
92
96
  def get_int_strategy(
93
97
  abi_type: BasicType, registry: StrategyRegistry
94
98
  ) -> st.SearchStrategy:
95
- bits = abi_type.sub
99
+ bits = cast(int, abi_type.sub)
96
100
 
97
101
  return st.integers(
98
102
  min_value=-(2 ** (bits - 1)),
@@ -107,7 +111,7 @@ bool_strategy: Final = st.booleans()
107
111
  def get_ufixed_strategy(
108
112
  abi_type: BasicType, registry: StrategyRegistry
109
113
  ) -> st.SearchStrategy:
110
- bits, places = abi_type.sub
114
+ bits, places = cast(Tuple[int, int], abi_type.sub)
111
115
 
112
116
  return st.decimals(
113
117
  min_value=0,
@@ -119,7 +123,7 @@ def get_ufixed_strategy(
119
123
  def get_fixed_strategy(
120
124
  abi_type: BasicType, registry: StrategyRegistry
121
125
  ) -> st.SearchStrategy:
122
- bits, places = abi_type.sub
126
+ bits, places = cast(Tuple[int, int], abi_type.sub)
123
127
 
124
128
  return st.decimals(
125
129
  min_value=-(2 ** (bits - 1)),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: faster_eth_abi
3
- Version: 5.2.10
3
+ Version: 5.2.12
4
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
@@ -25,6 +25,7 @@ Description-Content-Type: text/markdown
25
25
  License-File: LICENSE
26
26
  Requires-Dist: cchecksum<0.4,>=0.2.6
27
27
  Requires-Dist: faster-eth-utils>=2.0.0
28
+ Requires-Dist: eth-abi<6,>=5.0.1
28
29
  Requires-Dist: eth-typing>=3.0.0
29
30
  Requires-Dist: mypy_extensions
30
31
  Requires-Dist: parsimonious<0.11.0,>=0.10.0
@@ -32,7 +33,7 @@ Provides-Extra: dev
32
33
  Requires-Dist: build>=0.9.0; extra == "dev"
33
34
  Requires-Dist: bump_my_version>=0.19.0; extra == "dev"
34
35
  Requires-Dist: ipython; extra == "dev"
35
- Requires-Dist: mypy==1.10.0; extra == "dev"
36
+ Requires-Dist: mypy==1.18.2; extra == "dev"
36
37
  Requires-Dist: pre-commit>=3.4.0; extra == "dev"
37
38
  Requires-Dist: tox>=4.0.0; extra == "dev"
38
39
  Requires-Dist: twine; extra == "dev"
@@ -42,7 +43,7 @@ Requires-Dist: pytest-benchmark; extra == "dev"
42
43
  Requires-Dist: sphinx>=6.0.0; extra == "dev"
43
44
  Requires-Dist: sphinx-autobuild>=2021.3.14; extra == "dev"
44
45
  Requires-Dist: sphinx_rtd_theme>=1.0.0; extra == "dev"
45
- Requires-Dist: towncrier<25,>=24; extra == "dev"
46
+ Requires-Dist: towncrier<26,>=25; extra == "dev"
46
47
  Requires-Dist: pytest>=7.0.0; extra == "dev"
47
48
  Requires-Dist: pytest-timeout>=2.0.0; extra == "dev"
48
49
  Requires-Dist: pytest-xdist>=2.4.0; extra == "dev"
@@ -53,7 +54,7 @@ Provides-Extra: docs
53
54
  Requires-Dist: sphinx>=6.0.0; extra == "docs"
54
55
  Requires-Dist: sphinx-autobuild>=2021.3.14; extra == "docs"
55
56
  Requires-Dist: sphinx_rtd_theme>=1.0.0; extra == "docs"
56
- Requires-Dist: towncrier<25,>=24; extra == "docs"
57
+ Requires-Dist: towncrier<26,>=25; extra == "docs"
57
58
  Provides-Extra: test
58
59
  Requires-Dist: pytest>=7.0.0; extra == "test"
59
60
  Requires-Dist: pytest-timeout>=2.0.0; extra == "test"
@@ -85,10 +86,14 @@ Dynamic: summary
85
86
 
86
87
  ##### This fork will be kept up-to-date with [eth-abi](https://github.com/ethereum/eth-abi). I will pull updates as they are released and push new [faster-eth-abi](https://github.com/BobTheBuidler/faster-eth-abi) releases to [PyPI](https://pypi.org/project/faster-eth-abi/).
87
88
 
88
- ##### You can find the compiled C code on faster-eth-abi [master](https://github.com/BobTheBuidler/eth-abi/tree/master) branch.
89
+ ##### Starting in [v5.2.12](https://github.com/BobTheBuidler/faster-eth-abi/releases/tag/v5.2.12), all `faster-eth-abi` Exception classes inherit from the matching Exception class in `eth-abi`, so porting to `faster-eth-abi` does not require any change to your existing exception handlers. All existing exception handling in your codebase will continue to work as it did when originaly implemented.
89
90
 
90
91
  ##### We benchmark `faster-eth-abi` against the original `eth-abi` for your convenience. [See results](https://github.com/BobTheBuidler/faster-eth-abi/tree/master/benchmarks/results).
91
92
 
93
+ ##### You can find the compiled C code and header files in the [build](https://github.com/BobTheBuidler/faster-eth-abi/tree/master/build) directory.
94
+
95
+ ###### You may also be interested in: [faster-web3.py](https://github.com/BobTheBuidler/faster-web3.py/), [faster-hexbytes](https://github.com/BobTheBuidler/faster-hexbytes/), and [faster-eth-utils](https://github.com/BobTheBuidler/faster-eth-utils/)
96
+
92
97
  ##### The original eth-abi readme is below:
93
98
 
94
99
  # Ethereum Contract Interface (ABI) Utility
@@ -0,0 +1,46 @@
1
+ faster_eth_abi__mypyc.cp310-win_amd64.pyd,sha256=G-oUQASs9sUGEgHiPoouJV8sRNpisxQautk-LhqitsA,207360
2
+ faster_eth_abi/__init__.py,sha256=JpTfPTiusUGMmX8sEsGAxvILxFbvhh3MEyfiKOd5o9g,217
3
+ faster_eth_abi/_codec.cp310-win_amd64.pyd,sha256=e76x-FkX73DNnZF6rAI0RIZdjIj_eA2NDln4fGyj8DI,10752
4
+ faster_eth_abi/_codec.py,sha256=9l49XZv5CHdbSU_WShfvjCOGwrRhH75aFsh6eaZ-e0E,2341
5
+ faster_eth_abi/_decoding.cp310-win_amd64.pyd,sha256=qXzYkVgHbuMnbOQ93xFFVRNvyZH9nF3K5ytUcBCMrcg,10752
6
+ faster_eth_abi/_decoding.py,sha256=06ddzblp834cZ_6SA5Q3J3_XnQTa0gmWeM4gYRxrcSk,4555
7
+ faster_eth_abi/_encoding.cp310-win_amd64.pyd,sha256=UFOm6TWrx4zdFcqSclhNGYdu_YxpjB1HHFkE3xV9l6g,10752
8
+ faster_eth_abi/_encoding.py,sha256=rsZihtFUqYu80ANOsxP9QwpFJDH73VBVJSzOrllBm2k,3340
9
+ faster_eth_abi/_grammar.cp310-win_amd64.pyd,sha256=ZjkUTFCNAe8Ru9kNgGH667-LlJVXGnHjRXNEaJVWW7s,10752
10
+ faster_eth_abi/_grammar.py,sha256=IyftL6Ayb-6C1jR2xAt4y_NRnqdGtH08gwoz5zrF3rc,10491
11
+ faster_eth_abi/abi.cp310-win_amd64.pyd,sha256=pomCaJ8-Bh3kMhoIKa5-lAtYuIK-q74AcStB8xBGmnE,10752
12
+ faster_eth_abi/abi.py,sha256=-t9OVBSCxy6SuWpCu3cxHrCqkx8_svPIRb0MSFXEl5Q,383
13
+ faster_eth_abi/base.py,sha256=y4IXpQJWGfUISl3xjCO420Grxido3tE2ebPV2rK-DvM,1229
14
+ faster_eth_abi/codec.py,sha256=QZFGQ8Fg2BRVGDVLVpmrkmqjtkdMVG1Gqr9AD7dSEI0,4557
15
+ faster_eth_abi/constants.cp310-win_amd64.pyd,sha256=G1k8lM9KRyaabjnonXsOeW6d0s2LuGqP-3PZOjEjtYY,10752
16
+ faster_eth_abi/constants.py,sha256=q3FGynS-Eb78cnrL6mBoAvTDz16PF3tW2OylTMd6ajs,114
17
+ faster_eth_abi/decoding.py,sha256=7zOcSLdiQhAJWnCOSAdFg2AtSMoj8ZdN2IYE_aZKHQU,17028
18
+ faster_eth_abi/encoding.py,sha256=P1svhYylcZa55cQ9LPj6jV8iJVLSL_c5SIZT1Umol58,19679
19
+ faster_eth_abi/exceptions.py,sha256=r4O6bmcxRzw44lNNgz_QdhukQfrnRfTm10xK2wPuba4,3701
20
+ faster_eth_abi/from_type_str.cp310-win_amd64.pyd,sha256=qMgKmXl8xh7Nwp4OhU-ev8Ac78haG9ECSd097_pnKo4,10752
21
+ faster_eth_abi/from_type_str.py,sha256=PV697XdxjhwHYCBbaA-H_9I2CrfkQ5vsSkSxpCOt8eg,4474
22
+ faster_eth_abi/grammar.py,sha256=a2FopTc3TtRvjYVHlOPo18IPEXueuD8IqDdCyiuFStM,4681
23
+ faster_eth_abi/io.py,sha256=E_QX7aYAjGYnkNAZmJMmSmx1lqvl_FDNmMFruTi9UX4,3831
24
+ faster_eth_abi/packed.cp310-win_amd64.pyd,sha256=QfRCtyg9QK5QUx22wPGijrVWe63Y6zm8DXZ3USyWkrc,10752
25
+ faster_eth_abi/packed.py,sha256=RZ2chvsx9_AL9OxY1ixHTsaUJHaR_tmrNdViOIp-xSg,316
26
+ faster_eth_abi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ faster_eth_abi/registry.py,sha256=WYkH4BF2of91Pv8xLxBPTgBP0xV2uJ0FsYlYx-XrUcc,21758
28
+ faster_eth_abi/tools/__init__.cp310-win_amd64.pyd,sha256=nIQKnKmfxaVQtrUIMLh9ANKjLMQ3fQTVl7SlGPDvGo8,10752
29
+ faster_eth_abi/tools/__init__.py,sha256=jxyQnb34ldRjCTYi3Ajb5h5QlFQ6ODfKQNhOCVwR7Ao,54
30
+ faster_eth_abi/tools/_strategies.cp310-win_amd64.pyd,sha256=vuNeDYUsjSjFoZSMf00B1aiKFCoch3EBb_7gmMCnT7w,10752
31
+ faster_eth_abi/tools/_strategies.py,sha256=02wmJpj336nOFu7pBVaH4ucj3FORweKkiGqlaRgy-8c,6330
32
+ faster_eth_abi/utils/__init__.cp310-win_amd64.pyd,sha256=LH4XOJ5cLQ0txCCb4TVlcbNCDEdLJCwIzUafbQ22ln4,10752
33
+ faster_eth_abi/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ faster_eth_abi/utils/numeric.cp310-win_amd64.pyd,sha256=8NVMO3t4fg1bm-05fqQ-8QQ0w-Gq65YmlpLoziUNTEc,10752
35
+ faster_eth_abi/utils/numeric.py,sha256=saAVL12dfDrMXZeao3u2jar-U2y57YKVUqF6VOzoLxs,3395
36
+ faster_eth_abi/utils/padding.cp310-win_amd64.pyd,sha256=dIz4GLQbhFJtBSVFPvOrTmsta1eJmdwOtk3_nij17Q4,10752
37
+ faster_eth_abi/utils/padding.py,sha256=k6dkOiQ3k0OhQUZ6blCiL1VOQVYGyynucafbySjcFfY,515
38
+ faster_eth_abi/utils/string.cp310-win_amd64.pyd,sha256=rjjsh8knd-UGtskNV3P-6wQzCnhxZsEaYt64nvVFk6U,10752
39
+ faster_eth_abi/utils/string.py,sha256=wYcvWof4kuitrGGSe_NOduQaxE4HHYmpraCPXKcZxMs,455
40
+ faster_eth_abi/utils/validation.cp310-win_amd64.pyd,sha256=aKSjQpDE6WXh2IABYYD-MnGyhNV-AGFZJxOnr67Xiu4,10752
41
+ faster_eth_abi/utils/validation.py,sha256=9veO7wyQsmcFgeaGrsKdSifjV1gaXfTDDKAt1EbKHYY,539
42
+ faster_eth_abi-5.2.12.dist-info/licenses/LICENSE,sha256=Q1lDDWXR057JL2Y7HTAwclCF32_LCloN4sGUkXO1YeI,1127
43
+ faster_eth_abi-5.2.12.dist-info/METADATA,sha256=E4sFIP3_tN7CYkNFZ9jmQqKB4jZs0fRhDuGuceQvPwo,6210
44
+ faster_eth_abi-5.2.12.dist-info/WHEEL,sha256=KUuBC6lxAbHCKilKua8R9W_TM71_-9Sg5uEP3uDWcoU,101
45
+ faster_eth_abi-5.2.12.dist-info/top_level.txt,sha256=Y0kTTMPnPpssaR0jlmJwQ2XbkYXMEj_80Ewd7quo1Cg,37
46
+ faster_eth_abi-5.2.12.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ faster_eth_abi
2
+ faster_eth_abi__mypyc
@@ -1,44 +0,0 @@
1
- 76f9a3652d4d2667c55c__mypyc.cp310-win_amd64.pyd,sha256=MZoVKEvo2-6KbXZP_A50-VQ060ea-OmOZI8P-zWMTE0,165376
2
- faster_eth_abi/__init__.py,sha256=JpTfPTiusUGMmX8sEsGAxvILxFbvhh3MEyfiKOd5o9g,217
3
- faster_eth_abi/_codec.cp310-win_amd64.pyd,sha256=q3nX6wdxsXXo__2PsfRL4nb5RbXFHDQt47qu2R5XV3w,10752
4
- faster_eth_abi/_codec.py,sha256=fLRvqvrD8F38U4m1wZztvx-7JJbZaPikwXS5u9BzY14,2509
5
- faster_eth_abi/_decoding.cp310-win_amd64.pyd,sha256=IpUOb4AVj-bxSR9S_IJA7oxS3VMk03OzZWJx87PXyRE,10752
6
- faster_eth_abi/_decoding.py,sha256=06ddzblp834cZ_6SA5Q3J3_XnQTa0gmWeM4gYRxrcSk,4555
7
- faster_eth_abi/_encoding.cp310-win_amd64.pyd,sha256=hhJghgdMJUg0EVy6ZvTRxjCpxA2_FUsXmIDcbDjkeGg,10752
8
- faster_eth_abi/_encoding.py,sha256=rsZihtFUqYu80ANOsxP9QwpFJDH73VBVJSzOrllBm2k,3340
9
- faster_eth_abi/abi.cp310-win_amd64.pyd,sha256=8AyZ76PVTggbuQy65OrAedcl6z8gn9bCuvTz8Fahp50,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.cp310-win_amd64.pyd,sha256=sBtn8irTmvQlIGWkNZfs6cAwnDPtyRL8S9A0Swi3onY,10752
14
- faster_eth_abi/constants.py,sha256=q3FGynS-Eb78cnrL6mBoAvTDz16PF3tW2OylTMd6ajs,114
15
- faster_eth_abi/decoding.py,sha256=7zOcSLdiQhAJWnCOSAdFg2AtSMoj8ZdN2IYE_aZKHQU,17028
16
- faster_eth_abi/encoding.py,sha256=P1svhYylcZa55cQ9LPj6jV8iJVLSL_c5SIZT1Umol58,19679
17
- faster_eth_abi/exceptions.py,sha256=KzNYRc9t0CvlkveozWvLeo1WC_GarcBkwzV67aY_5yI,3067
18
- faster_eth_abi/from_type_str.cp310-win_amd64.pyd,sha256=sSs_Tv2kIlg9GsvNkapHOgUKETC411t9teg-5ea6C7Y,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.cp310-win_amd64.pyd,sha256=dm4JgEfYsOJIBgV0I65-lY3y4emMKz7KWYO5ZQ3q4Y0,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__.cp310-win_amd64.pyd,sha256=oL9D3WrlR5ZlkLYMy5NxRct66VBOHEwgouqxPWMML_8,10752
27
- faster_eth_abi/tools/__init__.py,sha256=jxyQnb34ldRjCTYi3Ajb5h5QlFQ6ODfKQNhOCVwR7Ao,54
28
- faster_eth_abi/tools/_strategies.cp310-win_amd64.pyd,sha256=FIHPw3W2PY9amxIpn1bdsJwM1CHcOS9ddjho5lUIYuA,10752
29
- faster_eth_abi/tools/_strategies.py,sha256=HCFdQFLa84SMf7Deui2-szTH34hxTfc0Rog_kmpTg_w,6197
30
- faster_eth_abi/utils/__init__.cp310-win_amd64.pyd,sha256=LDDdNhEb0rCuIGeC0oBI84EmihLN7aHw3Lp5DlQAmuQ,10752
31
- faster_eth_abi/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
- faster_eth_abi/utils/numeric.cp310-win_amd64.pyd,sha256=I7VmpCpnvR1MRpddK9cd6-WFwv1tcLyWE1pYCMhrzY8,10752
33
- faster_eth_abi/utils/numeric.py,sha256=saAVL12dfDrMXZeao3u2jar-U2y57YKVUqF6VOzoLxs,3395
34
- faster_eth_abi/utils/padding.cp310-win_amd64.pyd,sha256=mgLssSD11VTNXy_l7O3wK8hqLxQCAeWvVbC7qKPL9_k,10752
35
- faster_eth_abi/utils/padding.py,sha256=k6dkOiQ3k0OhQUZ6blCiL1VOQVYGyynucafbySjcFfY,515
36
- faster_eth_abi/utils/string.cp310-win_amd64.pyd,sha256=h_3W35xq8OkeOAZTcxVwFpnBYVgPY-urlJeoQ13X1iU,10752
37
- faster_eth_abi/utils/string.py,sha256=wYcvWof4kuitrGGSe_NOduQaxE4HHYmpraCPXKcZxMs,455
38
- faster_eth_abi/utils/validation.cp310-win_amd64.pyd,sha256=yq66eslHK901f1BBBl0Ap1Ot1Npxlo_iFQXBaL8Thhs,10752
39
- faster_eth_abi/utils/validation.py,sha256=9veO7wyQsmcFgeaGrsKdSifjV1gaXfTDDKAt1EbKHYY,539
40
- faster_eth_abi-5.2.10.dist-info/licenses/LICENSE,sha256=Q1lDDWXR057JL2Y7HTAwclCF32_LCloN4sGUkXO1YeI,1127
41
- faster_eth_abi-5.2.10.dist-info/METADATA,sha256=3Fa7x64NATEJZqCSbkEInZ9LqpR2h52CZKVSQoIcdsc,5499
42
- faster_eth_abi-5.2.10.dist-info/WHEEL,sha256=KUuBC6lxAbHCKilKua8R9W_TM71_-9Sg5uEP3uDWcoU,101
43
- faster_eth_abi-5.2.10.dist-info/top_level.txt,sha256=CO2FQwf61aFzjYze7Wywa5KQdJ6bbLkzDoGEjDF2g9o,43
44
- faster_eth_abi-5.2.10.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- 76f9a3652d4d2667c55c__mypyc
2
- faster_eth_abi