web3 7.0.0b2__py3-none-any.whl → 7.7.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.
Files changed (144) hide show
  1. ens/__init__.py +13 -2
  2. ens/_normalization.py +4 -4
  3. ens/async_ens.py +27 -15
  4. ens/base_ens.py +3 -1
  5. ens/contract_data.py +2 -2
  6. ens/ens.py +10 -7
  7. ens/exceptions.py +16 -29
  8. ens/specs/nf.json +1 -1
  9. ens/specs/normalization_spec.json +1 -1
  10. ens/utils.py +24 -32
  11. web3/__init__.py +23 -12
  12. web3/_utils/abi.py +157 -263
  13. web3/_utils/async_transactions.py +34 -20
  14. web3/_utils/batching.py +217 -0
  15. web3/_utils/blocks.py +6 -2
  16. web3/_utils/caching/__init__.py +12 -0
  17. web3/_utils/caching/caching_utils.py +433 -0
  18. web3/_utils/caching/request_caching_validation.py +287 -0
  19. web3/_utils/compat/__init__.py +2 -3
  20. web3/_utils/contract_sources/compile_contracts.py +1 -1
  21. web3/_utils/contract_sources/contract_data/ambiguous_function_contract.py +42 -0
  22. web3/_utils/contract_sources/contract_data/arrays_contract.py +3 -3
  23. web3/_utils/contract_sources/contract_data/bytes_contracts.py +5 -5
  24. web3/_utils/contract_sources/contract_data/constructor_contracts.py +7 -7
  25. web3/_utils/contract_sources/contract_data/contract_caller_tester.py +3 -3
  26. web3/_utils/contract_sources/contract_data/emitter_contract.py +3 -3
  27. web3/_utils/contract_sources/contract_data/event_contracts.py +50 -5
  28. web3/_utils/contract_sources/contract_data/extended_resolver.py +3 -3
  29. web3/_utils/contract_sources/contract_data/fallback_function_contract.py +3 -3
  30. web3/_utils/contract_sources/contract_data/function_name_tester_contract.py +3 -3
  31. web3/_utils/contract_sources/contract_data/math_contract.py +3 -3
  32. web3/_utils/contract_sources/contract_data/offchain_lookup.py +3 -3
  33. web3/_utils/contract_sources/contract_data/offchain_resolver.py +3 -3
  34. web3/_utils/contract_sources/contract_data/panic_errors_contract.py +3 -3
  35. web3/_utils/contract_sources/contract_data/payable_tester.py +3 -3
  36. web3/_utils/contract_sources/contract_data/receive_function_contracts.py +5 -5
  37. web3/_utils/contract_sources/contract_data/reflector_contracts.py +3 -3
  38. web3/_utils/contract_sources/contract_data/revert_contract.py +3 -3
  39. web3/_utils/contract_sources/contract_data/simple_resolver.py +3 -3
  40. web3/_utils/contract_sources/contract_data/storage_contract.py +3 -3
  41. web3/_utils/contract_sources/contract_data/string_contract.py +3 -3
  42. web3/_utils/contract_sources/contract_data/tuple_contracts.py +5 -5
  43. web3/_utils/contracts.py +172 -220
  44. web3/_utils/datatypes.py +5 -1
  45. web3/_utils/decorators.py +6 -1
  46. web3/_utils/empty.py +1 -1
  47. web3/_utils/encoding.py +16 -12
  48. web3/_utils/error_formatters_utils.py +5 -3
  49. web3/_utils/events.py +78 -72
  50. web3/_utils/fee_utils.py +1 -3
  51. web3/_utils/filters.py +24 -22
  52. web3/_utils/formatters.py +2 -2
  53. web3/_utils/http.py +8 -2
  54. web3/_utils/http_session_manager.py +314 -0
  55. web3/_utils/math.py +14 -15
  56. web3/_utils/method_formatters.py +161 -34
  57. web3/_utils/module.py +2 -1
  58. web3/_utils/module_testing/__init__.py +3 -2
  59. web3/_utils/module_testing/eth_module.py +736 -583
  60. web3/_utils/module_testing/go_ethereum_debug_module.py +128 -0
  61. web3/_utils/module_testing/module_testing_utils.py +81 -24
  62. web3/_utils/module_testing/persistent_connection_provider.py +702 -220
  63. web3/_utils/module_testing/utils.py +114 -33
  64. web3/_utils/module_testing/web3_module.py +438 -17
  65. web3/_utils/normalizers.py +13 -11
  66. web3/_utils/rpc_abi.py +10 -22
  67. web3/_utils/threads.py +8 -7
  68. web3/_utils/transactions.py +32 -25
  69. web3/_utils/type_conversion.py +5 -1
  70. web3/_utils/validation.py +20 -17
  71. web3/beacon/__init__.py +5 -0
  72. web3/beacon/api_endpoints.py +3 -0
  73. web3/beacon/async_beacon.py +29 -6
  74. web3/beacon/beacon.py +24 -6
  75. web3/contract/__init__.py +7 -0
  76. web3/contract/async_contract.py +285 -82
  77. web3/contract/base_contract.py +556 -258
  78. web3/contract/contract.py +295 -84
  79. web3/contract/utils.py +251 -55
  80. web3/datastructures.py +49 -34
  81. web3/eth/__init__.py +7 -0
  82. web3/eth/async_eth.py +89 -69
  83. web3/eth/base_eth.py +7 -3
  84. web3/eth/eth.py +43 -66
  85. web3/exceptions.py +158 -83
  86. web3/gas_strategies/time_based.py +8 -6
  87. web3/geth.py +53 -184
  88. web3/main.py +77 -17
  89. web3/manager.py +362 -95
  90. web3/method.py +43 -15
  91. web3/middleware/__init__.py +17 -0
  92. web3/middleware/attrdict.py +12 -22
  93. web3/middleware/base.py +55 -2
  94. web3/middleware/filter.py +45 -23
  95. web3/middleware/formatting.py +6 -3
  96. web3/middleware/names.py +4 -1
  97. web3/middleware/signing.py +15 -6
  98. web3/middleware/stalecheck.py +2 -1
  99. web3/module.py +61 -25
  100. web3/providers/__init__.py +21 -0
  101. web3/providers/async_base.py +87 -32
  102. web3/providers/base.py +77 -32
  103. web3/providers/eth_tester/__init__.py +5 -0
  104. web3/providers/eth_tester/defaults.py +2 -55
  105. web3/providers/eth_tester/main.py +41 -15
  106. web3/providers/eth_tester/middleware.py +16 -17
  107. web3/providers/ipc.py +41 -17
  108. web3/providers/legacy_websocket.py +26 -1
  109. web3/providers/persistent/__init__.py +7 -0
  110. web3/providers/persistent/async_ipc.py +61 -121
  111. web3/providers/persistent/persistent.py +323 -16
  112. web3/providers/persistent/persistent_connection.py +54 -5
  113. web3/providers/persistent/request_processor.py +136 -56
  114. web3/providers/persistent/subscription_container.py +56 -0
  115. web3/providers/persistent/subscription_manager.py +233 -0
  116. web3/providers/persistent/websocket.py +29 -92
  117. web3/providers/rpc/__init__.py +5 -0
  118. web3/providers/rpc/async_rpc.py +73 -18
  119. web3/providers/rpc/rpc.py +73 -30
  120. web3/providers/rpc/utils.py +1 -13
  121. web3/scripts/install_pre_releases.py +33 -0
  122. web3/scripts/parse_pygeth_version.py +16 -0
  123. web3/testing.py +4 -4
  124. web3/tracing.py +9 -5
  125. web3/types.py +141 -74
  126. web3/utils/__init__.py +64 -5
  127. web3/utils/abi.py +790 -10
  128. web3/utils/address.py +8 -0
  129. web3/utils/async_exception_handling.py +20 -11
  130. web3/utils/caching.py +34 -4
  131. web3/utils/exception_handling.py +9 -12
  132. web3/utils/subscriptions.py +285 -0
  133. {web3-7.0.0b2.dist-info → web3-7.7.0.dist-info}/LICENSE +1 -1
  134. web3-7.7.0.dist-info/METADATA +130 -0
  135. web3-7.7.0.dist-info/RECORD +171 -0
  136. {web3-7.0.0b2.dist-info → web3-7.7.0.dist-info}/WHEEL +1 -1
  137. web3/_utils/caching.py +0 -155
  138. web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
  139. web3/_utils/module_testing/go_ethereum_personal_module.py +0 -300
  140. web3/_utils/request.py +0 -265
  141. web3-7.0.0b2.dist-info/METADATA +0 -106
  142. web3-7.0.0b2.dist-info/RECORD +0 -163
  143. /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
  144. {web3-7.0.0b2.dist-info → web3-7.7.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,8 @@
1
1
  from typing import (
2
2
  TYPE_CHECKING,
3
+ Dict,
3
4
  Optional,
5
+ Union,
4
6
  cast,
5
7
  )
6
8
 
@@ -24,6 +26,9 @@ from web3._utils.utility_methods import (
24
26
  from web3.constants import (
25
27
  DYNAMIC_FEE_TXN_PARAMS,
26
28
  )
29
+ from web3.exceptions import (
30
+ Web3ValueError,
31
+ )
27
32
  from web3.types import (
28
33
  BlockIdentifier,
29
34
  TxData,
@@ -39,21 +44,32 @@ if TYPE_CHECKING:
39
44
  )
40
45
 
41
46
 
42
- async def _estimate_gas(async_w3: "AsyncWeb3", tx: TxParams) -> int:
47
+ # unused vars present in these funcs because they all need to have the same signature
48
+ async def _estimate_gas(
49
+ async_w3: "AsyncWeb3", tx: TxParams, _defaults: Dict[str, Union[bytes, int]]
50
+ ) -> int:
43
51
  return await async_w3.eth.estimate_gas(tx)
44
52
 
45
53
 
46
- async def _max_fee_per_gas(async_w3: "AsyncWeb3", _tx: TxParams) -> Wei:
54
+ async def _max_fee_per_gas(
55
+ async_w3: "AsyncWeb3", tx: TxParams, defaults: Dict[str, Union[bytes, int]]
56
+ ) -> Wei:
47
57
  block = await async_w3.eth.get_block("latest")
48
- max_priority_fee = await async_w3.eth.max_priority_fee
49
- return Wei(max_priority_fee + (2 * block["baseFeePerGas"]))
58
+ max_priority_fee = tx.get(
59
+ "maxPriorityFeePerGas", defaults.get("maxPriorityFeePerGas")
60
+ )
61
+ return Wei(int(max_priority_fee) + (2 * int(block["baseFeePerGas"])))
50
62
 
51
63
 
52
- async def _max_priority_fee_gas(async_w3: "AsyncWeb3", _tx: TxParams) -> Wei:
64
+ async def _max_priority_fee_gas(
65
+ async_w3: "AsyncWeb3", _tx: TxParams, _defaults: Dict[str, Union[bytes, int]]
66
+ ) -> Wei:
53
67
  return await async_w3.eth.max_priority_fee
54
68
 
55
69
 
56
- async def _chain_id(async_w3: "AsyncWeb3", _tx: TxParams) -> int:
70
+ async def _chain_id(
71
+ async_w3: "AsyncWeb3", _tx: TxParams, _defaults: Dict[str, Union[bytes, int]]
72
+ ) -> int:
57
73
  return await async_w3.eth.chain_id
58
74
 
59
75
 
@@ -61,9 +77,9 @@ TRANSACTION_DEFAULTS = {
61
77
  "value": 0,
62
78
  "data": b"",
63
79
  "gas": _estimate_gas,
64
- "gasPrice": lambda async_w3, tx: async_w3.eth.generate_gas_price(tx),
65
- "maxFeePerGas": _max_fee_per_gas,
80
+ "gasPrice": lambda async_w3, tx, _defaults: async_w3.eth.generate_gas_price(tx),
66
81
  "maxPriorityFeePerGas": _max_priority_fee_gas,
82
+ "maxFeePerGas": _max_fee_per_gas,
67
83
  "chainId": _chain_id,
68
84
  }
69
85
 
@@ -71,9 +87,7 @@ TRANSACTION_DEFAULTS = {
71
87
  async def get_block_gas_limit(
72
88
  web3_eth: "AsyncEth", block_identifier: Optional[BlockIdentifier] = None
73
89
  ) -> int:
74
- if block_identifier is None:
75
- block_identifier = await web3_eth.block_number
76
- block = await web3_eth.get_block(block_identifier)
90
+ block = await web3_eth.get_block(block_identifier or "latest")
77
91
  return block["gasLimit"]
78
92
 
79
93
 
@@ -87,9 +101,9 @@ async def get_buffered_gas_estimate(
87
101
  gas_limit = await get_block_gas_limit(async_w3.eth)
88
102
 
89
103
  if gas_estimate > gas_limit:
90
- raise ValueError(
91
- "Contract does not appear to be deployable within the "
92
- f"current network gas limits. Estimated: {gas_estimate}. "
104
+ raise Web3ValueError(
105
+ "Gas estimate for transaction is higher than current network gas limits. "
106
+ f"Transaction could not be sent. Estimated: {gas_estimate}. "
93
107
  f"Current gas limit: {gas_limit}"
94
108
  )
95
109
 
@@ -110,7 +124,7 @@ async def async_fill_transaction_defaults(
110
124
  async_w3: "AsyncWeb3", transaction: TxParams
111
125
  ) -> TxParams:
112
126
  """
113
- if async_w3 is None, fill as much as possible while offline
127
+ If async_w3 is None, fill as much as possible while offline
114
128
  """
115
129
  strategy_based_gas_price = async_w3.eth.generate_gas_price(transaction)
116
130
 
@@ -119,7 +133,7 @@ async def async_fill_transaction_defaults(
119
133
  or any_in_dict(DYNAMIC_FEE_TXN_PARAMS, transaction)
120
134
  )
121
135
 
122
- defaults = {}
136
+ defaults: Dict[str, Union[bytes, int]] = {}
123
137
  for key, default_getter in TRANSACTION_DEFAULTS.items():
124
138
  if key not in transaction:
125
139
  if (
@@ -134,15 +148,15 @@ async def async_fill_transaction_defaults(
134
148
 
135
149
  if callable(default_getter):
136
150
  if async_w3 is None:
137
- raise ValueError(
151
+ raise Web3ValueError(
138
152
  f"You must specify a '{key}' value in the transaction"
139
153
  )
140
154
  if key == "gasPrice":
141
155
  # `generate_gas_price()` is on the `BaseEth` class and does not
142
156
  # need to be awaited
143
- default_val = default_getter(async_w3, transaction)
157
+ default_val = default_getter(async_w3, transaction, defaults)
144
158
  else:
145
- default_val = await default_getter(async_w3, transaction)
159
+ default_val = await default_getter(async_w3, transaction, defaults)
146
160
  else:
147
161
  default_val = default_getter
148
162
 
@@ -155,7 +169,7 @@ async def async_get_required_transaction(
155
169
  ) -> TxData:
156
170
  current_transaction = await async_w3.eth.get_transaction(transaction_hash)
157
171
  if not current_transaction:
158
- raise ValueError(
172
+ raise Web3ValueError(
159
173
  f"Supplied transaction with hash {transaction_hash!r} does not exist"
160
174
  )
161
175
  return current_transaction
@@ -0,0 +1,217 @@
1
+ from copy import (
2
+ copy,
3
+ )
4
+ from types import (
5
+ TracebackType,
6
+ )
7
+ from typing import (
8
+ TYPE_CHECKING,
9
+ Any,
10
+ Callable,
11
+ Coroutine,
12
+ Dict,
13
+ Generic,
14
+ List,
15
+ Sequence,
16
+ Tuple,
17
+ Type,
18
+ Union,
19
+ cast,
20
+ )
21
+ import warnings
22
+
23
+ from web3._utils.compat import (
24
+ Self,
25
+ )
26
+ from web3.contract.async_contract import (
27
+ AsyncContractFunction,
28
+ )
29
+ from web3.contract.contract import (
30
+ ContractFunction,
31
+ )
32
+ from web3.exceptions import (
33
+ Web3ValueError,
34
+ )
35
+ from web3.types import (
36
+ TFunc,
37
+ TReturn,
38
+ )
39
+
40
+ if TYPE_CHECKING:
41
+ from web3 import ( # noqa: F401
42
+ AsyncWeb3,
43
+ Web3,
44
+ )
45
+ from web3.method import ( # noqa: F401
46
+ Method,
47
+ )
48
+ from web3.providers import ( # noqa: F401
49
+ PersistentConnectionProvider,
50
+ )
51
+ from web3.providers.async_base import ( # noqa: F401
52
+ AsyncJSONBaseProvider,
53
+ )
54
+ from web3.providers.base import ( # noqa: F401
55
+ JSONBaseProvider,
56
+ )
57
+ from web3.types import ( # noqa: F401
58
+ RPCEndpoint,
59
+ RPCResponse,
60
+ )
61
+
62
+
63
+ BATCH_REQUEST_ID = "batch_request" # for use as the cache key for batch requests
64
+
65
+ BatchRequestInformation = Tuple[Tuple["RPCEndpoint", Any], Sequence[Any]]
66
+ RPC_METHODS_UNSUPPORTED_DURING_BATCH = {
67
+ "eth_subscribe",
68
+ "eth_unsubscribe",
69
+ "eth_sendRawTransaction",
70
+ "eth_sendTransaction",
71
+ "eth_signTransaction",
72
+ "eth_sign",
73
+ "eth_signTypedData",
74
+ }
75
+
76
+
77
+ class RequestBatcher(Generic[TFunc]):
78
+ def __init__(self, web3: Union["AsyncWeb3", "Web3"]) -> None:
79
+ self.web3 = web3
80
+ self._requests_info: List[BatchRequestInformation] = []
81
+ self._async_requests_info: List[
82
+ Coroutine[Any, Any, BatchRequestInformation]
83
+ ] = []
84
+ self._initialize_batching()
85
+
86
+ @property
87
+ def _provider(self) -> Union["JSONBaseProvider", "AsyncJSONBaseProvider"]:
88
+ return (
89
+ cast("AsyncJSONBaseProvider", self.web3.provider)
90
+ if self.web3.provider.is_async
91
+ else cast("JSONBaseProvider", self.web3.provider)
92
+ )
93
+
94
+ def _validate_is_batching(self) -> None:
95
+ if not self._provider._is_batching:
96
+ raise Web3ValueError(
97
+ "Batch has already been executed or cancelled. Create a new batch to "
98
+ "issue batched requests."
99
+ )
100
+
101
+ def _initialize_batching(self) -> None:
102
+ self._provider._is_batching = True
103
+ self.clear()
104
+
105
+ def _end_batching(self) -> None:
106
+ self.clear()
107
+ self._provider._is_batching = False
108
+ if self._provider.has_persistent_connection:
109
+ provider = cast("PersistentConnectionProvider", self._provider)
110
+ provider._batch_request_counter = None
111
+
112
+ def add(self, batch_payload: TReturn) -> None:
113
+ self._validate_is_batching()
114
+
115
+ if isinstance(batch_payload, (ContractFunction, AsyncContractFunction)):
116
+ batch_payload = batch_payload.call() # type: ignore
117
+
118
+ # When batching, we don't make a request. Instead, we will get the request
119
+ # information and store it in the `_requests_info` list. So we have to cast the
120
+ # apparent "request" into the BatchRequestInformation type.
121
+ if self._provider.is_async:
122
+ self._async_requests_info.append(
123
+ cast(Coroutine[Any, Any, BatchRequestInformation], batch_payload)
124
+ )
125
+ else:
126
+ self._requests_info.append(cast(BatchRequestInformation, batch_payload))
127
+
128
+ def add_mapping(
129
+ self,
130
+ batch_payload: Dict[
131
+ Union[
132
+ "Method[Callable[..., Any]]",
133
+ Callable[..., Any],
134
+ ContractFunction,
135
+ AsyncContractFunction,
136
+ ],
137
+ List[Any],
138
+ ],
139
+ ) -> None:
140
+ self._validate_is_batching()
141
+ for method, params in batch_payload.items():
142
+ for param in params:
143
+ self.add(method(param))
144
+
145
+ def execute(self) -> List["RPCResponse"]:
146
+ self._validate_is_batching()
147
+ responses = self.web3.manager._make_batch_request(self._requests_info)
148
+ self._end_batching()
149
+ return responses
150
+
151
+ def clear(self) -> None:
152
+ self._requests_info = []
153
+ self._async_requests_info = []
154
+ if self._provider.has_persistent_connection:
155
+ provider = cast("PersistentConnectionProvider", self._provider)
156
+ provider._batch_request_counter = next(copy(provider.request_counter))
157
+
158
+ def cancel(self) -> None:
159
+ self._end_batching()
160
+
161
+ # -- context manager -- #
162
+
163
+ def __enter__(self) -> Self:
164
+ self._initialize_batching()
165
+ return self
166
+
167
+ def __exit__(
168
+ self,
169
+ exc_type: Type[BaseException],
170
+ exc_val: BaseException,
171
+ exc_tb: TracebackType,
172
+ ) -> None:
173
+ self._end_batching()
174
+
175
+ # -- async -- #
176
+
177
+ async def async_execute(self) -> List["RPCResponse"]:
178
+ self._validate_is_batching()
179
+ responses = await self.web3.manager._async_make_batch_request(
180
+ self._async_requests_info
181
+ )
182
+ self._end_batching()
183
+ return responses
184
+
185
+ # -- async context manager -- #
186
+
187
+ async def __aenter__(self) -> Self:
188
+ self._initialize_batching()
189
+ return self
190
+
191
+ async def __aexit__(
192
+ self,
193
+ exc_type: Type[BaseException],
194
+ exc_val: BaseException,
195
+ exc_tb: TracebackType,
196
+ ) -> None:
197
+ self._end_batching()
198
+
199
+
200
+ def sort_batch_response_by_response_ids(
201
+ responses: List["RPCResponse"],
202
+ ) -> List["RPCResponse"]:
203
+ if all(response.get("id") is not None for response in responses):
204
+ # If all responses have an `id`, sort them by `id, since the JSON-RPC 2.0 spec
205
+ # doesn't guarantee order.
206
+ return sorted(responses, key=lambda response: response["id"])
207
+ else:
208
+ # If any response is missing an `id`, which should only happen on particular
209
+ # errors, return them in the order they were received and hope that the
210
+ # provider is returning them in order. Issue a warning.
211
+ warnings.warn(
212
+ "Received batch response with missing `id` for one or more responses. "
213
+ "Relying on provider to return these responses in order.",
214
+ RuntimeWarning,
215
+ stacklevel=2,
216
+ )
217
+ return responses
web3/_utils/blocks.py CHANGED
@@ -15,6 +15,10 @@ from eth_utils.toolz import (
15
15
  curry,
16
16
  )
17
17
 
18
+ from web3.exceptions import (
19
+ Web3TypeError,
20
+ Web3ValueError,
21
+ )
18
22
  from web3.types import (
19
23
  RPCEndpoint,
20
24
  )
@@ -32,7 +36,7 @@ def is_predefined_block_number(value: Any) -> bool:
32
36
  elif is_integer(value):
33
37
  return False
34
38
  else:
35
- raise TypeError(f"unrecognized block reference: {value!r}")
39
+ raise Web3TypeError(f"unrecognized block reference: {value!r}")
36
40
 
37
41
  return value_text in {"latest", "pending", "earliest", "safe", "finalized"}
38
42
 
@@ -70,6 +74,6 @@ def select_method_for_block_identifier(
70
74
  elif is_hex_encoded_block_number(value):
71
75
  return if_number
72
76
  else:
73
- raise ValueError(
77
+ raise Web3ValueError(
74
78
  f"Value did not match any of the recognized block identifiers: {value}"
75
79
  )
@@ -0,0 +1,12 @@
1
+ from .request_caching_validation import (
2
+ ASYNC_PROVIDER_TYPE,
3
+ SYNC_PROVIDER_TYPE,
4
+ )
5
+ from .caching_utils import (
6
+ CACHEABLE_REQUESTS,
7
+ async_handle_request_caching,
8
+ generate_cache_key,
9
+ handle_request_caching,
10
+ is_cacheable_request,
11
+ RequestInformation,
12
+ )