web3 6.20.2__py3-none-any.whl → 7.0.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 (270) hide show
  1. ens/__init__.py +13 -2
  2. ens/_normalization.py +2 -17
  3. ens/async_ens.py +33 -21
  4. ens/base_ens.py +3 -1
  5. ens/ens.py +16 -11
  6. ens/exceptions.py +16 -29
  7. ens/specs/nf.json +1 -1
  8. ens/specs/normalization_spec.json +1 -1
  9. ens/utils.py +52 -63
  10. web3/__init__.py +20 -24
  11. web3/_utils/abi.py +115 -271
  12. web3/_utils/async_transactions.py +7 -4
  13. web3/_utils/batching.py +217 -0
  14. web3/_utils/blocks.py +6 -2
  15. web3/_utils/caching.py +128 -5
  16. web3/_utils/compat/__init__.py +2 -3
  17. web3/_utils/contract_sources/compile_contracts.py +1 -1
  18. web3/_utils/contract_sources/contract_data/arrays_contract.py +3 -3
  19. web3/_utils/contract_sources/contract_data/bytes_contracts.py +5 -5
  20. web3/_utils/contract_sources/contract_data/constructor_contracts.py +7 -7
  21. web3/_utils/contract_sources/contract_data/contract_caller_tester.py +3 -3
  22. web3/_utils/contract_sources/contract_data/emitter_contract.py +3 -3
  23. web3/_utils/contract_sources/contract_data/event_contracts.py +5 -5
  24. web3/_utils/contract_sources/contract_data/extended_resolver.py +3 -3
  25. web3/_utils/contract_sources/contract_data/fallback_function_contract.py +3 -3
  26. web3/_utils/contract_sources/contract_data/function_name_tester_contract.py +3 -3
  27. web3/_utils/contract_sources/contract_data/math_contract.py +3 -3
  28. web3/_utils/contract_sources/contract_data/offchain_lookup.py +3 -3
  29. web3/_utils/contract_sources/contract_data/offchain_resolver.py +3 -3
  30. web3/_utils/contract_sources/contract_data/panic_errors_contract.py +3 -3
  31. web3/_utils/contract_sources/contract_data/payable_tester.py +3 -3
  32. web3/_utils/contract_sources/contract_data/receive_function_contracts.py +5 -5
  33. web3/_utils/contract_sources/contract_data/reflector_contracts.py +3 -3
  34. web3/_utils/contract_sources/contract_data/revert_contract.py +3 -3
  35. web3/_utils/contract_sources/contract_data/simple_resolver.py +3 -3
  36. web3/_utils/contract_sources/contract_data/storage_contract.py +3 -3
  37. web3/_utils/contract_sources/contract_data/string_contract.py +3 -3
  38. web3/_utils/contract_sources/contract_data/tuple_contracts.py +5 -5
  39. web3/_utils/contracts.py +130 -236
  40. web3/_utils/datatypes.py +5 -1
  41. web3/_utils/decorators.py +13 -23
  42. web3/_utils/empty.py +1 -1
  43. web3/_utils/encoding.py +16 -12
  44. web3/_utils/ens.py +2 -1
  45. web3/_utils/error_formatters_utils.py +5 -3
  46. web3/_utils/events.py +66 -69
  47. web3/_utils/fee_utils.py +1 -3
  48. web3/_utils/filters.py +24 -22
  49. web3/_utils/formatters.py +2 -2
  50. web3/_utils/http.py +5 -3
  51. web3/_utils/http_session_manager.py +303 -0
  52. web3/_utils/math.py +14 -15
  53. web3/_utils/method_formatters.py +34 -36
  54. web3/_utils/module.py +2 -1
  55. web3/_utils/module_testing/__init__.py +0 -3
  56. web3/_utils/module_testing/eth_module.py +695 -643
  57. web3/_utils/module_testing/module_testing_utils.py +61 -34
  58. web3/_utils/module_testing/persistent_connection_provider.py +56 -25
  59. web3/_utils/module_testing/utils.py +258 -0
  60. web3/_utils/module_testing/web3_module.py +438 -17
  61. web3/_utils/normalizers.py +13 -11
  62. web3/_utils/rpc_abi.py +5 -32
  63. web3/_utils/threads.py +8 -7
  64. web3/_utils/transactions.py +14 -12
  65. web3/_utils/type_conversion.py +5 -1
  66. web3/_utils/validation.py +17 -17
  67. web3/auto/gethdev.py +7 -2
  68. web3/beacon/__init__.py +6 -1
  69. web3/beacon/async_beacon.py +9 -5
  70. web3/beacon/{main.py → beacon.py} +7 -5
  71. web3/contract/__init__.py +7 -0
  72. web3/contract/async_contract.py +47 -46
  73. web3/contract/base_contract.py +183 -158
  74. web3/contract/contract.py +49 -43
  75. web3/contract/utils.py +203 -59
  76. web3/datastructures.py +79 -31
  77. web3/eth/__init__.py +7 -0
  78. web3/eth/async_eth.py +39 -51
  79. web3/eth/base_eth.py +17 -10
  80. web3/eth/eth.py +30 -68
  81. web3/exceptions.py +108 -82
  82. web3/gas_strategies/time_based.py +8 -6
  83. web3/geth.py +1 -254
  84. web3/main.py +75 -122
  85. web3/manager.py +316 -146
  86. web3/method.py +38 -31
  87. web3/middleware/__init__.py +67 -89
  88. web3/middleware/attrdict.py +36 -49
  89. web3/middleware/base.py +174 -0
  90. web3/middleware/buffered_gas_estimate.py +20 -21
  91. web3/middleware/filter.py +157 -117
  92. web3/middleware/formatting.py +124 -108
  93. web3/middleware/gas_price_strategy.py +20 -32
  94. web3/middleware/names.py +29 -26
  95. web3/middleware/proof_of_authority.py +68 -0
  96. web3/middleware/pythonic.py +2 -2
  97. web3/middleware/signing.py +74 -89
  98. web3/middleware/stalecheck.py +52 -79
  99. web3/middleware/validation.py +5 -13
  100. web3/module.py +54 -10
  101. web3/providers/__init__.py +10 -6
  102. web3/providers/async_base.py +117 -39
  103. web3/providers/auto.py +3 -3
  104. web3/providers/base.py +89 -33
  105. web3/providers/eth_tester/__init__.py +5 -0
  106. web3/providers/eth_tester/defaults.py +1 -64
  107. web3/providers/eth_tester/main.py +99 -31
  108. web3/providers/eth_tester/middleware.py +45 -73
  109. web3/providers/ipc.py +42 -46
  110. web3/providers/{websocket/websocket.py → legacy_websocket.py} +32 -7
  111. web3/providers/persistent/__init__.py +22 -0
  112. web3/providers/persistent/async_ipc.py +153 -0
  113. web3/providers/{persistent.py → persistent/persistent.py} +106 -25
  114. web3/providers/persistent/persistent_connection.py +84 -0
  115. web3/providers/{websocket → persistent}/request_processor.py +94 -32
  116. web3/providers/persistent/utils.py +43 -0
  117. web3/providers/{websocket/websocket_v2.py → persistent/websocket.py} +29 -28
  118. web3/providers/rpc/__init__.py +11 -0
  119. web3/providers/rpc/async_rpc.py +171 -0
  120. web3/providers/rpc/rpc.py +179 -0
  121. web3/providers/rpc/utils.py +92 -0
  122. web3/testing.py +4 -4
  123. web3/tools/benchmark/main.py +22 -22
  124. web3/tools/benchmark/node.py +2 -8
  125. web3/tools/benchmark/reporting.py +2 -2
  126. web3/tools/benchmark/utils.py +1 -1
  127. web3/tracing.py +9 -5
  128. web3/types.py +30 -107
  129. web3/utils/__init__.py +58 -5
  130. web3/utils/abi.py +575 -10
  131. web3/utils/async_exception_handling.py +19 -7
  132. web3/utils/caching.py +32 -13
  133. web3/utils/exception_handling.py +7 -5
  134. {web3-6.20.2.dist-info → web3-7.0.0.dist-info}/LICENSE +1 -1
  135. web3-7.0.0.dist-info/METADATA +112 -0
  136. web3-7.0.0.dist-info/RECORD +167 -0
  137. {web3-6.20.2.dist-info → web3-7.0.0.dist-info}/WHEEL +1 -1
  138. {web3-6.20.2.dist-info → web3-7.0.0.dist-info}/top_level.txt +0 -1
  139. ethpm/__init__.py +0 -20
  140. ethpm/_utils/__init__.py +0 -0
  141. ethpm/_utils/backend.py +0 -93
  142. ethpm/_utils/cache.py +0 -44
  143. ethpm/_utils/chains.py +0 -119
  144. ethpm/_utils/contract.py +0 -35
  145. ethpm/_utils/deployments.py +0 -145
  146. ethpm/_utils/ipfs.py +0 -116
  147. ethpm/_utils/protobuf/__init__.py +0 -0
  148. ethpm/_utils/protobuf/ipfs_file_pb2.py +0 -33
  149. ethpm/_utils/registry.py +0 -29
  150. ethpm/assets/__init__.py +0 -0
  151. ethpm/assets/ens/v3.json +0 -1
  152. ethpm/assets/escrow/with_bytecode_v3.json +0 -1
  153. ethpm/assets/ipfs_file.proto +0 -32
  154. ethpm/assets/owned/output_v3.json +0 -1
  155. ethpm/assets/owned/with_contract_type_v3.json +0 -1
  156. ethpm/assets/registry/contracts/Authority.sol +0 -156
  157. ethpm/assets/registry/contracts/IndexedOrderedSetLib.sol +0 -106
  158. ethpm/assets/registry/contracts/PackageDB.sol +0 -225
  159. ethpm/assets/registry/contracts/PackageRegistry.sol +0 -361
  160. ethpm/assets/registry/contracts/PackageRegistryInterface.sol +0 -97
  161. ethpm/assets/registry/contracts/ReleaseDB.sol +0 -309
  162. ethpm/assets/registry/contracts/ReleaseValidator.sol +0 -152
  163. ethpm/assets/registry/solc_input.json +0 -1
  164. ethpm/assets/registry/solc_output.json +0 -1
  165. ethpm/assets/registry/v3.json +0 -1
  166. ethpm/assets/safe-math-lib/v3-strict-no-deployments.json +0 -1
  167. ethpm/assets/simple-registry/contracts/Ownable.sol +0 -63
  168. ethpm/assets/simple-registry/contracts/PackageRegistry.sol +0 -373
  169. ethpm/assets/simple-registry/contracts/PackageRegistryInterface.sol +0 -96
  170. ethpm/assets/simple-registry/solc_input.json +0 -33
  171. ethpm/assets/simple-registry/solc_output.json +0 -1
  172. ethpm/assets/simple-registry/v3.json +0 -1
  173. ethpm/assets/standard-token/output_v3.json +0 -1
  174. ethpm/assets/standard-token/with_bytecode_v3.json +0 -1
  175. ethpm/assets/vyper_registry/0.1.0.json +0 -1
  176. ethpm/assets/vyper_registry/registry.vy +0 -216
  177. ethpm/assets/vyper_registry/registry_with_delete.vy +0 -244
  178. ethpm/backends/__init__.py +0 -0
  179. ethpm/backends/base.py +0 -43
  180. ethpm/backends/http.py +0 -108
  181. ethpm/backends/ipfs.py +0 -219
  182. ethpm/backends/registry.py +0 -154
  183. ethpm/constants.py +0 -17
  184. ethpm/contract.py +0 -187
  185. ethpm/dependencies.py +0 -58
  186. ethpm/deployments.py +0 -80
  187. ethpm/ethpm-spec/examples/escrow/1.0.0-pretty.json +0 -146
  188. ethpm/ethpm-spec/examples/escrow/1.0.0.json +0 -1
  189. ethpm/ethpm-spec/examples/escrow/contracts/Escrow.sol +0 -32
  190. ethpm/ethpm-spec/examples/escrow/contracts/SafeSendLib.sol +0 -20
  191. ethpm/ethpm-spec/examples/escrow/v3-pretty.json +0 -171
  192. ethpm/ethpm-spec/examples/escrow/v3.json +0 -1
  193. ethpm/ethpm-spec/examples/owned/1.0.0-pretty.json +0 -21
  194. ethpm/ethpm-spec/examples/owned/1.0.0.json +0 -1
  195. ethpm/ethpm-spec/examples/owned/contracts/Owned.sol +0 -12
  196. ethpm/ethpm-spec/examples/owned/v3-pretty.json +0 -27
  197. ethpm/ethpm-spec/examples/owned/v3.json +0 -1
  198. ethpm/ethpm-spec/examples/piper-coin/1.0.0-pretty.json +0 -31
  199. ethpm/ethpm-spec/examples/piper-coin/1.0.0.json +0 -1
  200. ethpm/ethpm-spec/examples/piper-coin/v3-pretty.json +0 -21
  201. ethpm/ethpm-spec/examples/piper-coin/v3.json +0 -1
  202. ethpm/ethpm-spec/examples/safe-math-lib/1.0.0-pretty.json +0 -85
  203. ethpm/ethpm-spec/examples/safe-math-lib/1.0.0.json +0 -1
  204. ethpm/ethpm-spec/examples/safe-math-lib/contracts/SafeMathLib.sol +0 -24
  205. ethpm/ethpm-spec/examples/safe-math-lib/v3-pretty.json +0 -117
  206. ethpm/ethpm-spec/examples/safe-math-lib/v3.json +0 -1
  207. ethpm/ethpm-spec/examples/standard-token/1.0.0-pretty.json +0 -55
  208. ethpm/ethpm-spec/examples/standard-token/1.0.0.json +0 -1
  209. ethpm/ethpm-spec/examples/standard-token/contracts/AbstractToken.sol +0 -20
  210. ethpm/ethpm-spec/examples/standard-token/contracts/StandardToken.sol +0 -84
  211. ethpm/ethpm-spec/examples/standard-token/v3-pretty.json +0 -460
  212. ethpm/ethpm-spec/examples/standard-token/v3.json +0 -1
  213. ethpm/ethpm-spec/examples/transferable/1.0.0-pretty.json +0 -21
  214. ethpm/ethpm-spec/examples/transferable/1.0.0.json +0 -1
  215. ethpm/ethpm-spec/examples/transferable/contracts/Transferable.sol +0 -14
  216. ethpm/ethpm-spec/examples/transferable/v3-pretty.json +0 -27
  217. ethpm/ethpm-spec/examples/transferable/v3.json +0 -1
  218. ethpm/ethpm-spec/examples/wallet/1.0.0-pretty.json +0 -120
  219. ethpm/ethpm-spec/examples/wallet/1.0.0.json +0 -1
  220. ethpm/ethpm-spec/examples/wallet/contracts/Wallet.sol +0 -41
  221. ethpm/ethpm-spec/examples/wallet/v3-pretty.json +0 -181
  222. ethpm/ethpm-spec/examples/wallet/v3.json +0 -1
  223. ethpm/ethpm-spec/examples/wallet-with-send/1.0.0-pretty.json +0 -135
  224. ethpm/ethpm-spec/examples/wallet-with-send/1.0.0.json +0 -1
  225. ethpm/ethpm-spec/examples/wallet-with-send/contracts/WalletWithSend.sol +0 -18
  226. ethpm/ethpm-spec/examples/wallet-with-send/v3-pretty.json +0 -207
  227. ethpm/ethpm-spec/examples/wallet-with-send/v3.json +0 -1
  228. ethpm/ethpm-spec/spec/package.spec.json +0 -379
  229. ethpm/ethpm-spec/spec/v3.spec.json +0 -483
  230. ethpm/exceptions.py +0 -68
  231. ethpm/package.py +0 -438
  232. ethpm/tools/__init__.py +0 -4
  233. ethpm/tools/builder.py +0 -930
  234. ethpm/tools/checker.py +0 -312
  235. ethpm/tools/get_manifest.py +0 -19
  236. ethpm/uri.py +0 -141
  237. ethpm/validation/__init__.py +0 -0
  238. ethpm/validation/manifest.py +0 -146
  239. ethpm/validation/misc.py +0 -39
  240. ethpm/validation/package.py +0 -80
  241. ethpm/validation/uri.py +0 -163
  242. web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
  243. web3/_utils/miner.py +0 -88
  244. web3/_utils/module_testing/go_ethereum_personal_module.py +0 -323
  245. web3/_utils/request.py +0 -265
  246. web3/middleware/abi.py +0 -11
  247. web3/middleware/async_cache.py +0 -99
  248. web3/middleware/cache.py +0 -374
  249. web3/middleware/exception_handling.py +0 -49
  250. web3/middleware/exception_retry_request.py +0 -188
  251. web3/middleware/fixture.py +0 -190
  252. web3/middleware/geth_poa.py +0 -81
  253. web3/middleware/normalize_request_parameters.py +0 -11
  254. web3/middleware/simulate_unmined_transaction.py +0 -43
  255. web3/pm.py +0 -602
  256. web3/providers/async_rpc.py +0 -99
  257. web3/providers/rpc.py +0 -98
  258. web3/providers/websocket/__init__.py +0 -11
  259. web3/providers/websocket/websocket_connection.py +0 -42
  260. web3/tools/__init__.py +0 -4
  261. web3/tools/pytest_ethereum/__init__.py +0 -0
  262. web3/tools/pytest_ethereum/_utils.py +0 -145
  263. web3/tools/pytest_ethereum/deployer.py +0 -48
  264. web3/tools/pytest_ethereum/exceptions.py +0 -22
  265. web3/tools/pytest_ethereum/linker.py +0 -128
  266. web3/tools/pytest_ethereum/plugins.py +0 -33
  267. web3-6.20.2.dist-info/METADATA +0 -103
  268. web3-6.20.2.dist-info/RECORD +0 -283
  269. web3-6.20.2.dist-info/entry_points.txt +0 -2
  270. /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
