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
web3/_utils/encoding.py CHANGED
@@ -55,6 +55,10 @@ from web3._utils.validation import (
55
55
  from web3.datastructures import (
56
56
  AttributeDict,
57
57
  )
58
+ from web3.exceptions import (
59
+ Web3TypeError,
60
+ Web3ValueError,
61
+ )
58
62
 
59
63
 
60
64
  def hex_encode_abi_type(
@@ -90,7 +94,7 @@ def hex_encode_abi_type(
90
94
  elif is_string_type(abi_type):
91
95
  return to_hex(text=value)
92
96
  else:
93
- raise ValueError(f"Unsupported ABI type: {abi_type}")
97
+ raise Web3ValueError(f"Unsupported ABI type: {abi_type}")
94
98
 
95
99
 
96
100
  def to_hex_twos_compliment(value: Any, bit_size: int) -> HexStr:
@@ -169,7 +173,7 @@ def hexstr_if_str(
169
173
  if isinstance(hexstr_or_primitive, str):
170
174
  (primitive, hexstr) = (None, hexstr_or_primitive)
171
175
  if remove_0x_prefix(HexStr(hexstr)) and not is_hex(hexstr):
172
- raise ValueError(
176
+ raise Web3ValueError(
173
177
  "when sending a str, it must be a hex string. "
174
178
  f"Got: {hexstr_or_primitive!r}"
175
179
  )
@@ -210,12 +214,12 @@ class FriendlyJsonSerde:
210
214
  except TypeError as full_exception:
211
215
  if hasattr(obj, "items"):
212
216
  item_errors = "; ".join(self._json_mapping_errors(obj))
213
- raise TypeError(
217
+ raise Web3TypeError(
214
218
  f"dict had unencodable value at keys: {{{item_errors}}}"
215
219
  )
216
220
  elif is_list_like(obj):
217
221
  element_errors = "; ".join(self._json_list_errors(obj))
218
- raise TypeError(
222
+ raise Web3TypeError(
219
223
  f"list had unencodable value at index: [{element_errors}]"
220
224
  )
221
225
  else:
@@ -237,14 +241,16 @@ class FriendlyJsonSerde:
237
241
  try:
238
242
  return self._friendly_json_encode(obj, cls=cls)
239
243
  except TypeError as exc:
240
- raise TypeError(f"Could not encode to JSON: {exc}")
244
+ raise Web3TypeError(f"Could not encode to JSON: {exc}")
241
245
 
242
246
 
243
247
  def to_4byte_hex(hex_or_str_or_bytes: Union[HexStr, str, bytes, int]) -> HexStr:
244
248
  size_of_4bytes = 4 * 8
245
249
  byte_str = hexstr_if_str(to_bytes, hex_or_str_or_bytes)
246
250
  if len(byte_str) > 4:
247
- raise ValueError(f"expected value of size 4 bytes. Got: {len(byte_str)} bytes")
251
+ raise Web3ValueError(
252
+ f"expected value of size 4 bytes. Got: {len(byte_str)} bytes"
253
+ )
248
254
  hex_str = encode_hex(byte_str)
249
255
  return pad_hex(hex_str, size_of_4bytes)
250
256
 
@@ -253,7 +259,7 @@ class DynamicArrayPackedEncoder(BaseArrayEncoder):
253
259
  is_dynamic = True
254
260
 
255
261
  def encode(self, value: Sequence[Any]) -> bytes:
256
- encoded_elements = self.encode_elements(value)
262
+ encoded_elements = self.encode_elements(value) # type: ignore[no-untyped-call]
257
263
  encoded_value = encoded_elements
258
264
 
259
265
  return encoded_value
@@ -272,10 +278,10 @@ def encode_single_packed(_type: TypeStr, value: Any) -> bytes:
272
278
  )
273
279
 
274
280
  abi_type = abi_type_parser.parse(_type)
275
- if has_arrlist(_type):
281
+ if has_arrlist(_type): # type: ignore[no-untyped-call]
276
282
  item_encoder = registry.get_encoder(abi_type.item_type.to_type_str())
277
283
  if abi_type.arrlist[-1] != 1:
278
- return DynamicArrayPackedEncoder(item_encoder=item_encoder).encode(value)
284
+ return DynamicArrayPackedEncoder(item_encoder=item_encoder).encode(value) # type: ignore[no-untyped-call] # noqa: E501
279
285
  else:
280
286
  raise NotImplementedError(
281
287
  "Fixed arrays are not implemented in this packed encoder prototype"
@@ -291,9 +297,7 @@ class Web3JsonEncoder(json.JSONEncoder):
291
297
  def default(self, obj: Any) -> Union[Dict[Any, Any], HexStr]:
292
298
  if isinstance(obj, AttributeDict):
293
299
  return obj.__dict__
294
- elif isinstance(obj, HexBytes):
295
- return HexStr(obj.hex())
296
- elif isinstance(obj, bytes):
300
+ elif isinstance(obj, (HexBytes, bytes)):
297
301
  return to_hex(obj)
298
302
  return json.JSONEncoder.default(self, obj)
299
303
 
@@ -13,6 +13,7 @@ from web3.exceptions import (
13
13
  ContractPanicError,
14
14
  OffchainLookup,
15
15
  TransactionIndexingInProgress,
16
+ Web3ValueError,
16
17
  )
17
18
  from web3.types import (
18
19
  RPCResponse,
@@ -76,7 +77,9 @@ def _parse_error_with_reverted_prefix(data: str) -> str:
76
77
  try:
77
78
  error = bytes.fromhex(error).decode("utf8")
78
79
  except UnicodeDecodeError:
79
- warnings.warn("Could not decode revert reason as UTF-8", RuntimeWarning)
80
+ warnings.warn(
81
+ "Could not decode revert reason as UTF-8", RuntimeWarning, stacklevel=2
82
+ )
80
83
  raise ContractLogicError("execution reverted", data=data)
81
84
 
82
85
  return error
@@ -140,7 +143,7 @@ def raise_contract_logic_error_on_revert(response: RPCResponse) -> RPCResponse:
140
143
  """
141
144
  error = response.get("error")
142
145
  if error is None or isinstance(error, str):
143
- raise ValueError(error)
146
+ raise Web3ValueError(error)
144
147
 
145
148
  message = error.get("message")
146
149
  message_present = message is not None and message != ""
@@ -172,7 +175,6 @@ def raise_transaction_indexing_error_if_indexing(response: RPCResponse) -> RPCRe
172
175
  Raise an error if ``eth_getTransactionReceipt`` returns an error indicating that
173
176
  transactions are still being indexed.
174
177
  """
175
-
176
178
  error = response.get("error")
177
179
  if not isinstance(error, str) and error is not None:
178
180
  message = error.get("message")
web3/_utils/events.py CHANGED
@@ -27,13 +27,16 @@ from eth_abi.codec import (
27
27
  ABICodec,
28
28
  )
29
29
  from eth_typing import (
30
+ ABIComponent,
31
+ ABIComponentIndexed,
32
+ ABIEvent,
30
33
  ChecksumAddress,
31
34
  HexStr,
35
+ Primitives,
32
36
  TypeStr,
33
37
  )
34
38
  from eth_utils import (
35
39
  encode_hex,
36
- event_abi_to_log_topic,
37
40
  is_list_like,
38
41
  keccak,
39
42
  to_bytes,
@@ -41,6 +44,11 @@ from eth_utils import (
41
44
  to_hex,
42
45
  to_tuple,
43
46
  )
47
+ from eth_utils.abi import (
48
+ collapse_if_tuple,
49
+ event_abi_to_log_topic,
50
+ get_abi_input_names,
51
+ )
44
52
  from eth_utils.curried import (
45
53
  apply_formatter_if,
46
54
  )
@@ -56,7 +64,6 @@ import web3
56
64
  from web3._utils.abi import (
57
65
  exclude_indexed_event_inputs,
58
66
  get_indexed_event_inputs,
59
- get_normalized_abi_arg_type,
60
67
  map_abi_data,
61
68
  named_tree,
62
69
  normalize_event_input_types,
@@ -74,18 +81,16 @@ from web3.datastructures import (
74
81
  from web3.exceptions import (
75
82
  InvalidEventABI,
76
83
  LogTopicError,
77
- MismatchedABI,
84
+ Web3ValueError,
78
85
  )
79
86
  from web3.types import (
80
- ABIEvent,
81
- ABIEventParams,
82
87
  BlockIdentifier,
83
88
  EventData,
84
89
  FilterParams,
85
90
  LogReceipt,
86
91
  )
87
- from web3.utils import (
88
- get_abi_input_names,
92
+ from web3.utils.abi import (
93
+ get_event_log_topics,
89
94
  )
90
95
 
91
96
  if TYPE_CHECKING:
@@ -99,16 +104,22 @@ if TYPE_CHECKING:
99
104
  )
100
105
 
101
106
 
107
+ def _log_entry_data_to_bytes(
108
+ log_entry_data: Union[Primitives, HexStr, str],
109
+ ) -> bytes:
110
+ return hexstr_if_str(to_bytes, log_entry_data)
111
+
112
+
102
113
  def construct_event_topic_set(
103
114
  event_abi: ABIEvent,
104
115
  abi_codec: ABICodec,
105
- arguments: Optional[Union[Sequence[Any], Dict[str, Any]]] = None,
116
+ arguments: Optional[Union[List[Any], Tuple[Any], Dict[str, Any]]] = None,
106
117
  ) -> List[HexStr]:
107
118
  if arguments is None:
108
119
  arguments = {}
109
- if isinstance(arguments, (list, tuple)):
120
+ elif isinstance(arguments, (list, tuple)):
110
121
  if len(arguments) != len(event_abi["inputs"]):
111
- raise ValueError(
122
+ raise Web3ValueError(
112
123
  "When passing an argument list, the number of arguments must "
113
124
  "match the event constructor."
114
125
  )
@@ -116,16 +127,12 @@ def construct_event_topic_set(
116
127
  arg["name"]: [arg_value]
117
128
  for arg, arg_value in zip(event_abi["inputs"], arguments)
118
129
  }
119
-
120
130
  normalized_args = {
121
131
  key: value if is_list_like(value) else [value]
122
- # type ignored b/c arguments is always a dict at this point
123
- for key, value in arguments.items() # type: ignore
132
+ for key, value in arguments.items()
124
133
  }
125
134
 
126
- # typed dict cannot be used w/ a normal Dict
127
- # https://github.com/python/mypy/issues/4976
128
- event_topic = encode_hex(event_abi_to_log_topic(event_abi)) # type: ignore
135
+ event_topic = encode_hex(event_abi_to_log_topic(event_abi))
129
136
  indexed_args = get_indexed_event_inputs(event_abi)
130
137
  zipped_abi_and_args = [
131
138
  (arg, normalized_args.get(arg["name"], [None])) for arg in indexed_args
@@ -155,7 +162,7 @@ def construct_event_data_set(
155
162
  arguments = {}
156
163
  if isinstance(arguments, (list, tuple)):
157
164
  if len(arguments) != len(event_abi["inputs"]):
158
- raise ValueError(
165
+ raise Web3ValueError(
159
166
  "When passing an argument list, the number of arguments must "
160
167
  "match the event constructor."
161
168
  )
@@ -200,7 +207,7 @@ def is_dynamic_sized_type(type_str: TypeStr) -> bool:
200
207
 
201
208
  @to_tuple
202
209
  def get_event_abi_types_for_decoding(
203
- event_inputs: Sequence[ABIEventParams],
210
+ event_inputs: Sequence[Union[ABIComponent, ABIComponentIndexed]],
204
211
  ) -> Iterable[TypeStr]:
205
212
  """
206
213
  Event logs use the `keccak(value)` for indexed inputs of type `bytes` or
@@ -208,10 +215,10 @@ def get_event_abi_types_for_decoding(
208
215
  decode the log entries using the correct types.
209
216
  """
210
217
  for input_abi in event_inputs:
211
- if input_abi["indexed"] and is_dynamic_sized_type(input_abi["type"]):
218
+ if input_abi.get("indexed") and is_dynamic_sized_type(input_abi["type"]):
212
219
  yield "bytes32"
213
220
  else:
214
- yield get_normalized_abi_arg_type(input_abi)
221
+ yield collapse_if_tuple(input_abi)
215
222
 
216
223
 
217
224
  @curry
@@ -224,31 +231,27 @@ def get_event_data(
224
231
  Given an event ABI and a log entry for that event, return the decoded
225
232
  event data
226
233
  """
227
- if event_abi["anonymous"]:
228
- log_topics = log_entry["topics"]
229
- elif not log_entry["topics"]:
230
- raise MismatchedABI("Expected non-anonymous event to have 1 or more topics")
231
- # type ignored b/c event_abi_to_log_topic(event_abi: Dict[str, Any])
232
- elif event_abi_to_log_topic(event_abi) != log_entry["topics"][0]: # type: ignore
233
- raise MismatchedABI("The event signature did not match the provided ABI")
234
- else:
235
- log_topics = log_entry["topics"][1:]
236
-
234
+ log_topics = get_event_log_topics(event_abi, log_entry["topics"])
235
+ log_topics_bytes = [_log_entry_data_to_bytes(topic) for topic in log_topics]
237
236
  log_topics_abi = get_indexed_event_inputs(event_abi)
238
237
  log_topic_normalized_inputs = normalize_event_input_types(log_topics_abi)
239
238
  log_topic_types = get_event_abi_types_for_decoding(log_topic_normalized_inputs)
240
- log_topic_names = get_abi_input_names(ABIEvent({"inputs": log_topics_abi}))
239
+ log_topic_names = get_abi_input_names(
240
+ ABIEvent({"name": event_abi["name"], "type": "event", "inputs": log_topics_abi})
241
+ )
241
242
 
242
- if len(log_topics) != len(log_topic_types):
243
+ if len(log_topics_bytes) != len(log_topic_types):
243
244
  raise LogTopicError(
244
- f"Expected {len(log_topic_types)} log topics. Got {len(log_topics)}"
245
+ f"Expected {len(log_topic_types)} log topics. Got {len(log_topics_bytes)}"
245
246
  )
246
247
 
247
- log_data = hexstr_if_str(to_bytes, log_entry["data"])
248
+ log_data = _log_entry_data_to_bytes(log_entry["data"])
248
249
  log_data_abi = exclude_indexed_event_inputs(event_abi)
249
250
  log_data_normalized_inputs = normalize_event_input_types(log_data_abi)
250
251
  log_data_types = get_event_abi_types_for_decoding(log_data_normalized_inputs)
251
- log_data_names = get_abi_input_names(ABIEvent({"inputs": log_data_abi}))
252
+ log_data_names = get_abi_input_names(
253
+ ABIEvent({"name": event_abi["name"], "type": "event", "inputs": log_data_abi})
254
+ )
252
255
 
253
256
  # sanity check that there are not name intersections between the topic
254
257
  # names and the data argument names.
@@ -270,7 +273,7 @@ def get_event_data(
270
273
 
271
274
  decoded_topic_data = [
272
275
  abi_codec.decode([topic_type], topic_data)[0]
273
- for topic_type, topic_data in zip(log_topic_types, log_topics)
276
+ for topic_type, topic_data in zip(log_topic_types, log_topics_bytes)
274
277
  ]
275
278
  normalized_topic_data = map_abi_data(
276
279
  BASE_RETURN_NORMALIZERS, log_topic_types, decoded_topic_data
@@ -332,8 +335,8 @@ is_not_indexed = complement(is_indexed)
332
335
 
333
336
  class BaseEventFilterBuilder:
334
337
  formatter = None
335
- _fromBlock = None
336
- _toBlock = None
338
+ _from_block = None
339
+ _to_block = None
337
340
  _address = None
338
341
  _immutable = False
339
342
 
@@ -353,30 +356,30 @@ class BaseEventFilterBuilder:
353
356
  self._ordered_arg_names = tuple(arg["name"] for arg in event_abi["inputs"])
354
357
 
355
358
  @property
356
- def fromBlock(self) -> BlockIdentifier:
357
- return self._fromBlock
359
+ def from_block(self) -> BlockIdentifier:
360
+ return self._from_block
358
361
 
359
- @fromBlock.setter
360
- def fromBlock(self, value: BlockIdentifier) -> None:
361
- if self._fromBlock is None and not self._immutable:
362
- self._fromBlock = value
362
+ @from_block.setter
363
+ def from_block(self, value: BlockIdentifier) -> None:
364
+ if self._from_block is None and not self._immutable:
365
+ self._from_block = value
363
366
  else:
364
- raise ValueError(
365
- f"fromBlock is already set to {self._fromBlock!r}. "
367
+ raise Web3ValueError(
368
+ f"from_block is already set to {self._from_block!r}. "
366
369
  "Resetting filter parameters is not permitted"
367
370
  )
368
371
 
369
372
  @property
370
- def toBlock(self) -> BlockIdentifier:
371
- return self._toBlock
373
+ def to_block(self) -> BlockIdentifier:
374
+ return self._to_block
372
375
 
373
- @toBlock.setter
374
- def toBlock(self, value: BlockIdentifier) -> None:
375
- if self._toBlock is None and not self._immutable:
376
- self._toBlock = value
376
+ @to_block.setter
377
+ def to_block(self, value: BlockIdentifier) -> None:
378
+ if self._to_block is None and not self._immutable:
379
+ self._to_block = value
377
380
  else:
378
- raise ValueError(
379
- f"toBlock is already set to {self._toBlock!r}. "
381
+ raise Web3ValueError(
382
+ f"toBlock is already set to {self._to_block!r}. "
380
383
  "Resetting filter parameters is not permitted"
381
384
  )
382
385
 
@@ -389,7 +392,7 @@ class BaseEventFilterBuilder:
389
392
  if self._address is None and not self._immutable:
390
393
  self._address = value
391
394
  else:
392
- raise ValueError(
395
+ raise Web3ValueError(
393
396
  f"address is already set to {self.address!r}. "
394
397
  "Resetting filter parameters is not permitted"
395
398
  )
@@ -424,8 +427,8 @@ class BaseEventFilterBuilder:
424
427
  def filter_params(self) -> FilterParams:
425
428
  params = {
426
429
  "topics": self.topics,
427
- "fromBlock": self.fromBlock,
428
- "toBlock": self.toBlock,
430
+ "fromBlock": self.from_block,
431
+ "toBlock": self.to_block,
429
432
  "address": self.address,
430
433
  }
431
434
  return valfilter(lambda x: x is not None, params)
@@ -434,10 +437,10 @@ class BaseEventFilterBuilder:
434
437
  class EventFilterBuilder(BaseEventFilterBuilder):
435
438
  def deploy(self, w3: "Web3") -> "LogFilter":
436
439
  if not isinstance(w3, web3.Web3):
437
- raise ValueError(f"Invalid web3 argument: got: {w3!r}")
440
+ raise Web3ValueError(f"Invalid web3 argument: got: {w3!r}")
438
441
 
439
- for arg in AttributeDict.values(self.args): # type: ignore[arg-type]
440
- arg._immutable = True # type: ignore[attr-defined]
442
+ for arg in self.args.values():
443
+ arg._immutable = True
441
444
  self._immutable = True
442
445
 
443
446
  log_filter = cast("LogFilter", w3.eth.filter(self.filter_params))
@@ -452,10 +455,10 @@ class EventFilterBuilder(BaseEventFilterBuilder):
452
455
  class AsyncEventFilterBuilder(BaseEventFilterBuilder):
453
456
  async def deploy(self, async_w3: "AsyncWeb3") -> "AsyncLogFilter":
454
457
  if not isinstance(async_w3, web3.AsyncWeb3):
455
- raise ValueError(f"Invalid web3 argument: got: {async_w3!r}")
458
+ raise Web3ValueError(f"Invalid web3 argument: got: {async_w3!r}")
456
459
 
457
- for arg in AttributeDict.values(self.args): # type: ignore[arg-type]
458
- arg._immutable = True # type: ignore[attr-defined]
460
+ for arg in self.args.values():
461
+ arg._immutable = True
459
462
  self._immutable = True
460
463
 
461
464
  log_filter = await async_w3.eth.filter(self.filter_params)
@@ -470,8 +473,7 @@ class AsyncEventFilterBuilder(BaseEventFilterBuilder):
470
473
 
471
474
  def initialize_event_topics(event_abi: ABIEvent) -> Union[bytes, List[Any]]:
472
475
  if event_abi["anonymous"] is False:
473
- # https://github.com/python/mypy/issues/4976
474
- return event_abi_to_log_topic(event_abi) # type: ignore
476
+ return event_abi_to_log_topic(event_abi)
475
477
  else:
476
478
  return list()
477
479
 
@@ -483,12 +485,12 @@ def _build_argument_filters_from_event_abi(
483
485
  for item in event_abi["inputs"]:
484
486
  key = item["name"]
485
487
  value: "BaseArgumentFilter"
486
- if item["indexed"] is True:
488
+ if item.get("indexed") is True:
487
489
  value = TopicArgumentFilter(
488
- abi_codec=abi_codec, arg_type=get_normalized_abi_arg_type(item)
490
+ abi_codec=abi_codec, arg_type=collapse_if_tuple(item)
489
491
  )
490
492
  else:
491
- value = DataArgumentFilter(arg_type=get_normalized_abi_arg_type(item))
493
+ value = DataArgumentFilter(arg_type=collapse_if_tuple(item))
492
494
  yield key, value
493
495
 
494
496
 
@@ -510,19 +512,23 @@ class BaseArgumentFilter(ABC):
510
512
 
511
513
  def match_single(self, value: Any) -> None:
512
514
  if self._immutable:
513
- raise ValueError("Setting values is forbidden after filter is deployed.")
515
+ raise Web3ValueError(
516
+ "Setting values is forbidden after filter is deployed."
517
+ )
514
518
  if self._match_values is None:
515
519
  self._match_values = _normalize_match_values((value,))
516
520
  else:
517
- raise ValueError("An argument match value/s has already been set.")
521
+ raise Web3ValueError("An argument match value/s has already been set.")
518
522
 
519
523
  def match_any(self, *values: Collection[Any]) -> None:
520
524
  if self._immutable:
521
- raise ValueError("Setting values is forbidden after filter is deployed.")
525
+ raise Web3ValueError(
526
+ "Setting values is forbidden after filter is deployed."
527
+ )
522
528
  if self._match_values is None:
523
529
  self._match_values = _normalize_match_values(values)
524
530
  else:
525
- raise ValueError("An argument match value/s has already been set.")
531
+ raise Web3ValueError("An argument match value/s has already been set.")
526
532
 
527
533
  @property
528
534
  @abstractmethod
web3/_utils/fee_utils.py CHANGED
@@ -53,7 +53,5 @@ async def async_fee_history_priority_fee(async_eth: "AsyncEth") -> Wei:
53
53
  # This is a tested internal call so no need for type hinting. We can keep
54
54
  # better consistency between the sync and async calls by unpacking
55
55
  # PRIORITY_FEE_HISTORY_PARAMS as constants here.
56
- fee_history = await async_eth.fee_history(
57
- *PRIORITY_FEE_HISTORY_PARAMS # type: ignore
58
- )
56
+ fee_history = await async_eth.fee_history(*PRIORITY_FEE_HISTORY_PARAMS) # type: ignore # noqa: E501
59
57
  return _fee_history_priority_fee_estimate(fee_history)
web3/_utils/filters.py CHANGED
@@ -19,6 +19,7 @@ from eth_abi.grammar import (
19
19
  parse as parse_type_string,
20
20
  )
21
21
  from eth_typing import (
22
+ ABIEvent,
22
23
  ChecksumAddress,
23
24
  HexStr,
24
25
  TypeStr,
@@ -50,10 +51,11 @@ from web3._utils.validation import (
50
51
  validate_address,
51
52
  )
52
53
  from web3.exceptions import (
54
+ Web3TypeError,
53
55
  Web3ValidationError,
56
+ Web3ValueError,
54
57
  )
55
58
  from web3.types import (
56
- ABIEvent,
57
59
  BlockIdentifier,
58
60
  FilterParams,
59
61
  LogReceipt,
@@ -71,8 +73,8 @@ def construct_event_filter_params(
71
73
  contract_address: Optional[ChecksumAddress] = None,
72
74
  argument_filters: Optional[Dict[str, Any]] = None,
73
75
  topics: Optional[Sequence[HexStr]] = None,
74
- fromBlock: Optional[BlockIdentifier] = None,
75
- toBlock: Optional[BlockIdentifier] = None,
76
+ from_block: Optional[BlockIdentifier] = None,
77
+ to_block: Optional[BlockIdentifier] = None,
76
78
  address: Optional[ChecksumAddress] = None,
77
79
  ) -> Tuple[List[List[Optional[HexStr]]], FilterParams]:
78
80
  filter_params: FilterParams = {}
@@ -82,17 +84,13 @@ def construct_event_filter_params(
82
84
 
83
85
  if topics is not None:
84
86
  if len(topic_set) > 1:
85
- raise TypeError(
87
+ raise Web3TypeError(
86
88
  "Merging the topics argument with topics generated "
87
89
  "from argument_filters is not supported."
88
90
  )
89
91
  topic_set = topics
90
92
 
91
- if len(topic_set) == 1 and is_list_like(topic_set[0]):
92
- # type ignored b/c list-like check on line 88
93
- filter_params["topics"] = topic_set[0] # type: ignore
94
- else:
95
- filter_params["topics"] = topic_set
93
+ filter_params["topics"] = topic_set
96
94
 
97
95
  if address and contract_address:
98
96
  if is_list_like(address):
@@ -104,7 +102,7 @@ def construct_event_filter_params(
104
102
  else [address]
105
103
  )
106
104
  else:
107
- raise ValueError(
105
+ raise Web3ValueError(
108
106
  f"Unsupported type for `address` parameter: {type(address)}"
109
107
  )
110
108
  elif address:
@@ -120,11 +118,11 @@ def construct_event_filter_params(
120
118
  else:
121
119
  validate_address(filter_params["address"])
122
120
 
123
- if fromBlock is not None:
124
- filter_params["fromBlock"] = fromBlock
121
+ if from_block is not None:
122
+ filter_params["fromBlock"] = from_block
125
123
 
126
- if toBlock is not None:
127
- filter_params["toBlock"] = toBlock
124
+ if to_block is not None:
125
+ filter_params["toBlock"] = to_block
128
126
 
129
127
  data_filters_set = construct_event_data_set(event_abi, abi_codec, argument_filters)
130
128
 
@@ -178,7 +176,7 @@ class BaseFilter:
178
176
  class Filter(BaseFilter):
179
177
  def __init__(self, filter_id: HexStr, eth_module: "Eth") -> None:
180
178
  self.eth_module = eth_module
181
- super(Filter, self).__init__(filter_id)
179
+ super().__init__(filter_id)
182
180
 
183
181
  def get_new_entries(self) -> List[LogReceipt]:
184
182
  log_entries = self._filter_valid_entries(
@@ -196,7 +194,7 @@ class Filter(BaseFilter):
196
194
  class AsyncFilter(BaseFilter):
197
195
  def __init__(self, filter_id: HexStr, eth_module: "AsyncEth") -> None:
198
196
  self.eth_module = eth_module
199
- super(AsyncFilter, self).__init__(filter_id)
197
+ super().__init__(filter_id)
200
198
 
201
199
  async def get_new_entries(self) -> List[LogReceipt]:
202
200
  filter_changes = await self.eth_module.get_filter_changes(self.filter_id)
@@ -250,7 +248,8 @@ class LogFilter(Filter):
250
248
  def set_data_filters(
251
249
  self, data_filter_set: Collection[Tuple[TypeStr, Any]]
252
250
  ) -> None:
253
- """Sets the data filters (non indexed argument filters)
251
+ """
252
+ Sets the data filters (non indexed argument filters)
254
253
 
255
254
  Expects a set of tuples with the type and value, e.g.:
256
255
  (('uint256', [12345, 54321]), ('string', ('a-single-string',)))
@@ -292,7 +291,8 @@ class AsyncLogFilter(AsyncFilter):
292
291
  def set_data_filters(
293
292
  self, data_filter_set: Collection[Tuple[TypeStr, Any]]
294
293
  ) -> None:
295
- """Sets the data filters (non indexed argument filters)
294
+ """
295
+ Sets the data filters (non indexed argument filters)
296
296
 
297
297
  Expects a set of tuples with the type and value, e.g.:
298
298
  (('uint256', [12345, 54321]), ('string', ('a-single-string',)))
@@ -318,7 +318,8 @@ normalize_to_text = apply_formatter_if(not_text, decode_utf8_bytes)
318
318
 
319
319
 
320
320
  def normalize_data_values(type_string: TypeStr, data_value: Any) -> Any:
321
- """Decodes utf-8 bytes to strings for abi string values.
321
+ """
322
+ Decodes utf-8 bytes to strings for abi string values.
322
323
 
323
324
  eth-abi v1 returns utf-8 bytes for string values.
324
325
  This can be removed once eth-abi v2 is required.
@@ -326,7 +327,7 @@ def normalize_data_values(type_string: TypeStr, data_value: Any) -> Any:
326
327
  _type = parse_type_string(type_string)
327
328
  if _type.base == "string":
328
329
  if _type.arrlist is not None:
329
- return tuple((normalize_to_text(value) for value in data_value))
330
+ return tuple(normalize_to_text(value) for value in data_value)
330
331
  else:
331
332
  return normalize_to_text(data_value)
332
333
  return data_value
@@ -336,7 +337,8 @@ def normalize_data_values(type_string: TypeStr, data_value: Any) -> Any:
336
337
  def match_fn(
337
338
  codec: ABICodec, match_values_and_abi: Collection[Tuple[str, Any]], data: Any
338
339
  ) -> bool:
339
- """Match function used for filtering non-indexed event arguments.
340
+ """
341
+ Match function used for filtering non-indexed event arguments.
340
342
 
341
343
  Values provided through the match_values_and_abi parameter are
342
344
  compared to the abi decoded log data.
@@ -352,7 +354,7 @@ def match_fn(
352
354
  normalized_data = normalize_data_values(abi_type, data_value)
353
355
  for value in match_values:
354
356
  if not codec.is_encodable(abi_type, value):
355
- raise ValueError(
357
+ raise Web3ValueError(
356
358
  f"Value {value} is of the wrong abi type. "
357
359
  f"Expected {abi_type} typed value."
358
360
  )
web3/_utils/formatters.py CHANGED
@@ -114,13 +114,13 @@ def apply_key_map(
114
114
  def is_array_of_strings(value: Any) -> bool:
115
115
  if not is_list_like(value):
116
116
  return False
117
- return all((is_string(item) for item in value))
117
+ return all(is_string(item) for item in value)
118
118
 
119
119
 
120
120
  def is_array_of_dicts(value: Any) -> bool:
121
121
  if not is_list_like(value):
122
122
  return False
123
- return all((is_dict(item) for item in value))
123
+ return all(is_dict(item) for item in value)
124
124
 
125
125
 
126
126
  @curry
web3/_utils/http.py CHANGED
@@ -1,6 +1,12 @@
1
- def construct_user_agent(class_type: type) -> str:
1
+ DEFAULT_HTTP_TIMEOUT = 30.0
2
+
3
+
4
+ def construct_user_agent(
5
+ module: str,
6
+ class_name: str,
7
+ ) -> str:
2
8
  from web3 import (
3
9
  __version__ as web3_version,
4
10
  )
5
11
 
6
- return f"web3.py/{web3_version}/{class_type.__module__}.{class_type.__qualname__}"
12
+ return f"web3.py/{web3_version}/{module}.{class_name}"