web3 6.20.3__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.3.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.3.dist-info → web3-7.0.0.dist-info}/top_level.txt +0 -1
  138. ethpm/__init__.py +0 -20
  139. ethpm/_utils/__init__.py +0 -0
  140. ethpm/_utils/backend.py +0 -93
  141. ethpm/_utils/cache.py +0 -44
  142. ethpm/_utils/chains.py +0 -119
  143. ethpm/_utils/contract.py +0 -35
  144. ethpm/_utils/deployments.py +0 -145
  145. ethpm/_utils/ipfs.py +0 -116
  146. ethpm/_utils/protobuf/__init__.py +0 -0
  147. ethpm/_utils/protobuf/ipfs_file_pb2.py +0 -33
  148. ethpm/_utils/registry.py +0 -29
  149. ethpm/assets/__init__.py +0 -0
  150. ethpm/assets/ens/v3.json +0 -1
  151. ethpm/assets/escrow/with_bytecode_v3.json +0 -1
  152. ethpm/assets/ipfs_file.proto +0 -32
  153. ethpm/assets/owned/output_v3.json +0 -1
  154. ethpm/assets/owned/with_contract_type_v3.json +0 -1
  155. ethpm/assets/registry/contracts/Authority.sol +0 -156
  156. ethpm/assets/registry/contracts/IndexedOrderedSetLib.sol +0 -106
  157. ethpm/assets/registry/contracts/PackageDB.sol +0 -225
  158. ethpm/assets/registry/contracts/PackageRegistry.sol +0 -361
  159. ethpm/assets/registry/contracts/PackageRegistryInterface.sol +0 -97
  160. ethpm/assets/registry/contracts/ReleaseDB.sol +0 -309
  161. ethpm/assets/registry/contracts/ReleaseValidator.sol +0 -152
  162. ethpm/assets/registry/solc_input.json +0 -1
  163. ethpm/assets/registry/solc_output.json +0 -1
  164. ethpm/assets/registry/v3.json +0 -1
  165. ethpm/assets/safe-math-lib/v3-strict-no-deployments.json +0 -1
  166. ethpm/assets/simple-registry/contracts/Ownable.sol +0 -63
  167. ethpm/assets/simple-registry/contracts/PackageRegistry.sol +0 -373
  168. ethpm/assets/simple-registry/contracts/PackageRegistryInterface.sol +0 -96
  169. ethpm/assets/simple-registry/solc_input.json +0 -33
  170. ethpm/assets/simple-registry/solc_output.json +0 -1
  171. ethpm/assets/simple-registry/v3.json +0 -1
  172. ethpm/assets/standard-token/output_v3.json +0 -1
  173. ethpm/assets/standard-token/with_bytecode_v3.json +0 -1
  174. ethpm/assets/vyper_registry/0.1.0.json +0 -1
  175. ethpm/assets/vyper_registry/registry.vy +0 -216
  176. ethpm/assets/vyper_registry/registry_with_delete.vy +0 -244
  177. ethpm/backends/__init__.py +0 -0
  178. ethpm/backends/base.py +0 -43
  179. ethpm/backends/http.py +0 -108
  180. ethpm/backends/ipfs.py +0 -219
  181. ethpm/backends/registry.py +0 -154
  182. ethpm/constants.py +0 -17
  183. ethpm/contract.py +0 -187
  184. ethpm/dependencies.py +0 -58
  185. ethpm/deployments.py +0 -80
  186. ethpm/ethpm-spec/examples/escrow/1.0.0-pretty.json +0 -146
  187. ethpm/ethpm-spec/examples/escrow/1.0.0.json +0 -1
  188. ethpm/ethpm-spec/examples/escrow/contracts/Escrow.sol +0 -32
  189. ethpm/ethpm-spec/examples/escrow/contracts/SafeSendLib.sol +0 -20
  190. ethpm/ethpm-spec/examples/escrow/v3-pretty.json +0 -171
  191. ethpm/ethpm-spec/examples/escrow/v3.json +0 -1
  192. ethpm/ethpm-spec/examples/owned/1.0.0-pretty.json +0 -21
  193. ethpm/ethpm-spec/examples/owned/1.0.0.json +0 -1
  194. ethpm/ethpm-spec/examples/owned/contracts/Owned.sol +0 -12
  195. ethpm/ethpm-spec/examples/owned/v3-pretty.json +0 -27
  196. ethpm/ethpm-spec/examples/owned/v3.json +0 -1
  197. ethpm/ethpm-spec/examples/piper-coin/1.0.0-pretty.json +0 -31
  198. ethpm/ethpm-spec/examples/piper-coin/1.0.0.json +0 -1
  199. ethpm/ethpm-spec/examples/piper-coin/v3-pretty.json +0 -21
  200. ethpm/ethpm-spec/examples/piper-coin/v3.json +0 -1
  201. ethpm/ethpm-spec/examples/safe-math-lib/1.0.0-pretty.json +0 -85
  202. ethpm/ethpm-spec/examples/safe-math-lib/1.0.0.json +0 -1
  203. ethpm/ethpm-spec/examples/safe-math-lib/contracts/SafeMathLib.sol +0 -24
  204. ethpm/ethpm-spec/examples/safe-math-lib/v3-pretty.json +0 -117
  205. ethpm/ethpm-spec/examples/safe-math-lib/v3.json +0 -1
  206. ethpm/ethpm-spec/examples/standard-token/1.0.0-pretty.json +0 -55
  207. ethpm/ethpm-spec/examples/standard-token/1.0.0.json +0 -1
  208. ethpm/ethpm-spec/examples/standard-token/contracts/AbstractToken.sol +0 -20
  209. ethpm/ethpm-spec/examples/standard-token/contracts/StandardToken.sol +0 -84
  210. ethpm/ethpm-spec/examples/standard-token/v3-pretty.json +0 -460
  211. ethpm/ethpm-spec/examples/standard-token/v3.json +0 -1
  212. ethpm/ethpm-spec/examples/transferable/1.0.0-pretty.json +0 -21
  213. ethpm/ethpm-spec/examples/transferable/1.0.0.json +0 -1
  214. ethpm/ethpm-spec/examples/transferable/contracts/Transferable.sol +0 -14
  215. ethpm/ethpm-spec/examples/transferable/v3-pretty.json +0 -27
  216. ethpm/ethpm-spec/examples/transferable/v3.json +0 -1
  217. ethpm/ethpm-spec/examples/wallet/1.0.0-pretty.json +0 -120
  218. ethpm/ethpm-spec/examples/wallet/1.0.0.json +0 -1
  219. ethpm/ethpm-spec/examples/wallet/contracts/Wallet.sol +0 -41
  220. ethpm/ethpm-spec/examples/wallet/v3-pretty.json +0 -181
  221. ethpm/ethpm-spec/examples/wallet/v3.json +0 -1
  222. ethpm/ethpm-spec/examples/wallet-with-send/1.0.0-pretty.json +0 -135
  223. ethpm/ethpm-spec/examples/wallet-with-send/1.0.0.json +0 -1
  224. ethpm/ethpm-spec/examples/wallet-with-send/contracts/WalletWithSend.sol +0 -18
  225. ethpm/ethpm-spec/examples/wallet-with-send/v3-pretty.json +0 -207
  226. ethpm/ethpm-spec/examples/wallet-with-send/v3.json +0 -1
  227. ethpm/ethpm-spec/spec/package.spec.json +0 -379
  228. ethpm/ethpm-spec/spec/v3.spec.json +0 -483
  229. ethpm/exceptions.py +0 -68
  230. ethpm/package.py +0 -438
  231. ethpm/tools/__init__.py +0 -4
  232. ethpm/tools/builder.py +0 -930
  233. ethpm/tools/checker.py +0 -312
  234. ethpm/tools/get_manifest.py +0 -19
  235. ethpm/uri.py +0 -141
  236. ethpm/validation/__init__.py +0 -0
  237. ethpm/validation/manifest.py +0 -146
  238. ethpm/validation/misc.py +0 -39
  239. ethpm/validation/package.py +0 -80
  240. ethpm/validation/uri.py +0 -163
  241. web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
  242. web3/_utils/miner.py +0 -88
  243. web3/_utils/module_testing/go_ethereum_personal_module.py +0 -323
  244. web3/_utils/request.py +0 -265
  245. web3/middleware/abi.py +0 -11
  246. web3/middleware/async_cache.py +0 -99
  247. web3/middleware/cache.py +0 -374
  248. web3/middleware/exception_handling.py +0 -49
  249. web3/middleware/exception_retry_request.py +0 -188
  250. web3/middleware/fixture.py +0 -190
  251. web3/middleware/geth_poa.py +0 -81
  252. web3/middleware/normalize_request_parameters.py +0 -11
  253. web3/middleware/simulate_unmined_transaction.py +0 -43
  254. web3/pm.py +0 -602
  255. web3/providers/async_rpc.py +0 -99
  256. web3/providers/rpc.py +0 -98
  257. web3/providers/websocket/__init__.py +0 -11
  258. web3/providers/websocket/websocket_connection.py +0 -42
  259. web3/tools/__init__.py +0 -4
  260. web3/tools/pytest_ethereum/__init__.py +0 -0
  261. web3/tools/pytest_ethereum/_utils.py +0 -145
  262. web3/tools/pytest_ethereum/deployer.py +0 -48
  263. web3/tools/pytest_ethereum/exceptions.py +0 -22
  264. web3/tools/pytest_ethereum/linker.py +0 -128
  265. web3/tools/pytest_ethereum/plugins.py +0 -33
  266. web3-6.20.3.dist-info/METADATA +0 -104
  267. web3-6.20.3.dist-info/RECORD +0 -283
  268. web3-6.20.3.dist-info/entry_points.txt +0 -2
  269. /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
  270. {web3-6.20.3.dist-info → web3-7.0.0.dist-info}/WHEEL +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: