web3 7.0.0b1__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 (261) hide show
  1. ens/__init__.py +13 -2
  2. ens/_normalization.py +4 -4
  3. ens/async_ens.py +31 -21
  4. ens/base_ens.py +3 -1
  5. ens/contract_data.py +2 -2
  6. ens/ens.py +14 -11
  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 +33 -41
  11. web3/__init__.py +23 -12
  12. web3/_utils/abi.py +162 -274
  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 +56 -41
  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 -43
  89. web3/manager.py +368 -101
  90. web3/method.py +43 -15
  91. web3/middleware/__init__.py +26 -8
  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 +62 -26
  100. web3/providers/__init__.py +21 -0
  101. web3/providers/async_base.py +93 -38
  102. web3/providers/base.py +85 -40
  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 +57 -35
  106. web3/providers/eth_tester/middleware.py +16 -17
  107. web3/providers/ipc.py +42 -18
  108. web3/providers/legacy_websocket.py +27 -2
  109. web3/providers/persistent/__init__.py +7 -0
  110. web3/providers/persistent/async_ipc.py +61 -121
  111. web3/providers/persistent/persistent.py +324 -17
  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.0b1.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.0b1.dist-info → web3-7.7.0.dist-info}/WHEEL +1 -1
  137. {web3-7.0.0b1.dist-info → web3-7.7.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/caching.py +0 -155
  242. web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
  243. web3/_utils/module_testing/go_ethereum_personal_module.py +0 -300
  244. web3/_utils/request.py +0 -265
  245. web3/pm.py +0 -602
  246. web3/tools/__init__.py +0 -4
  247. web3/tools/benchmark/__init__.py +0 -0
  248. web3/tools/benchmark/main.py +0 -185
  249. web3/tools/benchmark/node.py +0 -126
  250. web3/tools/benchmark/reporting.py +0 -39
  251. web3/tools/benchmark/utils.py +0 -69
  252. web3/tools/pytest_ethereum/__init__.py +0 -0
  253. web3/tools/pytest_ethereum/_utils.py +0 -145
  254. web3/tools/pytest_ethereum/deployer.py +0 -48
  255. web3/tools/pytest_ethereum/exceptions.py +0 -22
  256. web3/tools/pytest_ethereum/linker.py +0 -128
  257. web3/tools/pytest_ethereum/plugins.py +0 -33
  258. web3-7.0.0b1.dist-info/METADATA +0 -114
  259. web3-7.0.0b1.dist-info/RECORD +0 -280
  260. web3-7.0.0b1.dist-info/entry_points.txt +0 -2
  261. /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
  )
@@ -45,11 +48,11 @@ class RPC:
45
48
 
46
49
  # eth
47
50
  eth_accounts = RPCEndpoint("eth_accounts")
51
+ eth_blobBaseFee = RPCEndpoint("eth_blobBaseFee")
48
52
  eth_blockNumber = RPCEndpoint("eth_blockNumber")
49
53
  eth_call = RPCEndpoint("eth_call")
50
54
  eth_createAccessList = RPCEndpoint("eth_createAccessList")
51
55
  eth_chainId = RPCEndpoint("eth_chainId")
52
- eth_coinbase = RPCEndpoint("eth_coinbase")
53
56
  eth_estimateGas = RPCEndpoint("eth_estimateGas")
54
57
  eth_feeHistory = RPCEndpoint("eth_feeHistory")
55
58
  eth_maxPriorityFeePerGas = RPCEndpoint("eth_maxPriorityFeePerGas")
@@ -57,6 +60,7 @@ class RPC:
57
60
  eth_getBalance = RPCEndpoint("eth_getBalance")
58
61
  eth_getBlockByHash = RPCEndpoint("eth_getBlockByHash")
59
62
  eth_getBlockByNumber = RPCEndpoint("eth_getBlockByNumber")
63
+ eth_getBlockReceipts = RPCEndpoint("eth_getBlockReceipts")
60
64
  eth_getBlockTransactionCountByHash = RPCEndpoint(
61
65
  "eth_getBlockTransactionCountByHash"
62
66
  )
@@ -90,8 +94,6 @@ class RPC:
90
94
  eth_getUncleCountByBlockHash = RPCEndpoint("eth_getUncleCountByBlockHash")
91
95
  eth_getUncleCountByBlockNumber = RPCEndpoint("eth_getUncleCountByBlockNumber")
92
96
  eth_getWork = RPCEndpoint("eth_getWork")
93
- eth_hashrate = RPCEndpoint("eth_hashrate")
94
- eth_mining = RPCEndpoint("eth_mining")
95
97
  eth_newBlockFilter = RPCEndpoint("eth_newBlockFilter")
96
98
  eth_newFilter = RPCEndpoint("eth_newFilter")
97
99
  eth_newPendingTransactionFilter = RPCEndpoint("eth_newPendingTransactionFilter")
@@ -119,18 +121,6 @@ class RPC:
119
121
  net_peerCount = RPCEndpoint("net_peerCount")
120
122
  net_version = RPCEndpoint("net_version")
121
123
 
122
- # personal
123
- personal_ecRecover = RPCEndpoint("personal_ecRecover")
124
- personal_importRawKey = RPCEndpoint("personal_importRawKey")
125
- personal_listAccounts = RPCEndpoint("personal_listAccounts")
126
- personal_listWallets = RPCEndpoint("personal_listWallets")
127
- personal_lockAccount = RPCEndpoint("personal_lockAccount")
128
- personal_newAccount = RPCEndpoint("personal_newAccount")
129
- personal_sendTransaction = RPCEndpoint("personal_sendTransaction")
130
- personal_sign = RPCEndpoint("personal_sign")
131
- personal_signTypedData = RPCEndpoint("personal_signTypedData")
132
- personal_unlockAccount = RPCEndpoint("personal_unlockAccount")
133
-
134
124
  # testing
135
125
  testing_timeTravel = RPCEndpoint("testing_timeTravel")
136
126
 
@@ -151,12 +141,16 @@ class RPC:
151
141
  # web3
152
142
  web3_clientVersion = RPCEndpoint("web3_clientVersion")
153
143
 
144
+ # debug
145
+ debug_traceTransaction = RPCEndpoint("debug_traceTransaction")
146
+
154
147
 
155
148
  TRANSACTION_PARAMS_ABIS = {
156
149
  "data": "bytes",
157
150
  "from": "address",
158
151
  "gas": "uint",
159
152
  "gasPrice": "uint",
153
+ "maxFeePerBlobGas": "uint",
160
154
  "maxFeePerGas": "uint",
161
155
  "maxPriorityFeePerGas": "uint",
162
156
  "nonce": "uint",
@@ -206,12 +200,6 @@ RPC_ABIS: Dict[str, Union[Sequence[Any], Dict[str, str]]] = {
206
200
  "eth_signTypedData": ["address", None],
207
201
  "eth_submitHashrate": ["uint", "bytes32"],
208
202
  "eth_submitWork": ["bytes8", "bytes32", "bytes32"],
209
- # personal
210
- "personal_sendTransaction": TRANSACTION_PARAMS_ABIS,
211
- "personal_lockAccount": ["address"],
212
- "personal_unlockAccount": ["address", None, None],
213
- "personal_sign": [None, "address", None],
214
- "personal_signTypedData": [None, "address", None],
215
203
  "trace_call": TRANSACTION_PARAMS_ABIS,
216
204
  "trace_filter": TRACE_FILTER_PARAM_ABIS,
217
205
  }
@@ -245,6 +233,6 @@ def abi_request_formatters(
245
233
  single_dict_formatter = apply_abi_formatters_to_dict(normalizers, abi_types)
246
234
  yield method, apply_formatter_at_index(single_dict_formatter, 0)
247
235
  else:
248
- raise TypeError(
236
+ raise Web3TypeError(
249
237
  f"ABI definitions must be a list or dictionary, got {abi_types!r}"
250
238
  )
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: