web3 7.0.0b2__py3-none-any.whl → 7.0.0b4__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 (83) hide show
  1. ens/_normalization.py +1 -3
  2. ens/async_ens.py +14 -11
  3. ens/contract_data.py +2 -2
  4. ens/ens.py +10 -7
  5. ens/exceptions.py +19 -27
  6. ens/specs/nf.json +1 -1
  7. ens/specs/normalization_spec.json +1 -1
  8. ens/utils.py +24 -15
  9. web3/__init__.py +2 -7
  10. web3/_utils/abi.py +30 -29
  11. web3/_utils/async_transactions.py +7 -4
  12. web3/_utils/blocks.py +6 -2
  13. web3/_utils/caching.py +7 -3
  14. web3/_utils/compat/__init__.py +0 -3
  15. web3/_utils/contract_sources/compile_contracts.py +1 -1
  16. web3/_utils/contracts.py +12 -12
  17. web3/_utils/datatypes.py +5 -1
  18. web3/_utils/decorators.py +6 -1
  19. web3/_utils/empty.py +1 -1
  20. web3/_utils/encoding.py +15 -10
  21. web3/_utils/error_formatters_utils.py +5 -3
  22. web3/_utils/events.py +35 -24
  23. web3/_utils/fee_utils.py +2 -4
  24. web3/_utils/filters.py +17 -12
  25. web3/_utils/formatters.py +2 -2
  26. web3/_utils/math.py +14 -15
  27. web3/_utils/method_formatters.py +31 -5
  28. web3/_utils/module.py +2 -1
  29. web3/_utils/module_testing/eth_module.py +129 -75
  30. web3/_utils/module_testing/go_ethereum_personal_module.py +1 -1
  31. web3/_utils/module_testing/module_testing_utils.py +1 -3
  32. web3/_utils/module_testing/utils.py +14 -7
  33. web3/_utils/normalizers.py +3 -3
  34. web3/_utils/request.py +4 -4
  35. web3/_utils/rpc_abi.py +6 -1
  36. web3/_utils/threads.py +8 -7
  37. web3/_utils/transactions.py +18 -12
  38. web3/_utils/type_conversion.py +5 -1
  39. web3/_utils/validation.py +12 -10
  40. web3/contract/async_contract.py +12 -7
  41. web3/contract/base_contract.py +51 -57
  42. web3/contract/contract.py +12 -6
  43. web3/contract/utils.py +11 -6
  44. web3/datastructures.py +22 -12
  45. web3/eth/async_eth.py +53 -30
  46. web3/eth/base_eth.py +7 -3
  47. web3/eth/eth.py +31 -14
  48. web3/exceptions.py +41 -59
  49. web3/gas_strategies/time_based.py +2 -4
  50. web3/geth.py +1 -3
  51. web3/main.py +6 -2
  52. web3/manager.py +13 -12
  53. web3/method.py +13 -5
  54. web3/middleware/base.py +4 -2
  55. web3/middleware/filter.py +27 -17
  56. web3/middleware/formatting.py +6 -3
  57. web3/middleware/names.py +4 -1
  58. web3/middleware/signing.py +6 -2
  59. web3/middleware/stalecheck.py +2 -1
  60. web3/providers/eth_tester/defaults.py +1 -1
  61. web3/providers/eth_tester/main.py +5 -4
  62. web3/providers/eth_tester/middleware.py +10 -1
  63. web3/providers/ipc.py +7 -3
  64. web3/providers/persistent/async_ipc.py +6 -7
  65. web3/providers/persistent/persistent.py +12 -2
  66. web3/providers/persistent/request_processor.py +10 -12
  67. web3/providers/persistent/websocket.py +3 -3
  68. web3/providers/rpc/async_rpc.py +23 -6
  69. web3/providers/rpc/rpc.py +27 -16
  70. web3/testing.py +4 -4
  71. web3/tools/benchmark/__init__.py +0 -0
  72. web3/tools/benchmark/main.py +189 -0
  73. web3/tools/benchmark/node.py +126 -0
  74. web3/tools/benchmark/reporting.py +39 -0
  75. web3/tools/benchmark/utils.py +69 -0
  76. web3/tracing.py +9 -5
  77. web3/types.py +23 -22
  78. web3/utils/caching.py +2 -4
  79. {web3-7.0.0b2.dist-info → web3-7.0.0b4.dist-info}/METADATA +13 -26
  80. {web3-7.0.0b2.dist-info → web3-7.0.0b4.dist-info}/RECORD +83 -78
  81. {web3-7.0.0b2.dist-info → web3-7.0.0b4.dist-info}/LICENSE +0 -0
  82. {web3-7.0.0b2.dist-info → web3-7.0.0b4.dist-info}/WHEEL +0 -0
  83. {web3-7.0.0b2.dist-info → web3-7.0.0b4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,189 @@
1
+ import argparse
2
+ import asyncio
3
+ from collections import (
4
+ defaultdict,
5
+ )
6
+ import logging
7
+ import sys
8
+ import timeit
9
+ from typing import (
10
+ Any,
11
+ Callable,
12
+ Dict,
13
+ Union,
14
+ )
15
+
16
+ from web3 import (
17
+ AsyncHTTPProvider,
18
+ AsyncWeb3,
19
+ HTTPProvider,
20
+ Web3,
21
+ )
22
+ from web3.middleware import (
23
+ BufferedGasEstimateMiddleware,
24
+ GasPriceStrategyMiddleware,
25
+ )
26
+ from web3.tools.benchmark.node import (
27
+ GethBenchmarkFixture,
28
+ )
29
+ from web3.tools.benchmark.reporting import (
30
+ print_entry,
31
+ print_footer,
32
+ print_header,
33
+ )
34
+ from web3.tools.benchmark.utils import (
35
+ wait_for_aiohttp,
36
+ wait_for_http,
37
+ )
38
+ from web3.types import (
39
+ Wei,
40
+ )
41
+
42
+ KEYFILE_PW = "web3py-test"
43
+
44
+ parser = argparse.ArgumentParser()
45
+ parser.add_argument(
46
+ "--num-calls",
47
+ type=int,
48
+ default=10,
49
+ help="The number of RPC calls to make",
50
+ )
51
+
52
+ # TODO - layers to test:
53
+ # contract.functions.method(...).call()
54
+ # w3.eth.call(...)
55
+ # HTTPProvider.make_request(...)
56
+
57
+
58
+ def build_web3_http(endpoint_uri: str) -> Web3:
59
+ wait_for_http(endpoint_uri)
60
+ _w3 = Web3(
61
+ HTTPProvider(endpoint_uri),
62
+ middleware=[GasPriceStrategyMiddleware, BufferedGasEstimateMiddleware],
63
+ )
64
+ return _w3
65
+
66
+
67
+ async def build_async_w3_http(endpoint_uri: str) -> AsyncWeb3:
68
+ await wait_for_aiohttp(endpoint_uri)
69
+ _w3 = AsyncWeb3(
70
+ AsyncHTTPProvider(endpoint_uri),
71
+ middleware=[GasPriceStrategyMiddleware, BufferedGasEstimateMiddleware],
72
+ )
73
+ return _w3
74
+
75
+
76
+ def sync_benchmark(func: Callable[..., Any], n: int) -> Union[float, str]:
77
+ try:
78
+ starttime = timeit.default_timer()
79
+ for _ in range(n):
80
+ func()
81
+ endtime = timeit.default_timer()
82
+ execution_time = endtime - starttime
83
+ return execution_time
84
+ except Exception:
85
+ return "N/A"
86
+
87
+
88
+ async def async_benchmark(func: Callable[..., Any], n: int) -> Union[float, str]:
89
+ try:
90
+ starttime = timeit.default_timer()
91
+ for result in asyncio.as_completed([func() for _ in range(n)]):
92
+ await result
93
+ execution_time = timeit.default_timer() - starttime
94
+ return execution_time
95
+ except Exception:
96
+ return "N/A"
97
+
98
+
99
+ def main(logger: logging.Logger, num_calls: int) -> None:
100
+ fixture = GethBenchmarkFixture()
101
+ for built_fixture in fixture.build():
102
+ for _ in built_fixture:
103
+ w3_http = build_web3_http(fixture.endpoint_uri)
104
+ try:
105
+ loop = asyncio.get_running_loop()
106
+ except RuntimeError:
107
+ loop = asyncio.new_event_loop()
108
+ asyncio.set_event_loop(loop)
109
+
110
+ # -- sync -- #
111
+ coinbase = w3_http.eth.coinbase
112
+
113
+ # -- async -- #
114
+ async_w3_http = loop.run_until_complete(
115
+ build_async_w3_http(fixture.endpoint_uri)
116
+ )
117
+ async_coinbase = loop.run_until_complete(async_w3_http.eth.coinbase)
118
+
119
+ methods = [
120
+ {
121
+ "name": "eth_gasPrice",
122
+ "params": {},
123
+ "exec": lambda w3_http=w3_http: w3_http.eth.gas_price,
124
+ "async_exec": lambda async_w3_http=async_w3_http: async_w3_http.eth.gas_price, # noqa: E501
125
+ },
126
+ {
127
+ "name": "eth_sendTransaction",
128
+ "params": {},
129
+ "exec": lambda w3_http=w3_http, coinbase=coinbase: w3_http.eth.send_transaction( # noqa: E501
130
+ {
131
+ "to": "0xd3CdA913deB6f67967B99D67aCDFa1712C293601",
132
+ "from": coinbase,
133
+ "value": Wei(1),
134
+ }
135
+ ),
136
+ "async_exec": lambda async_w3_http=async_w3_http, async_coinbase=async_coinbase: async_w3_http.eth.send_transaction( # noqa: E501
137
+ {
138
+ "to": "0xd3CdA913deB6f67967B99D67aCDFa1712C293601",
139
+ "from": async_coinbase,
140
+ "value": Wei(1),
141
+ }
142
+ ),
143
+ },
144
+ {
145
+ "name": "eth_blockNumber",
146
+ "params": {},
147
+ "exec": lambda w3_http=w3_http: w3_http.eth.block_number,
148
+ "async_exec": lambda async_w3_http=async_w3_http: async_w3_http.eth.block_number, # noqa: E501
149
+ },
150
+ {
151
+ "name": "eth_getBlock",
152
+ "params": {},
153
+ "exec": lambda w3_http=w3_http: w3_http.eth.get_block(1),
154
+ "async_exec": lambda async_w3_http=async_w3_http: async_w3_http.eth.get_block( # noqa: E501
155
+ 1
156
+ ),
157
+ },
158
+ ]
159
+
160
+ def benchmark(
161
+ method: Dict[str, Any], loop: asyncio.AbstractEventLoop = loop
162
+ ) -> None:
163
+ outcomes: Dict[str, Union[str, float]] = defaultdict(lambda: "N/A")
164
+ outcomes["name"] = method["name"]
165
+ outcomes["HTTPProvider"] = sync_benchmark(
166
+ method["exec"],
167
+ num_calls,
168
+ )
169
+ outcomes["AsyncHTTPProvider"] = loop.run_until_complete(
170
+ async_benchmark(method["async_exec"], num_calls)
171
+ )
172
+ print_entry(logger, outcomes)
173
+
174
+ print_header(logger, num_calls)
175
+
176
+ for method in methods:
177
+ benchmark(method)
178
+
179
+ print_footer(logger)
180
+
181
+
182
+ if __name__ == "__main__":
183
+ args = parser.parse_args()
184
+
185
+ logger = logging.getLogger()
186
+ logger.setLevel(logging.INFO)
187
+ logger.addHandler(logging.StreamHandler(sys.stdout))
188
+
189
+ main(logger, args.num_calls)
@@ -0,0 +1,126 @@
1
+ import os
2
+ import socket
3
+ from subprocess import (
4
+ PIPE,
5
+ Popen,
6
+ check_output,
7
+ )
8
+ from tempfile import (
9
+ TemporaryDirectory,
10
+ )
11
+ from typing import (
12
+ Any,
13
+ Generator,
14
+ Sequence,
15
+ )
16
+ import zipfile
17
+
18
+ from geth.install import (
19
+ get_executable_path,
20
+ install_geth,
21
+ )
22
+
23
+ from web3.tools.benchmark.utils import (
24
+ kill_proc_gracefully,
25
+ )
26
+
27
+ GETH_FIXTURE_ZIP = "geth-1.13.11-fixture.zip"
28
+
29
+ # use same coinbase value as in `web3.py/tests/integration/generate_fixtures/common.py`
30
+ COINBASE = "0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd"
31
+
32
+
33
+ class GethBenchmarkFixture:
34
+ def __init__(self) -> None:
35
+ self.rpc_port = self._rpc_port()
36
+ self.endpoint_uri = self._endpoint_uri()
37
+ self.geth_binary = self._geth_binary()
38
+
39
+ def build(self) -> Generator[Any, None, None]:
40
+ with TemporaryDirectory() as base_dir:
41
+ zipfile_path = os.path.abspath(
42
+ os.path.join(
43
+ os.path.dirname(__file__),
44
+ "../../../tests/integration/",
45
+ GETH_FIXTURE_ZIP,
46
+ )
47
+ )
48
+ tmp_datadir = os.path.join(str(base_dir), "datadir")
49
+ with zipfile.ZipFile(zipfile_path, "r") as zip_ref:
50
+ zip_ref.extractall(tmp_datadir)
51
+ self.datadir = tmp_datadir
52
+
53
+ genesis_file = os.path.join(self.datadir, "genesis.json")
54
+
55
+ yield self._geth_process(self.datadir, genesis_file, self.rpc_port)
56
+
57
+ def _rpc_port(self) -> str:
58
+ sock = socket.socket()
59
+ sock.bind(("127.0.0.1", 0))
60
+ port = sock.getsockname()[1]
61
+ sock.close()
62
+ return str(port)
63
+
64
+ def _endpoint_uri(self) -> str:
65
+ return f"http://localhost:{self.rpc_port}"
66
+
67
+ def _geth_binary(self) -> str:
68
+ if "GETH_BINARY" in os.environ:
69
+ return os.environ["GETH_BINARY"]
70
+ elif "GETH_VERSION" in os.environ:
71
+ geth_version = os.environ["GETH_VERSION"]
72
+ _geth_binary = get_executable_path(geth_version)
73
+ if not os.path.exists(_geth_binary):
74
+ install_geth(geth_version)
75
+ assert os.path.exists(_geth_binary)
76
+ return _geth_binary
77
+ else:
78
+ return "geth"
79
+
80
+ def _geth_command_arguments(self, datadir: str) -> Sequence[str]:
81
+ return (
82
+ self.geth_binary,
83
+ "--dev",
84
+ "--dev.period",
85
+ "100",
86
+ "--datadir",
87
+ str(datadir),
88
+ "--nodiscover",
89
+ "--http",
90
+ "--http.port",
91
+ self.rpc_port,
92
+ "--http.api",
93
+ "admin,eth,net,web3",
94
+ "--ipcdisable",
95
+ "--allow-insecure-unlock",
96
+ "--miner.etherbase",
97
+ COINBASE[2:],
98
+ "--password",
99
+ os.path.join(datadir, "keystore", "pw.txt"),
100
+ )
101
+
102
+ def _geth_process(
103
+ self, datadir: str, genesis_file: str, rpc_port: str
104
+ ) -> Generator[Any, None, None]:
105
+ init_datadir_command = (
106
+ self.geth_binary,
107
+ "--datadir",
108
+ str(datadir),
109
+ "init",
110
+ str(genesis_file),
111
+ )
112
+ check_output(
113
+ init_datadir_command,
114
+ stdin=PIPE,
115
+ stderr=PIPE,
116
+ )
117
+ proc = Popen(
118
+ self._geth_command_arguments(datadir),
119
+ stdin=PIPE,
120
+ stdout=PIPE,
121
+ stderr=PIPE,
122
+ )
123
+ try:
124
+ yield proc
125
+ finally:
126
+ kill_proc_gracefully(proc)
@@ -0,0 +1,39 @@
1
+ from logging import (
2
+ Logger,
3
+ )
4
+ from typing import (
5
+ Any,
6
+ Dict,
7
+ )
8
+
9
+
10
+ def print_header(logger: Logger, num_calls: int) -> None:
11
+ logger.info(
12
+ "|{:^26}|{:^20}|{:^20}|{:^20}|{:^20}|".format(
13
+ f"Method ({num_calls} calls)",
14
+ "HTTPProvider",
15
+ "AsyncHTTProvider",
16
+ "IPCProvider",
17
+ "WebSocketProvider",
18
+ )
19
+ )
20
+ logger.info("-" * 112)
21
+
22
+
23
+ def print_entry(
24
+ logger: Logger,
25
+ method_benchmarks: Dict[str, Any],
26
+ ) -> None:
27
+ logger.info(
28
+ "|{:^26}|{:^20.10}|{:^20.10}|{:^20.10}|{:^20.10}|".format(
29
+ method_benchmarks["name"],
30
+ method_benchmarks["HTTPProvider"],
31
+ method_benchmarks["AsyncHTTPProvider"],
32
+ method_benchmarks["IPCProvider"],
33
+ method_benchmarks["WebSocketProvider"],
34
+ )
35
+ )
36
+
37
+
38
+ def print_footer(logger: Logger) -> None:
39
+ logger.info("-" * 112)
@@ -0,0 +1,69 @@
1
+ import asyncio
2
+ import signal
3
+ import socket
4
+ import time
5
+ from typing import (
6
+ Any,
7
+ )
8
+
9
+ import aiohttp
10
+ import requests
11
+
12
+
13
+ def wait_for_socket(ipc_path: str, timeout: int = 30) -> None:
14
+ start = time.time()
15
+ while time.time() < start + timeout:
16
+ try:
17
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
18
+ sock.connect(ipc_path)
19
+ sock.settimeout(timeout)
20
+ except OSError:
21
+ time.sleep(0.01)
22
+ else:
23
+ break
24
+
25
+
26
+ def wait_for_http(endpoint_uri: str, timeout: int = 60) -> None:
27
+ start = time.time()
28
+ while time.time() < start + timeout:
29
+ try:
30
+ requests.get(endpoint_uri)
31
+ except requests.ConnectionError:
32
+ time.sleep(0.01)
33
+ else:
34
+ break
35
+
36
+
37
+ async def wait_for_aiohttp(endpoint_uri: str, timeout: int = 60) -> None:
38
+ start = time.time()
39
+ while time.time() < start + timeout:
40
+ try:
41
+ async with aiohttp.ClientSession() as session:
42
+ await session.get(endpoint_uri)
43
+ except aiohttp.client_exceptions.ClientConnectorError:
44
+ await asyncio.sleep(0.01)
45
+ else:
46
+ break
47
+
48
+
49
+ def wait_for_popen(proc: Any, timeout: int) -> None:
50
+ start = time.time()
51
+ while time.time() < start + timeout:
52
+ if proc.poll() is None:
53
+ time.sleep(0.01)
54
+ else:
55
+ break
56
+
57
+
58
+ def kill_proc_gracefully(proc: Any) -> None:
59
+ if proc.poll() is None:
60
+ proc.send_signal(signal.SIGINT)
61
+ wait_for_popen(proc, 13)
62
+
63
+ if proc.poll() is None:
64
+ proc.terminate()
65
+ wait_for_popen(proc, 5)
66
+
67
+ if proc.poll() is None:
68
+ proc.kill()
69
+ wait_for_popen(proc, 2)
web3/tracing.py CHANGED
@@ -53,10 +53,10 @@ class Tracing(Module):
53
53
  self._default_block = value
54
54
 
55
55
  def trace_replay_transaction_munger(
56
- self,
57
- block_identifier: Union[_Hash32, BlockIdentifier],
58
- mode: TraceMode = ["trace"],
56
+ self, block_identifier: Union[_Hash32, BlockIdentifier], mode: TraceMode = None
59
57
  ) -> Tuple[Union[BlockIdentifier, _Hash32], TraceMode]:
58
+ if mode is None:
59
+ mode = ["trace"]
60
60
  return (block_identifier, mode)
61
61
 
62
62
  trace_replay_transaction: Method[Callable[..., BlockTrace]] = Method(
@@ -86,9 +86,11 @@ class Tracing(Module):
86
86
  def trace_call_munger(
87
87
  self,
88
88
  transaction: TxParams,
89
- mode: TraceMode = ["trace"],
89
+ mode: TraceMode = None,
90
90
  block_identifier: Optional[BlockIdentifier] = None,
91
91
  ) -> Tuple[TxParams, TraceMode, BlockIdentifier]:
92
+ if mode is None:
93
+ mode = ["trace"]
92
94
  if "from" not in transaction and is_checksum_address(
93
95
  self.w3.eth.default_account
94
96
  ):
@@ -105,8 +107,10 @@ class Tracing(Module):
105
107
  )
106
108
 
107
109
  def trace_transactions_munger(
108
- self, raw_transaction: HexStr, mode: TraceMode = ["trace"]
110
+ self, raw_transaction: HexStr, mode: TraceMode = None
109
111
  ) -> Tuple[HexStr, TraceMode]:
112
+ if mode is None:
113
+ mode = ["trace"]
110
114
  return raw_transaction, mode
111
115
 
112
116
  trace_raw_transaction: Method[Callable[..., BlockTrace]] = Method(
web3/types.py CHANGED
@@ -5,10 +5,12 @@ from typing import (
5
5
  Coroutine,
6
6
  Dict,
7
7
  List,
8
+ Literal,
8
9
  NewType,
9
10
  Optional,
10
11
  Sequence,
11
12
  Type,
13
+ TypedDict,
12
14
  TypeVar,
13
15
  Union,
14
16
  )
@@ -25,9 +27,7 @@ from hexbytes import (
25
27
  )
26
28
 
27
29
  from web3._utils.compat import (
28
- Literal,
29
30
  NotRequired,
30
- TypedDict,
31
31
  )
32
32
  from web3._utils.function_identifiers import (
33
33
  FallbackFn,
@@ -135,6 +135,7 @@ TxData = TypedDict(
135
135
  "TxData",
136
136
  {
137
137
  "accessList": AccessList,
138
+ "blobVersionedHashes": Sequence[HexBytes],
138
139
  "blockHash": HexBytes,
139
140
  "blockNumber": BlockNumber,
140
141
  "chainId": int,
@@ -142,6 +143,7 @@ TxData = TypedDict(
142
143
  "from": ChecksumAddress,
143
144
  "gas": int,
144
145
  "gasPrice": Wei,
146
+ "maxFeePerBlobGas": Wei,
145
147
  "maxFeePerGas": Wei,
146
148
  "maxPriorityFeePerGas": Wei,
147
149
  "hash": HexBytes,
@@ -163,6 +165,8 @@ TxData = TypedDict(
163
165
  TxParams = TypedDict(
164
166
  "TxParams",
165
167
  {
168
+ "accessList": AccessList,
169
+ "blobVersionedHashes": Sequence[Union[str, HexStr, bytes, HexBytes]],
166
170
  "chainId": int,
167
171
  "data": Union[bytes, HexStr],
168
172
  # addr or ens
@@ -170,6 +174,7 @@ TxParams = TypedDict(
170
174
  "gas": int,
171
175
  # legacy pricing
172
176
  "gasPrice": Wei,
177
+ "maxFeePerBlobGas": Union[str, Wei],
173
178
  # dynamic fee pricing
174
179
  "maxFeePerGas": Union[str, Wei],
175
180
  "maxPriorityFeePerGas": Union[str, Wei],
@@ -183,15 +188,11 @@ TxParams = TypedDict(
183
188
  )
184
189
 
185
190
 
186
- WithdrawalData = TypedDict(
187
- "WithdrawalData",
188
- {
189
- "index": int,
190
- "validator_index": int,
191
- "address": ChecksumAddress,
192
- "amount": Gwei,
193
- },
194
- )
191
+ class WithdrawalData(TypedDict):
192
+ index: int
193
+ validator_index: int
194
+ address: ChecksumAddress
195
+ amount: Gwei
195
196
 
196
197
 
197
198
  class BlockData(TypedDict, total=False):
@@ -218,6 +219,9 @@ class BlockData(TypedDict, total=False):
218
219
  uncles: Sequence[HexBytes]
219
220
  withdrawals: Sequence[WithdrawalData]
220
221
  withdrawalsRoot: HexBytes
222
+ parentBeaconBlockRoot: HexBytes
223
+ blobGasUsed: int
224
+ excessBlobGas: int
221
225
 
222
226
  # ExtraDataToPOAMiddleware replaces extraData w/ proofOfAuthorityData
223
227
  proofOfAuthorityData: HexBytes
@@ -338,17 +342,12 @@ class FeeHistory(TypedDict):
338
342
  reward: List[List[Wei]]
339
343
 
340
344
 
341
- StateOverrideParams = TypedDict(
342
- "StateOverrideParams",
343
- {
344
- "balance": Optional[Wei],
345
- "nonce": Optional[int],
346
- "code": Optional[Union[bytes, HexStr]],
347
- "state": Optional[Dict[HexStr, HexStr]],
348
- "stateDiff": Optional[Dict[HexStr, HexStr]],
349
- },
350
- total=False,
351
- )
345
+ class StateOverrideParams(TypedDict, total=False):
346
+ balance: Optional[Wei]
347
+ nonce: Optional[int]
348
+ code: Optional[Union[bytes, HexStr]]
349
+ state: Optional[Dict[HexStr, HexStr]]
350
+ stateDiff: Optional[Dict[HexStr, HexStr]]
352
351
 
353
352
 
354
353
  StateOverride = Dict[ChecksumAddress, StateOverrideParams]
@@ -381,6 +380,8 @@ TxReceipt = TypedDict(
381
380
  },
382
381
  )
383
382
 
383
+ BlockReceipts = List[TxReceipt]
384
+
384
385
 
385
386
  class SignedTx(TypedDict, total=False):
386
387
  raw: bytes
web3/utils/caching.py CHANGED
@@ -16,22 +16,20 @@ class SimpleCache:
16
16
  self._data: OrderedDict[str, Any] = OrderedDict()
17
17
 
18
18
  def cache(self, key: str, value: Any) -> Tuple[Any, Dict[str, Any]]:
19
- evicted_items = None
19
+ evicted_items = {}
20
20
  # If the key is already in the OrderedDict just update it
21
21
  # and don't evict any values. Ideally, we could still check to see
22
22
  # if there are too many items in the OrderedDict but that may rearrange
23
23
  # the order it should be unlikely that the size could grow over the limit
24
24
  if key not in self._data:
25
25
  while len(self._data) >= self._size:
26
- if evicted_items is None:
27
- evicted_items = {}
28
26
  k, v = self._data.popitem(last=False)
29
27
  evicted_items[k] = v
30
28
  self._data[key] = value
31
29
 
32
30
  # Return the cached value along with the evicted items at the same time. No
33
31
  # need to reach back into the cache to grab the value.
34
- return value, evicted_items
32
+ return value, evicted_items or None
35
33
 
36
34
  def get_cache_entry(self, key: str) -> Optional[Any]:
37
35
  return self._data[key] if key in self._data else None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: web3
3
- Version: 7.0.0b2
3
+ Version: 7.0.0b4
4
4
  Summary: web3.py
5
5
  Home-page: https://github.com/ethereum/web3.py
6
6
  Author: The Ethereum Foundation
@@ -20,12 +20,12 @@ Requires-Python: >=3.8
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
22
  Requires-Dist: aiohttp >=3.7.4.post0
23
- Requires-Dist: eth-abi >=4.0.0
24
- Requires-Dist: eth-account >=0.8.0
23
+ Requires-Dist: eth-abi >=5.0.1
24
+ Requires-Dist: eth-account >=0.12.0
25
25
  Requires-Dist: eth-hash[pycryptodome] >=0.5.1
26
- Requires-Dist: eth-typing >=3.0.0
26
+ Requires-Dist: eth-typing >=4.0.0
27
27
  Requires-Dist: eth-utils >=4.0.0
28
- Requires-Dist: hexbytes <0.4.0,>=0.1.0
28
+ Requires-Dist: hexbytes >=1.2.0
29
29
  Requires-Dist: pydantic >=2.4.0
30
30
  Requires-Dist: requests >=2.16.0
31
31
  Requires-Dist: typing-extensions >=4.0.1
@@ -33,44 +33,31 @@ Requires-Dist: websockets >=10.0.0
33
33
  Requires-Dist: pyunormalize >=15.0.0
34
34
  Requires-Dist: pywin32 >=223 ; platform_system == "Windows"
35
35
  Provides-Extra: dev
36
- Requires-Dist: eth-tester[py-evm] ==v0.10.0-b.3 ; extra == 'dev'
36
+ Requires-Dist: eth-tester[py-evm] <0.12.0b1,>=0.11.0b1 ; extra == 'dev'
37
37
  Requires-Dist: py-geth >=4.1.0 ; extra == 'dev'
38
- Requires-Dist: black >=22.1.0 ; extra == 'dev'
39
- Requires-Dist: flake8 ==3.8.3 ; extra == 'dev'
40
- Requires-Dist: isort >=5.11.0 ; extra == 'dev'
41
- Requires-Dist: mypy ==1.4.1 ; extra == 'dev'
42
- Requires-Dist: types-setuptools >=57.4.4 ; extra == 'dev'
43
- Requires-Dist: types-requests >=2.26.1 ; extra == 'dev'
44
38
  Requires-Dist: sphinx >=5.3.0 ; extra == 'dev'
45
39
  Requires-Dist: sphinx-rtd-theme >=1.0.0 ; extra == 'dev'
46
40
  Requires-Dist: towncrier <22,>=21 ; extra == 'dev'
41
+ Requires-Dist: build >=0.9.0 ; extra == 'dev'
47
42
  Requires-Dist: bumpversion ; extra == 'dev'
48
43
  Requires-Dist: flaky >=3.7.0 ; extra == 'dev'
49
44
  Requires-Dist: hypothesis >=3.31.2 ; extra == 'dev'
50
- Requires-Dist: pytest >=7.0.0 ; extra == 'dev'
45
+ Requires-Dist: pre-commit >=3.4.0 ; extra == 'dev'
51
46
  Requires-Dist: pytest-asyncio <0.23,>=0.18.1 ; extra == 'dev'
52
47
  Requires-Dist: pytest-mock >=1.10 ; extra == 'dev'
53
48
  Requires-Dist: pytest-watch >=4.2 ; extra == 'dev'
54
49
  Requires-Dist: pytest-xdist >=1.29 ; extra == 'dev'
50
+ Requires-Dist: pytest >=7.0.0 ; extra == 'dev'
55
51
  Requires-Dist: setuptools >=38.6.0 ; extra == 'dev'
56
52
  Requires-Dist: tox >=3.18.0 ; extra == 'dev'
57
53
  Requires-Dist: tqdm >4.32 ; extra == 'dev'
58
54
  Requires-Dist: twine >=1.13 ; extra == 'dev'
59
- Requires-Dist: build >=0.9.0 ; extra == 'dev'
60
- Requires-Dist: importlib-metadata <5.0 ; (python_version < "3.8") and extra == 'dev'
61
55
  Provides-Extra: docs
62
56
  Requires-Dist: sphinx >=5.3.0 ; extra == 'docs'
63
57
  Requires-Dist: sphinx-rtd-theme >=1.0.0 ; extra == 'docs'
64
58
  Requires-Dist: towncrier <22,>=21 ; extra == 'docs'
65
- Provides-Extra: linter
66
- Requires-Dist: black >=22.1.0 ; extra == 'linter'
67
- Requires-Dist: flake8 ==3.8.3 ; extra == 'linter'
68
- Requires-Dist: isort >=5.11.0 ; extra == 'linter'
69
- Requires-Dist: mypy ==1.4.1 ; extra == 'linter'
70
- Requires-Dist: types-setuptools >=57.4.4 ; extra == 'linter'
71
- Requires-Dist: types-requests >=2.26.1 ; extra == 'linter'
72
59
  Provides-Extra: tester
73
- Requires-Dist: eth-tester[py-evm] ==v0.10.0-b.3 ; extra == 'tester'
60
+ Requires-Dist: eth-tester[py-evm] <0.12.0b1,>=0.11.0b1 ; extra == 'tester'
74
61
  Requires-Dist: py-geth >=4.1.0 ; extra == 'tester'
75
62
 
76
63
  # web3.py
@@ -81,9 +68,9 @@ Requires-Dist: py-geth >=4.1.0 ; extra == 'tester'
81
68
 
82
69
  A Python library for interacting with Ethereum.
83
70
 
84
- - Python 3.8+ support
71
+ - Python 3.8+ support
85
72
 
86
- ---
73
+ ______________________________________________________________________
87
74
 
88
75
  ## Quickstart
89
76
 
@@ -101,6 +88,6 @@ guidelines for [contributing](https://web3py.readthedocs.io/en/latest/contributi
101
88
  then check out issues that are labeled
102
89
  [Good First Issue](https://github.com/ethereum/web3.py/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+First+Issue%22).
103
90
 
104
- ---
91
+ ______________________________________________________________________
105
92
 
106
93
  #### Questions on implementation or usage? Join the conversation on [discord](https://discord.gg/GHryRvPB84).