@@ -1,12 +1,14 @@
1
1
  import pytest
2
2
  from typing import (
3
+ TYPE_CHECKING,
3
4
  Any,
4
5
  NoReturn,
5
6
  Sequence,
6
- Union,
7
+ cast,
7
8
  )
8
9
 
9
10
  from eth_typing import (
11
+ Address,
10
12
  ChecksumAddress,
11
13
  HexAddress,
12
14
  HexStr,
@@ -23,10 +25,23 @@ from web3 import (
23
25
  from web3._utils.ens import (
24
26
  ens_addresses,
25
27
  )
28
+ from web3.contract import (
29
+ Contract,
30
+ )
26
31
  from web3.exceptions import (
27
32
  InvalidAddress,
33
+ MethodNotSupported,
34
+ Web3ValueError,
35
+ )
36
+ from web3.types import (
37
+ BlockData,
28
38
  )
29
39
 
40
+ if TYPE_CHECKING:
41
+ from web3.contract import ( # noqa: F401
42
+ AsyncContract,
43
+ )
44
+
30
45
 
31
46
  class Web3ModuleTest:
32
47
  def test_web3_client_version(self, w3: Web3) -> None:
@@ -223,16 +238,9 @@ class Web3ModuleTest:
223
238
  ),
224
239
  ),
225
240
  )
226
- @pytest.mark.parametrize(
227
- "w3",
228
- (
229
- Web3,
230
- AsyncWeb3,
231
- ),
232
- )
233
241
  def test_solidity_keccak(
234
242
  self,
235
- w3: Union["Web3", "AsyncWeb3"],
243
+ w3: "Web3",
236
244
  types: Sequence[TypeStr],
237
245
  values: Sequence[Any],
238
246
  expected: HexBytes,
@@ -264,16 +272,9 @@ class Web3ModuleTest:
264
272
  ),
265
273
  ),
266
274
  )
267
- @pytest.mark.parametrize(
268
- "w3",
269
- (
270
- Web3(),
271
- AsyncWeb3(),
272
- ),
273
- )
274
275
  def test_solidity_keccak_ens(
275
276
  self,
276
- w3: Union["Web3", "AsyncWeb3"],
277
+ w3: "Web3",
277
278
  types: Sequence[TypeStr],
278
279
  values: Sequence[str],
279
280
  expected: HexBytes,
@@ -313,3 +314,423 @@ class Web3ModuleTest:
313
314
 
314
315
  def test_is_connected(self, w3: "Web3") -> None:
315
316
  assert w3.is_connected()
317
+
318
+ def test_batch_requests(self, w3: "Web3", math_contract: Contract) -> None:
319
+ with w3.batch_requests() as batch:
320
+ batch.add(w3.eth.get_block(6))
321
+ batch.add(w3.eth.get_block(4))
322
+ batch.add(w3.eth.get_block(2))
323
+ batch.add(w3.eth.get_block(0))
324
+ batch.add(math_contract.functions.multiply7(0))
325
+
326
+ batch.add_mapping(
327
+ {
328
+ math_contract.functions.multiply7: [1, 2, 3],
329
+ w3.eth.get_block: [1, 3, 5],
330
+ }
331
+ )
332
+
333
+ assert len(batch._requests_info) == 11
334
+ responses = batch.execute()
335
+ assert len(responses) == 11
336
+
337
+ # assert proper batch cleanup after execution
338
+ assert batch._requests_info == []
339
+ assert not batch._provider._is_batching
340
+
341
+ # assert batch cannot be added to after execution
342
+ with pytest.raises(
343
+ Web3ValueError,
344
+ match="Batch has already been executed or cancelled",
345
+ ):
346
+ batch.add(w3.eth.get_block(5))
347
+
348
+ # assert batch cannot be executed again
349
+ with pytest.raises(
350
+ Web3ValueError,
351
+ match="Batch has already been executed or cancelled",
352
+ ):
353
+ batch.execute()
354
+
355
+ # assert can make a request after executing
356
+ block_num = w3.eth.block_number
357
+ assert isinstance(block_num, int)
358
+
359
+ first_four_responses: Sequence[BlockData] = cast(
360
+ Sequence[BlockData], responses[:4]
361
+ )
362
+ assert first_four_responses[0]["number"] == 6
363
+ assert first_four_responses[1]["number"] == 4
364
+ assert first_four_responses[2]["number"] == 2
365
+ assert first_four_responses[3]["number"] == 0
366
+
367
+ responses_five_through_eight: Sequence[int] = cast(
368
+ Sequence[int], responses[4:8]
369
+ )
370
+ assert responses_five_through_eight[0] == 0
371
+ assert responses_five_through_eight[1] == 7
372
+ assert responses_five_through_eight[2] == 14
373
+ assert responses_five_through_eight[3] == 21
374
+
375
+ last_three_responses: Sequence[BlockData] = cast(
376
+ Sequence[BlockData], responses[8:]
377
+ )
378
+ assert last_three_responses[0]["number"] == 1
379
+ assert last_three_responses[1]["number"] == 3
380
+ assert last_three_responses[2]["number"] == 5
381
+
382
+ def test_batch_requests_initialized_as_object(
383
+ self, w3: "Web3", math_contract: Contract
384
+ ) -> None:
385
+ batch = w3.batch_requests()
386
+ batch.add(w3.eth.get_block(1))
387
+ batch.add(w3.eth.get_block(2))
388
+ batch.add(math_contract.functions.multiply7(0))
389
+ batch.add_mapping(
390
+ {math_contract.functions.multiply7: [1, 2], w3.eth.get_block: [3, 4]}
391
+ )
392
+
393
+ assert len(batch._requests_info) == 7
394
+ b1, b2, m0, m1, m2, b3, b4 = batch.execute()
395
+
396
+ # assert proper batch cleanup after execution
397
+ assert batch._requests_info == []
398
+ assert not batch._provider._is_batching
399
+
400
+ # assert batch cannot be added to after execution
401
+ with pytest.raises(
402
+ Web3ValueError,
403
+ match="Batch has already been executed or cancelled",
404
+ ):
405
+ batch.add(w3.eth.get_block(5))
406
+
407
+ # assert batch cannot be executed again
408
+ with pytest.raises(
409
+ Web3ValueError,
410
+ match="Batch has already been executed or cancelled",
411
+ ):
412
+ batch.execute()
413
+
414
+ # assert can make a request after executing
415
+ block_num = w3.eth.block_number
416
+ assert isinstance(block_num, int)
417
+
418
+ assert cast(BlockData, b1)["number"] == 1
419
+ assert cast(BlockData, b2)["number"] == 2
420
+ assert cast(int, m0) == 0
421
+ assert cast(int, m1) == 7
422
+ assert cast(int, m2) == 14
423
+ assert cast(BlockData, b3)["number"] == 3
424
+ assert cast(BlockData, b4)["number"] == 4
425
+
426
+ def test_batch_requests_clear(self, w3: "Web3") -> None:
427
+ with w3.batch_requests() as batch:
428
+ batch.add(w3.eth.get_block(1))
429
+ batch.add(w3.eth.get_block(2))
430
+
431
+ assert len(batch._requests_info) == 2
432
+ batch.clear()
433
+ assert batch._requests_info == []
434
+
435
+ batch.add(w3.eth.get_block(3))
436
+ batch.add(w3.eth.get_block(4))
437
+
438
+ r1, r2 = batch.execute()
439
+
440
+ assert cast(BlockData, r1)["number"] == 3
441
+ assert cast(BlockData, r2)["number"] == 4
442
+
443
+ new_batch = w3.batch_requests()
444
+ new_batch.add(w3.eth.get_block(5))
445
+
446
+ assert len(new_batch._requests_info) == 1
447
+ new_batch.clear()
448
+ assert new_batch._requests_info == []
449
+
450
+ new_batch.add(w3.eth.get_block(6))
451
+ (r3,) = new_batch.execute()
452
+ assert cast(BlockData, r3)["number"] == 6
453
+
454
+ def test_batch_requests_cancel(self, w3: "Web3") -> None:
455
+ # as context manager
456
+ with w3.batch_requests() as batch:
457
+ batch.add(w3.eth.get_block(1))
458
+ batch.cancel()
459
+ with pytest.raises(
460
+ Web3ValueError,
461
+ match="Batch has already been executed or cancelled",
462
+ ):
463
+ batch.add(w3.eth.get_block(2))
464
+ with pytest.raises(
465
+ Web3ValueError,
466
+ match="Batch has already been executed or cancelled",
467
+ ):
468
+ batch.execute()
469
+
470
+ # can make a request after cancelling
471
+ block_num = w3.eth.block_number
472
+ assert isinstance(block_num, int)
473
+
474
+ # as obj
475
+ new_batch = w3.batch_requests()
476
+ new_batch.add(w3.eth.get_block(1))
477
+ new_batch.cancel()
478
+ with pytest.raises(
479
+ Web3ValueError,
480
+ match="Batch has already been executed or cancelled",
481
+ ):
482
+ new_batch.add(w3.eth.get_block(2))
483
+ with pytest.raises(
484
+ Web3ValueError,
485
+ match="Batch has already been executed or cancelled",
486
+ ):
487
+ new_batch.execute()
488
+
489
+ # assert can make a request after cancelling
490
+ block_num = w3.eth.block_number
491
+ assert isinstance(block_num, int)
492
+
493
+ def test_batch_requests_raises_for_common_unsupported_methods(
494
+ self, w3: "Web3", math_contract: Contract
495
+ ) -> None:
496
+ with w3.batch_requests() as batch:
497
+ with pytest.raises(MethodNotSupported, match="eth_sendTransaction"):
498
+ batch.add(w3.eth.send_transaction({}))
499
+ batch.execute()
500
+
501
+ with w3.batch_requests() as batch:
502
+ with pytest.raises(MethodNotSupported, match="eth_sendTransaction"):
503
+ batch.add(math_contract.functions.multiply7(1).transact({}))
504
+ batch.execute()
505
+
506
+ with w3.batch_requests() as batch:
507
+ with pytest.raises(MethodNotSupported, match="eth_sendRawTransaction"):
508
+ batch.add(w3.eth.send_raw_transaction(b""))
509
+ batch.execute()
510
+
511
+ with w3.batch_requests() as batch:
512
+ with pytest.raises(MethodNotSupported, match="eth_sign"):
513
+ batch.add(w3.eth.sign(Address(b"\x00" * 20)))
514
+ batch.execute()
515
+
516
+
517
+ # -- async -- #
518
+
519
+
520
+ class AsyncWeb3ModuleTest(Web3ModuleTest):
521
+ # Note: Any test that overrides the synchronous test from `Web3ModuleTest` with
522
+ # an asynchronous test should have the exact same name.
523
+
524
+ @pytest.mark.asyncio
525
+ async def test_web3_client_version(self, async_w3: AsyncWeb3) -> None: # type: ignore[override] # noqa: E501
526
+ client_version = await async_w3.client_version
527
+ self._check_web3_client_version(client_version)
528
+
529
+ @pytest.mark.asyncio
530
+ async def test_batch_requests( # type: ignore[override]
531
+ self, async_w3: AsyncWeb3, async_math_contract: "AsyncContract"
532
+ ) -> None:
533
+ async with async_w3.batch_requests() as batch:
534
+ batch.add(async_w3.eth.get_block(6))
535
+ batch.add(async_w3.eth.get_block(4))
536
+ batch.add(async_w3.eth.get_block(2))
537
+ batch.add(async_w3.eth.get_block(0))
538
+
539
+ batch.add(async_math_contract.functions.multiply7(0))
540
+
541
+ batch.add_mapping(
542
+ {
543
+ async_math_contract.functions.multiply7: [1, 2, 3],
544
+ async_w3.eth.get_block: [1, 3, 5],
545
+ }
546
+ )
547
+
548
+ assert len(batch._async_requests_info) == 11
549
+ responses = await batch.async_execute()
550
+ assert len(responses) == 11
551
+
552
+ # assert proper batch cleanup after execution
553
+ assert batch._async_requests_info == []
554
+ assert not batch._provider._is_batching
555
+
556
+ # assert batch cannot be added to after execution
557
+ with pytest.raises(
558
+ Web3ValueError,
559
+ match="Batch has already been executed or cancelled",
560
+ ):
561
+ batch.add(async_w3.eth.get_block(5))
562
+
563
+ # assert batch cannot be executed again
564
+ with pytest.raises(
565
+ Web3ValueError,
566
+ match="Batch has already been executed or cancelled",
567
+ ):
568
+ await batch.async_execute()
569
+
570
+ # assert can make a request after executing
571
+ block_num = await async_w3.eth.block_number
572
+ assert isinstance(block_num, int)
573
+
574
+ first_four_responses: Sequence[BlockData] = cast(
575
+ Sequence[BlockData], responses[:4]
576
+ )
577
+ assert first_four_responses[0]["number"] == 6
578
+ assert first_four_responses[1]["number"] == 4
579
+ assert first_four_responses[2]["number"] == 2
580
+ assert first_four_responses[3]["number"] == 0
581
+
582
+ responses_five_through_eight: Sequence[int] = cast(
583
+ Sequence[int], responses[4:8]
584
+ )
585
+ assert responses_five_through_eight[0] == 0
586
+ assert responses_five_through_eight[1] == 7
587
+ assert responses_five_through_eight[2] == 14
588
+ assert responses_five_through_eight[3] == 21
589
+
590
+ last_three_responses: Sequence[BlockData] = cast(
591
+ Sequence[BlockData], responses[8:]
592
+ )
593
+ assert last_three_responses[0]["number"] == 1
594
+ assert last_three_responses[1]["number"] == 3
595
+ assert last_three_responses[2]["number"] == 5
596
+
597
+ @pytest.mark.asyncio
598
+ async def test_batch_requests_initialized_as_object( # type: ignore[override]
599
+ self, async_w3: AsyncWeb3, async_math_contract: "AsyncContract" # type: ignore[override] # noqa: E501
600
+ ) -> None:
601
+ batch = async_w3.batch_requests()
602
+ batch.add(async_w3.eth.get_block(1))
603
+ batch.add(async_w3.eth.get_block(2))
604
+ batch.add(async_math_contract.functions.multiply7(0))
605
+ batch.add_mapping(
606
+ {
607
+ async_math_contract.functions.multiply7: [1, 2],
608
+ async_w3.eth.get_block: [3, 4],
609
+ }
610
+ )
611
+
612
+ assert len(batch._async_requests_info) == 7
613
+ b1, b2, m0, m1, m2, b3, b4 = await batch.async_execute()
614
+
615
+ # assert proper batch cleanup after execution
616
+ assert batch._async_requests_info == []
617
+ assert not batch._provider._is_batching
618
+
619
+ # assert batch cannot be added to after execution
620
+ with pytest.raises(
621
+ Web3ValueError,
622
+ match="Batch has already been executed or cancelled",
623
+ ):
624
+ batch.add(async_w3.eth.get_block(5))
625
+
626
+ # assert batch cannot be executed again
627
+ with pytest.raises(
628
+ Web3ValueError,
629
+ match="Batch has already been executed or cancelled",
630
+ ):
631
+ await batch.async_execute()
632
+
633
+ # assert can make a request after executing
634
+ block_num = await async_w3.eth.block_number
635
+ assert isinstance(block_num, int)
636
+
637
+ assert cast(BlockData, b1)["number"] == 1
638
+ assert cast(BlockData, b2)["number"] == 2
639
+ assert cast(int, m0) == 0
640
+ assert cast(int, m1) == 7
641
+ assert cast(int, m2) == 14
642
+ assert cast(BlockData, b3)["number"] == 3
643
+ assert cast(BlockData, b4)["number"] == 4
644
+
645
+ @pytest.mark.asyncio
646
+ async def test_batch_requests_clear(self, async_w3: AsyncWeb3) -> None: # type: ignore[override] # noqa: E501
647
+ async with async_w3.batch_requests() as batch:
648
+ batch.add(async_w3.eth.get_block(1))
649
+ batch.add(async_w3.eth.get_block(2))
650
+
651
+ assert len(batch._async_requests_info) == 2
652
+ batch.clear()
653
+ assert batch._async_requests_info == []
654
+
655
+ batch.add(async_w3.eth.get_block(3))
656
+ batch.add(async_w3.eth.get_block(4))
657
+
658
+ r1, r2 = await batch.async_execute()
659
+
660
+ assert cast(BlockData, r1)["number"] == 3
661
+ assert cast(BlockData, r2)["number"] == 4
662
+
663
+ new_batch = async_w3.batch_requests()
664
+ new_batch.add(async_w3.eth.get_block(5))
665
+
666
+ assert len(new_batch._async_requests_info) == 1
667
+ new_batch.clear()
668
+ assert new_batch._async_requests_info == []
669
+
670
+ new_batch.add(async_w3.eth.get_block(6))
671
+ (r3,) = await new_batch.async_execute()
672
+ assert cast(BlockData, r3)["number"] == 6
673
+
674
+ @pytest.mark.asyncio
675
+ async def test_batch_requests_cancel(self, async_w3: AsyncWeb3) -> None: # type: ignore[override] # noqa: E501
676
+ # as context manager
677
+ async with async_w3.batch_requests() as batch:
678
+ batch.add(async_w3.eth.get_block(1))
679
+ batch.cancel()
680
+ with pytest.raises(
681
+ Web3ValueError,
682
+ match="Batch has already been executed or cancelled",
683
+ ):
684
+ batch.add(async_w3.eth.get_block(2))
685
+ with pytest.raises(
686
+ Web3ValueError,
687
+ match="Batch has already been executed or cancelled",
688
+ ):
689
+ await batch.async_execute()
690
+
691
+ # can make a request after cancelling
692
+ block_num = await async_w3.eth.block_number
693
+ assert isinstance(block_num, int)
694
+
695
+ # as obj
696
+ new_batch = async_w3.batch_requests()
697
+ new_batch.add(async_w3.eth.get_block(1))
698
+ new_batch.cancel()
699
+ with pytest.raises(
700
+ Web3ValueError,
701
+ match="Batch has already been executed or cancelled",
702
+ ):
703
+ new_batch.add(async_w3.eth.get_block(2))
704
+ with pytest.raises(
705
+ Web3ValueError,
706
+ match="Batch has already been executed or cancelled",
707
+ ):
708
+ await new_batch.async_execute()
709
+
710
+ # can make a request after cancelling
711
+ block_num = await async_w3.eth.block_number
712
+ assert isinstance(block_num, int)
713
+
714
+ @pytest.mark.asyncio
715
+ async def test_batch_requests_raises_for_common_unsupported_methods( # type: ignore[override] # noqa: E501
716
+ self, async_w3: AsyncWeb3, async_math_contract: "AsyncContract" # type: ignore[override] # noqa: E501
717
+ ) -> None:
718
+ async with async_w3.batch_requests() as batch:
719
+ with pytest.raises(MethodNotSupported, match="eth_sendTransaction"):
720
+ batch.add(async_w3.eth.send_transaction({}))
721
+ await batch.async_execute()
722
+
723
+ async with async_w3.batch_requests() as batch:
724
+ with pytest.raises(MethodNotSupported, match="eth_sendTransaction"):
725
+ batch.add(async_math_contract.functions.multiply7(1).transact({}))
726
+ await batch.async_execute()
727
+
728
+ async with async_w3.batch_requests() as batch:
729
+ with pytest.raises(MethodNotSupported, match="eth_sendRawTransaction"):
730
+ batch.add(async_w3.eth.send_raw_transaction(b""))
731
+ await batch.async_execute()
732
+
733
+ async with async_w3.batch_requests() as batch:
734
+ with pytest.raises(MethodNotSupported, match="eth_sign"):
735
+ batch.add(async_w3.eth.sign(Address(b"\x00" * 20)))
736
+ await batch.async_execute()
@@ -19,6 +19,7 @@ from eth_abi.grammar import (
19
19
  parse,
20
20
  )
21
21
  from eth_typing import (
22
+ ABI,
22
23
  ChecksumAddress,
23
24
  HexStr,
24
25
  TypeStr,
@@ -60,9 +61,7 @@ from web3._utils.validation import (
60
61
  from web3.exceptions import (
61
62
  InvalidAddress,
62
63
  NameNotFound,
63
- )
64
- from web3.types import (
65
- ABI,
64
+ Web3ValueError,
66
65
  )
67
66
 
68
67
  if TYPE_CHECKING:
@@ -151,7 +150,7 @@ def abi_bytes_to_hex(
151
150
 
152
151
  num_bytes = abi_type.sub
153
152
  if len(bytes_data) > num_bytes:
154
- raise ValueError(
153
+ raise Web3ValueError(
155
154
  f"This value was expected to be at most {num_bytes} bytes, "
156
155
  f"but instead was {len(bytes_data)}: {data!r}"
157
156
  )
@@ -255,7 +254,9 @@ def normalize_abi(abi: Union[ABI, str]) -> ABI:
255
254
  return cast(ABI, abi)
256
255
 
257
256
 
258
- def normalize_address(ens: ENS, address: ChecksumAddress) -> ChecksumAddress:
257
+ def normalize_address(
258
+ ens: ENS, address: Optional[ChecksumAddress]
259
+ ) -> Union[ChecksumAddress, None]:
259
260
  if address:
260
261
  if is_ens_name(address):
261
262
  validate_name_has_address(ens, address)
@@ -264,17 +265,18 @@ def normalize_address(ens: ENS, address: ChecksumAddress) -> ChecksumAddress:
264
265
  return address
265
266
 
266
267
 
267
- def normalize_address_no_ens(address: ChecksumAddress) -> ChecksumAddress:
268
+ def normalize_address_no_ens(
269
+ address: Optional[ChecksumAddress],
270
+ ) -> Union[ChecksumAddress, None]:
268
271
  if address:
269
272
  validate_address(address)
270
273
  return address
271
274
 
272
275
 
273
- def normalize_bytecode(bytecode: bytes) -> HexBytes:
274
- if bytecode:
275
- bytecode = HexBytes(bytecode)
276
- # type ignored b/c bytecode is converted to HexBytes above
277
- return bytecode # type: ignore
276
+ def normalize_bytecode(bytecode: Optional[bytes]) -> Union[HexBytes, None]:
277
+ if bytecode is not None:
278
+ return HexBytes(bytecode)
279
+ return bytecode
278
280
 
279
281
 
280
282
  # --- async -- #
web3/_utils/rpc_abi.py CHANGED
@@ -24,6 +24,9 @@ from eth_utils.toolz import (
24
24
  from web3._utils.abi import (
25
25
  map_abi_data,
26
26
  )
27
+ from web3.exceptions import (
28
+ Web3TypeError,
29
+ )
27
30
  from web3.types import (
28
31
  RPCEndpoint,
29
32
  )
@@ -49,7 +52,6 @@ class RPC:
49
52
  eth_call = RPCEndpoint("eth_call")
50
53
  eth_createAccessList = RPCEndpoint("eth_createAccessList")
51
54
  eth_chainId = RPCEndpoint("eth_chainId")
52
- eth_coinbase = RPCEndpoint("eth_coinbase")
53
55
  eth_estimateGas = RPCEndpoint("eth_estimateGas")
54
56
  eth_feeHistory = RPCEndpoint("eth_feeHistory")
55
57
  eth_maxPriorityFeePerGas = RPCEndpoint("eth_maxPriorityFeePerGas")
@@ -57,6 +59,7 @@ class RPC:
57
59
  eth_getBalance = RPCEndpoint("eth_getBalance")
58
60
  eth_getBlockByHash = RPCEndpoint("eth_getBlockByHash")
59
61
  eth_getBlockByNumber = RPCEndpoint("eth_getBlockByNumber")
62
+ eth_getBlockReceipts = RPCEndpoint("eth_getBlockReceipts")
60
63
  eth_getBlockTransactionCountByHash = RPCEndpoint(
61
64
  "eth_getBlockTransactionCountByHash"
62
65
  )
@@ -90,8 +93,6 @@ class RPC:
90
93
  eth_getUncleCountByBlockHash = RPCEndpoint("eth_getUncleCountByBlockHash")
91
94
  eth_getUncleCountByBlockNumber = RPCEndpoint("eth_getUncleCountByBlockNumber")
92
95
  eth_getWork = RPCEndpoint("eth_getWork")
93
- eth_hashrate = RPCEndpoint("eth_hashrate")
94
- eth_mining = RPCEndpoint("eth_mining")
95
96
  eth_newBlockFilter = RPCEndpoint("eth_newBlockFilter")
96
97
  eth_newFilter = RPCEndpoint("eth_newFilter")
97
98
  eth_newPendingTransactionFilter = RPCEndpoint("eth_newPendingTransactionFilter")
@@ -114,33 +115,11 @@ class RPC:
114
115
  evm_revert = RPCEndpoint("evm_revert")
115
116
  evm_snapshot = RPCEndpoint("evm_snapshot")
116
117
 
117
- # miner
118
- miner_makeDag = RPCEndpoint("miner_makeDag")
119
- miner_setExtra = RPCEndpoint("miner_setExtra")
120
- miner_setEtherbase = RPCEndpoint("miner_setEtherbase")
121
- miner_setGasPrice = RPCEndpoint("miner_setGasPrice")
122
- miner_start = RPCEndpoint("miner_start")
123
- miner_stop = RPCEndpoint("miner_stop")
124
- miner_startAutoDag = RPCEndpoint("miner_startAutoDag")
125
- miner_stopAutoDag = RPCEndpoint("miner_stopAutoDag")
126
-
127
118
  # net
128
119
  net_listening = RPCEndpoint("net_listening")
129
120
  net_peerCount = RPCEndpoint("net_peerCount")
130
121
  net_version = RPCEndpoint("net_version")
131
122
 
132
- # personal
133
- personal_ecRecover = RPCEndpoint("personal_ecRecover")
134
- personal_importRawKey = RPCEndpoint("personal_importRawKey")
135
- personal_listAccounts = RPCEndpoint("personal_listAccounts")
136
- personal_listWallets = RPCEndpoint("personal_listWallets")
137
- personal_lockAccount = RPCEndpoint("personal_lockAccount")
138
- personal_newAccount = RPCEndpoint("personal_newAccount")
139
- personal_sendTransaction = RPCEndpoint("personal_sendTransaction")
140
- personal_sign = RPCEndpoint("personal_sign")
141
- personal_signTypedData = RPCEndpoint("personal_signTypedData")
142
- personal_unlockAccount = RPCEndpoint("personal_unlockAccount")
143
-
144
123
  # testing
145
124
  testing_timeTravel = RPCEndpoint("testing_timeTravel")
146
125
 
@@ -217,12 +196,6 @@ RPC_ABIS: Dict[str, Union[Sequence[Any], Dict[str, str]]] = {
217
196
  "eth_signTypedData": ["address", None],
218
197
  "eth_submitHashrate": ["uint", "bytes32"],
219
198
  "eth_submitWork": ["bytes8", "bytes32", "bytes32"],
220
- # personal
221
- "personal_sendTransaction": TRANSACTION_PARAMS_ABIS,
222
- "personal_lockAccount": ["address"],
223
- "personal_unlockAccount": ["address", None, None],
224
- "personal_sign": [None, "address", None],
225
- "personal_signTypedData": [None, "address", None],
226
199
  "trace_call": TRANSACTION_PARAMS_ABIS,
227
200
  "trace_filter": TRACE_FILTER_PARAM_ABIS,
228
201
  }
@@ -256,6 +229,6 @@ def abi_request_formatters(
256
229
  single_dict_formatter = apply_abi_formatters_to_dict(normalizers, abi_types)
257
230
  yield method, apply_formatter_at_index(single_dict_formatter, 0)
258
231
  else:
259
- raise TypeError(
232
+ raise Web3TypeError(
260
233
  f"ABI definitions must be a list or dictionary, got {abi_types!r}"
261
234
  )
web3/_utils/threads.py CHANGED
@@ -12,11 +12,12 @@ from typing import (
12
12
  Any,
13
13
  Callable,
14
14
  Generic,
15
+ Literal,
15
16
  Type,
16
17
  )
17
18
 
18
- from web3._utils.compat import (
19
- Literal,
19
+ from web3.exceptions import (
20
+ Web3ValueError,
20
21
  )
21
22
  from web3.types import (
22
23
  TReturn,
@@ -63,24 +64,24 @@ class Timeout(Exception):
63
64
  @property
64
65
  def expire_at(self) -> int:
65
66
  if self.seconds is None:
66
- raise ValueError(
67
+ raise Web3ValueError(
67
68
  "Timeouts with `seconds == None` do not have an expiration time"
68
69
  )
69
70
  elif self.begun_at is None:
70
- raise ValueError("Timeout has not been started")
71
+ raise Web3ValueError("Timeout has not been started")
71
72
  return self.begun_at + self.seconds
72
73
 
73
74
  def start(self) -> None:
74
75
  if self.is_running is not None:
75
- raise ValueError("Timeout has already been started")
76
+ raise Web3ValueError("Timeout has already been started")
76
77
  self.begun_at = time.time()
77
78
  self.is_running = True
78
79
 
79
80
  def check(self) -> None:
80
81
  if self.is_running is None:
81
- raise ValueError("Timeout has not been started")
82
+ raise Web3ValueError("Timeout has not been started")
82
83
  elif self.is_running is False:
83
- raise ValueError("Timeout has already been cancelled")
84
+ raise Web3ValueError("Timeout has already been cancelled")
84
85
  elif self.seconds is None:
85
86
  return
86
87
  elif time.time() > self.expire_at: