web3 7.0.0b3__py3-none-any.whl → 7.0.0b4__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/_normalization.py +1 -3
- ens/async_ens.py +12 -9
- ens/contract_data.py +2 -2
- ens/ens.py +8 -5
- ens/exceptions.py +19 -27
- ens/specs/nf.json +1 -1
- ens/specs/normalization_spec.json +1 -1
- ens/utils.py +17 -10
- web3/__init__.py +2 -7
- web3/_utils/abi.py +30 -29
- web3/_utils/async_transactions.py +7 -4
- web3/_utils/blocks.py +6 -2
- web3/_utils/caching.py +7 -3
- web3/_utils/compat/__init__.py +0 -3
- web3/_utils/contract_sources/compile_contracts.py +1 -1
- web3/_utils/contracts.py +12 -12
- web3/_utils/datatypes.py +5 -1
- web3/_utils/decorators.py +6 -1
- web3/_utils/empty.py +1 -1
- web3/_utils/encoding.py +15 -10
- web3/_utils/error_formatters_utils.py +5 -3
- web3/_utils/events.py +20 -18
- web3/_utils/fee_utils.py +2 -4
- web3/_utils/filters.py +17 -12
- web3/_utils/formatters.py +2 -2
- web3/_utils/math.py +3 -2
- web3/_utils/method_formatters.py +24 -5
- web3/_utils/module.py +2 -1
- web3/_utils/module_testing/eth_module.py +62 -69
- web3/_utils/module_testing/go_ethereum_personal_module.py +1 -1
- web3/_utils/module_testing/module_testing_utils.py +1 -3
- web3/_utils/module_testing/utils.py +14 -7
- web3/_utils/normalizers.py +3 -3
- web3/_utils/request.py +4 -4
- web3/_utils/rpc_abi.py +5 -1
- web3/_utils/threads.py +8 -7
- web3/_utils/transactions.py +14 -12
- web3/_utils/type_conversion.py +5 -1
- web3/_utils/validation.py +12 -10
- web3/contract/async_contract.py +12 -7
- web3/contract/base_contract.py +50 -56
- web3/contract/contract.py +12 -6
- web3/contract/utils.py +11 -6
- web3/datastructures.py +22 -12
- web3/eth/async_eth.py +33 -28
- web3/eth/base_eth.py +7 -3
- web3/eth/eth.py +18 -13
- web3/exceptions.py +30 -59
- web3/gas_strategies/time_based.py +2 -4
- web3/geth.py +1 -3
- web3/main.py +6 -2
- web3/manager.py +7 -5
- web3/method.py +13 -5
- web3/middleware/base.py +4 -2
- web3/middleware/filter.py +27 -17
- web3/middleware/formatting.py +6 -3
- web3/middleware/names.py +4 -1
- web3/middleware/signing.py +6 -2
- web3/middleware/stalecheck.py +2 -1
- web3/providers/eth_tester/defaults.py +1 -1
- web3/providers/eth_tester/main.py +5 -4
- web3/providers/eth_tester/middleware.py +10 -1
- web3/providers/ipc.py +7 -3
- web3/providers/persistent/async_ipc.py +6 -7
- web3/providers/persistent/persistent.py +11 -1
- web3/providers/persistent/request_processor.py +7 -7
- web3/providers/persistent/websocket.py +3 -3
- web3/providers/rpc/async_rpc.py +23 -6
- web3/providers/rpc/rpc.py +27 -16
- web3/testing.py +4 -4
- web3/tools/benchmark/main.py +13 -9
- web3/tools/benchmark/utils.py +1 -1
- web3/tracing.py +9 -5
- web3/types.py +19 -22
- {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/METADATA +13 -28
- {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/RECORD +79 -79
- {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/LICENSE +0 -0
- {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/WHEEL +0 -0
- {web3-7.0.0b3.dist-info → web3-7.0.0b4.dist-info}/top_level.txt +0 -0
web3/_utils/events.py
CHANGED
|
@@ -76,6 +76,7 @@ from web3.exceptions import (
|
|
|
76
76
|
InvalidEventABI,
|
|
77
77
|
LogTopicError,
|
|
78
78
|
MismatchedABI,
|
|
79
|
+
Web3ValueError,
|
|
79
80
|
)
|
|
80
81
|
from web3.types import (
|
|
81
82
|
ABIEvent,
|
|
@@ -115,7 +116,7 @@ def construct_event_topic_set(
|
|
|
115
116
|
arguments = {}
|
|
116
117
|
if isinstance(arguments, (list, tuple)):
|
|
117
118
|
if len(arguments) != len(event_abi["inputs"]):
|
|
118
|
-
raise
|
|
119
|
+
raise Web3ValueError(
|
|
119
120
|
"When passing an argument list, the number of arguments must "
|
|
120
121
|
"match the event constructor."
|
|
121
122
|
)
|
|
@@ -130,9 +131,7 @@ def construct_event_topic_set(
|
|
|
130
131
|
for key, value in arguments.items() # type: ignore
|
|
131
132
|
}
|
|
132
133
|
|
|
133
|
-
|
|
134
|
-
# https://github.com/python/mypy/issues/4976
|
|
135
|
-
event_topic = encode_hex(event_abi_to_log_topic(event_abi)) # type: ignore
|
|
134
|
+
event_topic = encode_hex(event_abi_to_log_topic(event_abi))
|
|
136
135
|
indexed_args = get_indexed_event_inputs(event_abi)
|
|
137
136
|
zipped_abi_and_args = [
|
|
138
137
|
(arg, normalized_args.get(arg["name"], [None])) for arg in indexed_args
|
|
@@ -162,7 +161,7 @@ def construct_event_data_set(
|
|
|
162
161
|
arguments = {}
|
|
163
162
|
if isinstance(arguments, (list, tuple)):
|
|
164
163
|
if len(arguments) != len(event_abi["inputs"]):
|
|
165
|
-
raise
|
|
164
|
+
raise Web3ValueError(
|
|
166
165
|
"When passing an argument list, the number of arguments must "
|
|
167
166
|
"match the event constructor."
|
|
168
167
|
)
|
|
@@ -370,7 +369,7 @@ class BaseEventFilterBuilder:
|
|
|
370
369
|
if self._fromBlock is None and not self._immutable:
|
|
371
370
|
self._fromBlock = value
|
|
372
371
|
else:
|
|
373
|
-
raise
|
|
372
|
+
raise Web3ValueError(
|
|
374
373
|
f"fromBlock is already set to {self._fromBlock!r}. "
|
|
375
374
|
"Resetting filter parameters is not permitted"
|
|
376
375
|
)
|
|
@@ -384,7 +383,7 @@ class BaseEventFilterBuilder:
|
|
|
384
383
|
if self._toBlock is None and not self._immutable:
|
|
385
384
|
self._toBlock = value
|
|
386
385
|
else:
|
|
387
|
-
raise
|
|
386
|
+
raise Web3ValueError(
|
|
388
387
|
f"toBlock is already set to {self._toBlock!r}. "
|
|
389
388
|
"Resetting filter parameters is not permitted"
|
|
390
389
|
)
|
|
@@ -398,7 +397,7 @@ class BaseEventFilterBuilder:
|
|
|
398
397
|
if self._address is None and not self._immutable:
|
|
399
398
|
self._address = value
|
|
400
399
|
else:
|
|
401
|
-
raise
|
|
400
|
+
raise Web3ValueError(
|
|
402
401
|
f"address is already set to {self.address!r}. "
|
|
403
402
|
"Resetting filter parameters is not permitted"
|
|
404
403
|
)
|
|
@@ -443,9 +442,9 @@ class BaseEventFilterBuilder:
|
|
|
443
442
|
class EventFilterBuilder(BaseEventFilterBuilder):
|
|
444
443
|
def deploy(self, w3: "Web3") -> "LogFilter":
|
|
445
444
|
if not isinstance(w3, web3.Web3):
|
|
446
|
-
raise
|
|
445
|
+
raise Web3ValueError(f"Invalid web3 argument: got: {w3!r}")
|
|
447
446
|
|
|
448
|
-
for arg in AttributeDict.values(self.args):
|
|
447
|
+
for arg in AttributeDict.values(self.args):
|
|
449
448
|
arg._immutable = True # type: ignore[attr-defined]
|
|
450
449
|
self._immutable = True
|
|
451
450
|
|
|
@@ -461,9 +460,9 @@ class EventFilterBuilder(BaseEventFilterBuilder):
|
|
|
461
460
|
class AsyncEventFilterBuilder(BaseEventFilterBuilder):
|
|
462
461
|
async def deploy(self, async_w3: "AsyncWeb3") -> "AsyncLogFilter":
|
|
463
462
|
if not isinstance(async_w3, web3.AsyncWeb3):
|
|
464
|
-
raise
|
|
463
|
+
raise Web3ValueError(f"Invalid web3 argument: got: {async_w3!r}")
|
|
465
464
|
|
|
466
|
-
for arg in AttributeDict.values(self.args):
|
|
465
|
+
for arg in AttributeDict.values(self.args):
|
|
467
466
|
arg._immutable = True # type: ignore[attr-defined]
|
|
468
467
|
self._immutable = True
|
|
469
468
|
|
|
@@ -479,8 +478,7 @@ class AsyncEventFilterBuilder(BaseEventFilterBuilder):
|
|
|
479
478
|
|
|
480
479
|
def initialize_event_topics(event_abi: ABIEvent) -> Union[bytes, List[Any]]:
|
|
481
480
|
if event_abi["anonymous"] is False:
|
|
482
|
-
|
|
483
|
-
return event_abi_to_log_topic(event_abi) # type: ignore
|
|
481
|
+
return event_abi_to_log_topic(event_abi)
|
|
484
482
|
else:
|
|
485
483
|
return list()
|
|
486
484
|
|
|
@@ -519,19 +517,23 @@ class BaseArgumentFilter(ABC):
|
|
|
519
517
|
|
|
520
518
|
def match_single(self, value: Any) -> None:
|
|
521
519
|
if self._immutable:
|
|
522
|
-
raise
|
|
520
|
+
raise Web3ValueError(
|
|
521
|
+
"Setting values is forbidden after filter is deployed."
|
|
522
|
+
)
|
|
523
523
|
if self._match_values is None:
|
|
524
524
|
self._match_values = _normalize_match_values((value,))
|
|
525
525
|
else:
|
|
526
|
-
raise
|
|
526
|
+
raise Web3ValueError("An argument match value/s has already been set.")
|
|
527
527
|
|
|
528
528
|
def match_any(self, *values: Collection[Any]) -> None:
|
|
529
529
|
if self._immutable:
|
|
530
|
-
raise
|
|
530
|
+
raise Web3ValueError(
|
|
531
|
+
"Setting values is forbidden after filter is deployed."
|
|
532
|
+
)
|
|
531
533
|
if self._match_values is None:
|
|
532
534
|
self._match_values = _normalize_match_values(values)
|
|
533
535
|
else:
|
|
534
|
-
raise
|
|
536
|
+
raise Web3ValueError("An argument match value/s has already been set.")
|
|
535
537
|
|
|
536
538
|
@property
|
|
537
539
|
@abstractmethod
|
web3/_utils/fee_utils.py
CHANGED
|
@@ -45,7 +45,7 @@ def fee_history_priority_fee(eth: "Eth") -> Wei:
|
|
|
45
45
|
# This is a tested internal call so no need for type hinting. We can keep
|
|
46
46
|
# better consistency between the sync and async calls by unpacking
|
|
47
47
|
# PRIORITY_FEE_HISTORY_PARAMS as constants here.
|
|
48
|
-
fee_history = eth.fee_history(*PRIORITY_FEE_HISTORY_PARAMS)
|
|
48
|
+
fee_history = eth.fee_history(*PRIORITY_FEE_HISTORY_PARAMS)
|
|
49
49
|
return _fee_history_priority_fee_estimate(fee_history)
|
|
50
50
|
|
|
51
51
|
|
|
@@ -53,7 +53,5 @@ async def async_fee_history_priority_fee(async_eth: "AsyncEth") -> Wei:
|
|
|
53
53
|
# This is a tested internal call so no need for type hinting. We can keep
|
|
54
54
|
# better consistency between the sync and async calls by unpacking
|
|
55
55
|
# PRIORITY_FEE_HISTORY_PARAMS as constants here.
|
|
56
|
-
fee_history = await async_eth.fee_history(
|
|
57
|
-
*PRIORITY_FEE_HISTORY_PARAMS # type: ignore
|
|
58
|
-
)
|
|
56
|
+
fee_history = await async_eth.fee_history(*PRIORITY_FEE_HISTORY_PARAMS)
|
|
59
57
|
return _fee_history_priority_fee_estimate(fee_history)
|
web3/_utils/filters.py
CHANGED
|
@@ -50,7 +50,9 @@ from web3._utils.validation import (
|
|
|
50
50
|
validate_address,
|
|
51
51
|
)
|
|
52
52
|
from web3.exceptions import (
|
|
53
|
+
Web3TypeError,
|
|
53
54
|
Web3ValidationError,
|
|
55
|
+
Web3ValueError,
|
|
54
56
|
)
|
|
55
57
|
from web3.types import (
|
|
56
58
|
ABIEvent,
|
|
@@ -82,15 +84,14 @@ def construct_event_filter_params(
|
|
|
82
84
|
|
|
83
85
|
if topics is not None:
|
|
84
86
|
if len(topic_set) > 1:
|
|
85
|
-
raise
|
|
87
|
+
raise Web3TypeError(
|
|
86
88
|
"Merging the topics argument with topics generated "
|
|
87
89
|
"from argument_filters is not supported."
|
|
88
90
|
)
|
|
89
91
|
topic_set = topics
|
|
90
92
|
|
|
91
93
|
if len(topic_set) == 1 and is_list_like(topic_set[0]):
|
|
92
|
-
|
|
93
|
-
filter_params["topics"] = topic_set[0] # type: ignore
|
|
94
|
+
filter_params["topics"] = topic_set[0]
|
|
94
95
|
else:
|
|
95
96
|
filter_params["topics"] = topic_set
|
|
96
97
|
|
|
@@ -104,7 +105,7 @@ def construct_event_filter_params(
|
|
|
104
105
|
else [address]
|
|
105
106
|
)
|
|
106
107
|
else:
|
|
107
|
-
raise
|
|
108
|
+
raise Web3ValueError(
|
|
108
109
|
f"Unsupported type for `address` parameter: {type(address)}"
|
|
109
110
|
)
|
|
110
111
|
elif address:
|
|
@@ -178,7 +179,7 @@ class BaseFilter:
|
|
|
178
179
|
class Filter(BaseFilter):
|
|
179
180
|
def __init__(self, filter_id: HexStr, eth_module: "Eth") -> None:
|
|
180
181
|
self.eth_module = eth_module
|
|
181
|
-
super(
|
|
182
|
+
super().__init__(filter_id)
|
|
182
183
|
|
|
183
184
|
def get_new_entries(self) -> List[LogReceipt]:
|
|
184
185
|
log_entries = self._filter_valid_entries(
|
|
@@ -196,7 +197,7 @@ class Filter(BaseFilter):
|
|
|
196
197
|
class AsyncFilter(BaseFilter):
|
|
197
198
|
def __init__(self, filter_id: HexStr, eth_module: "AsyncEth") -> None:
|
|
198
199
|
self.eth_module = eth_module
|
|
199
|
-
super(
|
|
200
|
+
super().__init__(filter_id)
|
|
200
201
|
|
|
201
202
|
async def get_new_entries(self) -> List[LogReceipt]:
|
|
202
203
|
filter_changes = await self.eth_module.get_filter_changes(self.filter_id)
|
|
@@ -250,7 +251,8 @@ class LogFilter(Filter):
|
|
|
250
251
|
def set_data_filters(
|
|
251
252
|
self, data_filter_set: Collection[Tuple[TypeStr, Any]]
|
|
252
253
|
) -> None:
|
|
253
|
-
"""
|
|
254
|
+
"""
|
|
255
|
+
Sets the data filters (non indexed argument filters)
|
|
254
256
|
|
|
255
257
|
Expects a set of tuples with the type and value, e.g.:
|
|
256
258
|
(('uint256', [12345, 54321]), ('string', ('a-single-string',)))
|
|
@@ -292,7 +294,8 @@ class AsyncLogFilter(AsyncFilter):
|
|
|
292
294
|
def set_data_filters(
|
|
293
295
|
self, data_filter_set: Collection[Tuple[TypeStr, Any]]
|
|
294
296
|
) -> None:
|
|
295
|
-
"""
|
|
297
|
+
"""
|
|
298
|
+
Sets the data filters (non indexed argument filters)
|
|
296
299
|
|
|
297
300
|
Expects a set of tuples with the type and value, e.g.:
|
|
298
301
|
(('uint256', [12345, 54321]), ('string', ('a-single-string',)))
|
|
@@ -318,7 +321,8 @@ normalize_to_text = apply_formatter_if(not_text, decode_utf8_bytes)
|
|
|
318
321
|
|
|
319
322
|
|
|
320
323
|
def normalize_data_values(type_string: TypeStr, data_value: Any) -> Any:
|
|
321
|
-
"""
|
|
324
|
+
"""
|
|
325
|
+
Decodes utf-8 bytes to strings for abi string values.
|
|
322
326
|
|
|
323
327
|
eth-abi v1 returns utf-8 bytes for string values.
|
|
324
328
|
This can be removed once eth-abi v2 is required.
|
|
@@ -326,7 +330,7 @@ def normalize_data_values(type_string: TypeStr, data_value: Any) -> Any:
|
|
|
326
330
|
_type = parse_type_string(type_string)
|
|
327
331
|
if _type.base == "string":
|
|
328
332
|
if _type.arrlist is not None:
|
|
329
|
-
return tuple(
|
|
333
|
+
return tuple(normalize_to_text(value) for value in data_value)
|
|
330
334
|
else:
|
|
331
335
|
return normalize_to_text(data_value)
|
|
332
336
|
return data_value
|
|
@@ -336,7 +340,8 @@ def normalize_data_values(type_string: TypeStr, data_value: Any) -> Any:
|
|
|
336
340
|
def match_fn(
|
|
337
341
|
codec: ABICodec, match_values_and_abi: Collection[Tuple[str, Any]], data: Any
|
|
338
342
|
) -> bool:
|
|
339
|
-
"""
|
|
343
|
+
"""
|
|
344
|
+
Match function used for filtering non-indexed event arguments.
|
|
340
345
|
|
|
341
346
|
Values provided through the match_values_and_abi parameter are
|
|
342
347
|
compared to the abi decoded log data.
|
|
@@ -352,7 +357,7 @@ def match_fn(
|
|
|
352
357
|
normalized_data = normalize_data_values(abi_type, data_value)
|
|
353
358
|
for value in match_values:
|
|
354
359
|
if not codec.is_encodable(abi_type, value):
|
|
355
|
-
raise
|
|
360
|
+
raise Web3ValueError(
|
|
356
361
|
f"Value {value} is of the wrong abi type. "
|
|
357
362
|
f"Expected {abi_type} typed value."
|
|
358
363
|
)
|
web3/_utils/formatters.py
CHANGED
|
@@ -114,13 +114,13 @@ def apply_key_map(
|
|
|
114
114
|
def is_array_of_strings(value: Any) -> bool:
|
|
115
115
|
if not is_list_like(value):
|
|
116
116
|
return False
|
|
117
|
-
return all(
|
|
117
|
+
return all(is_string(item) for item in value)
|
|
118
118
|
|
|
119
119
|
|
|
120
120
|
def is_array_of_dicts(value: Any) -> bool:
|
|
121
121
|
if not is_list_like(value):
|
|
122
122
|
return False
|
|
123
|
-
return all(
|
|
123
|
+
return all(is_dict(item) for item in value)
|
|
124
124
|
|
|
125
125
|
|
|
126
126
|
@curry
|
web3/_utils/math.py
CHANGED
|
@@ -5,6 +5,7 @@ from typing import (
|
|
|
5
5
|
|
|
6
6
|
from web3.exceptions import (
|
|
7
7
|
InsufficientData,
|
|
8
|
+
Web3ValueError,
|
|
8
9
|
)
|
|
9
10
|
|
|
10
11
|
|
|
@@ -17,9 +18,9 @@ def percentile(
|
|
|
17
18
|
f"Expected a sequence of at least 1 integers, got {values!r}"
|
|
18
19
|
)
|
|
19
20
|
if percentile is None:
|
|
20
|
-
raise
|
|
21
|
+
raise Web3ValueError(f"Expected a percentile choice, got {percentile}")
|
|
21
22
|
if percentile < 0 or percentile > 100:
|
|
22
|
-
raise
|
|
23
|
+
raise Web3ValueError("percentile must be in the range [0, 100]")
|
|
23
24
|
|
|
24
25
|
sorted_values = sorted(values)
|
|
25
26
|
|
web3/_utils/method_formatters.py
CHANGED
|
@@ -99,6 +99,8 @@ from web3.datastructures import (
|
|
|
99
99
|
from web3.exceptions import (
|
|
100
100
|
BlockNotFound,
|
|
101
101
|
TransactionNotFound,
|
|
102
|
+
Web3TypeError,
|
|
103
|
+
Web3ValueError,
|
|
102
104
|
)
|
|
103
105
|
from web3.types import (
|
|
104
106
|
BlockIdentifier,
|
|
@@ -136,7 +138,7 @@ def to_hexbytes(
|
|
|
136
138
|
if isinstance(val, (str, int, bytes)):
|
|
137
139
|
result = HexBytes(val)
|
|
138
140
|
else:
|
|
139
|
-
raise
|
|
141
|
+
raise Web3TypeError(f"Cannot convert {val!r} to HexBytes")
|
|
140
142
|
|
|
141
143
|
extra_bytes = len(result) - num_bytes
|
|
142
144
|
if extra_bytes == 0 or (variable_length and extra_bytes < 0):
|
|
@@ -144,7 +146,7 @@ def to_hexbytes(
|
|
|
144
146
|
elif all(byte == 0 for byte in result[:extra_bytes]):
|
|
145
147
|
return HexBytes(result[extra_bytes:])
|
|
146
148
|
else:
|
|
147
|
-
raise
|
|
149
|
+
raise Web3ValueError(
|
|
148
150
|
f"The value {result!r} is {len(result)} bytes, but should be {num_bytes}"
|
|
149
151
|
)
|
|
150
152
|
|
|
@@ -177,9 +179,9 @@ def type_aware_apply_formatters_to_dict_keys_and_values(
|
|
|
177
179
|
"""
|
|
178
180
|
Preserve ``AttributeDict`` types if original ``value`` was an ``AttributeDict``.
|
|
179
181
|
"""
|
|
180
|
-
formatted_dict =
|
|
181
|
-
|
|
182
|
-
|
|
182
|
+
formatted_dict = {
|
|
183
|
+
key_formatters(k): value_formatters(v) for k, v in dict_like_object.items()
|
|
184
|
+
}
|
|
183
185
|
return (
|
|
184
186
|
AttributeDict.recursive(formatted_dict)
|
|
185
187
|
if is_attrdict(dict_like_object)
|
|
@@ -285,6 +287,8 @@ RECEIPT_FORMATTERS = {
|
|
|
285
287
|
"to": apply_formatter_if(is_address, to_checksum_address),
|
|
286
288
|
"effectiveGasPrice": to_integer_if_hex,
|
|
287
289
|
"type": to_integer_if_hex,
|
|
290
|
+
"blobGasPrice": to_integer_if_hex,
|
|
291
|
+
"blobGasUsed": to_integer_if_hex,
|
|
288
292
|
}
|
|
289
293
|
|
|
290
294
|
|
|
@@ -423,7 +427,22 @@ filter_result_formatter = apply_one_of_formatters(
|
|
|
423
427
|
)
|
|
424
428
|
)
|
|
425
429
|
|
|
430
|
+
ACCESS_LIST_REQUEST_FORMATTER = type_aware_apply_formatters_to_dict(
|
|
431
|
+
{
|
|
432
|
+
"accessList": apply_formatter_if(
|
|
433
|
+
is_not_null,
|
|
434
|
+
apply_list_to_array_formatter(
|
|
435
|
+
apply_formatters_to_dict(
|
|
436
|
+
{
|
|
437
|
+
"storageKeys": apply_list_to_array_formatter(to_hex_if_bytes),
|
|
438
|
+
}
|
|
439
|
+
)
|
|
440
|
+
),
|
|
441
|
+
),
|
|
442
|
+
}
|
|
443
|
+
)
|
|
426
444
|
transaction_param_formatter = compose(
|
|
445
|
+
ACCESS_LIST_REQUEST_FORMATTER,
|
|
427
446
|
remove_key_if("to", lambda txn: txn["to"] in {"", b"", None}),
|
|
428
447
|
remove_key_if("gasPrice", lambda txn: txn["gasPrice"] in {"", b"", None}),
|
|
429
448
|
)
|
web3/_utils/module.py
CHANGED
|
@@ -13,6 +13,7 @@ from typing import (
|
|
|
13
13
|
)
|
|
14
14
|
|
|
15
15
|
from web3.exceptions import (
|
|
16
|
+
Web3AttributeError,
|
|
16
17
|
Web3ValidationError,
|
|
17
18
|
)
|
|
18
19
|
from web3.module import (
|
|
@@ -50,7 +51,7 @@ def attach_modules(
|
|
|
50
51
|
module_class = module_info[0] if module_info_is_list_like else module_info
|
|
51
52
|
|
|
52
53
|
if hasattr(parent_module, module_name):
|
|
53
|
-
raise
|
|
54
|
+
raise Web3AttributeError(
|
|
54
55
|
f"Cannot set {parent_module} module named '{module_name}'. "
|
|
55
56
|
" The web3 object already has an attribute with that name"
|
|
56
57
|
)
|