faster-eth-utils 4.1.7__cp314-cp314t-win_amd64.whl → 5.3.22__cp314-cp314t-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-utils might be problematic. Click here for more details.
- faster_eth_utils/__init__.py +19 -1
- faster_eth_utils/abi.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/abi.py +834 -34
- faster_eth_utils/address.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/address.py +19 -43
- faster_eth_utils/applicators.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/applicators.py +109 -64
- faster_eth_utils/conversions.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/conversions.py +36 -29
- faster_eth_utils/crypto.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/crypto.py +3 -8
- faster_eth_utils/currency.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/currency.py +55 -21
- faster_eth_utils/curried/__init__.py +91 -67
- faster_eth_utils/debug.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/decorators.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/decorators.py +65 -29
- faster_eth_utils/encoding.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/encoding.py +1 -1
- faster_eth_utils/exceptions.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/exceptions.py +8 -1
- faster_eth_utils/functional.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/functional.py +10 -12
- faster_eth_utils/hexadecimal.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/hexadecimal.py +19 -16
- faster_eth_utils/humanize.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/humanize.py +35 -23
- faster_eth_utils/logging.py +54 -61
- faster_eth_utils/module_loading.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/network.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/network.py +2 -3
- faster_eth_utils/numeric.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/pydantic.py +103 -0
- faster_eth_utils/toolz.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/types.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils/types.py +20 -17
- faster_eth_utils/units.cp314t-win_amd64.pyd +0 -0
- {faster_eth_utils-4.1.7.dist-info → faster_eth_utils-5.3.22.dist-info}/METADATA +59 -17
- faster_eth_utils-5.3.22.dist-info/RECORD +53 -0
- {faster_eth_utils-4.1.7.dist-info → faster_eth_utils-5.3.22.dist-info}/licenses/LICENSE +1 -1
- faster_eth_utils-5.3.22.dist-info/top_level.txt +3 -0
- faster_eth_utils__mypyc.cp314t-win_amd64.pyd +0 -0
- 99c07adba6ff961eaf3e__mypyc.cp314t-win_amd64.pyd +0 -0
- faster_eth_utils-4.1.7.dist-info/RECORD +0 -52
- faster_eth_utils-4.1.7.dist-info/top_level.txt +0 -3
- {faster_eth_utils-4.1.7.dist-info → faster_eth_utils-5.3.22.dist-info}/WHEEL +0 -0
faster_eth_utils/humanize.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
from collections.abc import (
|
|
2
|
+
Iterable,
|
|
3
|
+
Iterator,
|
|
4
|
+
)
|
|
1
5
|
from typing import (
|
|
2
6
|
Any,
|
|
3
7
|
Final,
|
|
4
|
-
Iterable,
|
|
5
|
-
Iterator,
|
|
6
|
-
Tuple,
|
|
7
|
-
Union,
|
|
8
8
|
)
|
|
9
9
|
from urllib import (
|
|
10
10
|
parse,
|
|
@@ -20,19 +20,17 @@ from faster_eth_utils.currency import (
|
|
|
20
20
|
from_wei,
|
|
21
21
|
)
|
|
22
22
|
|
|
23
|
-
from .
|
|
24
|
-
sliding_window,
|
|
25
|
-
take,
|
|
26
|
-
)
|
|
23
|
+
from . import toolz
|
|
27
24
|
|
|
28
25
|
|
|
29
|
-
def humanize_seconds(seconds:
|
|
30
|
-
|
|
26
|
+
def humanize_seconds(seconds: float | int) -> str:
|
|
27
|
+
seconds_int = int(seconds)
|
|
28
|
+
if seconds_int == 0:
|
|
31
29
|
return "0s"
|
|
32
30
|
|
|
33
|
-
unit_values = _consume_leading_zero_units(_humanize_seconds(
|
|
31
|
+
unit_values = _consume_leading_zero_units(_humanize_seconds(seconds_int))
|
|
34
32
|
|
|
35
|
-
return "".join(
|
|
33
|
+
return "".join(f"{amount}{unit}" for amount, unit in toolz.take(3, unit_values))
|
|
36
34
|
|
|
37
35
|
|
|
38
36
|
SECOND: Final = 1
|
|
@@ -56,8 +54,8 @@ UNITS: Final = (
|
|
|
56
54
|
|
|
57
55
|
|
|
58
56
|
def _consume_leading_zero_units(
|
|
59
|
-
units_iter: Iterator[
|
|
60
|
-
) -> Iterator[
|
|
57
|
+
units_iter: Iterator[tuple[int, str]]
|
|
58
|
+
) -> Iterator[tuple[int, str]]:
|
|
61
59
|
for amount, unit in units_iter:
|
|
62
60
|
if amount == 0:
|
|
63
61
|
continue
|
|
@@ -68,7 +66,7 @@ def _consume_leading_zero_units(
|
|
|
68
66
|
yield from units_iter
|
|
69
67
|
|
|
70
68
|
|
|
71
|
-
def _humanize_seconds(seconds: int) -> Iterator[
|
|
69
|
+
def _humanize_seconds(seconds: int) -> Iterator[tuple[int, str]]:
|
|
72
70
|
remainder = seconds
|
|
73
71
|
|
|
74
72
|
for duration, unit in UNITS:
|
|
@@ -93,6 +91,21 @@ def humanize_bytes(value: bytes) -> str:
|
|
|
93
91
|
return f"{head}..{tail}"
|
|
94
92
|
|
|
95
93
|
|
|
94
|
+
def humanize_hexstr(value: str) -> str:
|
|
95
|
+
tail = value[-1 * DISPLAY_HASH_CHARS :]
|
|
96
|
+
|
|
97
|
+
if value[:2] == "0x":
|
|
98
|
+
if len(value[2:]) <= DISPLAY_HASH_CHARS * 2:
|
|
99
|
+
return value
|
|
100
|
+
head = value[2 : DISPLAY_HASH_CHARS + 2]
|
|
101
|
+
return f"0x{head}..{tail}"
|
|
102
|
+
else:
|
|
103
|
+
if len(value) <= DISPLAY_HASH_CHARS * 2:
|
|
104
|
+
return value
|
|
105
|
+
head = value[:DISPLAY_HASH_CHARS]
|
|
106
|
+
return f"{head}..{tail}"
|
|
107
|
+
|
|
108
|
+
|
|
96
109
|
def humanize_hash(value: Hash32) -> str:
|
|
97
110
|
return humanize_bytes(value)
|
|
98
111
|
|
|
@@ -128,9 +141,9 @@ def _is_CIDv0_ipfs_hash(ipfs_hash: str) -> bool:
|
|
|
128
141
|
return False
|
|
129
142
|
|
|
130
143
|
|
|
131
|
-
def _find_breakpoints(
|
|
144
|
+
def _find_breakpoints(values: tuple[int, ...]) -> Iterator[int]:
|
|
132
145
|
yield 0
|
|
133
|
-
for index, (left, right) in enumerate(sliding_window(2, values), 1):
|
|
146
|
+
for index, (left, right) in enumerate(toolz.sliding_window(2, values), 1):
|
|
134
147
|
if left + 1 == right:
|
|
135
148
|
continue
|
|
136
149
|
else:
|
|
@@ -138,7 +151,7 @@ def _find_breakpoints(*values: int) -> Iterator[int]:
|
|
|
138
151
|
yield len(values)
|
|
139
152
|
|
|
140
153
|
|
|
141
|
-
def _extract_integer_ranges(
|
|
154
|
+
def _extract_integer_ranges(values: tuple[int, ...]) -> Iterator[tuple[int, int]]:
|
|
142
155
|
"""
|
|
143
156
|
Return a tuple of consecutive ranges of integers.
|
|
144
157
|
|
|
@@ -148,12 +161,12 @@ def _extract_integer_ranges(*values: int) -> Iterator[Tuple[int, int]]:
|
|
|
148
161
|
- fn(1, 2, 3, 7, 8, 9) -> ((1, 3), (7, 9))
|
|
149
162
|
- fn(1, 7, 8, 9) -> ((1, 1), (7, 9))
|
|
150
163
|
"""
|
|
151
|
-
for left, right in sliding_window(2, _find_breakpoints(
|
|
164
|
+
for left, right in toolz.sliding_window(2, _find_breakpoints(values)):
|
|
152
165
|
chunk = values[left:right]
|
|
153
166
|
yield chunk[0], chunk[-1]
|
|
154
167
|
|
|
155
168
|
|
|
156
|
-
def _humanize_range(bounds:
|
|
169
|
+
def _humanize_range(bounds: tuple[int, int]) -> str:
|
|
157
170
|
left, right = bounds
|
|
158
171
|
if left == right:
|
|
159
172
|
return str(left)
|
|
@@ -174,7 +187,7 @@ def humanize_integer_sequence(values_iter: Iterable[int]) -> str:
|
|
|
174
187
|
if not values:
|
|
175
188
|
return "(empty)"
|
|
176
189
|
else:
|
|
177
|
-
return "|".join(
|
|
190
|
+
return "|".join(_humanize_range(range) for range in _extract_integer_ranges(values))
|
|
178
191
|
|
|
179
192
|
|
|
180
193
|
def humanize_wei(number: int) -> str:
|
|
@@ -185,5 +198,4 @@ def humanize_wei(number: int) -> str:
|
|
|
185
198
|
else:
|
|
186
199
|
unit = "wei"
|
|
187
200
|
amount = from_wei(number, unit)
|
|
188
|
-
|
|
189
|
-
return x
|
|
201
|
+
return f"{str(amount)} {unit}"
|
faster_eth_utils/logging.py
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import
|
|
1
|
+
import logging
|
|
2
|
+
from collections.abc import (
|
|
3
|
+
Iterator,
|
|
4
|
+
)
|
|
5
|
+
from contextlib import (
|
|
6
|
+
contextmanager,
|
|
7
|
+
)
|
|
2
8
|
from functools import (
|
|
3
9
|
cached_property,
|
|
4
10
|
)
|
|
5
|
-
import logging
|
|
6
11
|
from typing import (
|
|
7
12
|
Any,
|
|
8
|
-
|
|
9
|
-
Iterator,
|
|
10
|
-
Tuple,
|
|
11
|
-
Type,
|
|
13
|
+
Final,
|
|
12
14
|
TypeVar,
|
|
13
|
-
Union,
|
|
14
15
|
cast,
|
|
16
|
+
overload,
|
|
15
17
|
)
|
|
16
18
|
|
|
17
19
|
from .toolz import (
|
|
@@ -22,6 +24,11 @@ DEBUG2_LEVEL_NUM = 8
|
|
|
22
24
|
|
|
23
25
|
TLogger = TypeVar("TLogger", bound=logging.Logger)
|
|
24
26
|
|
|
27
|
+
Logger: Final = logging.Logger
|
|
28
|
+
getLogger: Final = logging.getLogger
|
|
29
|
+
getLoggerClass: Final = logging.getLoggerClass
|
|
30
|
+
setLoggerClass: Final = logging.setLoggerClass
|
|
31
|
+
|
|
25
32
|
|
|
26
33
|
class ExtendedDebugLogger(logging.Logger):
|
|
27
34
|
"""
|
|
@@ -41,7 +48,7 @@ class ExtendedDebugLogger(logging.Logger):
|
|
|
41
48
|
# lambda to further speed up
|
|
42
49
|
self.__dict__["debug2"] = lambda message, *args, **kwargs: None
|
|
43
50
|
|
|
44
|
-
def __reduce__(self) ->
|
|
51
|
+
def __reduce__(self) -> tuple[Any, ...]:
|
|
45
52
|
# This is needed because our parent's implementation could
|
|
46
53
|
# cause us to become a regular Logger on unpickling.
|
|
47
54
|
return get_extended_debug_logger, (self.name,)
|
|
@@ -53,37 +60,38 @@ def setup_DEBUG2_logging() -> None:
|
|
|
53
60
|
"""
|
|
54
61
|
if not hasattr(logging, "DEBUG2"):
|
|
55
62
|
logging.addLevelName(DEBUG2_LEVEL_NUM, "DEBUG2")
|
|
56
|
-
logging.DEBUG2 = DEBUG2_LEVEL_NUM # type: ignore
|
|
63
|
+
logging.DEBUG2 = DEBUG2_LEVEL_NUM # type: ignore [attr-defined]
|
|
57
64
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
logging.setLoggerClass(logger_class)
|
|
65
|
+
@contextmanager
|
|
66
|
+
def _use_logger_class(logger_class: type[logging.Logger]) -> Iterator[None]:
|
|
67
|
+
original_logger_class = getLoggerClass()
|
|
68
|
+
setLoggerClass(logger_class)
|
|
63
69
|
try:
|
|
64
70
|
yield
|
|
65
71
|
finally:
|
|
66
|
-
|
|
72
|
+
setLoggerClass(original_logger_class)
|
|
67
73
|
|
|
68
74
|
|
|
69
|
-
|
|
75
|
+
@overload
|
|
76
|
+
def get_logger(name: str, logger_class: type[TLogger]) -> TLogger: ...
|
|
77
|
+
@overload
|
|
78
|
+
def get_logger(name: str, logger_class: None = None) -> logging.Logger: ...
|
|
79
|
+
def get_logger(name: str, logger_class: type[TLogger] | None = None) -> TLogger | logging.Logger:
|
|
70
80
|
if logger_class is None:
|
|
71
|
-
return
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
del manager.loggerDict[name]
|
|
86
|
-
return cast(TLogger, logging.getLogger(name))
|
|
81
|
+
return getLogger(name)
|
|
82
|
+
|
|
83
|
+
with _use_logger_class(logger_class):
|
|
84
|
+
# The logging module caches logger instances. The following code
|
|
85
|
+
# ensures that if there is a cached instance that we don't
|
|
86
|
+
# accidentally return the incorrect logger type because the logging
|
|
87
|
+
# module does not *update* the cached instance in the event that
|
|
88
|
+
# the global logging class changes.
|
|
89
|
+
manager = Logger.manager
|
|
90
|
+
logger_dict = manager.loggerDict
|
|
91
|
+
cached_logger = logger_dict.get(name)
|
|
92
|
+
if cached_logger is not None and type(cached_logger) is not logger_class:
|
|
93
|
+
del logger_dict[name]
|
|
94
|
+
return cast(TLogger, getLogger(name))
|
|
87
95
|
|
|
88
96
|
|
|
89
97
|
def get_extended_debug_logger(name: str) -> ExtendedDebugLogger:
|
|
@@ -101,13 +109,13 @@ class HasLoggerMeta(type):
|
|
|
101
109
|
to use when creating the associated logger for a given class.
|
|
102
110
|
"""
|
|
103
111
|
|
|
104
|
-
logger_class =
|
|
112
|
+
logger_class = Logger
|
|
105
113
|
|
|
106
114
|
def __new__(
|
|
107
|
-
mcls:
|
|
115
|
+
mcls: type[THasLoggerMeta],
|
|
108
116
|
name: str,
|
|
109
|
-
bases:
|
|
110
|
-
namespace:
|
|
117
|
+
bases: tuple[type[Any]],
|
|
118
|
+
namespace: dict[str, Any],
|
|
111
119
|
) -> THasLoggerMeta:
|
|
112
120
|
if "logger" in namespace:
|
|
113
121
|
# If a logger was explicitly declared we shouldn't do anything to
|
|
@@ -115,45 +123,30 @@ class HasLoggerMeta(type):
|
|
|
115
123
|
return super().__new__(mcls, name, bases, namespace)
|
|
116
124
|
if "__qualname__" not in namespace:
|
|
117
125
|
raise AttributeError("Missing __qualname__")
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
logger = logging.getLogger(namespace["__qualname__"])
|
|
126
|
+
|
|
127
|
+
logger = get_logger(namespace["__qualname__"], mcls.logger_class)
|
|
121
128
|
|
|
122
129
|
return super().__new__(mcls, name, bases, assoc(namespace, "logger", logger))
|
|
123
130
|
|
|
124
131
|
@classmethod
|
|
125
132
|
def replace_logger_class(
|
|
126
|
-
mcls:
|
|
127
|
-
) ->
|
|
133
|
+
mcls: type[THasLoggerMeta], value: type[logging.Logger]
|
|
134
|
+
) -> type[THasLoggerMeta]:
|
|
128
135
|
return type(mcls.__name__, (mcls,), {"logger_class": value})
|
|
129
136
|
|
|
130
137
|
@classmethod
|
|
131
138
|
def meta_compat(
|
|
132
|
-
mcls:
|
|
133
|
-
) ->
|
|
139
|
+
mcls: type[THasLoggerMeta], other: type[type]
|
|
140
|
+
) -> type[THasLoggerMeta]:
|
|
134
141
|
return type(mcls.__name__, (mcls, other), {})
|
|
135
142
|
|
|
136
143
|
|
|
137
|
-
class
|
|
138
|
-
|
|
139
|
-
# python3.5 is deprecated this can be removed in favor of a simple type
|
|
140
|
-
# annotation on the main class.
|
|
141
|
-
logger = logging.Logger("") # type: logging.Logger
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
class HasLogger(_BaseHasLogger):
|
|
145
|
-
pass
|
|
144
|
+
class HasLogger(metaclass=HasLoggerMeta):
|
|
145
|
+
logger: logging.Logger
|
|
146
146
|
|
|
147
147
|
|
|
148
148
|
HasExtendedDebugLoggerMeta = HasLoggerMeta.replace_logger_class(ExtendedDebugLogger)
|
|
149
149
|
|
|
150
150
|
|
|
151
|
-
class
|
|
152
|
-
|
|
153
|
-
# python3.5 is deprecated this can be removed in favor of a simple type
|
|
154
|
-
# annotation on the main class.
|
|
155
|
-
logger = ExtendedDebugLogger("") # type: ExtendedDebugLogger
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
class HasExtendedDebugLogger(_BaseHasExtendedDebugLogger):
|
|
159
|
-
pass
|
|
151
|
+
class HasExtendedDebugLogger(metaclass=HasExtendedDebugLoggerMeta): # type: ignore[metaclass]
|
|
152
|
+
logger: ExtendedDebugLogger
|
|
Binary file
|
|
Binary file
|
faster_eth_utils/network.py
CHANGED
|
@@ -9,14 +9,13 @@ from pathlib import (
|
|
|
9
9
|
)
|
|
10
10
|
from typing import (
|
|
11
11
|
Final,
|
|
12
|
-
List,
|
|
13
12
|
)
|
|
14
13
|
|
|
15
14
|
from eth_typing import (
|
|
16
15
|
ChainId,
|
|
17
16
|
)
|
|
18
17
|
|
|
19
|
-
from faster_eth_utils import (
|
|
18
|
+
from faster_eth_utils.exceptions import (
|
|
20
19
|
ValidationError,
|
|
21
20
|
)
|
|
22
21
|
|
|
@@ -32,7 +31,7 @@ class Network:
|
|
|
32
31
|
symbol: ChainId
|
|
33
32
|
|
|
34
33
|
|
|
35
|
-
def initialize_network_objects() ->
|
|
34
|
+
def initialize_network_objects() -> list[Network]:
|
|
36
35
|
networks_obj = []
|
|
37
36
|
|
|
38
37
|
networks_json_path = os.path.abspath(
|
|
Binary file
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
Any,
|
|
3
|
+
cast,
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
from pydantic import (
|
|
7
|
+
BaseModel,
|
|
8
|
+
ConfigDict,
|
|
9
|
+
)
|
|
10
|
+
from pydantic._internal._core_utils import (
|
|
11
|
+
CoreSchemaField,
|
|
12
|
+
)
|
|
13
|
+
from pydantic.alias_generators import (
|
|
14
|
+
to_camel,
|
|
15
|
+
)
|
|
16
|
+
from pydantic.json_schema import (
|
|
17
|
+
DEFAULT_REF_TEMPLATE,
|
|
18
|
+
GenerateJsonSchema,
|
|
19
|
+
JsonSchemaMode,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class OmitJsonSchema(GenerateJsonSchema): # type: ignore[misc]
|
|
24
|
+
"""
|
|
25
|
+
Custom JSON schema generator that omits the schema generation for fields that are
|
|
26
|
+
invalid. Excluded fields (``Field(exclude=True)``) are generally useful as
|
|
27
|
+
properties of the model but are not meant to be serialized to JSON.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def field_is_present(self, field: CoreSchemaField) -> bool:
|
|
31
|
+
# override ``field_is_present`` and omit excluded fields from the schema
|
|
32
|
+
if field.get("serialization_exclude", False):
|
|
33
|
+
return False
|
|
34
|
+
return cast(bool, super().field_is_present(field))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class CamelModel(BaseModel): # type: ignore[misc]
|
|
38
|
+
"""
|
|
39
|
+
Camel-case pydantic model. This model is used to ensure serialization in a
|
|
40
|
+
consistent manner, aliasing as camelCase serialization. This is useful for models
|
|
41
|
+
that are used in JSON-RPC requests and responses, marking useful fields for the
|
|
42
|
+
model, but that are not part of the JSON-RPC object, with ``Field(exclude=True)``.
|
|
43
|
+
To serialize a model to the expected JSON-RPC format, or camelCase, use
|
|
44
|
+
``model_dump(by_alias=True)``.
|
|
45
|
+
|
|
46
|
+
.. code-block:: python
|
|
47
|
+
|
|
48
|
+
>>> from eth_utils.pydantic import CamelModel
|
|
49
|
+
>>> from pydantic import Field
|
|
50
|
+
|
|
51
|
+
>>> class SignedSetCodeAuthorization(CamelModel):
|
|
52
|
+
... chain_id: int
|
|
53
|
+
... address: bytes
|
|
54
|
+
... nonce: int
|
|
55
|
+
...
|
|
56
|
+
... # useful fields for the object but excluded from serialization
|
|
57
|
+
... # (not part of the JSON-RPC object)
|
|
58
|
+
... authorization_hash: bytes = Field(exclude=True)
|
|
59
|
+
... signature: bytes = Field(exclude=True)
|
|
60
|
+
|
|
61
|
+
>>> auth = SignedSetCodeAuthorization(
|
|
62
|
+
... chain_id=1,
|
|
63
|
+
... address=b"0x0000000000000000000000000000000000000000",
|
|
64
|
+
... nonce=0,
|
|
65
|
+
... authorization_hash=generated_hash,
|
|
66
|
+
... signature=generated_signature,
|
|
67
|
+
... )
|
|
68
|
+
>>> auth.model_dump(by_alias=True)
|
|
69
|
+
{'chainId': 1, 'address': '0x000000000000000000000000000000000000', 'nonce': 0}
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
model_config = ConfigDict(
|
|
73
|
+
arbitrary_types_allowed=True,
|
|
74
|
+
# populate by snake_case (python) args
|
|
75
|
+
populate_by_name=True,
|
|
76
|
+
# serialize by camelCase (json-rpc) keys
|
|
77
|
+
alias_generator=to_camel,
|
|
78
|
+
# validate default values
|
|
79
|
+
validate_default=True,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
@classmethod
|
|
83
|
+
def model_json_schema( # type: ignore [override]
|
|
84
|
+
cls,
|
|
85
|
+
by_alias: bool = True,
|
|
86
|
+
ref_template: str = DEFAULT_REF_TEMPLATE,
|
|
87
|
+
# default to ``OmitJsonSchema`` to prevent errors from excluded fields
|
|
88
|
+
schema_generator: type[GenerateJsonSchema] = OmitJsonSchema,
|
|
89
|
+
mode: JsonSchemaMode = "validation",
|
|
90
|
+
) -> dict[str, Any]:
|
|
91
|
+
"""
|
|
92
|
+
Omits excluded fields from the JSON schema, preventing errors that would
|
|
93
|
+
otherwise be raised by the default schema generator.
|
|
94
|
+
"""
|
|
95
|
+
return cast(
|
|
96
|
+
dict[str, Any],
|
|
97
|
+
super().model_json_schema(
|
|
98
|
+
by_alias=by_alias,
|
|
99
|
+
ref_template=ref_template,
|
|
100
|
+
schema_generator=schema_generator,
|
|
101
|
+
mode=mode,
|
|
102
|
+
),
|
|
103
|
+
)
|
|
Binary file
|
|
Binary file
|
faster_eth_utils/types.py
CHANGED
|
@@ -2,35 +2,38 @@ import collections.abc
|
|
|
2
2
|
import numbers
|
|
3
3
|
from typing import (
|
|
4
4
|
Any,
|
|
5
|
-
|
|
5
|
+
Final,
|
|
6
6
|
Literal,
|
|
7
|
-
Tuple,
|
|
8
|
-
Union,
|
|
9
7
|
)
|
|
10
8
|
|
|
11
|
-
from
|
|
9
|
+
from typing import (
|
|
12
10
|
TypeGuard,
|
|
13
11
|
)
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
Mapping: Final = collections.abc.Mapping
|
|
14
|
+
Sequence: Final = collections.abc.Sequence
|
|
15
|
+
|
|
16
|
+
Number: Final = numbers.Number
|
|
17
|
+
|
|
18
|
+
bytes_types: Final = (bytes, bytearray)
|
|
19
|
+
integer_types: Final = (int,)
|
|
20
|
+
text_types: Final = (str,)
|
|
21
|
+
string_types: Final = (bytes, str, bytearray)
|
|
19
22
|
|
|
20
23
|
|
|
21
24
|
def is_integer(value: Any) -> TypeGuard[int]:
|
|
22
|
-
return isinstance(value,
|
|
25
|
+
return isinstance(value, int) and not isinstance(value, bool)
|
|
23
26
|
|
|
24
27
|
|
|
25
|
-
def is_bytes(value: Any) -> TypeGuard[
|
|
28
|
+
def is_bytes(value: Any) -> TypeGuard[bytes | bytearray]:
|
|
26
29
|
return isinstance(value, bytes_types)
|
|
27
30
|
|
|
28
31
|
|
|
29
32
|
def is_text(value: Any) -> TypeGuard[str]:
|
|
30
|
-
return isinstance(value,
|
|
33
|
+
return isinstance(value, str)
|
|
31
34
|
|
|
32
35
|
|
|
33
|
-
def is_string(value: Any) -> TypeGuard[
|
|
36
|
+
def is_string(value: Any) -> TypeGuard[bytes | str | bytearray]:
|
|
34
37
|
return isinstance(value, string_types)
|
|
35
38
|
|
|
36
39
|
|
|
@@ -39,18 +42,18 @@ def is_boolean(value: Any) -> TypeGuard[bool]:
|
|
|
39
42
|
|
|
40
43
|
|
|
41
44
|
def is_dict(obj: Any) -> TypeGuard[collections.abc.Mapping[Any, Any]]:
|
|
42
|
-
return isinstance(obj,
|
|
45
|
+
return isinstance(obj, dict) or isinstance(obj, Mapping)
|
|
43
46
|
|
|
44
47
|
|
|
45
48
|
def is_list_like(obj: Any) -> TypeGuard[collections.abc.Sequence[Any]]:
|
|
46
|
-
return not is_string(obj) and isinstance(obj,
|
|
49
|
+
return isinstance(obj, (list, tuple)) or not is_string(obj) and isinstance(obj, Sequence)
|
|
47
50
|
|
|
48
51
|
|
|
49
|
-
def is_list(obj: Any) -> TypeGuard[
|
|
52
|
+
def is_list(obj: Any) -> TypeGuard[list[Any]]:
|
|
50
53
|
return isinstance(obj, list)
|
|
51
54
|
|
|
52
55
|
|
|
53
|
-
def is_tuple(obj: Any) -> TypeGuard[
|
|
56
|
+
def is_tuple(obj: Any) -> TypeGuard[tuple[Any, ...]]:
|
|
54
57
|
return isinstance(obj, tuple)
|
|
55
58
|
|
|
56
59
|
|
|
@@ -59,4 +62,4 @@ def is_null(obj: Any) -> TypeGuard[Literal[None]]:
|
|
|
59
62
|
|
|
60
63
|
|
|
61
64
|
def is_number(obj: Any) -> TypeGuard[numbers.Number]:
|
|
62
|
-
return isinstance(obj,
|
|
65
|
+
return isinstance(obj, Number)
|
|
Binary file
|
|
@@ -1,34 +1,45 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: faster-eth-utils
|
|
3
|
-
Version:
|
|
4
|
-
Summary: A fork of eth-utils: Common utility functions for python code that interacts with Ethereum
|
|
5
|
-
Home-page: https://github.com/BobTheBuidler/eth-utils
|
|
3
|
+
Version: 5.3.22
|
|
4
|
+
Summary: A faster fork of eth-utils: Common utility functions for python code that interacts with Ethereum. Implemented in C
|
|
5
|
+
Home-page: https://github.com/BobTheBuidler/faster-eth-utils
|
|
6
6
|
Author: The Ethereum Foundation
|
|
7
7
|
Author-email: snakecharmers@ethereum.org
|
|
8
8
|
License: MIT
|
|
9
|
+
Project-URL: Documentation, https://eth-utils.readthedocs.io/en/stable/
|
|
10
|
+
Project-URL: Release Notes, https://github.com/BobTheBuidler/faster-eth-utils/releases
|
|
11
|
+
Project-URL: Issues, https://github.com/BobTheBuidler/faster-eth-utils/issues
|
|
12
|
+
Project-URL: Source - Precompiled (.py), https://github.com/BobTheBuidler/faster-eth-utils/tree/master/faster_eth_utils
|
|
13
|
+
Project-URL: Source - Compiled (.c), https://github.com/BobTheBuidler/faster-eth-utils/tree/master/build
|
|
14
|
+
Project-URL: Benchmarks, https://github.com/BobTheBuidler/faster-eth-utils/tree/master/benchmarks
|
|
15
|
+
Project-URL: Benchmarks - Results, https://github.com/BobTheBuidler/faster-eth-utils/tree/master/benchmarks/results
|
|
16
|
+
Project-URL: Original, https://github.com/ethereum/eth-utils
|
|
9
17
|
Keywords: ethereum
|
|
10
18
|
Classifier: Intended Audience :: Developers
|
|
11
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
12
19
|
Classifier: Natural Language :: English
|
|
13
20
|
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
16
21
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
23
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
26
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
20
|
-
Requires-Python: >=3.
|
|
27
|
+
Requires-Python: >=3.10, <4
|
|
21
28
|
Description-Content-Type: text/markdown
|
|
22
29
|
License-File: LICENSE
|
|
30
|
+
Requires-Dist: cchecksum==0.3.9
|
|
23
31
|
Requires-Dist: eth-hash>=0.3.1
|
|
24
|
-
Requires-Dist: eth-typing
|
|
32
|
+
Requires-Dist: eth-typing==5.2.1
|
|
33
|
+
Requires-Dist: eth-utils==5.3.1
|
|
25
34
|
Requires-Dist: toolz>0.8.2; implementation_name == "pypy"
|
|
26
35
|
Requires-Dist: cytoolz>=0.10.1; implementation_name == "cpython"
|
|
36
|
+
Requires-Dist: pydantic<3,>=2.0.0
|
|
27
37
|
Provides-Extra: dev
|
|
28
38
|
Requires-Dist: build>=0.9.0; extra == "dev"
|
|
29
|
-
Requires-Dist:
|
|
39
|
+
Requires-Dist: bump_my_version>=0.19.0; extra == "dev"
|
|
30
40
|
Requires-Dist: eth-hash[pycryptodome]; extra == "dev"
|
|
31
41
|
Requires-Dist: ipython; extra == "dev"
|
|
42
|
+
Requires-Dist: mypy[mypyc]<1.20,>=1.14.1; extra == "dev"
|
|
32
43
|
Requires-Dist: pre-commit>=3.4.0; extra == "dev"
|
|
33
44
|
Requires-Dist: tox>=4.0.0; extra == "dev"
|
|
34
45
|
Requires-Dist: twine; extra == "dev"
|
|
@@ -36,21 +47,31 @@ Requires-Dist: wheel; extra == "dev"
|
|
|
36
47
|
Requires-Dist: sphinx>=6.0.0; extra == "dev"
|
|
37
48
|
Requires-Dist: sphinx-autobuild>=2021.3.14; extra == "dev"
|
|
38
49
|
Requires-Dist: sphinx_rtd_theme>=1.0.0; extra == "dev"
|
|
39
|
-
Requires-Dist: towncrier<
|
|
50
|
+
Requires-Dist: towncrier<26,>=24; extra == "dev"
|
|
40
51
|
Requires-Dist: hypothesis>=4.43.0; extra == "dev"
|
|
41
|
-
Requires-Dist: mypy
|
|
42
|
-
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
52
|
+
Requires-Dist: mypy[mypyc]<1.20,>=1.14.1; extra == "dev"
|
|
43
53
|
Requires-Dist: pytest-xdist>=2.4.0; extra == "dev"
|
|
54
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
44
55
|
Provides-Extra: docs
|
|
45
56
|
Requires-Dist: sphinx>=6.0.0; extra == "docs"
|
|
46
57
|
Requires-Dist: sphinx-autobuild>=2021.3.14; extra == "docs"
|
|
47
58
|
Requires-Dist: sphinx_rtd_theme>=1.0.0; extra == "docs"
|
|
48
|
-
Requires-Dist: towncrier<
|
|
59
|
+
Requires-Dist: towncrier<26,>=24; extra == "docs"
|
|
49
60
|
Provides-Extra: test
|
|
50
61
|
Requires-Dist: hypothesis>=4.43.0; extra == "test"
|
|
51
|
-
Requires-Dist: mypy
|
|
52
|
-
Requires-Dist: pytest>=7.0.0; extra == "test"
|
|
62
|
+
Requires-Dist: mypy[mypyc]<1.20,>=1.14.1; extra == "test"
|
|
53
63
|
Requires-Dist: pytest-xdist>=2.4.0; extra == "test"
|
|
64
|
+
Requires-Dist: pytest>=7.0.0; extra == "test"
|
|
65
|
+
Provides-Extra: codspeed
|
|
66
|
+
Requires-Dist: pytest-codspeed<4.3,>=4.2; extra == "codspeed"
|
|
67
|
+
Requires-Dist: pytest-test-groups; extra == "codspeed"
|
|
68
|
+
Requires-Dist: pytest>=7.0.0; extra == "codspeed"
|
|
69
|
+
Provides-Extra: benchmark
|
|
70
|
+
Requires-Dist: eth-utils==5.3.1; extra == "benchmark"
|
|
71
|
+
Requires-Dist: pytest-benchmark<5.3,>=5.2; extra == "benchmark"
|
|
72
|
+
Requires-Dist: pytest-codspeed<4.3,>=4.2; extra == "benchmark"
|
|
73
|
+
Requires-Dist: pytest-test-groups; extra == "benchmark"
|
|
74
|
+
Requires-Dist: pytest>=7.0.0; extra == "benchmark"
|
|
54
75
|
Dynamic: author
|
|
55
76
|
Dynamic: author-email
|
|
56
77
|
Dynamic: classifier
|
|
@@ -60,11 +81,30 @@ Dynamic: home-page
|
|
|
60
81
|
Dynamic: keywords
|
|
61
82
|
Dynamic: license
|
|
62
83
|
Dynamic: license-file
|
|
84
|
+
Dynamic: project-url
|
|
63
85
|
Dynamic: provides-extra
|
|
64
86
|
Dynamic: requires-dist
|
|
65
87
|
Dynamic: requires-python
|
|
66
88
|
Dynamic: summary
|
|
67
89
|
|
|
90
|
+
### I forked eth-utils and compiled it to C. It does the same stuff, now faster
|
|
91
|
+
|
|
92
|
+
[](https://pypi.org/project/faster-eth-utils)
|
|
93
|
+
[](https://pypistats.org/packages/faster-eth-utils)
|
|
94
|
+
[](https://codspeed.io/BobTheBuidler/faster-eth-utils)
|
|
95
|
+
|
|
96
|
+
##### This fork will be kept up-to-date with [eth-utils](https://github.com/ethereum/eth-utils). I will pull updates as they are released and push new [faster-eth-utils](https://github.com/BobTheBuidler/faster-eth-utils) releases to [PyPI](https://pypi.org/project/faster-eth-utils/).
|
|
97
|
+
|
|
98
|
+
##### Starting in [v5.3.11](https://github.com/BobTheBuidler/faster-eth-utils/releases/tag/v5.3.11), all `faster-eth-utils` Exception classes inherit from the matching Exception class in `eth-utils`, so porting to `faster-eth-utils` 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.
|
|
99
|
+
|
|
100
|
+
##### We benchmark `faster-eth-utils` against the original `eth-utils` for your convenience. [See results](https://github.com/BobTheBuidler/faster-eth-utils/tree/master/benchmarks/results).
|
|
101
|
+
|
|
102
|
+
##### You can find the compiled C code and header files in the [build](https://github.com/BobTheBuidler/eth-utils/tree/master/build) directory.
|
|
103
|
+
|
|
104
|
+
###### You may also be interested in: [faster-web3.py](https://github.com/BobTheBuidler/faster-web3.py/), [faster-eth-abi](https://github.com/BobTheBuidler/faster-eth-abi/), and [faster-hexbytes](https://github.com/BobTheBuidler/faster-hexbytes/)
|
|
105
|
+
|
|
106
|
+
##### The original eth-utils readme is below:
|
|
107
|
+
|
|
68
108
|
# Ethereum Utilities
|
|
69
109
|
|
|
70
110
|
[](https://discord.gg/GHryRvPB84)
|
|
@@ -75,9 +115,11 @@ Dynamic: summary
|
|
|
75
115
|
|
|
76
116
|
Common utility functions for python code that interacts with Ethereum
|
|
77
117
|
|
|
78
|
-
Read
|
|
118
|
+
Read the [documentation](https://eth-utils.readthedocs.io/).
|
|
119
|
+
|
|
120
|
+
View the [change log](https://eth-utils.readthedocs.io/en/latest/release_notes.html).
|
|
79
121
|
|
|
80
|
-
##
|
|
122
|
+
## Installation
|
|
81
123
|
|
|
82
124
|
```sh
|
|
83
125
|
python -m pip install eth-utils
|