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/abi.py CHANGED
@@ -25,7 +25,6 @@ from typing import (
25
25
  )
26
26
 
27
27
  from eth_abi import (
28
- codec,
29
28
  decoding,
30
29
  encoding,
31
30
  )
@@ -47,11 +46,24 @@ from eth_abi.registry import (
47
46
  registry as default_registry,
48
47
  )
49
48
  from eth_typing import (
49
+ ABI,
50
+ ABIComponent,
51
+ ABIComponentIndexed,
52
+ ABIConstructor,
53
+ ABIElement,
54
+ ABIEvent,
55
+ ABIFallback,
56
+ ABIFunction,
57
+ ABIReceive,
50
58
  HexStr,
51
59
  TypeStr,
52
60
  )
53
61
  from eth_utils import (
62
+ collapse_if_tuple,
54
63
  decode_hex,
64
+ filter_abi_by_type,
65
+ get_abi_input_names,
66
+ get_abi_input_types,
55
67
  is_bytes,
56
68
  is_list_like,
57
69
  is_string,
@@ -59,15 +71,16 @@ from eth_utils import (
59
71
  to_text,
60
72
  to_tuple,
61
73
  )
62
- from eth_utils.abi import (
63
- collapse_if_tuple,
64
- )
65
74
  from eth_utils.toolz import (
66
75
  curry,
67
76
  partial,
68
77
  pipe,
69
78
  )
70
79
 
80
+ from web3._utils.abi_element_identifiers import (
81
+ FallbackFn,
82
+ ReceiveFn,
83
+ )
71
84
  from web3._utils.decorators import (
72
85
  reject_recursive_repeats,
73
86
  )
@@ -78,20 +91,15 @@ from web3._utils.formatters import (
78
91
  recursive_map,
79
92
  )
80
93
  from web3.exceptions import (
81
- FallbackNotFound,
82
94
  MismatchedABI,
95
+ Web3AttributeError,
96
+ Web3TypeError,
97
+ Web3ValueError,
83
98
  )
84
99
  from web3.types import (
85
- ABI,
86
- ABIEvent,
87
- ABIEventParams,
88
- ABIFunction,
89
- ABIFunctionParams,
100
+ ABIElementIdentifier,
90
101
  TReturn,
91
102
  )
92
- from web3.utils import ( # public utils module
93
- get_abi_input_names,
94
- )
95
103
 
96
104
  if TYPE_CHECKING:
97
105
  from web3 import ( # noqa: F401
@@ -99,92 +107,94 @@ if TYPE_CHECKING:
99
107
  )
100
108
 
101
109
 
102
- def filter_by_type(_type: str, contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
103
- return [abi for abi in contract_abi if abi["type"] == _type]
104
-
110
+ def fallback_func_abi_exists(contract_abi: ABI) -> Sequence[ABIFallback]:
111
+ return filter_abi_by_type("fallback", contract_abi)
105
112
 
106
- def filter_by_name(name: str, contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
107
- return [
108
- abi
109
- for abi in contract_abi
110
- if (
111
- abi["type"] not in ("fallback", "constructor", "receive")
112
- and abi["name"] == name
113
- )
114
- ]
115
113
 
116
-
117
- def get_abi_input_types(abi: ABIFunction) -> List[str]:
118
- if "inputs" not in abi and (abi["type"] == "fallback" or abi["type"] == "receive"):
119
- return []
120
- else:
121
- return [collapse_if_tuple(cast(Dict[str, Any], arg)) for arg in abi["inputs"]]
122
-
123
-
124
- def get_abi_output_types(abi: ABIFunction) -> List[str]:
125
- if abi["type"] == "fallback":
126
- return []
127
- else:
128
- return [collapse_if_tuple(cast(Dict[str, Any], arg)) for arg in abi["outputs"]]
114
+ def receive_func_abi_exists(contract_abi: ABI) -> Sequence[ABIReceive]:
115
+ return filter_abi_by_type("receive", contract_abi)
129
116
 
130
117
 
131
- def get_receive_func_abi(contract_abi: ABI) -> ABIFunction:
132
- receive_abis = filter_by_type("receive", contract_abi)
133
- if receive_abis:
134
- return cast(ABIFunction, receive_abis[0])
135
- else:
136
- raise FallbackNotFound("No receive function was found in the contract ABI.")
137
-
118
+ def get_indexed_event_inputs(event_abi: ABIEvent) -> Sequence[ABIComponentIndexed]:
119
+ return [arg for arg in event_abi["inputs"] if arg["indexed"] is True]
138
120
 
139
- def get_fallback_func_abi(contract_abi: ABI) -> ABIFunction:
140
- fallback_abis = filter_by_type("fallback", contract_abi)
141
- if fallback_abis:
142
- return cast(ABIFunction, fallback_abis[0])
143
- else:
144
- raise FallbackNotFound("No fallback function was found in the contract ABI.")
145
121
 
122
+ def exclude_indexed_event_inputs(event_abi: ABIEvent) -> Sequence[ABIComponentIndexed]:
123
+ return [arg for arg in event_abi["inputs"] if arg["indexed"] is False]
146
124
 
147
- def fallback_func_abi_exists(contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
148
- return filter_by_type("fallback", contract_abi)
149
125
 
126
+ def filter_by_types(types: Collection[str], contract_abi: ABI) -> Sequence[ABIElement]:
127
+ return [abi_element for abi_element in contract_abi if abi_element["type"] in types]
150
128
 
151
- def receive_func_abi_exists(contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
152
- return filter_by_type("receive", contract_abi)
153
129
 
130
+ def filter_by_argument_name(
131
+ argument_names: Collection[str], contract_abi: ABI
132
+ ) -> Sequence[ABIElement]:
133
+ """
134
+ Return a list of each ``ABIElement`` which contain arguments matching provided
135
+ names.
136
+ """
137
+ abis_with_matching_args = []
138
+ for abi_element in contract_abi:
139
+ try:
140
+ abi_arg_names = get_abi_input_names(abi_element)
154
141
 
155
- def get_indexed_event_inputs(event_abi: ABIEvent) -> List[ABIEventParams]:
156
- return [arg for arg in event_abi["inputs"] if arg["indexed"] is True]
142
+ if set(argument_names).intersection(abi_arg_names) == set(argument_names):
143
+ abis_with_matching_args.append(abi_element)
144
+ except TypeError:
145
+ # fallback or receive functions do not have arguments
146
+ # proceed to next ABIElement
147
+ continue
157
148
 
149
+ return abis_with_matching_args
158
150
 
159
- def exclude_indexed_event_inputs(event_abi: ABIEvent) -> List[ABIEventParams]:
160
- return [arg for arg in event_abi["inputs"] if arg["indexed"] is False]
161
151
 
162
-
163
- def get_normalized_abi_arg_type(abi_arg: ABIEventParams) -> str:
152
+ def filter_by_argument_type(
153
+ argument_types: Collection[str], contract_abi: ABI
154
+ ) -> List[ABIElement]:
164
155
  """
165
- Return the normalized type for the abi argument provided.
166
- In order to account for tuple argument types, this abstraction
167
- makes use of `collapse_if_tuple()` to collapse the appropriate component
168
- types within a tuple type, if present.
156
+ Return a list of each ``ABIElement`` which contain arguments matching provided
157
+ types.
169
158
  """
170
- return collapse_if_tuple(dict(abi_arg))
159
+ abis_with_matching_args = []
160
+ for abi_element in contract_abi:
161
+ try:
162
+ abi_arg_types = get_abi_input_types(abi_element)
163
+
164
+ if set(argument_types).intersection(abi_arg_types) == set(argument_types):
165
+ abis_with_matching_args.append(abi_element)
166
+ except ValueError:
167
+ # fallback or receive functions do not have arguments
168
+ # proceed to next ABIElement
169
+ continue
170
+
171
+ return abis_with_matching_args
172
+
173
+
174
+ def get_name_from_abi_element_identifier(
175
+ abi_element_identifier: ABIElementIdentifier,
176
+ ) -> str:
177
+ if abi_element_identifier in ["fallback", FallbackFn]:
178
+ return "fallback"
179
+ elif abi_element_identifier in ["receive", ReceiveFn]:
180
+ return "receive"
181
+ elif is_text(abi_element_identifier):
182
+ return str(abi_element_identifier).split("(")[0]
183
+ else:
184
+ raise Web3TypeError("Unsupported function identifier")
171
185
 
172
186
 
173
- def filter_by_argument_count(
174
- num_arguments: int, contract_abi: ABI
175
- ) -> List[Union[ABIFunction, ABIEvent]]:
176
- return [abi for abi in contract_abi if len(abi["inputs"]) == num_arguments]
187
+ def get_abi_element_signature(
188
+ abi_element_identifier: ABIElementIdentifier,
189
+ abi_element_argument_types: Optional[Sequence[str]] = None,
190
+ ) -> str:
191
+ element_name = get_name_from_abi_element_identifier(abi_element_identifier)
192
+ argument_types = ",".join(abi_element_argument_types or [])
177
193
 
194
+ if element_name in ["fallback", "receive"]:
195
+ return element_name
178
196
 
179
- def filter_by_argument_name(
180
- argument_names: Collection[str], contract_abi: ABI
181
- ) -> List[Union[ABIFunction, ABIEvent]]:
182
- return [
183
- abi
184
- for abi in contract_abi
185
- if set(argument_names).intersection(get_abi_input_names(abi))
186
- == set(argument_names)
187
- ]
197
+ return f"{element_name}({argument_types})"
188
198
 
189
199
 
190
200
  class AddressEncoder(encoding.AddressEncoder):
@@ -193,7 +203,7 @@ class AddressEncoder(encoding.AddressEncoder):
193
203
  if is_ens_name(value):
194
204
  return
195
205
 
196
- super().validate_value(value)
206
+ super().validate_value(value) # type: ignore[no-untyped-call]
197
207
 
198
208
 
199
209
  class AcceptsHexStrEncoder(encoding.BaseEncoder):
@@ -208,7 +218,7 @@ class AcceptsHexStrEncoder(encoding.BaseEncoder):
208
218
  subencoder: encoding.BaseEncoder,
209
219
  **kwargs: Dict[str, Any],
210
220
  ) -> None:
211
- super().__init__(**kwargs)
221
+ super().__init__(**kwargs) # type: ignore[no-untyped-call]
212
222
  self.subencoder = subencoder
213
223
  self.is_dynamic = subencoder.is_dynamic
214
224
 
@@ -220,14 +230,14 @@ class AcceptsHexStrEncoder(encoding.BaseEncoder):
220
230
  # cast b/c expects BaseCoder but `from_type_string`
221
231
  # restricted to BaseEncoder subclasses
222
232
  subencoder = cast(
223
- encoding.BaseEncoder, subencoder_cls.from_type_str(abi_type, registry)
233
+ encoding.BaseEncoder, subencoder_cls.from_type_str(abi_type, registry) # type: ignore[no-untyped-call] # noqa: E501
224
234
  )
225
235
  return cls(subencoder)
226
236
 
227
237
  @classmethod
228
238
  def get_subencoder_class(cls) -> Type[encoding.BaseEncoder]:
229
239
  if cls.subencoder_cls is None:
230
- raise AttributeError(f"No subencoder class is set. {cls.__name__}")
240
+ raise Web3AttributeError(f"No subencoder class is set. {cls.__name__}")
231
241
  return cls.subencoder_cls
232
242
 
233
243
  def validate_value(self, value: Any) -> None:
@@ -285,35 +295,39 @@ class ExactLengthBytesEncoder(BytesEncoder):
285
295
  is_strict = True
286
296
 
287
297
  def validate(self) -> None:
288
- super().validate()
298
+ super().validate() # type: ignore[no-untyped-call]
289
299
  if self.value_bit_size is None:
290
- raise ValueError("`value_bit_size` may not be none")
300
+ raise Web3ValueError("`value_bit_size` may not be none")
291
301
  if self.data_byte_size is None:
292
- raise ValueError("`data_byte_size` may not be none")
302
+ raise Web3ValueError("`data_byte_size` may not be none")
293
303
  if self.is_big_endian is None:
294
- raise ValueError("`is_big_endian` may not be none")
304
+ raise Web3ValueError("`is_big_endian` may not be none")
295
305
 
296
306
  if self.value_bit_size % 8 != 0:
297
- raise ValueError(
307
+ raise Web3ValueError(
298
308
  f"Invalid value bit size: {self.value_bit_size}. "
299
309
  "Must be a multiple of 8"
300
310
  )
301
311
 
302
312
  if self.value_bit_size > self.data_byte_size * 8:
303
- raise ValueError("Value byte size exceeds data size")
313
+ raise Web3ValueError("Value byte size exceeds data size")
304
314
 
305
- @parse_type_str("bytes")
315
+ @parse_type_str("bytes") # type: ignore[no-untyped-call]
306
316
  def from_type_str(
307
317
  cls, abi_type: BasicType, registry: ABIRegistry
308
318
  ) -> "ExactLengthBytesEncoder":
309
319
  subencoder_cls = cls.get_subencoder_class()
310
- subencoder = subencoder_cls.from_type_str(abi_type.to_type_str(), registry)
311
- # type ignored b/c @parse_type_str decorator turns it into a classmethod,
312
- # so mypy thinks cls(...) is a call to __call__, but actually calls __init__
313
- return cls( # type: ignore
314
- subencoder,
315
- value_bit_size=abi_type.sub * 8,
316
- data_byte_size=abi_type.sub,
320
+ subencoder = subencoder_cls.from_type_str(abi_type.to_type_str(), registry) # type: ignore[no-untyped-call] # noqa: E501
321
+ return cast(
322
+ ExactLengthBytesEncoder,
323
+ # type ignored b/c mypy thinks the __call__ is from BaseEncoder, but it's
324
+ # from ExactLengthBytesEncoder, which does have value_bit_size and
325
+ # data_byte_size attributes
326
+ cls( # type: ignore[call-arg]
327
+ subencoder,
328
+ value_bit_size=abi_type.sub * 8,
329
+ data_byte_size=abi_type.sub,
330
+ ),
317
331
  )
318
332
 
319
333
 
@@ -339,110 +353,7 @@ class TextStringEncoder(encoding.TextStringEncoder):
339
353
  msg="not decodable as unicode string",
340
354
  )
341
355
 
342
- super().validate_value(value)
343
-
344
-
345
- def filter_by_encodability(
346
- abi_codec: codec.ABIEncoder,
347
- args: Sequence[Any],
348
- kwargs: Dict[str, Any],
349
- contract_abi: ABI,
350
- ) -> List[ABIFunction]:
351
- return [
352
- cast(ABIFunction, function_abi)
353
- for function_abi in contract_abi
354
- if check_if_arguments_can_be_encoded(
355
- cast(ABIFunction, function_abi), abi_codec, args, kwargs
356
- )
357
- ]
358
-
359
-
360
- def check_if_arguments_can_be_encoded(
361
- function_abi: ABIFunction,
362
- abi_codec: codec.ABIEncoder,
363
- args: Sequence[Any],
364
- kwargs: Dict[str, Any],
365
- ) -> bool:
366
- try:
367
- arguments = merge_args_and_kwargs(function_abi, args, kwargs)
368
- except TypeError:
369
- return False
370
-
371
- if len(function_abi.get("inputs", [])) != len(arguments):
372
- return False
373
-
374
- try:
375
- types, aligned_args = get_aligned_abi_inputs(function_abi, arguments)
376
- except TypeError:
377
- return False
378
-
379
- return all(
380
- abi_codec.is_encodable(_type, arg) for _type, arg in zip(types, aligned_args)
381
- )
382
-
383
-
384
- def merge_args_and_kwargs(
385
- function_abi: ABIFunction, args: Sequence[Any], kwargs: Dict[str, Any]
386
- ) -> Tuple[Any, ...]:
387
- """
388
- Takes a list of positional args (``args``) and a dict of keyword args
389
- (``kwargs``) defining values to be passed to a call to the contract function
390
- described by ``function_abi``. Checks to ensure that the correct number of
391
- args were given, no duplicate args were given, and no unknown args were
392
- given. Returns a list of argument values aligned to the order of inputs
393
- defined in ``function_abi``.
394
- """
395
- # Ensure the function is being applied to the correct number of args
396
- if len(args) + len(kwargs) != len(function_abi.get("inputs", [])):
397
- raise TypeError(
398
- f"Incorrect argument count. Expected '{len(function_abi['inputs'])}'"
399
- f". Got '{len(args) + len(kwargs)}'"
400
- )
401
-
402
- # If no keyword args were given, we don't need to align them
403
- if not kwargs:
404
- return cast(Tuple[Any, ...], args)
405
-
406
- kwarg_names = set(kwargs.keys())
407
- sorted_arg_names = tuple(arg_abi["name"] for arg_abi in function_abi["inputs"])
408
- args_as_kwargs = dict(zip(sorted_arg_names, args))
409
-
410
- # Check for duplicate args
411
- duplicate_args = kwarg_names.intersection(args_as_kwargs.keys())
412
- if duplicate_args:
413
- raise TypeError(
414
- f"{function_abi.get('name')}() got multiple values for argument(s) "
415
- f"'{', '.join(duplicate_args)}'"
416
- )
417
-
418
- # Check for unknown args
419
- unknown_args = kwarg_names.difference(sorted_arg_names)
420
- if unknown_args:
421
- if function_abi.get("name"):
422
- raise TypeError(
423
- f"{function_abi.get('name')}() got unexpected keyword argument(s)"
424
- f" '{', '.join(unknown_args)}'"
425
- )
426
- raise TypeError(
427
- f"Type: '{function_abi.get('type')}' got unexpected keyword argument(s)"
428
- f" '{', '.join(unknown_args)}'"
429
- )
430
-
431
- # Sort args according to their position in the ABI and unzip them from their
432
- # names
433
- sorted_args = tuple(
434
- zip(
435
- *sorted(
436
- itertools.chain(kwargs.items(), args_as_kwargs.items()),
437
- key=lambda kv: sorted_arg_names.index(kv[0]),
438
- )
439
- )
440
- )
441
-
442
- if sorted_args:
443
- return sorted_args[1]
444
- else:
445
- return tuple()
356
+ super().validate_value(value) # type: ignore[no-untyped-call]
446
357
 
447
358
 
448
359
  TUPLE_TYPE_STR_RE = re.compile(r"^(tuple)((\[([1-9]\d*\b)?])*)??$")
@@ -464,7 +375,9 @@ def get_tuple_type_str_parts(s: str) -> Optional[Tuple[str, Optional[str]]]:
464
375
  return None
465
376
 
466
377
 
467
- def _align_abi_input(arg_abi: ABIFunctionParams, arg: Any) -> Tuple[Any, ...]:
378
+ def _align_abi_input(
379
+ arg_abi: Union[ABIComponent, ABIComponentIndexed], arg: Any
380
+ ) -> Tuple[Any, ...]:
468
381
  """
469
382
  Aligns the values of any mapping at any level of nesting in ``arg``
470
383
  according to the layout of the corresponding abi spec.
@@ -488,7 +401,7 @@ def _align_abi_input(arg_abi: ABIFunctionParams, arg: Any) -> Tuple[Any, ...]:
488
401
  new_abi = copy.copy(arg_abi)
489
402
  new_abi["type"] = tuple_prefix + "[]" * (num_dims - 1)
490
403
 
491
- sub_abis = itertools.repeat(new_abi) # type: ignore
404
+ sub_abis = [cast(ABIComponent, abi) for abi in itertools.repeat(new_abi)]
492
405
 
493
406
  if isinstance(arg, abc.Mapping):
494
407
  # Arg is mapping. Align values according to abi order.
@@ -497,7 +410,7 @@ def _align_abi_input(arg_abi: ABIFunctionParams, arg: Any) -> Tuple[Any, ...]:
497
410
  aligned_arg = arg
498
411
 
499
412
  if not is_list_like(aligned_arg):
500
- raise TypeError(
413
+ raise Web3TypeError(
501
414
  f'Expected non-string sequence for "{arg_abi.get("type")}" '
502
415
  f"component type: got {aligned_arg}"
503
416
  )
@@ -511,38 +424,21 @@ def _align_abi_input(arg_abi: ABIFunctionParams, arg: Any) -> Tuple[Any, ...]:
511
424
  )
512
425
 
513
426
 
514
- def get_aligned_abi_inputs(
515
- abi: ABIFunction, args: Union[Tuple[Any, ...], Mapping[Any, Any]]
516
- ) -> Tuple[Tuple[Any, ...], Tuple[Any, ...]]:
427
+ def find_constructor_abi_element_by_type(contract_abi: ABI) -> ABIConstructor:
517
428
  """
518
- Takes a function ABI (``abi``) and a sequence or mapping of args (``args``).
519
- Returns a list of type strings for the function's inputs and a list of
520
- arguments which have been aligned to the layout of those types. The args
521
- contained in ``args`` may contain nested mappings or sequences corresponding
522
- to tuple-encoded values in ``abi``.
523
- """
524
- input_abis = abi.get("inputs", [])
525
-
526
- if isinstance(args, abc.Mapping):
527
- # `args` is mapping. Align values according to abi order.
528
- args = tuple(args[abi["name"]] for abi in input_abis)
529
-
530
- return (
531
- # typed dict cannot be used w/ a normal Dict
532
- # https://github.com/python/mypy/issues/4976
533
- tuple(collapse_if_tuple(abi) for abi in input_abis), # type: ignore
534
- type(args)(_align_abi_input(abi, arg) for abi, arg in zip(input_abis, args)),
535
- )
536
-
429
+ Find the constructor ABI element in the contract ABI.
537
430
 
538
- def get_constructor_abi(contract_abi: ABI) -> ABIFunction:
431
+ This function is often used in place of `web3.utils.abi.get_abi_element` to find
432
+ a constructor without considering it's argument types. This is used prior to
433
+ encoding the abi, since the argument types are not known at that time.
434
+ """
539
435
  candidates = [abi for abi in contract_abi if abi["type"] == "constructor"]
540
436
  if len(candidates) == 1:
541
437
  return candidates[0]
542
438
  elif len(candidates) == 0:
543
439
  return None
544
440
  elif len(candidates) > 1:
545
- raise ValueError("Found multiple constructors.")
441
+ raise Web3ValueError("Found multiple constructors.")
546
442
  return None
547
443
 
548
444
 
@@ -564,7 +460,7 @@ STATIC_TYPES = list(
564
460
  )
565
461
 
566
462
  BASE_TYPE_REGEX = "|".join(
567
- (_type + "(?![a-z0-9])" for _type in itertools.chain(STATIC_TYPES, DYNAMIC_TYPES))
463
+ _type + "(?![a-z0-9])" for _type in itertools.chain(STATIC_TYPES, DYNAMIC_TYPES)
568
464
  )
569
465
 
570
466
  SUB_TYPE_REGEX = r"\[" "[0-9]*" r"\]"
@@ -630,14 +526,14 @@ END_BRACKETS_OF_ARRAY_TYPE_REGEX = r"\[[^]]*\]$"
630
526
 
631
527
  def sub_type_of_array_type(abi_type: TypeStr) -> str:
632
528
  if not is_array_type(abi_type):
633
- raise ValueError(f"Cannot parse subtype of nonarray abi-type: {abi_type}")
529
+ raise Web3ValueError(f"Cannot parse subtype of nonarray abi-type: {abi_type}")
634
530
 
635
- return re.sub(END_BRACKETS_OF_ARRAY_TYPE_REGEX, "", abi_type, 1)
531
+ return re.sub(END_BRACKETS_OF_ARRAY_TYPE_REGEX, "", abi_type, count=1)
636
532
 
637
533
 
638
534
  def length_of_array_type(abi_type: TypeStr) -> int:
639
535
  if not is_array_type(abi_type):
640
- raise ValueError(f"Cannot parse length of nonarray abi-type: {abi_type}")
536
+ raise Web3ValueError(f"Cannot parse length of nonarray abi-type: {abi_type}")
641
537
 
642
538
  inner_brackets = (
643
539
  re.search(END_BRACKETS_OF_ARRAY_TYPE_REGEX, abi_type).group(0).strip("[]")
@@ -669,8 +565,8 @@ def is_probably_enum(abi_type: TypeStr) -> bool:
669
565
 
670
566
  @to_tuple
671
567
  def normalize_event_input_types(
672
- abi_args: Collection[Union[ABIFunction, ABIEvent]]
673
- ) -> Iterable[Union[ABIFunction, ABIEvent, Dict[TypeStr, Any]]]:
568
+ abi_args: Collection[ABIEvent],
569
+ ) -> Iterable[Union[ABIEvent, Dict[TypeStr, Any]]]:
674
570
  for arg in abi_args:
675
571
  if is_recognized_type(arg["type"]):
676
572
  yield arg
@@ -680,17 +576,6 @@ def normalize_event_input_types(
680
576
  yield arg
681
577
 
682
578
 
683
- def abi_to_signature(abi: Union[ABIFunction, ABIEvent]) -> str:
684
- function_signature = "{fn_name}({fn_input_types})".format(
685
- fn_name=abi["name"],
686
- fn_input_types=",".join(
687
- collapse_if_tuple(dict(arg))
688
- for arg in normalize_event_input_types(abi.get("inputs", []))
689
- ),
690
- )
691
- return function_signature
692
-
693
-
694
579
  ########################################################
695
580
  #
696
581
  # Conditionally modifying data, tagged with ABI Types
@@ -705,8 +590,8 @@ def map_abi_data(
705
590
  data: Sequence[Any],
706
591
  ) -> Any:
707
592
  """
708
- This function will apply normalizers to your data, in the
709
- context of the relevant types. Each normalizer is in the format:
593
+ Applies normalizers to your data, in the context of the relevant types.
594
+ Each normalizer is in the format:
710
595
 
711
596
  def normalizer(datatype, data):
712
597
  # Conditionally modify data
@@ -772,7 +657,7 @@ def data_tree_map(
772
657
 
773
658
  class ABITypedData(namedtuple("ABITypedData", "abi_type, data")):
774
659
  """
775
- This class marks data as having a certain ABI-type.
660
+ Marks data as having a certain ABI-type.
776
661
 
777
662
  >>> a1 = ABITypedData(['address', addr1])
778
663
  >>> a2 = ABITypedData(['address', addr2])
@@ -841,7 +726,7 @@ def strip_abi_type(elements: Any) -> Any:
841
726
  def build_non_strict_registry() -> ABIRegistry:
842
727
  # We make a copy here just to make sure that eth-abi's default registry is not
843
728
  # affected by our custom encoder subclasses
844
- registry = default_registry.copy()
729
+ registry = default_registry.copy() # type: ignore[no-untyped-call]
845
730
 
846
731
  registry.unregister("address")
847
732
  registry.unregister("bytes<M>")
@@ -849,25 +734,25 @@ def build_non_strict_registry() -> ABIRegistry:
849
734
  registry.unregister("string")
850
735
 
851
736
  registry.register(
852
- BaseEquals("address"),
737
+ BaseEquals("address"), # type: ignore[no-untyped-call]
853
738
  AddressEncoder,
854
739
  decoding.AddressDecoder,
855
740
  label="address",
856
741
  )
857
742
  registry.register(
858
- BaseEquals("bytes", with_sub=True),
743
+ BaseEquals("bytes", with_sub=True), # type: ignore[no-untyped-call]
859
744
  BytesEncoder,
860
745
  decoding.BytesDecoder,
861
746
  label="bytes<M>",
862
747
  )
863
748
  registry.register(
864
- BaseEquals("bytes", with_sub=False),
749
+ BaseEquals("bytes", with_sub=False), # type: ignore[no-untyped-call]
865
750
  ByteStringEncoder,
866
751
  decoding.ByteStringDecoder,
867
752
  label="bytes",
868
753
  )
869
754
  registry.register(
870
- BaseEquals("string"),
755
+ BaseEquals("string"), # type: ignore[no-untyped-call]
871
756
  TextStringEncoder,
872
757
  decoding.StringDecoder,
873
758
  label="string",
@@ -876,7 +761,7 @@ def build_non_strict_registry() -> ABIRegistry:
876
761
 
877
762
 
878
763
  def build_strict_registry() -> ABIRegistry:
879
- registry = default_registry.copy()
764
+ registry = default_registry.copy() # type: ignore[no-untyped-call]
880
765
 
881
766
  registry.unregister("address")
882
767
  registry.unregister("bytes<M>")
@@ -884,25 +769,25 @@ def build_strict_registry() -> ABIRegistry:
884
769
  registry.unregister("string")
885
770
 
886
771
  registry.register(
887
- BaseEquals("address"),
772
+ BaseEquals("address"), # type: ignore[no-untyped-call]
888
773
  AddressEncoder,
889
774
  decoding.AddressDecoder,
890
775
  label="address",
891
776
  )
892
777
  registry.register(
893
- BaseEquals("bytes", with_sub=True),
778
+ BaseEquals("bytes", with_sub=True), # type: ignore[no-untyped-call]
894
779
  ExactLengthBytesEncoder,
895
780
  decoding.BytesDecoder,
896
781
  label="bytes<M>",
897
782
  )
898
783
  registry.register(
899
- BaseEquals("bytes", with_sub=False),
784
+ BaseEquals("bytes", with_sub=False), # type: ignore[no-untyped-call]
900
785
  StrictByteStringEncoder,
901
786
  decoding.ByteStringDecoder,
902
787
  label="bytes",
903
788
  )
904
789
  registry.register(
905
- BaseEquals("string"),
790
+ BaseEquals("string"), # type: ignore[no-untyped-call]
906
791
  encoding.TextStringEncoder,
907
792
  decoding.StringDecoder,
908
793
  label="string",
@@ -911,7 +796,11 @@ def build_strict_registry() -> ABIRegistry:
911
796
 
912
797
 
913
798
  def named_tree(
914
- abi: Iterable[Union[ABIFunctionParams, ABIFunction, ABIEvent, Dict[TypeStr, Any]]],
799
+ abi: Iterable[
800
+ Union[
801
+ ABIComponent, ABIComponentIndexed, ABIFunction, ABIEvent, Dict[TypeStr, Any]
802
+ ]
803
+ ],
915
804
  data: Iterable[Tuple[Any, ...]],
916
805
  ) -> Dict[str, Any]:
917
806
  """
@@ -924,10 +813,12 @@ def named_tree(
924
813
 
925
814
 
926
815
  def _named_subtree(
927
- abi: Union[ABIFunctionParams, ABIFunction, ABIEvent, Dict[TypeStr, Any]],
816
+ abi: Union[
817
+ ABIComponent, ABIComponentIndexed, ABIFunction, ABIEvent, Dict[TypeStr, Any]
818
+ ],
928
819
  data: Tuple[Any, ...],
929
820
  ) -> Union[Dict[str, Any], Tuple[Any, ...], List[Any]]:
930
- abi_type = parse(collapse_if_tuple(dict(abi)))
821
+ abi_type = parse(collapse_if_tuple(cast(Dict[str, Any], abi)))
931
822
 
932
823
  if abi_type.is_array:
933
824
  item_type = abi_type.item_type.to_type_str()
@@ -936,7 +827,11 @@ def _named_subtree(
936
827
  return items
937
828
 
938
829
  elif isinstance(abi_type, TupleType):
939
- abi = cast(ABIFunctionParams, abi)
830
+ if abi.get("indexed"):
831
+ abi = cast(ABIComponentIndexed, abi)
832
+ else:
833
+ abi = cast(ABIComponent, abi)
834
+
940
835
  names = [item["name"] for item in abi["components"]]
941
836
  items = [_named_subtree(*item) for item in zip(abi["components"], data)]
942
837
 
@@ -1029,7 +924,6 @@ async def async_map_if_collection(
1029
924
  Apply an awaitable method to each element of a collection or value of a dictionary.
1030
925
  If the value is not a collection, return it unmodified.
1031
926
  """
1032
-
1033
927
  datatype = type(value)
1034
928
  if isinstance(value, Mapping):
1035
929
  return datatype({key: await func(val) for key, val in value.values()})