faster-eth-abi 5.2.25__cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.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-314-i386-linux-gnu.so +0 -0
  3. faster_eth_abi/_codec.py +83 -0
  4. faster_eth_abi/_decoding.cpython-314-i386-linux-gnu.so +0 -0
  5. faster_eth_abi/_decoding.py +371 -0
  6. faster_eth_abi/_encoding.cpython-314-i386-linux-gnu.so +0 -0
  7. faster_eth_abi/_encoding.py +514 -0
  8. faster_eth_abi/_grammar.cpython-314-i386-linux-gnu.so +0 -0
  9. faster_eth_abi/_grammar.py +389 -0
  10. faster_eth_abi/abi.cpython-314-i386-linux-gnu.so +0 -0
  11. faster_eth_abi/abi.py +17 -0
  12. faster_eth_abi/base.py +45 -0
  13. faster_eth_abi/codec.py +2809 -0
  14. faster_eth_abi/constants.cpython-314-i386-linux-gnu.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-314-i386-linux-gnu.so +0 -0
  19. faster_eth_abi/exceptions.py +127 -0
  20. faster_eth_abi/from_type_str.cpython-314-i386-linux-gnu.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-314-i386-linux-gnu.so +0 -0
  24. faster_eth_abi/io.py +137 -0
  25. faster_eth_abi/packed.cpython-314-i386-linux-gnu.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-314-i386-linux-gnu.so +0 -0
  30. faster_eth_abi/tools/__init__.py +3 -0
  31. faster_eth_abi/tools/_strategies.cpython-314-i386-linux-gnu.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-314-i386-linux-gnu.so +0 -0
  35. faster_eth_abi/utils/__init__.py +0 -0
  36. faster_eth_abi/utils/localcontext.cpython-314-i386-linux-gnu.so +0 -0
  37. faster_eth_abi/utils/localcontext.py +49 -0
  38. faster_eth_abi/utils/numeric.cpython-314-i386-linux-gnu.so +0 -0
  39. faster_eth_abi/utils/numeric.py +117 -0
  40. faster_eth_abi/utils/padding.cpython-314-i386-linux-gnu.so +0 -0
  41. faster_eth_abi/utils/padding.py +22 -0
  42. faster_eth_abi/utils/string.cpython-314-i386-linux-gnu.so +0 -0
  43. faster_eth_abi/utils/string.py +19 -0
  44. faster_eth_abi/utils/validation.cpython-314-i386-linux-gnu.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 +7 -0
  49. faster_eth_abi-5.2.25.dist-info/top_level.txt +2 -0
  50. faster_eth_abi__mypyc.cpython-314-i386-linux-gnu.so +0 -0
