web3 7.10.0__py3-none-any.whl → 7.11.0__py3-none-any.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.
- ens/exceptions.py +1 -1
- web3/_utils/batching.py +42 -1
- web3/_utils/encoding.py +8 -0
- web3/_utils/ens.py +9 -1
- web3/_utils/method_formatters.py +56 -7
- web3/_utils/module_testing/eth_module.py +153 -64
- web3/_utils/module_testing/module_testing_utils.py +0 -12
- web3/_utils/module_testing/persistent_connection_provider.py +3 -3
- web3/_utils/normalizers.py +1 -1
- web3/_utils/rpc_abi.py +5 -4
- web3/_utils/utility_methods.py +8 -6
- web3/providers/async_base.py +5 -6
- web3/providers/base.py +5 -5
- web3/providers/eth_tester/middleware.py +20 -0
- web3/providers/ipc.py +2 -0
- web3/providers/legacy_websocket.py +2 -0
- web3/providers/persistent/persistent.py +15 -10
- web3/providers/persistent/request_processor.py +10 -1
- web3/providers/rpc/async_rpc.py +2 -0
- web3/providers/rpc/rpc.py +2 -0
- web3/types.py +27 -0
- web3/utils/caching.py +8 -5
- {web3-7.10.0.dist-info → web3-7.11.0.dist-info}/METADATA +5 -5
- {web3-7.10.0.dist-info → web3-7.11.0.dist-info}/RECORD +27 -27
- {web3-7.10.0.dist-info → web3-7.11.0.dist-info}/WHEEL +1 -1
- {web3-7.10.0.dist-info → web3-7.11.0.dist-info}/licenses/LICENSE +0 -0
- {web3-7.10.0.dist-info → web3-7.11.0.dist-info}/top_level.txt +0 -0
ens/exceptions.py
CHANGED
|
@@ -32,7 +32,7 @@ class AddressMismatch(ENSException):
|
|
|
32
32
|
class InvalidName(idna.IDNAError, ENSException):
|
|
33
33
|
"""
|
|
34
34
|
Raised if the provided name does not meet the normalization
|
|
35
|
-
standards specified in `ENSIP-15
|
|
35
|
+
standards specified in `ENSIP-15`
|
|
36
36
|
<https://docs.ens.domains/ens-improvement-proposals/ensip-15-normalization-standard>`_.
|
|
37
37
|
"""
|
|
38
38
|
|
web3/_utils/batching.py
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
from copy import (
|
|
2
2
|
copy,
|
|
3
3
|
)
|
|
4
|
+
from functools import (
|
|
5
|
+
wraps,
|
|
6
|
+
)
|
|
4
7
|
from types import (
|
|
5
8
|
TracebackType,
|
|
6
9
|
)
|
|
@@ -12,9 +15,11 @@ from typing import (
|
|
|
12
15
|
Dict,
|
|
13
16
|
Generic,
|
|
14
17
|
List,
|
|
18
|
+
Protocol,
|
|
15
19
|
Sequence,
|
|
16
20
|
Tuple,
|
|
17
21
|
Type,
|
|
22
|
+
TypeVar,
|
|
18
23
|
Union,
|
|
19
24
|
cast,
|
|
20
25
|
)
|
|
@@ -33,6 +38,7 @@ from web3.exceptions import (
|
|
|
33
38
|
Web3ValueError,
|
|
34
39
|
)
|
|
35
40
|
from web3.types import (
|
|
41
|
+
RPCEndpoint,
|
|
36
42
|
TFunc,
|
|
37
43
|
TReturn,
|
|
38
44
|
)
|
|
@@ -55,7 +61,6 @@ if TYPE_CHECKING:
|
|
|
55
61
|
JSONBaseProvider,
|
|
56
62
|
)
|
|
57
63
|
from web3.types import ( # noqa: F401
|
|
58
|
-
RPCEndpoint,
|
|
59
64
|
RPCResponse,
|
|
60
65
|
)
|
|
61
66
|
|
|
@@ -215,3 +220,39 @@ def sort_batch_response_by_response_ids(
|
|
|
215
220
|
stacklevel=2,
|
|
216
221
|
)
|
|
217
222
|
return responses
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class SupportsBatching(Protocol):
|
|
226
|
+
_is_batching: bool
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
R = TypeVar("R")
|
|
230
|
+
T = TypeVar("T", bound=SupportsBatching)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def async_batching_context(
|
|
234
|
+
method: Callable[[T, List[Tuple[RPCEndpoint, Any]]], Coroutine[Any, Any, R]]
|
|
235
|
+
) -> Callable[[T, List[Tuple[RPCEndpoint, Any]]], Coroutine[Any, Any, R]]:
|
|
236
|
+
@wraps(method)
|
|
237
|
+
async def wrapper(self: T, requests: List[Tuple[RPCEndpoint, Any]]) -> R:
|
|
238
|
+
self._is_batching = True
|
|
239
|
+
try:
|
|
240
|
+
return await method(self, requests)
|
|
241
|
+
finally:
|
|
242
|
+
self._is_batching = False
|
|
243
|
+
|
|
244
|
+
return wrapper
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def batching_context(
|
|
248
|
+
method: Callable[[T, List[Tuple[RPCEndpoint, Any]]], R]
|
|
249
|
+
) -> Callable[[T, List[Tuple[RPCEndpoint, Any]]], R]:
|
|
250
|
+
@wraps(method)
|
|
251
|
+
def wrapper(self: T, requests: List[Tuple[RPCEndpoint, Any]]) -> R:
|
|
252
|
+
self._is_batching = True
|
|
253
|
+
try:
|
|
254
|
+
return method(self, requests)
|
|
255
|
+
finally:
|
|
256
|
+
self._is_batching = False
|
|
257
|
+
|
|
258
|
+
return wrapper
|
web3/_utils/encoding.py
CHANGED
|
@@ -36,6 +36,9 @@ from eth_utils.toolz import (
|
|
|
36
36
|
from hexbytes import (
|
|
37
37
|
HexBytes,
|
|
38
38
|
)
|
|
39
|
+
from pydantic import (
|
|
40
|
+
BaseModel,
|
|
41
|
+
)
|
|
39
42
|
|
|
40
43
|
from web3._utils.abi import (
|
|
41
44
|
is_address_type,
|
|
@@ -299,6 +302,11 @@ class Web3JsonEncoder(json.JSONEncoder):
|
|
|
299
302
|
return obj.__dict__
|
|
300
303
|
elif isinstance(obj, (HexBytes, bytes)):
|
|
301
304
|
return to_hex(obj)
|
|
305
|
+
elif isinstance(obj, BaseModel):
|
|
306
|
+
# TODO: For now we can assume all BaseModel objects behave this way, but
|
|
307
|
+
# internally we will start to use the CamelModel from eth-utils. Perhaps
|
|
308
|
+
# we should check for that type instead.
|
|
309
|
+
return obj.model_dump(by_alias=True)
|
|
302
310
|
return json.JSONEncoder.default(self, obj)
|
|
303
311
|
|
|
304
312
|
|
web3/_utils/ens.py
CHANGED
|
@@ -65,13 +65,21 @@ class StaticENS:
|
|
|
65
65
|
return self.registry.get(name, None)
|
|
66
66
|
|
|
67
67
|
|
|
68
|
+
class AsyncStaticENS:
|
|
69
|
+
def __init__(self, name_addr_pairs: Dict[str, ChecksumAddress]) -> None:
|
|
70
|
+
self.registry = dict(name_addr_pairs)
|
|
71
|
+
|
|
72
|
+
async def address(self, name: str) -> ChecksumAddress:
|
|
73
|
+
return self.registry.get(name, None)
|
|
74
|
+
|
|
75
|
+
|
|
68
76
|
@contextmanager
|
|
69
77
|
def ens_addresses(
|
|
70
78
|
w3: Union["Web3", "AsyncWeb3"], name_addr_pairs: Dict[str, ChecksumAddress]
|
|
71
79
|
) -> Iterator[None]:
|
|
72
80
|
original_ens = w3.ens
|
|
73
81
|
if w3.provider.is_async:
|
|
74
|
-
w3.ens = cast(AsyncENS,
|
|
82
|
+
w3.ens = cast(AsyncENS, AsyncStaticENS(name_addr_pairs))
|
|
75
83
|
else:
|
|
76
84
|
w3.ens = cast(ENS, StaticENS(name_addr_pairs))
|
|
77
85
|
yield
|
web3/_utils/method_formatters.py
CHANGED
|
@@ -47,6 +47,9 @@ from eth_utils.toolz import (
|
|
|
47
47
|
from hexbytes import (
|
|
48
48
|
HexBytes,
|
|
49
49
|
)
|
|
50
|
+
from pydantic import (
|
|
51
|
+
BaseModel,
|
|
52
|
+
)
|
|
50
53
|
|
|
51
54
|
from web3._utils.abi import (
|
|
52
55
|
is_length,
|
|
@@ -161,6 +164,12 @@ def type_aware_apply_formatters_to_dict(
|
|
|
161
164
|
"""
|
|
162
165
|
Preserve ``AttributeDict`` types if original ``value`` was an ``AttributeDict``.
|
|
163
166
|
"""
|
|
167
|
+
# TODO: In v8, Use eth-utils 5.3.0 as lower pin where ``apply_formatters_to_dict``
|
|
168
|
+
# already handles the CamelModel case, rather than generalizing to all BaseModel
|
|
169
|
+
# instances.
|
|
170
|
+
if isinstance(value, BaseModel):
|
|
171
|
+
value = value.model_dump(by_alias=True)
|
|
172
|
+
|
|
164
173
|
formatted_dict: Dict[str, Any] = apply_formatters_to_dict(formatters, dict(value))
|
|
165
174
|
return (
|
|
166
175
|
AttributeDict.recursive(formatted_dict)
|
|
@@ -177,6 +186,9 @@ def type_aware_apply_formatters_to_dict_keys_and_values(
|
|
|
177
186
|
"""
|
|
178
187
|
Preserve ``AttributeDict`` types if original ``value`` was an ``AttributeDict``.
|
|
179
188
|
"""
|
|
189
|
+
if isinstance(dict_like_object, BaseModel):
|
|
190
|
+
dict_like_object = dict_like_object.model_dump(by_alias=True)
|
|
191
|
+
|
|
180
192
|
formatted_dict = {
|
|
181
193
|
key_formatters(k): value_formatters(v) for k, v in dict_like_object.items()
|
|
182
194
|
}
|
|
@@ -223,6 +235,22 @@ ACCESS_LIST_RESPONSE_FORMATTER = type_aware_apply_formatters_to_dict(
|
|
|
223
235
|
}
|
|
224
236
|
)
|
|
225
237
|
|
|
238
|
+
AUTH_LIST_RESULT_FORMATTER = apply_formatter_if(
|
|
239
|
+
is_not_null,
|
|
240
|
+
apply_formatter_to_array(
|
|
241
|
+
type_aware_apply_formatters_to_dict(
|
|
242
|
+
{
|
|
243
|
+
"chainId": to_integer_if_hex,
|
|
244
|
+
"address": to_checksum_address,
|
|
245
|
+
"nonce": to_integer_if_hex,
|
|
246
|
+
"yParity": to_integer_if_hex,
|
|
247
|
+
"r": to_hexbytes(32, variable_length=True),
|
|
248
|
+
"s": to_hexbytes(32, variable_length=True),
|
|
249
|
+
}
|
|
250
|
+
),
|
|
251
|
+
),
|
|
252
|
+
)
|
|
253
|
+
|
|
226
254
|
TRANSACTION_RESULT_FORMATTERS = {
|
|
227
255
|
"blockHash": apply_formatter_if(is_not_null, to_hexbytes(32)),
|
|
228
256
|
"blockNumber": apply_formatter_if(is_not_null, to_integer_if_hex),
|
|
@@ -255,6 +283,7 @@ TRANSACTION_RESULT_FORMATTERS = {
|
|
|
255
283
|
"blobVersionedHashes": apply_formatter_if(
|
|
256
284
|
is_not_null, apply_formatter_to_array(to_hexbytes(32))
|
|
257
285
|
),
|
|
286
|
+
"authorizationList": AUTH_LIST_RESULT_FORMATTER,
|
|
258
287
|
}
|
|
259
288
|
|
|
260
289
|
|
|
@@ -332,6 +361,7 @@ BLOCK_REQUEST_FORMATTERS = {
|
|
|
332
361
|
"transactionsRoot": to_hex_if_bytes,
|
|
333
362
|
"withdrawalsRoot": to_hex_if_bytes,
|
|
334
363
|
"parentBeaconBlockRoot": to_hex_if_bytes,
|
|
364
|
+
"requestsHash": to_hex_if_bytes,
|
|
335
365
|
}
|
|
336
366
|
block_request_formatter = type_aware_apply_formatters_to_dict(BLOCK_REQUEST_FORMATTERS)
|
|
337
367
|
|
|
@@ -374,6 +404,7 @@ BLOCK_RESULT_FORMATTERS = {
|
|
|
374
404
|
"blobGasUsed": to_integer_if_hex,
|
|
375
405
|
"excessBlobGas": to_integer_if_hex,
|
|
376
406
|
"parentBeaconBlockRoot": apply_formatter_if(is_not_null, to_hexbytes(32)),
|
|
407
|
+
"requestsHash": apply_formatter_if(is_not_null, to_hexbytes(32)),
|
|
377
408
|
}
|
|
378
409
|
block_result_formatter = type_aware_apply_formatters_to_dict(BLOCK_RESULT_FORMATTERS)
|
|
379
410
|
|
|
@@ -466,6 +497,22 @@ filter_result_formatter = apply_one_of_formatters(
|
|
|
466
497
|
)
|
|
467
498
|
)
|
|
468
499
|
|
|
500
|
+
AUTH_LIST_REQUEST_FORMATTER = apply_formatter_if(
|
|
501
|
+
is_not_null,
|
|
502
|
+
apply_formatter_to_array(
|
|
503
|
+
type_aware_apply_formatters_to_dict(
|
|
504
|
+
{
|
|
505
|
+
"chainId": to_hex_if_integer,
|
|
506
|
+
"address": to_checksum_address,
|
|
507
|
+
"nonce": to_hex_if_integer,
|
|
508
|
+
"yParity": to_hex_if_integer,
|
|
509
|
+
"r": to_hex_if_integer,
|
|
510
|
+
"s": to_hex_if_integer,
|
|
511
|
+
}
|
|
512
|
+
),
|
|
513
|
+
),
|
|
514
|
+
)
|
|
515
|
+
|
|
469
516
|
TRANSACTION_REQUEST_FORMATTER = {
|
|
470
517
|
"from": to_checksum_address,
|
|
471
518
|
"to": apply_formatter_if(is_address, to_checksum_address),
|
|
@@ -477,12 +524,13 @@ TRANSACTION_REQUEST_FORMATTER = {
|
|
|
477
524
|
"maxFeePerGas": to_hex_if_integer,
|
|
478
525
|
"maxPriorityFeePerGas": to_hex_if_integer,
|
|
479
526
|
"chainId": to_hex_if_integer,
|
|
527
|
+
"authorizationList": AUTH_LIST_REQUEST_FORMATTER,
|
|
480
528
|
}
|
|
481
529
|
transaction_request_formatter = type_aware_apply_formatters_to_dict(
|
|
482
530
|
TRANSACTION_REQUEST_FORMATTER
|
|
483
531
|
)
|
|
484
532
|
|
|
485
|
-
|
|
533
|
+
ETH_CALL_TX_FORMATTER = type_aware_apply_formatters_to_dict(
|
|
486
534
|
{
|
|
487
535
|
"accessList": apply_formatter_if(
|
|
488
536
|
is_not_null,
|
|
@@ -494,10 +542,11 @@ ACCESS_LIST_REQUEST_FORMATTER = type_aware_apply_formatters_to_dict(
|
|
|
494
542
|
)
|
|
495
543
|
),
|
|
496
544
|
),
|
|
545
|
+
"authorizationList": AUTH_LIST_REQUEST_FORMATTER,
|
|
497
546
|
}
|
|
498
547
|
)
|
|
499
548
|
transaction_param_formatter = compose(
|
|
500
|
-
|
|
549
|
+
ETH_CALL_TX_FORMATTER,
|
|
501
550
|
remove_key_if("to", lambda txn: txn["to"] in {"", b"", None}),
|
|
502
551
|
remove_key_if("gasPrice", lambda txn: txn["gasPrice"] in {"", b"", None}),
|
|
503
552
|
)
|
|
@@ -1057,7 +1106,7 @@ def combine_formatters(
|
|
|
1057
1106
|
|
|
1058
1107
|
|
|
1059
1108
|
def get_request_formatters(
|
|
1060
|
-
method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]]
|
|
1109
|
+
method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]],
|
|
1061
1110
|
) -> Dict[str, Callable[..., Any]]:
|
|
1062
1111
|
request_formatter_maps = (
|
|
1063
1112
|
ABI_REQUEST_FORMATTERS,
|
|
@@ -1083,7 +1132,7 @@ def raise_block_not_found(params: Tuple[BlockIdentifier, bool]) -> NoReturn:
|
|
|
1083
1132
|
|
|
1084
1133
|
|
|
1085
1134
|
def raise_block_not_found_for_uncle_at_index(
|
|
1086
|
-
params: Tuple[BlockIdentifier, Union[HexStr, int]]
|
|
1135
|
+
params: Tuple[BlockIdentifier, Union[HexStr, int]],
|
|
1087
1136
|
) -> NoReturn:
|
|
1088
1137
|
try:
|
|
1089
1138
|
block_identifier = params[0]
|
|
@@ -1109,7 +1158,7 @@ def raise_transaction_not_found(params: Tuple[_Hash32]) -> NoReturn:
|
|
|
1109
1158
|
|
|
1110
1159
|
|
|
1111
1160
|
def raise_transaction_not_found_with_index(
|
|
1112
|
-
params: Tuple[BlockIdentifier, int]
|
|
1161
|
+
params: Tuple[BlockIdentifier, int],
|
|
1113
1162
|
) -> NoReturn:
|
|
1114
1163
|
try:
|
|
1115
1164
|
block_identifier = params[0]
|
|
@@ -1213,7 +1262,7 @@ def get_result_formatters(
|
|
|
1213
1262
|
|
|
1214
1263
|
|
|
1215
1264
|
def get_error_formatters(
|
|
1216
|
-
method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]]
|
|
1265
|
+
method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]],
|
|
1217
1266
|
) -> Callable[..., Any]:
|
|
1218
1267
|
# Note error formatters work on the full response dict
|
|
1219
1268
|
error_formatter_maps = (ERROR_FORMATTERS,)
|
|
@@ -1223,7 +1272,7 @@ def get_error_formatters(
|
|
|
1223
1272
|
|
|
1224
1273
|
|
|
1225
1274
|
def get_null_result_formatters(
|
|
1226
|
-
method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]]
|
|
1275
|
+
method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]],
|
|
1227
1276
|
) -> Callable[..., Any]:
|
|
1228
1277
|
formatters = combine_formatters((NULL_RESULT_FORMATTERS,), method_name)
|
|
1229
1278
|
|