web3 7.0.0b2__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 (144) hide show
  1. ens/__init__.py +13 -2
  2. ens/_normalization.py +4 -4
  3. ens/async_ens.py +27 -15
  4. ens/base_ens.py +3 -1
  5. ens/contract_data.py +2 -2
  6. ens/ens.py +10 -7
  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 +24 -32
  11. web3/__init__.py +23 -12
  12. web3/_utils/abi.py +157 -263
  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 +49 -34
  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 -17
  89. web3/manager.py +362 -95
  90. web3/method.py +43 -15
  91. web3/middleware/__init__.py +17 -0
  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 +61 -25
  100. web3/providers/__init__.py +21 -0
  101. web3/providers/async_base.py +87 -32
  102. web3/providers/base.py +77 -32
  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 +41 -15
  106. web3/providers/eth_tester/middleware.py +16 -17
  107. web3/providers/ipc.py +41 -17
  108. web3/providers/legacy_websocket.py +26 -1
  109. web3/providers/persistent/__init__.py +7 -0
  110. web3/providers/persistent/async_ipc.py +61 -121
  111. web3/providers/persistent/persistent.py +323 -16
  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.0b2.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.0b2.dist-info → web3-7.7.0.dist-info}/WHEEL +1 -1
  137. web3/_utils/caching.py +0 -155
  138. web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
  139. web3/_utils/module_testing/go_ethereum_personal_module.py +0 -300
  140. web3/_utils/request.py +0 -265
  141. web3-7.0.0b2.dist-info/METADATA +0 -106
  142. web3-7.0.0b2.dist-info/RECORD +0 -163
  143. /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
  144. {web3-7.0.0b2.dist-info → web3-7.7.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,128 @@
1
+ import pytest
2
+ from typing import (
3
+ cast,
4
+ )
5
+
6
+ from eth_typing import (
7
+ HexStr,
8
+ )
9
+
10
+ from web3 import (
11
+ AsyncWeb3,
12
+ Web3,
13
+ )
14
+ from web3.types import (
15
+ BlockData,
16
+ CallTrace,
17
+ ChecksumAddress,
18
+ DiffModeTrace,
19
+ OpcodeTrace,
20
+ PrestateTrace,
21
+ )
22
+
23
+
24
+ class GoEthereumAsyncDebugModuleTest:
25
+ @pytest.mark.asyncio
26
+ async def test_async_geth_debug_trace_transaction_opcode_logger(
27
+ self, async_w3: "AsyncWeb3", txn_hash_with_log: HexStr
28
+ ) -> None:
29
+ result = await async_w3.geth.debug.trace_transaction(txn_hash_with_log)
30
+ assert "structLogs" in dict(result).keys()
31
+ assert "gas" in dict(result).keys()
32
+ assert "failed" in dict(result).keys()
33
+
34
+ @pytest.mark.asyncio
35
+ async def test_async_geth_debug_trace_transaction_call_tracer(
36
+ self, async_w3: "AsyncWeb3", txn_hash_with_log: HexStr
37
+ ) -> None:
38
+ result = cast(
39
+ CallTrace,
40
+ await async_w3.geth.debug.trace_transaction(
41
+ txn_hash_with_log, {"tracer": "callTracer"}
42
+ ),
43
+ )
44
+ assert result.get("type") == "CALL"
45
+
46
+ @pytest.mark.asyncio
47
+ async def test_async_geth_debug_trace_transaction_prestate_tracer_diffMode(
48
+ self, async_w3: "AsyncWeb3", txn_hash_with_log: HexStr
49
+ ) -> None:
50
+ result = cast(
51
+ DiffModeTrace,
52
+ await async_w3.geth.debug.trace_transaction(
53
+ txn_hash_with_log,
54
+ {"tracer": "prestateTracer", "tracerConfig": {"diffMode": True}},
55
+ ),
56
+ )
57
+ assert "post" in dict(result).keys()
58
+ assert "pre" in dict(result).keys()
59
+
60
+ @pytest.mark.asyncio
61
+ async def test_async_geth_debug_trace_transaction_prestate_tracer(
62
+ self,
63
+ async_w3: "AsyncWeb3",
64
+ txn_hash_with_log: HexStr,
65
+ async_block_with_txn_with_log: BlockData,
66
+ ) -> None:
67
+ result = cast(
68
+ PrestateTrace,
69
+ await async_w3.geth.debug.trace_transaction(
70
+ txn_hash_with_log,
71
+ {"tracer": "prestateTracer"},
72
+ ),
73
+ )
74
+ tx = await async_w3.eth.get_transaction(txn_hash_with_log)
75
+ from_addr: ChecksumAddress = tx["from"]
76
+ assert isinstance(result[from_addr].get("balance"), int)
77
+ assert "post" not in dict(result).keys()
78
+ assert "pre" not in dict(result).keys()
79
+
80
+
81
+ class GoEthereumDebugModuleTest:
82
+ def test_geth_debug_trace_transaction_opcode_logger(
83
+ self, w3: "Web3", txn_hash_with_log: HexStr
84
+ ) -> None:
85
+ result = cast(OpcodeTrace, w3.geth.debug.trace_transaction(txn_hash_with_log))
86
+ assert "structLogs" in dict(result).keys()
87
+ assert "gas" in dict(result).keys()
88
+ assert "failed" in dict(result).keys()
89
+
90
+ def test_geth_debug_trace_transaction_call_tracer(
91
+ self, w3: "Web3", txn_hash_with_log: HexStr
92
+ ) -> None:
93
+ result = cast(
94
+ CallTrace,
95
+ w3.geth.debug.trace_transaction(
96
+ txn_hash_with_log, {"tracer": "callTracer"}
97
+ ),
98
+ )
99
+ assert result.get("type") == "CALL"
100
+
101
+ def test_geth_debug_trace_transaction_prestate_tracer_diffmode(
102
+ self, w3: "Web3", txn_hash_with_log: HexStr
103
+ ) -> None:
104
+ result = cast(
105
+ DiffModeTrace,
106
+ w3.geth.debug.trace_transaction(
107
+ txn_hash_with_log,
108
+ {"tracer": "prestateTracer", "tracerConfig": {"diffMode": True}},
109
+ ),
110
+ )
111
+ assert "post" in dict(result).keys()
112
+ assert "pre" in dict(result).keys()
113
+
114
+ def test_geth_debug_trace_transaction_prestate_tracer(
115
+ self, w3: "Web3", txn_hash_with_log: HexStr
116
+ ) -> None:
117
+ result = cast(
118
+ PrestateTrace,
119
+ w3.geth.debug.trace_transaction(
120
+ txn_hash_with_log,
121
+ {"tracer": "prestateTracer"},
122
+ ),
123
+ )
124
+ tx = w3.eth.get_transaction(txn_hash_with_log)
125
+ from_addr: ChecksumAddress = tx["from"]
126
+ assert isinstance(result[from_addr].get("balance"), int)
127
+ assert "post" not in dict(result).keys()
128
+ assert "pre" not in dict(result).keys()
@@ -1,17 +1,22 @@
1
- from collections import (
2
- deque,
3
- )
1
+ import asyncio
2
+ import functools
3
+ import pytest
4
4
  from typing import (
5
5
  TYPE_CHECKING,
6
6
  Any,
7
+ Callable,
7
8
  Collection,
8
9
  Dict,
9
10
  Generator,
11
+ Literal,
10
12
  Sequence,
13
+ Tuple,
14
+ Type,
11
15
  Union,
12
16
  )
13
17
 
14
18
  from aiohttp import (
19
+ ClientSession,
15
20
  ClientTimeout,
16
21
  )
17
22
  from eth_typing import (
@@ -27,13 +32,10 @@ from flaky import (
27
32
  from hexbytes import (
28
33
  HexBytes,
29
34
  )
35
+ import requests
30
36
 
31
- from web3._utils.compat import (
32
- Literal,
33
- )
34
- from web3._utils.request import (
35
- async_cache_and_return_session,
36
- cache_and_return_session,
37
+ from web3._utils.http import (
38
+ DEFAULT_HTTP_TIMEOUT,
37
39
  )
38
40
  from web3.types import (
39
41
  BlockData,
@@ -42,7 +44,9 @@ from web3.types import (
42
44
 
43
45
  if TYPE_CHECKING:
44
46
  from _pytest.monkeypatch import MonkeyPatch # noqa: F401
45
- from aiohttp import ClientResponse # noqa: F401
47
+ from aiohttp import ( # noqa: F401
48
+ ClientResponse,
49
+ )
46
50
  from requests import Response # noqa: F401
47
51
 
48
52
  from web3 import Web3 # noqa: F401
@@ -56,7 +60,44 @@ flaky_geth_dev_mining decorator for tests requiring a pending block
56
60
  for the duration of the test. This behavior can be flaky
57
61
  due to timing of the test running as a block is mined.
58
62
  """
59
- flaky_geth_dev_mining = flaky(max_runs=3)
63
+ flaky_geth_dev_mining = flaky(max_runs=3, min_passes=1)
64
+
65
+
66
+ def flaky_with_xfail_on_exception(
67
+ reason: str,
68
+ exception: Union[Type[Exception], Tuple[Type[Exception], ...]],
69
+ max_runs: int = 3,
70
+ min_passes: int = 1,
71
+ ) -> Callable[[Any], Any]:
72
+ """
73
+ Some tests inconsistently fail hard with a particular exception and retrying
74
+ these tests often times does not get them "unstuck". If we've exhausted all flaky
75
+ retries and this expected exception is raised, `xfail` the test with the given
76
+ reason.
77
+ """
78
+ runs = max_runs
79
+
80
+ def decorator(func: Any) -> Any:
81
+ @flaky(max_runs=max_runs, min_passes=min_passes)
82
+ @functools.wraps(func)
83
+ async def wrapper(self: Any, *args: Any, **kwargs: Any) -> Any:
84
+ nonlocal runs
85
+ try:
86
+ return await func(self, *args, **kwargs)
87
+ except exception:
88
+ # xfail the test only if the exception is raised and we have exhausted
89
+ # all flaky retries
90
+ if runs == 1:
91
+ pytest.xfail(reason)
92
+ runs -= 1
93
+ pytest.fail(f"xfailed but {runs} run(s) remaining with flaky...")
94
+ except Exception as e:
95
+ # let flaky handle it
96
+ raise e
97
+
98
+ return wrapper
99
+
100
+ return decorator
60
101
 
61
102
 
62
103
  def assert_contains_log(
@@ -65,7 +106,7 @@ def assert_contains_log(
65
106
  emitter_contract_address: ChecksumAddress,
66
107
  txn_hash_with_log: HexStr,
67
108
  ) -> None:
68
- assert len(result) == 1
109
+ assert len(result) > 0
69
110
  log_entry = result[0]
70
111
  assert log_entry["blockNumber"] == block_with_txn_with_log["number"]
71
112
  assert log_entry["blockHash"] == block_with_txn_with_log["hash"]
@@ -104,13 +145,13 @@ def mock_offchain_lookup_request_response(
104
145
 
105
146
  # mock response only to specified url while validating appropriate fields
106
147
  if url_from_args == mocked_request_url:
107
- assert kwargs["timeout"] == 30
148
+ assert kwargs["timeout"] == DEFAULT_HTTP_TIMEOUT
108
149
  if http_method.upper() == "POST":
109
- assert kwargs["data"] == {"data": calldata, "sender": sender}
150
+ assert kwargs["json"] == {"data": calldata, "sender": sender}
110
151
  return MockedResponse()
111
152
 
112
153
  # else, make a normal request (no mocking)
113
- session = cache_and_return_session(url_from_args)
154
+ session = requests.Session()
114
155
  return session.request(method=http_method.upper(), url=url_from_args, **kwargs)
115
156
 
116
157
  monkeypatch.setattr(
@@ -154,16 +195,18 @@ def async_mock_offchain_lookup_request_response(
154
195
 
155
196
  # mock response only to specified url while validating appropriate fields
156
197
  if url_from_args == mocked_request_url:
157
- assert kwargs["timeout"] == ClientTimeout(30)
158
- if http_method.upper() == "post":
159
- assert kwargs["data"] == {"data": calldata, "sender": sender}
198
+ assert kwargs["timeout"] == ClientTimeout(DEFAULT_HTTP_TIMEOUT)
199
+ if http_method.upper() == "POST":
200
+ assert kwargs["json"] == {"data": calldata, "sender": sender}
160
201
  return AsyncMockedResponse()
161
202
 
162
203
  # else, make a normal request (no mocking)
163
- session = await async_cache_and_return_session(url_from_args)
164
- return await session.request(
204
+ session = ClientSession()
205
+ response = await session.request(
165
206
  method=http_method.upper(), url=url_from_args, **kwargs
166
207
  )
208
+ await session.close()
209
+ return response
167
210
 
168
211
  monkeypatch.setattr(
169
212
  f"aiohttp.ClientSession.{http_method.lower()}", _mock_specific_request
@@ -176,20 +219,34 @@ class WebSocketMessageStreamMock:
176
219
  def __init__(
177
220
  self, messages: Collection[bytes] = None, raise_exception: Exception = None
178
221
  ) -> None:
179
- self.messages = deque(messages) if messages else deque()
222
+ self.queue = asyncio.Queue() # type: ignore # py38 issue
223
+ for msg in messages or []:
224
+ self.queue.put_nowait(msg)
180
225
  self.raise_exception = raise_exception
181
226
 
227
+ def __await__(self) -> Generator[Any, Any, "Self"]:
228
+ async def __async_init__() -> "Self":
229
+ return self
230
+
231
+ return __async_init__().__await__()
232
+
182
233
  def __aiter__(self) -> "Self":
183
234
  return self
184
235
 
185
236
  async def __anext__(self) -> bytes:
237
+ return await self.queue.get()
238
+
239
+ async def recv(self) -> bytes:
186
240
  if self.raise_exception:
187
241
  raise self.raise_exception
242
+ return await self.queue.get()
188
243
 
189
- elif len(self.messages) == 0:
190
- raise StopAsyncIteration
244
+ @staticmethod
245
+ async def pong() -> Literal[False]:
246
+ return False
191
247
 
192
- return self.messages.popleft()
248
+ async def connect(self) -> None:
249
+ pass
193
250
 
194
251
  async def send(self, data: bytes) -> None:
195
252
  pass