@@ -0,0 +1,127 @@
1
+ # mypy: disable-error-code="misc"
2
+ # cannot subclass `Any`
3
+
4
+ """
5
+ Exception classes for error handling during ABI encoding and decoding operations.
6
+
7
+ faster-eth-abi exceptions always inherit from eth-abi exceptions, so porting to faster-eth-abi
8
+ does not require any change to your existing exception handlers. They will continue to work.
9
+ """
10
+
11
+ import eth_abi.exceptions
12
+
13
+
14
+ class EncodingError(eth_abi.exceptions.EncodingError):
15
+ """
16
+ Base exception for any error that occurs during encoding.
17
+ """
18
+
19
+
20
+ class EncodingTypeError(EncodingError, eth_abi.exceptions.EncodingTypeError):
21
+ """
22
+ Raised when trying to encode a python value whose type is not supported for
23
+ the output ABI type.
24
+ """
25
+
26
+
27
+ class IllegalValue(EncodingError, eth_abi.exceptions.IllegalValue):
28
+ """
29
+ Raised when trying to encode a python value with the correct type but with
30
+ a value that is not considered legal for the output ABI type.
31
+
32
+ .. code-block:: python
33
+
34
+ fixed128x19_encoder(Decimal('NaN')) # cannot encode NaN
35
+
36
+ """
37
+
38
+
39
+ class ValueOutOfBounds(IllegalValue, eth_abi.exceptions.ValueOutOfBounds):
40
+ """
41
+ Raised when trying to encode a python value with the correct type but with
42
+ a value that appears outside the range of valid values for the output ABI
43
+ type.
44
+
45
+ .. code-block:: python
46
+
47
+ ufixed8x1_encoder(Decimal('25.6')) # out of bounds
48
+
49
+ """
50
+
51
+
52
+ class DecodingError(eth_abi.exceptions.DecodingError):
53
+ """
54
+ Base exception for any error that occurs during decoding.
55
+ """
56
+
57
+
58
+ class InsufficientDataBytes(DecodingError, eth_abi.exceptions.InsufficientDataBytes):
59
+ """
60
+ Raised when there are insufficient data to decode a value for a given ABI type.
61
+ """
62
+
63
+
64
+ class NonEmptyPaddingBytes(DecodingError, eth_abi.exceptions.NonEmptyPaddingBytes):
65
+ """
66
+ Raised when the padding bytes of an ABI value are malformed.
67
+ """
68
+
69
+
70
+ class InvalidPointer(DecodingError, eth_abi.exceptions.InvalidPointer):
71
+ """
72
+ Raised when the pointer to a value in the ABI encoding is invalid.
73
+ """
74
+
75
+
76
+ class ParseError(eth_abi.exceptions.ParseError):
77
+ """
78
+ Raised when an ABI type string cannot be parsed.
79
+ """
80
+
81
+ def __str__(self) -> str:
82
+ return (
83
+ f"Parse error at '{self.text[self.pos : self.pos + 5]}' "
84
+ f"(column {self.column()}) in type string '{self.text}'"
85
+ )
86
+
87
+
88
+ class ABITypeError(eth_abi.exceptions.ABITypeError):
89
+ """
90
+ Raised when a parsed ABI type has inconsistent properties; for example,
91
+ when trying to parse the type string ``'uint7'`` (which has a bit-width
92
+ that is not congruent with zero modulo eight).
93
+ """
94
+
95
+
96
+ class PredicateMappingError(eth_abi.exceptions.PredicateMappingError):
97
+ """
98
+ Raised when an error occurs in a registry's internal mapping.
99
+ """
100
+
101
+
102
+ class NoEntriesFound(PredicateMappingError, eth_abi.exceptions.NoEntriesFound):
103
+ """
104
+ Raised when no registration is found for a type string in a registry's
105
+ internal mapping.
106
+
107
+ .. warning::
108
+
109
+ In a future version of ``faster-eth-abi``, this error class will no longer
110
+ inherit from ``ValueError``.
111
+ """
112
+
113
+
114
+ class MultipleEntriesFound(
115
+ PredicateMappingError, eth_abi.exceptions.MultipleEntriesFound
116
+ ):
117
+ """
118
+ Raised when multiple registrations are found for a type string in a
119
+ registry's internal mapping. This error is non-recoverable and indicates
120
+ that a registry was configured incorrectly. Registrations are expected to
121
+ cover completely distinct ranges of type strings.
122
+
123
+ .. warning::
124
+
125
+ In a future version of ``faster-eth-abi``, this error class will no longer
126
+ inherit from ``ValueError``.
127
+ """
@@ -0,0 +1,141 @@
1
+ """Helpers for parsing and normalizing ABI type strings.
2
+
3
+ Provides decorators and utilities for implementing from_type_str methods on coder classes.
4
+ """
5
+ import functools
6
+ from typing import (
7
+ TYPE_CHECKING,
8
+ Any,
9
+ Callable,
10
+ Optional,
11
+ Type,
12
+ TypeVar,
13
+ )
14
+
15
+ from eth_typing import (
16
+ TypeStr,
17
+ )
18
+
19
+ from ._grammar import (
20
+ ABIType,
21
+ BasicType,
22
+ TupleType,
23
+ normalize,
24
+ )
25
+ from .grammar import (
26
+ parse,
27
+ )
28
+
29
+ if TYPE_CHECKING:
30
+ from .base import (
31
+ BaseCoder,
32
+ )
33
+
34
+
35
+ TType = TypeVar("TType", bound=Type["BaseCoder"])
36
+ OldFromTypeStr = Callable[["BaseCoder", ABIType, Any], TType]
37
+ if TYPE_CHECKING:
38
+ NewFromTypeStr = classmethod[TType, [TypeStr, Any], TType]
39
+
40
+
41
+ def parse_type_str(
42
+ expected_base: Optional[str] = None,
43
+ with_arrlist: bool = False,
44
+ ) -> Callable[[OldFromTypeStr[TType]], "NewFromTypeStr[TType]"]:
45
+ """
46
+ Used by BaseCoder subclasses as a convenience for implementing the
47
+ ``from_type_str`` method required by ``ABIRegistry``. Useful if normalizing
48
+ then parsing a type string with an (optional) expected base is required in
49
+ that method.
50
+ """
51
+
52
+ def decorator(old_from_type_str: OldFromTypeStr[TType]) -> "NewFromTypeStr[TType]":
53
+ @functools.wraps(old_from_type_str)
54
+ def new_from_type_str(cls: TType, type_str: TypeStr, registry: Any) -> TType:
55
+ normalized_type_str = normalize(type_str)
56
+ abi_type = parse(normalized_type_str)
57
+
58
+ type_str_repr = repr(type_str)
59
+ if type_str != normalized_type_str:
60
+ type_str_repr = (
61
+ f"{type_str_repr} (normalized to {normalized_type_str!r})"
62
+ )
63
+
64
+ if expected_base is not None:
65
+ if not isinstance(abi_type, BasicType):
66
+ raise ValueError(
67
+ "Cannot create {} for non-basic type {}".format(
68
+ cls.__name__,
69
+ type_str_repr,
70
+ )
71
+ )
72
+ if abi_type.base != expected_base:
73
+ raise ValueError(
74
+ "Cannot create {} for type {}: expected type with "
75
+ "base '{}'".format(
76
+ cls.__name__,
77
+ type_str_repr,
78
+ expected_base,
79
+ )
80
+ )
81
+
82
+ if not with_arrlist and abi_type.arrlist is not None:
83
+ raise ValueError(
84
+ "Cannot create {} for type {}: expected type with "
85
+ "no array dimension list".format(
86
+ cls.__name__,
87
+ type_str_repr,
88
+ )
89
+ )
90
+ if with_arrlist and abi_type.arrlist is None:
91
+ raise ValueError(
92
+ "Cannot create {} for type {}: expected type with "
93
+ "array dimension list".format(
94
+ cls.__name__,
95
+ type_str_repr,
96
+ )
97
+ )
98
+
99
+ # Perform general validation of default solidity types
100
+ abi_type.validate()
101
+
102
+ return old_from_type_str(cls, abi_type, registry)
103
+
104
+ return classmethod(new_from_type_str)
105
+
106
+ return decorator
107
+
108
+
109
+ def parse_tuple_type_str(
110
+ old_from_type_str: OldFromTypeStr[TType],
111
+ ) -> "NewFromTypeStr[TType]":
112
+ """
113
+ Used by BaseCoder subclasses as a convenience for implementing the
114
+ ``from_type_str`` method required by ``ABIRegistry``. Useful if normalizing
115
+ then parsing a tuple type string is required in that method.
116
+ """
117
+
118
+ @functools.wraps(old_from_type_str)
119
+ def new_from_type_str(cls: TType, type_str: TypeStr, registry: Any) -> TType:
120
+ normalized_type_str = normalize(type_str)
121
+ abi_type = parse(normalized_type_str)
122
+
123
+ if not isinstance(abi_type, TupleType):
124
+ type_str_repr = repr(type_str)
125
+ if type_str != normalized_type_str:
126
+ type_str_repr = "{} (normalized to {})".format(
127
+ type_str_repr,
128
+ repr(normalized_type_str),
129
+ )
130
+ raise ValueError(
131
+ "Cannot create {} for non-tuple type {}".format(
132
+ cls.__name__,
133
+ type_str_repr,
134
+ )
135
+ )
136
+
137
+ abi_type.validate()
138
+
139
+ return old_from_type_str(cls, abi_type, registry)
140
+
141
+ return classmethod(new_from_type_str)
@@ -0,0 +1,179 @@
1
+ """Parsing and normalization logic for ABI type strings.
2
+
3
+ Implements grammar, parsing, and type validation for ABI type strings.
4
+ """
5
+ import functools
6
+ from typing import (
7
+ Any,
8
+ Final,
9
+ TYPE_CHECKING,
10
+ final,
11
+ )
12
+
13
+ import parsimonious
14
+ from eth_typing import (
15
+ TypeStr,
16
+ )
17
+ from parsimonious import (
18
+ expressions,
19
+ )
20
+
21
+ from faster_eth_abi._grammar import (
22
+ TYPE_ALIAS_RE,
23
+ TYPE_ALIASES,
24
+ ABIType,
25
+ BasicType,
26
+ TupleType,
27
+ normalize,
28
+ )
29
+ from faster_eth_abi.exceptions import (
30
+ ParseError,
31
+ )
32
+
33
+ grammar: Final = parsimonious.Grammar(
34
+ r"""
35
+ type = tuple_type / basic_type
36
+
37
+ tuple_type = components arrlist?
38
+ components = non_zero_tuple
39
+
40
+ non_zero_tuple = "(" type next_type* ")"
41
+ next_type = "," type
42
+
43
+ basic_type = base sub? arrlist?
44
+
45
+ base = alphas
46
+
47
+ sub = two_size / digits
48
+ two_size = (digits "x" digits)
49
+
50
+ arrlist = (const_arr / dynam_arr)+
51
+ const_arr = "[" digits "]"
52
+ dynam_arr = "[]"
53
+
54
+ alphas = ~"[A-Za-z]+"
55
+ digits = ~"[1-9][0-9]*"
56
+ """
57
+ )
58
+
59
+
60
+ if TYPE_CHECKING:
61
+ _NodeVisitorBase = parsimonious.NodeVisitor[ABIType]
62
+ else:
63
+ _NodeVisitorBase = parsimonious.NodeVisitor
64
+
65
+
66
+ @final
67
+ class NodeVisitor(_NodeVisitorBase):
68
+ """
69
+ Parsimonious node visitor which performs both parsing of type strings and
70
+ post-processing of parse trees. Parsing operations are cached.
71
+ """
72
+
73
+ def __init__(self) -> None:
74
+ self.parse: Final = functools.lru_cache(maxsize=None)(self._parse_uncached)
75
+
76
+ grammar = grammar
77
+
78
+ def visit_non_zero_tuple(self, node, visited_children):
79
+ # Ignore left and right parens
80
+ _, first, rest, _ = visited_children
81
+
82
+ return (first,) + rest
83
+
84
+ def visit_tuple_type(self, node, visited_children):
85
+ components, arrlist = visited_children
86
+
87
+ return TupleType(components, arrlist, node=node)
88
+
89
+ def visit_next_type(self, node, visited_children):
90
+ # Ignore comma
91
+ _, abi_type = visited_children
92
+
93
+ return abi_type
94
+
95
+ def visit_basic_type(self, node, visited_children):
96
+ base, sub, arrlist = visited_children
97
+
98
+ return BasicType(base, sub, arrlist, node=node)
99
+
100
+ def visit_two_size(self, node, visited_children):
101
+ # Ignore "x"
102
+ first, _, second = visited_children
103
+
104
+ return first, second
105
+
106
+ def visit_const_arr(self, node, visited_children):
107
+ # Ignore left and right brackets
108
+ _, int_value, _ = visited_children
109
+
110
+ return (int_value,)
111
+
112
+ def visit_dynam_arr(self, node, visited_children):
113
+ return ()
114
+
115
+ def visit_alphas(self, node, visited_children):
116
+ return node.text
117
+
118
+ def visit_digits(self, node, visited_children):
119
+ return int(node.text)
120
+
121
+ def generic_visit(self, node, visited_children):
122
+ expr = node.expr
123
+ if isinstance(expr, expressions.OneOf):
124
+ # Unwrap value chosen from alternatives
125
+ return visited_children[0]
126
+
127
+ if isinstance(expr, expressions.Quantifier) and expr.min == 0 and expr.max == 1:
128
+ # Unwrap optional value or return `None`
129
+ if len(visited_children) != 0:
130
+ return visited_children[0]
131
+
132
+ return None
133
+
134
+ return tuple(visited_children)
135
+
136
+ def _parse_uncached(self, type_str: TypeStr, **kwargs: Any) -> ABIType:
137
+ """
138
+ Parses a type string into an appropriate instance of
139
+ :class:`~faster_eth_abi.grammar.ABIType`. If a type string cannot be parsed,
140
+ throws :class:`~faster_eth_abi.exceptions.ParseError`.
141
+
142
+ :param type_str: The type string to be parsed.
143
+ :returns: An instance of :class:`~faster_eth_abi.grammar.ABIType` containing
144
+ information about the parsed type string.
145
+ """
146
+ if not isinstance(type_str, str):
147
+ raise TypeError(f"Can only parse string values: got {type(type_str)}")
148
+
149
+ try:
150
+ return super().parse(type_str, **kwargs)
151
+ except parsimonious.ParseError as e:
152
+ # This is a good place to add some better messaging around the type string.
153
+ # If this logic grows any bigger, we should abstract it to its own function.
154
+ if "()" in type_str:
155
+ # validate against zero-sized tuple types
156
+ raise ValueError(
157
+ 'Zero-sized tuple types "()" are not supported.'
158
+ ) from None
159
+
160
+ raise ParseError(e.text, e.pos, e.expr) from e
161
+
162
+
163
+ visitor: Final = NodeVisitor()
164
+
165
+ parse: Final = visitor.parse
166
+
167
+
168
+ __all__ = [
169
+ "NodeVisitor",
170
+ "ABIType",
171
+ "TupleType",
172
+ "BasicType",
173
+ "grammar",
174
+ "parse",
175
+ "normalize",
176
+ "visitor",
177
+ "TYPE_ALIASES",
178
+ "TYPE_ALIAS_RE",
179
+ ]
faster_eth_abi/io.py ADDED
@@ -0,0 +1,137 @@
1
+ """
2
+ Context-aware byte stream for ABI decoding.
3
+
4
+ Implements a lightweight frame-aware reader that avoids BytesIO overhead in hot decoding paths.
5
+ """
6
+ from typing import (
7
+ Any,
8
+ Final,
9
+ final,
10
+ )
11
+
12
+
13
+ @final
14
+ class ContextFramesBytesIO:
15
+ """
16
+ A byte stream which can track a series of contextual frames in a stack. This
17
+ data structure is necessary to perform nested decodings using the
18
+ :py:class:``HeadTailDecoder`` since offsets present in head sections are
19
+ relative only to a particular encoded object. These offsets can only be
20
+ used to locate a position in a decoding stream if they are paired with a
21
+ contextual offset that establishes the position of the object in which they
22
+ are found.
23
+
24
+ For example, consider the encoding of a value for the following type::
25
+
26
+ type: (int,(int,int[]))
27
+ value: (1,(2,[3,3]))
28
+
29
+ There are two tuples in this type: one inner and one outer. The inner tuple
30
+ type contains a dynamic type ``int[]`` and, therefore, is itself dynamic.
31
+ This means that its value encoding will be placed in the tail section of the
32
+ outer tuple's encoding. Furthermore, the inner tuple's encoding will,
33
+ itself, contain a tail section with the encoding for ``[3,3]``. All
34
+ together, the encoded value of ``(1,(2,[3,3]))`` would look like this (the
35
+ data values are normally 32 bytes wide but have been truncated to remove the
36
+ redundant zeros at the beginnings of their encodings)::
37
+
38
+ offset data
39
+ --------------------------
40
+ ^ 0 0x01
41
+ | 32 0x40 <-- Offset of object A in global frame (64)
42
+ -----|--------------------
43
+ Global frame ^ 64 0x02 <-- Beginning of object A (64 w/offset 0 = 64)
44
+ | | 96 0x40 <-- Offset of object B in frame of object A (64)
45
+ -----|-Object A's frame---
46
+ | | 128 0x02 <-- Beginning of object B (64 w/offset 64 = 128)
47
+ | | 160 0x03
48
+ v v 192 0x03
49
+ --------------------------
50
+
51
+ Note that the offset of object B is encoded as 64 which only specifies the
52
+ beginning of its encoded value relative to the beginning of object A's
53
+ encoding. Globally, object B is located at offset 128. In order to make
54
+ sense out of object B's offset, it needs to be positioned in the context of
55
+ its enclosing object's frame (object A).
56
+ """
57
+
58
+ def __init__(self, initial_bytes: bytes | bytearray):
59
+ # NOTE: Non-contiguous buffers are intentionally unsupported (regression from
60
+ # BytesIO) because they are rare in our decode flow and we want to keep the
61
+ # compiled hot path fast. Callers with sliced memoryviews should wrap with
62
+ # bytes(...) if needed.
63
+ self._buffer = memoryview(initial_bytes)
64
+ self._position = 0
65
+ self._frames: Final[list[tuple[int, int]]] = []
66
+ self._total_offset = 0
67
+
68
+ def read(self, size: int = -1) -> bytes:
69
+ """
70
+ Read up to ``size`` bytes from the stream. If ``size`` is negative,
71
+ read until EOF.
72
+ """
73
+ remaining = len(self._buffer) - self._position
74
+ if size is None or size < 0:
75
+ size = remaining
76
+ elif size > remaining:
77
+ size = remaining
78
+
79
+ if size <= 0:
80
+ return b""
81
+
82
+ start = self._position
83
+ end = start + size
84
+ self._position = end
85
+ return self._buffer[start:end].tobytes()
86
+
87
+ def tell(self) -> int:
88
+ return self._position
89
+
90
+ def seek(self, pos: int, whence: int = 0) -> int:
91
+ if whence == 0:
92
+ new_pos = pos
93
+ elif whence == 1:
94
+ new_pos = self._position + pos
95
+ elif whence == 2:
96
+ new_pos = len(self._buffer) + pos
97
+ else:
98
+ raise ValueError(f"invalid whence ({whence}, should be 0, 1 or 2)")
99
+
100
+ if new_pos < 0:
101
+ raise ValueError("negative seek position")
102
+
103
+ self._position = new_pos
104
+ return new_pos
105
+
106
+ def getbuffer(self) -> memoryview:
107
+ return self._buffer
108
+
109
+ def seek_in_frame(self, pos: int, *args: Any, **kwargs: Any) -> None:
110
+ """
111
+ Seeks relative to the total offset of the current contextual frames.
112
+ """
113
+ self.seek(self._total_offset + pos, *args, **kwargs)
114
+
115
+ def push_frame(self, offset: int) -> None:
116
+ """
117
+ Pushes a new contextual frame onto the stack with the given offset and a
118
+ return position at the current cursor position then seeks to the new
119
+ total offset.
120
+ """
121
+ self._frames.append((offset, self.tell()))
122
+ self._total_offset += offset
123
+
124
+ self.seek_in_frame(0)
125
+
126
+ def pop_frame(self) -> None:
127
+ """
128
+ Pops the current contextual frame off of the stack and returns the
129
+ cursor to the frame's return position.
130
+ """
131
+ try:
132
+ offset, return_pos = self._frames.pop()
133
+ except IndexError:
134
+ raise IndexError("no frames to pop")
135
+ self._total_offset -= offset
136
+
137
+ self.seek(return_pos)
@@ -0,0 +1,19 @@
1
+ """Helpers for packed ABI encoding.
2
+
3
+ Defines functions and registry for packed encoding and encodability checks.
4
+ """
5
+ from typing import (
6
+ Final,
7
+ )
8
+
9
+ from .codec import (
10
+ ABIEncoder,
11
+ )
12
+ from .registry import (
13
+ registry_packed,
14
+ )
15
+
16
+ default_encoder_packed: Final = ABIEncoder(registry_packed)
17
+
18
+ encode_packed: Final = default_encoder_packed.encode
19
+ is_encodable_packed: Final = default_encoder_packed.is_encodable
File without changes