web3 7.0.0b7__py3-none-any.whl → 7.0.0b9__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 (50) hide show
  1. ens/async_ens.py +16 -7
  2. ens/base_ens.py +3 -1
  3. ens/exceptions.py +2 -7
  4. ens/utils.py +0 -17
  5. web3/_utils/abi.py +100 -257
  6. web3/_utils/compat/__init__.py +1 -0
  7. web3/_utils/contracts.py +116 -205
  8. web3/_utils/encoding.py +4 -5
  9. web3/_utils/events.py +28 -33
  10. web3/_utils/fee_utils.py +2 -2
  11. web3/_utils/filters.py +2 -5
  12. web3/_utils/http_session_manager.py +30 -7
  13. web3/_utils/method_formatters.py +21 -3
  14. web3/_utils/module_testing/eth_module.py +61 -39
  15. web3/_utils/module_testing/module_testing_utils.py +51 -10
  16. web3/_utils/module_testing/persistent_connection_provider.py +46 -16
  17. web3/_utils/module_testing/web3_module.py +8 -8
  18. web3/_utils/normalizers.py +10 -8
  19. web3/_utils/validation.py +5 -7
  20. web3/contract/async_contract.py +18 -17
  21. web3/contract/base_contract.py +116 -80
  22. web3/contract/contract.py +16 -17
  23. web3/contract/utils.py +86 -55
  24. web3/eth/async_eth.py +1 -2
  25. web3/eth/eth.py +1 -2
  26. web3/exceptions.py +28 -9
  27. web3/gas_strategies/time_based.py +4 -0
  28. web3/manager.py +68 -23
  29. web3/middleware/filter.py +3 -3
  30. web3/middleware/signing.py +6 -1
  31. web3/module.py +1 -1
  32. web3/providers/persistent/async_ipc.py +34 -79
  33. web3/providers/persistent/persistent.py +76 -7
  34. web3/providers/persistent/persistent_connection.py +47 -5
  35. web3/providers/persistent/websocket.py +19 -59
  36. web3/types.py +5 -45
  37. web3/utils/__init__.py +48 -4
  38. web3/utils/abi.py +575 -10
  39. web3/utils/caching.py +24 -0
  40. {web3-7.0.0b7.dist-info → web3-7.0.0b9.dist-info}/METADATA +14 -8
  41. {web3-7.0.0b7.dist-info → web3-7.0.0b9.dist-info}/RECORD +45 -50
  42. {web3-7.0.0b7.dist-info → web3-7.0.0b9.dist-info}/WHEEL +1 -1
  43. web3/tools/benchmark/__init__.py +0 -0
  44. web3/tools/benchmark/main.py +0 -190
  45. web3/tools/benchmark/node.py +0 -120
  46. web3/tools/benchmark/reporting.py +0 -39
  47. web3/tools/benchmark/utils.py +0 -69
  48. /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
  49. {web3-7.0.0b7.dist-info → web3-7.0.0b9.dist-info}/LICENSE +0 -0
  50. {web3-7.0.0b7.dist-info → web3-7.0.0b9.dist-info}/top_level.txt +0 -0
@@ -23,6 +23,7 @@ from web3.middleware import (
23
23
  )
24
24
  from web3.types import (
25
25
  FormattedEthSubscriptionResponse,
26
+ RPCEndpoint,
26
27
  )
27
28
 
28
29
  if TYPE_CHECKING:
@@ -31,6 +32,22 @@ if TYPE_CHECKING:
31
32
  )
32
33
 
33
34
 
35
+ SOME_BLOCK_KEYS = [
36
+ "number",
37
+ "hash",
38
+ "parentHash",
39
+ "transactionsRoot",
40
+ "stateRoot",
41
+ "receiptsRoot",
42
+ "size",
43
+ "gasLimit",
44
+ "gasUsed",
45
+ "timestamp",
46
+ "transactions",
47
+ "baseFeePerGas",
48
+ ]
49
+
50
+
34
51
  class PersistentConnectionProviderTest:
35
52
  @pytest.mark.asyncio
36
53
  @pytest.mark.parametrize(
@@ -372,22 +389,10 @@ class PersistentConnectionProviderTest:
372
389
  assert isinstance(pending, AttributeDict)
373
390
 
374
391
  # assert block values
375
- some_block_keys = [
376
- "number",
377
- "hash",
378
- "parentHash",
379
- "transactionsRoot",
380
- "stateRoot",
381
- "receiptsRoot",
382
- "size",
383
- "gasLimit",
384
- "gasUsed",
385
- "timestamp",
386
- "transactions",
387
- "baseFeePerGas",
388
- ]
389
- assert all(k in latest.keys() for k in some_block_keys)
390
- assert all(k in pending.keys() for k in some_block_keys)
392
+ assert latest is not None
393
+ assert all(k in latest.keys() for k in SOME_BLOCK_KEYS)
394
+ assert pending is not None
395
+ assert all(k in pending.keys() for k in SOME_BLOCK_KEYS)
391
396
 
392
397
  assert isinstance(block_num, int)
393
398
  assert latest["number"] == block_num
@@ -395,3 +400,28 @@ class PersistentConnectionProviderTest:
395
400
  assert isinstance(chain_id, int)
396
401
  assert isinstance(chain_id2, int)
397
402
  assert isinstance(chain_id3, int)
403
+
404
+ @pytest.mark.asyncio
405
+ async def test_public_socket_api(self, async_w3: "AsyncWeb3") -> None:
406
+ # send a request over the socket
407
+ await async_w3.socket.send(
408
+ RPCEndpoint("eth_getBlockByNumber"), ["latest", True]
409
+ )
410
+
411
+ # recv and validate the unprocessed response
412
+ response = await async_w3.socket.recv()
413
+ assert "id" in response, "Expected 'id' key in response."
414
+ assert "jsonrpc" in response, "Expected 'jsonrpc' key in response."
415
+ assert "result" in response, "Expected 'result' key in response."
416
+ assert all(k in response["result"].keys() for k in SOME_BLOCK_KEYS)
417
+ assert not isinstance(response["result"]["number"], int) # assert not processed
418
+
419
+ # make a request over the socket
420
+ response = await async_w3.socket.make_request(
421
+ RPCEndpoint("eth_getBlockByNumber"), ["latest", True]
422
+ )
423
+ assert "id" in response, "Expected 'id' key in response."
424
+ assert "jsonrpc" in response, "Expected 'jsonrpc' key in response."
425
+ assert "result" in response, "Expected 'result' key in response."
426
+ assert all(k in response["result"].keys() for k in SOME_BLOCK_KEYS)
427
+ assert not isinstance(response["result"]["number"], int) # assert not processed
@@ -522,12 +522,12 @@ class AsyncWeb3ModuleTest(Web3ModuleTest):
522
522
  # an asynchronous test should have the exact same name.
523
523
 
524
524
  @pytest.mark.asyncio
525
- async def test_web3_client_version(self, async_w3: AsyncWeb3) -> None:
525
+ async def test_web3_client_version(self, async_w3: AsyncWeb3) -> None: # type: ignore[override] # noqa: E501
526
526
  client_version = await async_w3.client_version
527
527
  self._check_web3_client_version(client_version)
528
528
 
529
529
  @pytest.mark.asyncio
530
- async def test_batch_requests(
530
+ async def test_batch_requests( # type: ignore[override]
531
531
  self, async_w3: AsyncWeb3, async_math_contract: "AsyncContract"
532
532
  ) -> None:
533
533
  async with async_w3.batch_requests() as batch:
@@ -595,8 +595,8 @@ class AsyncWeb3ModuleTest(Web3ModuleTest):
595
595
  assert last_three_responses[2]["number"] == 5
596
596
 
597
597
  @pytest.mark.asyncio
598
- async def test_batch_requests_initialized_as_object(
599
- self, async_w3: AsyncWeb3, async_math_contract: "AsyncContract"
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
600
  ) -> None:
601
601
  batch = async_w3.batch_requests()
602
602
  batch.add(async_w3.eth.get_block(1))
@@ -643,7 +643,7 @@ class AsyncWeb3ModuleTest(Web3ModuleTest):
643
643
  assert cast(BlockData, b4)["number"] == 4
644
644
 
645
645
  @pytest.mark.asyncio
646
- async def test_batch_requests_clear(self, async_w3: AsyncWeb3) -> None:
646
+ async def test_batch_requests_clear(self, async_w3: AsyncWeb3) -> None: # type: ignore[override] # noqa: E501
647
647
  async with async_w3.batch_requests() as batch:
648
648
  batch.add(async_w3.eth.get_block(1))
649
649
  batch.add(async_w3.eth.get_block(2))
@@ -672,7 +672,7 @@ class AsyncWeb3ModuleTest(Web3ModuleTest):
672
672
  assert cast(BlockData, r3)["number"] == 6
673
673
 
674
674
  @pytest.mark.asyncio
675
- async def test_batch_requests_cancel(self, async_w3: AsyncWeb3) -> None:
675
+ async def test_batch_requests_cancel(self, async_w3: AsyncWeb3) -> None: # type: ignore[override] # noqa: E501
676
676
  # as context manager
677
677
  async with async_w3.batch_requests() as batch:
678
678
  batch.add(async_w3.eth.get_block(1))
@@ -712,8 +712,8 @@ class AsyncWeb3ModuleTest(Web3ModuleTest):
712
712
  assert isinstance(block_num, int)
713
713
 
714
714
  @pytest.mark.asyncio
715
- async def test_batch_requests_raises_for_common_unsupported_methods(
716
- self, async_w3: AsyncWeb3, async_math_contract: "AsyncContract"
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
717
  ) -> None:
718
718
  async with async_w3.batch_requests() as batch:
719
719
  with pytest.raises(MethodNotSupported, match="eth_sendTransaction"):
@@ -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,
@@ -62,9 +63,6 @@ from web3.exceptions import (
62
63
  NameNotFound,
63
64
  Web3ValueError,
64
65
  )
65
- from web3.types import (
66
- ABI,
67
- )
68
66
 
69
67
  if TYPE_CHECKING:
70
68
  from web3 import ( # noqa: F401
@@ -256,7 +254,9 @@ def normalize_abi(abi: Union[ABI, str]) -> ABI:
256
254
  return cast(ABI, abi)
257
255
 
258
256
 
259
- def normalize_address(ens: ENS, address: ChecksumAddress) -> ChecksumAddress:
257
+ def normalize_address(
258
+ ens: ENS, address: Optional[ChecksumAddress]
259
+ ) -> Union[ChecksumAddress, None]:
260
260
  if address:
261
261
  if is_ens_name(address):
262
262
  validate_name_has_address(ens, address)
@@ -265,15 +265,17 @@ def normalize_address(ens: ENS, address: ChecksumAddress) -> ChecksumAddress:
265
265
  return address
266
266
 
267
267
 
268
- def normalize_address_no_ens(address: ChecksumAddress) -> ChecksumAddress:
268
+ def normalize_address_no_ens(
269
+ address: Optional[ChecksumAddress],
270
+ ) -> Union[ChecksumAddress, None]:
269
271
  if address:
270
272
  validate_address(address)
271
273
  return address
272
274
 
273
275
 
274
- def normalize_bytecode(bytecode: bytes) -> HexBytes:
275
- if bytecode:
276
- bytecode = HexBytes(bytecode)
276
+ def normalize_bytecode(bytecode: Optional[bytes]) -> Union[HexBytes, None]:
277
+ if bytecode is not None:
278
+ return HexBytes(bytecode)
277
279
  return bytecode
278
280
 
279
281
 
web3/_utils/validation.py CHANGED
@@ -5,10 +5,14 @@ from typing import (
5
5
  )
6
6
 
7
7
  from eth_typing import (
8
+ ABI,
9
+ ABIFunction,
8
10
  HexStr,
9
11
  TypeStr,
10
12
  )
11
13
  from eth_utils import (
14
+ abi_to_signature,
15
+ filter_abi_by_type,
12
16
  function_abi_to_4byte_selector,
13
17
  is_0x_prefixed,
14
18
  is_binary_address,
@@ -38,8 +42,6 @@ from ens.utils import (
38
42
  is_valid_ens_name,
39
43
  )
40
44
  from web3._utils.abi import (
41
- abi_to_signature,
42
- filter_by_type,
43
45
  is_address_type,
44
46
  is_array_type,
45
47
  is_bool_type,
@@ -56,10 +58,6 @@ from web3.exceptions import (
56
58
  Web3TypeError,
57
59
  Web3ValueError,
58
60
  )
59
- from web3.types import (
60
- ABI,
61
- ABIFunction,
62
- )
63
61
 
64
62
 
65
63
  def _prepare_selector_collision_msg(duplicates: Dict[HexStr, ABIFunction]) -> str:
@@ -81,7 +79,7 @@ def validate_abi(abi: ABI) -> None:
81
79
  if not all(is_dict(e) for e in abi):
82
80
  raise Web3ValueError("'abi' is not a list of dictionaries")
83
81
 
84
- functions = filter_by_type("function", abi)
82
+ functions = filter_abi_by_type("function", abi)
85
83
  selectors = groupby(compose(encode_hex, function_abi_to_4byte_selector), functions)
86
84
  duplicates = valfilter(lambda funcs: len(funcs) > 1, selectors)
87
85
  if duplicates:
@@ -14,11 +14,16 @@ from typing import (
14
14
  )
15
15
 
16
16
  from eth_typing import (
17
+ ABI,
17
18
  ChecksumAddress,
18
19
  )
19
20
  from eth_utils import (
20
21
  combomethod,
21
22
  )
23
+ from eth_utils.abi import (
24
+ get_abi_input_names,
25
+ get_all_function_abis,
26
+ )
22
27
  from eth_utils.toolz import (
23
28
  partial,
24
29
  )
@@ -28,9 +33,12 @@ from hexbytes import (
28
33
 
29
34
  from web3._utils.abi import (
30
35
  fallback_func_abi_exists,
31
- filter_by_type,
32
36
  receive_func_abi_exists,
33
37
  )
38
+ from web3._utils.abi_element_identifiers import (
39
+ FallbackFn,
40
+ ReceiveFn,
41
+ )
34
42
  from web3._utils.async_transactions import (
35
43
  async_fill_transaction_defaults,
36
44
  )
@@ -50,10 +58,6 @@ from web3._utils.events import (
50
58
  from web3._utils.filters import (
51
59
  AsyncLogFilter,
52
60
  )
53
- from web3._utils.function_identifiers import (
54
- FallbackFn,
55
- ReceiveFn,
56
- )
57
61
  from web3._utils.normalizers import (
58
62
  normalize_abi,
59
63
  normalize_address_no_ens,
@@ -88,15 +92,11 @@ from web3.exceptions import (
88
92
  Web3ValueError,
89
93
  )
90
94
  from web3.types import (
91
- ABI,
92
95
  BlockIdentifier,
93
96
  EventData,
94
97
  StateOverride,
95
98
  TxParams,
96
99
  )
97
- from web3.utils import (
98
- get_abi_input_names,
99
- )
100
100
 
101
101
  if TYPE_CHECKING:
102
102
  from ens import AsyncENS # noqa: F401
@@ -311,7 +311,7 @@ class AsyncContractFunction(BaseContractFunction):
311
311
  self.w3,
312
312
  self.address,
313
313
  self._return_data_normalizers,
314
- self.function_identifier,
314
+ self.abi_element_identifier,
315
315
  call_transaction,
316
316
  block_id,
317
317
  self.contract_abi,
@@ -328,7 +328,7 @@ class AsyncContractFunction(BaseContractFunction):
328
328
  return await async_transact_with_contract_function(
329
329
  self.address,
330
330
  self.w3,
331
- self.function_identifier,
331
+ self.abi_element_identifier,
332
332
  setup_transaction,
333
333
  self.contract_abi,
334
334
  self.abi,
@@ -346,7 +346,7 @@ class AsyncContractFunction(BaseContractFunction):
346
346
  return await async_estimate_gas_for_function(
347
347
  self.address,
348
348
  self.w3,
349
- self.function_identifier,
349
+ self.abi_element_identifier,
350
350
  setup_transaction,
351
351
  self.contract_abi,
352
352
  self.abi,
@@ -363,7 +363,7 @@ class AsyncContractFunction(BaseContractFunction):
363
363
  return await async_build_transaction_for_function(
364
364
  self.address,
365
365
  self.w3,
366
- self.function_identifier,
366
+ self.abi_element_identifier,
367
367
  built_transaction,
368
368
  self.contract_abi,
369
369
  self.abi,
@@ -383,7 +383,7 @@ class AsyncContractFunction(BaseContractFunction):
383
383
  w3=async_w3,
384
384
  contract_abi=abi,
385
385
  address=address,
386
- function_identifier=FallbackFn,
386
+ abi_element_identifier=FallbackFn,
387
387
  )()
388
388
  return cast(AsyncContractFunction, NonExistentFallbackFunction())
389
389
 
@@ -399,7 +399,7 @@ class AsyncContractFunction(BaseContractFunction):
399
399
  w3=async_w3,
400
400
  contract_abi=abi,
401
401
  address=address,
402
- function_identifier=ReceiveFn,
402
+ abi_element_identifier=ReceiveFn,
403
403
  )()
404
404
  return cast(AsyncContractFunction, NonExistentReceiveFunction())
405
405
 
@@ -577,14 +577,15 @@ class AsyncContractCaller(BaseContractCaller):
577
577
  if transaction is None:
578
578
  transaction = {}
579
579
 
580
- self._functions = filter_by_type("function", self.abi)
580
+ self._functions = get_all_function_abis(self.abi)
581
+
581
582
  for func in self._functions:
582
583
  fn = AsyncContractFunction.factory(
583
584
  func["name"],
584
585
  w3=w3,
585
586
  contract_abi=self.abi,
586
587
  address=self.address,
587
- function_identifier=func["name"],
588
+ abi_element_identifier=func["name"],
588
589
  decode_tuples=decode_tuples,
589
590
  )
590
591