web3 7.0.0b4__py3-none-any.whl → 7.0.0b6__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.
- web3/_utils/batching.py +217 -0
- web3/_utils/caching.py +26 -2
- web3/_utils/compat/__init__.py +1 -0
- web3/_utils/contracts.py +5 -5
- web3/_utils/events.py +20 -20
- web3/_utils/filters.py +6 -6
- web3/_utils/method_formatters.py +0 -23
- web3/_utils/module_testing/__init__.py +0 -3
- web3/_utils/module_testing/eth_module.py +442 -373
- web3/_utils/module_testing/module_testing_utils.py +13 -0
- web3/_utils/module_testing/web3_module.py +438 -17
- web3/_utils/rpc_abi.py +0 -18
- web3/contract/async_contract.py +11 -11
- web3/contract/base_contract.py +19 -18
- web3/contract/contract.py +13 -13
- web3/contract/utils.py +112 -4
- web3/eth/async_eth.py +10 -8
- web3/eth/eth.py +7 -6
- web3/exceptions.py +75 -21
- web3/gas_strategies/time_based.py +2 -2
- web3/geth.py +0 -188
- web3/main.py +21 -13
- web3/manager.py +237 -74
- web3/method.py +29 -9
- web3/middleware/base.py +43 -0
- web3/middleware/filter.py +18 -6
- web3/middleware/signing.py +2 -2
- web3/module.py +47 -7
- web3/providers/async_base.py +55 -23
- web3/providers/base.py +59 -26
- web3/providers/eth_tester/defaults.py +0 -48
- web3/providers/eth_tester/main.py +36 -11
- web3/providers/eth_tester/middleware.py +3 -8
- web3/providers/ipc.py +23 -8
- web3/providers/legacy_websocket.py +26 -1
- web3/providers/persistent/async_ipc.py +60 -76
- web3/providers/persistent/persistent.py +134 -10
- web3/providers/persistent/request_processor.py +98 -14
- web3/providers/persistent/websocket.py +43 -66
- web3/providers/rpc/async_rpc.py +20 -2
- web3/providers/rpc/rpc.py +22 -2
- web3/providers/rpc/utils.py +1 -10
- web3/tools/benchmark/node.py +2 -8
- web3/types.py +8 -2
- {web3-7.0.0b4.dist-info → web3-7.0.0b6.dist-info}/LICENSE +1 -1
- {web3-7.0.0b4.dist-info → web3-7.0.0b6.dist-info}/METADATA +32 -21
- {web3-7.0.0b4.dist-info → web3-7.0.0b6.dist-info}/RECORD +49 -49
- web3/_utils/module_testing/go_ethereum_personal_module.py +0 -300
- {web3-7.0.0b4.dist-info → web3-7.0.0b6.dist-info}/WHEEL +0 -0
- {web3-7.0.0b4.dist-info → web3-7.0.0b6.dist-info}/top_level.txt +0 -0
|
@@ -5,8 +5,11 @@ import os
|
|
|
5
5
|
from typing import (
|
|
6
6
|
Any,
|
|
7
7
|
Dict,
|
|
8
|
+
List,
|
|
8
9
|
Optional,
|
|
10
|
+
Tuple,
|
|
9
11
|
Union,
|
|
12
|
+
cast,
|
|
10
13
|
)
|
|
11
14
|
|
|
12
15
|
from eth_typing import (
|
|
@@ -25,6 +28,10 @@ from websockets.exceptions import (
|
|
|
25
28
|
WebSocketException,
|
|
26
29
|
)
|
|
27
30
|
|
|
31
|
+
from web3._utils.batching import (
|
|
32
|
+
BATCH_REQUEST_ID,
|
|
33
|
+
sort_batch_response_by_response_ids,
|
|
34
|
+
)
|
|
28
35
|
from web3._utils.caching import (
|
|
29
36
|
async_handle_request_caching,
|
|
30
37
|
)
|
|
@@ -61,7 +68,6 @@ class WebSocketProvider(PersistentConnectionProvider):
|
|
|
61
68
|
logger = logging.getLogger("web3.providers.WebSocketProvider")
|
|
62
69
|
is_async: bool = True
|
|
63
70
|
|
|
64
|
-
_max_connection_retries: int = 5
|
|
65
71
|
_ws: Optional[WebSocketClientProtocol] = None
|
|
66
72
|
|
|
67
73
|
def __init__(
|
|
@@ -116,47 +122,13 @@ class WebSocketProvider(PersistentConnectionProvider):
|
|
|
116
122
|
) from e
|
|
117
123
|
return False
|
|
118
124
|
|
|
119
|
-
async def
|
|
120
|
-
|
|
121
|
-
_backoff_rate_change = 1.75
|
|
122
|
-
_backoff_time = 1.75
|
|
123
|
-
|
|
124
|
-
while _connection_attempts != self._max_connection_retries:
|
|
125
|
-
try:
|
|
126
|
-
_connection_attempts += 1
|
|
127
|
-
self._ws = await connect(self.endpoint_uri, **self.websocket_kwargs)
|
|
128
|
-
self._message_listener_task = asyncio.create_task(
|
|
129
|
-
self._message_listener()
|
|
130
|
-
)
|
|
131
|
-
break
|
|
132
|
-
except WebSocketException as e:
|
|
133
|
-
if _connection_attempts == self._max_connection_retries:
|
|
134
|
-
raise ProviderConnectionError(
|
|
135
|
-
f"Could not connect to endpoint: {self.endpoint_uri}. "
|
|
136
|
-
f"Retries exceeded max of {self._max_connection_retries}."
|
|
137
|
-
) from e
|
|
138
|
-
self.logger.info(
|
|
139
|
-
f"Could not connect to endpoint: {self.endpoint_uri}. Retrying in "
|
|
140
|
-
f"{round(_backoff_time, 1)} seconds.",
|
|
141
|
-
exc_info=True,
|
|
142
|
-
)
|
|
143
|
-
await asyncio.sleep(_backoff_time)
|
|
144
|
-
_backoff_time *= _backoff_rate_change
|
|
125
|
+
async def _provider_specific_connect(self) -> None:
|
|
126
|
+
self._ws = await connect(self.endpoint_uri, **self.websocket_kwargs)
|
|
145
127
|
|
|
146
|
-
async def
|
|
128
|
+
async def _provider_specific_disconnect(self) -> None:
|
|
147
129
|
if self._ws is not None and not self._ws.closed:
|
|
148
130
|
await self._ws.close()
|
|
149
131
|
self._ws = None
|
|
150
|
-
self.logger.debug(
|
|
151
|
-
f'Successfully disconnected from endpoint: "{self.endpoint_uri}'
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
try:
|
|
155
|
-
self._message_listener_task.cancel()
|
|
156
|
-
await self._message_listener_task
|
|
157
|
-
except (asyncio.CancelledError, StopAsyncIteration):
|
|
158
|
-
pass
|
|
159
|
-
self._request_processor.clear_caches()
|
|
160
132
|
|
|
161
133
|
@async_handle_request_caching
|
|
162
134
|
async def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
|
|
@@ -176,34 +148,39 @@ class WebSocketProvider(PersistentConnectionProvider):
|
|
|
176
148
|
|
|
177
149
|
return response
|
|
178
150
|
|
|
179
|
-
async def
|
|
180
|
-
self
|
|
181
|
-
|
|
182
|
-
|
|
151
|
+
async def make_batch_request(
|
|
152
|
+
self, requests: List[Tuple[RPCEndpoint, Any]]
|
|
153
|
+
) -> List[RPCResponse]:
|
|
154
|
+
request_data = self.encode_batch_rpc_request(requests)
|
|
155
|
+
|
|
156
|
+
if self._ws is None:
|
|
157
|
+
raise ProviderConnectionError(
|
|
158
|
+
"Connection to websocket has not been initiated for the provider."
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
await asyncio.wait_for(
|
|
162
|
+
self._ws.send(request_data), timeout=self.request_timeout
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
response = cast(
|
|
166
|
+
List[RPCResponse],
|
|
167
|
+
await self._get_response_for_request_id(BATCH_REQUEST_ID),
|
|
183
168
|
)
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
169
|
+
return response
|
|
170
|
+
|
|
171
|
+
async def _provider_specific_message_listener(self) -> None:
|
|
172
|
+
async for raw_message in self._ws:
|
|
187
173
|
await asyncio.sleep(0)
|
|
188
174
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
for task in asyncio.all_tasks(loop=loop):
|
|
202
|
-
task.cancel()
|
|
203
|
-
raise e
|
|
204
|
-
|
|
205
|
-
self.logger.error(
|
|
206
|
-
"Exception caught in listener, error logging and keeping "
|
|
207
|
-
"listener background task alive."
|
|
208
|
-
f"\n error={e.__class__.__name__}: {e}"
|
|
209
|
-
)
|
|
175
|
+
response = json.loads(raw_message)
|
|
176
|
+
if isinstance(response, list):
|
|
177
|
+
response = sort_batch_response_by_response_ids(response)
|
|
178
|
+
|
|
179
|
+
subscription = (
|
|
180
|
+
response.get("method") == "eth_subscription"
|
|
181
|
+
if not isinstance(response, list)
|
|
182
|
+
else False
|
|
183
|
+
)
|
|
184
|
+
await self._request_processor.cache_raw_response(
|
|
185
|
+
response, subscription=subscription
|
|
186
|
+
)
|
web3/providers/rpc/async_rpc.py
CHANGED
|
@@ -4,9 +4,11 @@ from typing import (
|
|
|
4
4
|
Any,
|
|
5
5
|
Dict,
|
|
6
6
|
Iterable,
|
|
7
|
+
List,
|
|
7
8
|
Optional,
|
|
8
9
|
Tuple,
|
|
9
10
|
Union,
|
|
11
|
+
cast,
|
|
10
12
|
)
|
|
11
13
|
|
|
12
14
|
from aiohttp import (
|
|
@@ -37,6 +39,9 @@ from web3.types import (
|
|
|
37
39
|
RPCResponse,
|
|
38
40
|
)
|
|
39
41
|
|
|
42
|
+
from ..._utils.batching import (
|
|
43
|
+
sort_batch_response_by_response_ids,
|
|
44
|
+
)
|
|
40
45
|
from ..._utils.caching import (
|
|
41
46
|
async_handle_request_caching,
|
|
42
47
|
)
|
|
@@ -61,6 +66,7 @@ class AsyncHTTPProvider(AsyncJSONBaseProvider):
|
|
|
61
66
|
exception_retry_configuration: Union[
|
|
62
67
|
ExceptionRetryConfiguration, Empty
|
|
63
68
|
] = empty,
|
|
69
|
+
**kwargs: Any,
|
|
64
70
|
) -> None:
|
|
65
71
|
if endpoint_uri is None:
|
|
66
72
|
self.endpoint_uri = get_default_http_endpoint()
|
|
@@ -70,7 +76,7 @@ class AsyncHTTPProvider(AsyncJSONBaseProvider):
|
|
|
70
76
|
self._request_kwargs = request_kwargs or {}
|
|
71
77
|
self._exception_retry_configuration = exception_retry_configuration
|
|
72
78
|
|
|
73
|
-
super().__init__()
|
|
79
|
+
super().__init__(**kwargs)
|
|
74
80
|
|
|
75
81
|
async def cache_async_session(self, session: ClientSession) -> ClientSession:
|
|
76
82
|
return await _async_cache_and_return_session(self.endpoint_uri, session)
|
|
@@ -123,7 +129,7 @@ class AsyncHTTPProvider(AsyncJSONBaseProvider):
|
|
|
123
129
|
except tuple(self.exception_retry_configuration.errors):
|
|
124
130
|
if i < self.exception_retry_configuration.retries - 1:
|
|
125
131
|
await asyncio.sleep(
|
|
126
|
-
self.exception_retry_configuration.backoff_factor
|
|
132
|
+
self.exception_retry_configuration.backoff_factor * 2**i
|
|
127
133
|
)
|
|
128
134
|
continue
|
|
129
135
|
else:
|
|
@@ -147,3 +153,15 @@ class AsyncHTTPProvider(AsyncJSONBaseProvider):
|
|
|
147
153
|
f"Method: {method}, Response: {response}"
|
|
148
154
|
)
|
|
149
155
|
return response
|
|
156
|
+
|
|
157
|
+
async def make_batch_request(
|
|
158
|
+
self, batch_requests: List[Tuple[RPCEndpoint, Any]]
|
|
159
|
+
) -> List[RPCResponse]:
|
|
160
|
+
self.logger.debug(f"Making batch request HTTP - uri: `{self.endpoint_uri}`")
|
|
161
|
+
request_data = self.encode_batch_rpc_request(batch_requests)
|
|
162
|
+
raw_response = await async_make_post_request(
|
|
163
|
+
self.endpoint_uri, request_data, **self.get_request_kwargs()
|
|
164
|
+
)
|
|
165
|
+
self.logger.debug("Received batch response HTTP.")
|
|
166
|
+
responses_list = cast(List[RPCResponse], self.decode_rpc_response(raw_response))
|
|
167
|
+
return sort_batch_response_by_response_ids(responses_list)
|
web3/providers/rpc/rpc.py
CHANGED
|
@@ -5,9 +5,11 @@ from typing import (
|
|
|
5
5
|
Any,
|
|
6
6
|
Dict,
|
|
7
7
|
Iterable,
|
|
8
|
+
List,
|
|
8
9
|
Optional,
|
|
9
10
|
Tuple,
|
|
10
11
|
Union,
|
|
12
|
+
cast,
|
|
11
13
|
)
|
|
12
14
|
|
|
13
15
|
from eth_typing import (
|
|
@@ -35,6 +37,9 @@ from web3.types import (
|
|
|
35
37
|
RPCResponse,
|
|
36
38
|
)
|
|
37
39
|
|
|
40
|
+
from ..._utils.batching import (
|
|
41
|
+
sort_batch_response_by_response_ids,
|
|
42
|
+
)
|
|
38
43
|
from ..._utils.caching import (
|
|
39
44
|
handle_request_caching,
|
|
40
45
|
)
|
|
@@ -65,6 +70,7 @@ class HTTPProvider(JSONBaseProvider):
|
|
|
65
70
|
exception_retry_configuration: Union[
|
|
66
71
|
ExceptionRetryConfiguration, Empty
|
|
67
72
|
] = empty,
|
|
73
|
+
**kwargs: Any,
|
|
68
74
|
) -> None:
|
|
69
75
|
if endpoint_uri is None:
|
|
70
76
|
self.endpoint_uri = get_default_http_endpoint()
|
|
@@ -77,7 +83,7 @@ class HTTPProvider(JSONBaseProvider):
|
|
|
77
83
|
if session:
|
|
78
84
|
cache_and_return_session(self.endpoint_uri, session)
|
|
79
85
|
|
|
80
|
-
super().__init__()
|
|
86
|
+
super().__init__(**kwargs)
|
|
81
87
|
|
|
82
88
|
def __str__(self) -> str:
|
|
83
89
|
return f"RPC connection {self.endpoint_uri}"
|
|
@@ -130,7 +136,9 @@ class HTTPProvider(JSONBaseProvider):
|
|
|
130
136
|
)
|
|
131
137
|
except tuple(self.exception_retry_configuration.errors) as e:
|
|
132
138
|
if i < self.exception_retry_configuration.retries - 1:
|
|
133
|
-
time.sleep(
|
|
139
|
+
time.sleep(
|
|
140
|
+
self.exception_retry_configuration.backoff_factor * 2**i
|
|
141
|
+
)
|
|
134
142
|
continue
|
|
135
143
|
else:
|
|
136
144
|
raise e
|
|
@@ -153,3 +161,15 @@ class HTTPProvider(JSONBaseProvider):
|
|
|
153
161
|
f"Method: {method}, Response: {response}"
|
|
154
162
|
)
|
|
155
163
|
return response
|
|
164
|
+
|
|
165
|
+
def make_batch_request(
|
|
166
|
+
self, batch_requests: List[Tuple[RPCEndpoint, Any]]
|
|
167
|
+
) -> List[RPCResponse]:
|
|
168
|
+
self.logger.debug(f"Making batch request HTTP, uri: `{self.endpoint_uri}`")
|
|
169
|
+
request_data = self.encode_batch_rpc_request(batch_requests)
|
|
170
|
+
raw_response = make_post_request(
|
|
171
|
+
self.endpoint_uri, request_data, **self.get_request_kwargs()
|
|
172
|
+
)
|
|
173
|
+
self.logger.debug("Received batch response HTTP.")
|
|
174
|
+
responses_list = cast(List[RPCResponse], self.decode_rpc_response(raw_response))
|
|
175
|
+
return sort_batch_response_by_response_ids(responses_list)
|
web3/providers/rpc/utils.py
CHANGED
|
@@ -58,15 +58,6 @@ REQUEST_RETRY_ALLOWLIST = [
|
|
|
58
58
|
"eth_sign",
|
|
59
59
|
"eth_signTypedData",
|
|
60
60
|
"eth_sendRawTransaction",
|
|
61
|
-
"personal_importRawKey",
|
|
62
|
-
"personal_newAccount",
|
|
63
|
-
"personal_listAccounts",
|
|
64
|
-
"personal_listWallets",
|
|
65
|
-
"personal_lockAccount",
|
|
66
|
-
"personal_unlockAccount",
|
|
67
|
-
"personal_ecRecover",
|
|
68
|
-
"personal_sign",
|
|
69
|
-
"personal_signTypedData",
|
|
70
61
|
]
|
|
71
62
|
|
|
72
63
|
|
|
@@ -93,7 +84,7 @@ class ExceptionRetryConfiguration(BaseModel):
|
|
|
93
84
|
self,
|
|
94
85
|
errors: Sequence[Type[BaseException]] = None,
|
|
95
86
|
retries: int = 5,
|
|
96
|
-
backoff_factor: float = 0.
|
|
87
|
+
backoff_factor: float = 0.125,
|
|
97
88
|
method_allowlist: Sequence[str] = None,
|
|
98
89
|
):
|
|
99
90
|
super().__init__(
|
web3/tools/benchmark/node.py
CHANGED
|
@@ -24,10 +24,7 @@ from web3.tools.benchmark.utils import (
|
|
|
24
24
|
kill_proc_gracefully,
|
|
25
25
|
)
|
|
26
26
|
|
|
27
|
-
GETH_FIXTURE_ZIP = "geth-1.13.
|
|
28
|
-
|
|
29
|
-
# use same coinbase value as in `web3.py/tests/integration/generate_fixtures/common.py`
|
|
30
|
-
COINBASE = "0xdc544d1aa88ff8bbd2f2aec754b1f1e99e1812fd"
|
|
27
|
+
GETH_FIXTURE_ZIP = "geth-1.13.14-fixture.zip"
|
|
31
28
|
|
|
32
29
|
|
|
33
30
|
class GethBenchmarkFixture:
|
|
@@ -84,7 +81,7 @@ class GethBenchmarkFixture:
|
|
|
84
81
|
"--dev.period",
|
|
85
82
|
"100",
|
|
86
83
|
"--datadir",
|
|
87
|
-
|
|
84
|
+
datadir,
|
|
88
85
|
"--nodiscover",
|
|
89
86
|
"--http",
|
|
90
87
|
"--http.port",
|
|
@@ -92,9 +89,6 @@ class GethBenchmarkFixture:
|
|
|
92
89
|
"--http.api",
|
|
93
90
|
"admin,eth,net,web3",
|
|
94
91
|
"--ipcdisable",
|
|
95
|
-
"--allow-insecure-unlock",
|
|
96
|
-
"--miner.etherbase",
|
|
97
|
-
COINBASE[2:],
|
|
98
92
|
"--password",
|
|
99
93
|
os.path.join(datadir, "keystore", "pw.txt"),
|
|
100
94
|
)
|
web3/types.py
CHANGED
|
@@ -9,6 +9,7 @@ from typing import (
|
|
|
9
9
|
NewType,
|
|
10
10
|
Optional,
|
|
11
11
|
Sequence,
|
|
12
|
+
Tuple,
|
|
12
13
|
Type,
|
|
13
14
|
TypedDict,
|
|
14
15
|
TypeVar,
|
|
@@ -43,8 +44,9 @@ if TYPE_CHECKING:
|
|
|
43
44
|
)
|
|
44
45
|
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
TFunc = TypeVar("TFunc", bound=Callable[..., Any])
|
|
47
48
|
TParams = TypeVar("TParams")
|
|
49
|
+
TReturn = TypeVar("TReturn")
|
|
48
50
|
TValue = TypeVar("TValue")
|
|
49
51
|
|
|
50
52
|
BlockParams = Literal["latest", "earliest", "pending", "safe", "finalized"]
|
|
@@ -295,7 +297,7 @@ RPCId = Optional[Union[int, str]]
|
|
|
295
297
|
|
|
296
298
|
|
|
297
299
|
class RPCResponse(TypedDict, total=False):
|
|
298
|
-
error:
|
|
300
|
+
error: RPCError
|
|
299
301
|
id: RPCId
|
|
300
302
|
jsonrpc: Literal["2.0"]
|
|
301
303
|
result: Any
|
|
@@ -318,7 +320,11 @@ class CreateAccessListResponse(TypedDict):
|
|
|
318
320
|
|
|
319
321
|
|
|
320
322
|
MakeRequestFn = Callable[[RPCEndpoint, Any], RPCResponse]
|
|
323
|
+
MakeBatchRequestFn = Callable[[List[Tuple[RPCEndpoint, Any]]], List[RPCResponse]]
|
|
321
324
|
AsyncMakeRequestFn = Callable[[RPCEndpoint, Any], Coroutine[Any, Any, RPCResponse]]
|
|
325
|
+
AsyncMakeBatchRequestFn = Callable[
|
|
326
|
+
[List[Tuple[RPCEndpoint, Any]]], Coroutine[Any, Any, List[RPCResponse]]
|
|
327
|
+
]
|
|
322
328
|
|
|
323
329
|
|
|
324
330
|
class FormattersDict(TypedDict, total=False):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2016 The Ethereum Foundation
|
|
3
|
+
Copyright (c) 2016-2024 The Ethereum Foundation
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: web3
|
|
3
|
-
Version: 7.0.
|
|
4
|
-
Summary: web3
|
|
3
|
+
Version: 7.0.0b6
|
|
4
|
+
Summary: web3: A Python library for interacting with Ethereum
|
|
5
5
|
Home-page: https://github.com/ethereum/web3.py
|
|
6
6
|
Author: The Ethereum Foundation
|
|
7
7
|
Author-email: snakecharmers@ethereum.org
|
|
@@ -16,12 +16,13 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.9
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
-
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Requires-Python: >=3.8, <4
|
|
20
21
|
Description-Content-Type: text/markdown
|
|
21
22
|
License-File: LICENSE
|
|
22
23
|
Requires-Dist: aiohttp >=3.7.4.post0
|
|
23
24
|
Requires-Dist: eth-abi >=5.0.1
|
|
24
|
-
Requires-Dist: eth-account >=0.12.
|
|
25
|
+
Requires-Dist: eth-account >=0.12.2
|
|
25
26
|
Requires-Dist: eth-hash[pycryptodome] >=0.5.1
|
|
26
27
|
Requires-Dist: eth-typing >=4.0.0
|
|
27
28
|
Requires-Dist: eth-utils >=4.0.0
|
|
@@ -33,38 +34,48 @@ Requires-Dist: websockets >=10.0.0
|
|
|
33
34
|
Requires-Dist: pyunormalize >=15.0.0
|
|
34
35
|
Requires-Dist: pywin32 >=223 ; platform_system == "Windows"
|
|
35
36
|
Provides-Extra: dev
|
|
36
|
-
Requires-Dist: eth-tester[py-evm] <0.12.0b1,>=0.11.0b1 ; extra == 'dev'
|
|
37
|
-
Requires-Dist: py-geth >=4.1.0 ; extra == 'dev'
|
|
38
|
-
Requires-Dist: sphinx >=5.3.0 ; extra == 'dev'
|
|
39
|
-
Requires-Dist: sphinx-rtd-theme >=1.0.0 ; extra == 'dev'
|
|
40
|
-
Requires-Dist: towncrier <22,>=21 ; extra == 'dev'
|
|
41
37
|
Requires-Dist: build >=0.9.0 ; extra == 'dev'
|
|
42
|
-
Requires-Dist: bumpversion ; extra == 'dev'
|
|
38
|
+
Requires-Dist: bumpversion >=0.5.3 ; extra == 'dev'
|
|
43
39
|
Requires-Dist: flaky >=3.7.0 ; extra == 'dev'
|
|
44
40
|
Requires-Dist: hypothesis >=3.31.2 ; extra == 'dev'
|
|
41
|
+
Requires-Dist: ipython ; extra == 'dev'
|
|
45
42
|
Requires-Dist: pre-commit >=3.4.0 ; extra == 'dev'
|
|
46
|
-
Requires-Dist: pytest-asyncio <0.23,>=0.
|
|
43
|
+
Requires-Dist: pytest-asyncio <0.23,>=0.21.2 ; extra == 'dev'
|
|
47
44
|
Requires-Dist: pytest-mock >=1.10 ; extra == 'dev'
|
|
48
|
-
Requires-Dist: pytest-watch >=4.2 ; extra == 'dev'
|
|
49
|
-
Requires-Dist: pytest-xdist >=1.29 ; extra == 'dev'
|
|
50
|
-
Requires-Dist: pytest >=7.0.0 ; extra == 'dev'
|
|
51
45
|
Requires-Dist: setuptools >=38.6.0 ; extra == 'dev'
|
|
52
|
-
Requires-Dist: tox >=
|
|
46
|
+
Requires-Dist: tox >=4.0.0 ; extra == 'dev'
|
|
53
47
|
Requires-Dist: tqdm >4.32 ; extra == 'dev'
|
|
54
48
|
Requires-Dist: twine >=1.13 ; extra == 'dev'
|
|
49
|
+
Requires-Dist: wheel ; extra == 'dev'
|
|
50
|
+
Requires-Dist: sphinx >=6.0.0 ; extra == 'dev'
|
|
51
|
+
Requires-Dist: sphinx-autobuild >=2021.3.14 ; extra == 'dev'
|
|
52
|
+
Requires-Dist: sphinx-rtd-theme >=1.0.0 ; extra == 'dev'
|
|
53
|
+
Requires-Dist: towncrier <22,>=21 ; extra == 'dev'
|
|
54
|
+
Requires-Dist: eth-tester[py-evm] <0.12.0b1,>=0.11.0b1 ; extra == 'dev'
|
|
55
|
+
Requires-Dist: py-geth >=4.1.0 ; extra == 'dev'
|
|
56
|
+
Requires-Dist: pytest-asyncio <0.23,>=0.18.1 ; extra == 'dev'
|
|
57
|
+
Requires-Dist: pytest-xdist >=2.4.0 ; extra == 'dev'
|
|
58
|
+
Requires-Dist: pytest >=7.0.0 ; extra == 'dev'
|
|
55
59
|
Provides-Extra: docs
|
|
56
|
-
Requires-Dist: sphinx >=
|
|
60
|
+
Requires-Dist: sphinx >=6.0.0 ; extra == 'docs'
|
|
61
|
+
Requires-Dist: sphinx-autobuild >=2021.3.14 ; extra == 'docs'
|
|
57
62
|
Requires-Dist: sphinx-rtd-theme >=1.0.0 ; extra == 'docs'
|
|
58
63
|
Requires-Dist: towncrier <22,>=21 ; extra == 'docs'
|
|
59
|
-
Provides-Extra:
|
|
60
|
-
Requires-Dist: eth-tester[py-evm] <0.12.0b1,>=0.11.0b1 ; extra == '
|
|
61
|
-
Requires-Dist: py-geth >=4.1.0 ; extra == '
|
|
64
|
+
Provides-Extra: test
|
|
65
|
+
Requires-Dist: eth-tester[py-evm] <0.12.0b1,>=0.11.0b1 ; extra == 'test'
|
|
66
|
+
Requires-Dist: py-geth >=4.1.0 ; extra == 'test'
|
|
67
|
+
Requires-Dist: pytest-asyncio <0.23,>=0.18.1 ; extra == 'test'
|
|
68
|
+
Requires-Dist: pytest-mock >=1.10 ; extra == 'test'
|
|
69
|
+
Requires-Dist: pytest-xdist >=2.4.0 ; extra == 'test'
|
|
70
|
+
Requires-Dist: pytest >=7.0.0 ; extra == 'test'
|
|
62
71
|
|
|
63
72
|
# web3.py
|
|
64
73
|
|
|
65
|
-
[](https://discord.gg/GHryRvPB84)
|
|
74
|
+
[](https://discord.gg/GHryRvPB84)
|
|
67
75
|
[](https://circleci.com/gh/ethereum/web3.py)
|
|
76
|
+
[](https://badge.fury.io/py/web3)
|
|
77
|
+
[](https://pypi.python.org/pypi/web3)
|
|
78
|
+
[](https://web3py.readthedocs.io/en/latest/?badge=latest)
|
|
68
79
|
|
|
69
80
|
A Python library for interacting with Ethereum.
|
|
70
81
|
|