web3 7.0.0b8__py3-none-any.whl → 7.1.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 (46) hide show
  1. ens/async_ens.py +16 -7
  2. ens/base_ens.py +3 -1
  3. ens/exceptions.py +2 -7
  4. ens/utils.py +0 -17
  5. web3/_utils/abi.py +100 -257
  6. web3/_utils/compat/__init__.py +1 -0
  7. web3/_utils/contracts.py +116 -205
  8. web3/_utils/encoding.py +4 -5
  9. web3/_utils/events.py +28 -33
  10. web3/_utils/fee_utils.py +2 -2
  11. web3/_utils/filters.py +2 -5
  12. web3/_utils/http_session_manager.py +30 -7
  13. web3/_utils/method_formatters.py +3 -3
  14. web3/_utils/module_testing/eth_module.py +59 -37
  15. web3/_utils/module_testing/module_testing_utils.py +43 -1
  16. web3/_utils/module_testing/persistent_connection_provider.py +2 -0
  17. web3/_utils/module_testing/web3_module.py +8 -8
  18. web3/_utils/normalizers.py +10 -8
  19. web3/_utils/validation.py +5 -7
  20. web3/beacon/api_endpoints.py +3 -0
  21. web3/beacon/async_beacon.py +18 -2
  22. web3/beacon/beacon.py +18 -2
  23. web3/contract/async_contract.py +26 -25
  24. web3/contract/base_contract.py +116 -80
  25. web3/contract/contract.py +26 -25
  26. web3/contract/utils.py +86 -55
  27. web3/datastructures.py +21 -11
  28. web3/eth/async_eth.py +1 -2
  29. web3/eth/eth.py +1 -2
  30. web3/exceptions.py +22 -9
  31. web3/gas_strategies/time_based.py +4 -0
  32. web3/manager.py +34 -12
  33. web3/middleware/base.py +8 -0
  34. web3/middleware/filter.py +3 -3
  35. web3/middleware/signing.py +6 -1
  36. web3/scripts/install_pre_releases.py +33 -0
  37. web3/scripts/parse_pygeth_version.py +16 -0
  38. web3/types.py +5 -45
  39. web3/utils/__init__.py +48 -4
  40. web3/utils/abi.py +575 -10
  41. {web3-7.0.0b8.dist-info → web3-7.1.0.dist-info}/METADATA +10 -10
  42. {web3-7.0.0b8.dist-info → web3-7.1.0.dist-info}/RECORD +46 -44
  43. {web3-7.0.0b8.dist-info → web3-7.1.0.dist-info}/WHEEL +1 -1
  44. /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
  45. {web3-7.0.0b8.dist-info → web3-7.1.0.dist-info}/LICENSE +0 -0
  46. {web3-7.0.0b8.dist-info → web3-7.1.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,23 @@ 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,
55
66
  is_bytes,
56
67
  is_list_like,
57
68
  is_string,
@@ -59,9 +70,6 @@ from eth_utils import (
59
70
  to_text,
60
71
  to_tuple,
61
72
  )
62
- from eth_utils.abi import (
63
- collapse_if_tuple,
64
- )
65
73
  from eth_utils.toolz import (
66
74
  curry,
67
75
  partial,
@@ -78,23 +86,14 @@ from web3._utils.formatters import (
78
86
  recursive_map,
79
87
  )
80
88
  from web3.exceptions import (
81
- FallbackNotFound,
82
89
  MismatchedABI,
83
90
  Web3AttributeError,
84
91
  Web3TypeError,
85
92
  Web3ValueError,
86
93
  )
87
94
  from web3.types import (
88
- ABI,
89
- ABIEvent,
90
- ABIEventParams,
91
- ABIFunction,
92
- ABIFunctionParams,
93
95
  TReturn,
94
96
  )
95
- from web3.utils import ( # public utils module
96
- get_abi_input_names,
97
- )
98
97
 
99
98
  if TYPE_CHECKING:
100
99
  from web3 import ( # noqa: F401
@@ -102,106 +101,62 @@ if TYPE_CHECKING:
102
101
  )
103
102
 
104
103
 
105
- def filter_by_type(_type: str, contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
106
- return [abi for abi in contract_abi if abi["type"] == _type]
107
-
108
-
109
- def filter_by_name(name: str, contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
110
- return [
111
- abi
112
- for abi in contract_abi
113
- if (
114
- abi["type"] not in ("fallback", "constructor", "receive")
115
- and abi["name"] == name
116
- )
117
- ]
118
-
119
-
120
- def get_abi_input_types(abi: ABIFunction) -> List[str]:
121
- if "inputs" not in abi and (abi["type"] == "fallback" or abi["type"] == "receive"):
122
- return []
123
- else:
124
- return [collapse_if_tuple(cast(Dict[str, Any], arg)) for arg in abi["inputs"]]
125
-
126
-
127
- def get_abi_output_types(abi: ABIFunction) -> List[str]:
128
- if abi["type"] == "fallback":
129
- return []
130
- else:
131
- return [collapse_if_tuple(cast(Dict[str, Any], arg)) for arg in abi["outputs"]]
132
-
133
-
134
- def get_receive_func_abi(contract_abi: ABI) -> ABIFunction:
135
- receive_abis = filter_by_type("receive", contract_abi)
136
- if receive_abis:
137
- return cast(ABIFunction, receive_abis[0])
138
- else:
139
- raise FallbackNotFound("No receive function was found in the contract ABI.")
140
-
141
-
142
- def get_fallback_func_abi(contract_abi: ABI) -> ABIFunction:
143
- fallback_abis = filter_by_type("fallback", contract_abi)
144
- if fallback_abis:
145
- return cast(ABIFunction, fallback_abis[0])
146
- else:
147
- raise FallbackNotFound("No fallback function was found in the contract ABI.")
148
-
149
-
150
- def fallback_func_abi_exists(contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
151
- return filter_by_type("fallback", contract_abi)
104
+ def fallback_func_abi_exists(contract_abi: ABI) -> Sequence[ABIFallback]:
105
+ return filter_abi_by_type("fallback", contract_abi)
152
106
 
153
107
 
154
- def receive_func_abi_exists(contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
155
- return filter_by_type("receive", contract_abi)
108
+ def receive_func_abi_exists(contract_abi: ABI) -> Sequence[ABIReceive]:
109
+ return filter_abi_by_type("receive", contract_abi)
156
110
 
157
111
 
158
- def get_indexed_event_inputs(event_abi: ABIEvent) -> List[ABIEventParams]:
159
- return [arg for arg in event_abi["inputs"] if arg["indexed"] is True]
112
+ def get_indexed_event_inputs(event_abi: ABIEvent) -> Sequence[ABIComponentIndexed]:
113
+ return [
114
+ cast(ABIComponentIndexed, arg)
115
+ for arg in event_abi["inputs"]
116
+ if cast(ABIComponentIndexed, arg)["indexed"] is True
117
+ ]
160
118
 
161
119
 
162
- def exclude_indexed_event_inputs(event_abi: ABIEvent) -> List[ABIEventParams]:
163
- return [arg for arg in event_abi["inputs"] if arg["indexed"] is False]
120
+ def exclude_indexed_event_inputs(event_abi: ABIEvent) -> Sequence[ABIComponent]:
121
+ return [
122
+ arg
123
+ for arg in event_abi["inputs"]
124
+ if cast(ABIComponentIndexed, arg)["indexed"] is False
125
+ ]
164
126
 
165
127
 
166
- def get_normalized_abi_arg_type(abi_arg: ABIEventParams) -> str:
128
+ def filter_by_argument_name(
129
+ argument_names: Collection[str], contract_abi: ABI
130
+ ) -> List[ABIElement]:
167
131
  """
168
- Return the normalized type for the abi argument provided.
169
- In order to account for tuple argument types, this abstraction
170
- makes use of `collapse_if_tuple()` to collapse the appropriate component
171
- types within a tuple type, if present.
132
+ Return a list of each ``ABIElement`` which contain arguments matching provided
133
+ names.
172
134
  """
173
- return collapse_if_tuple(dict(abi_arg))
135
+ abis_with_matching_args = []
136
+ for abi_element in contract_abi:
137
+ try:
138
+ abi_arg_names = get_abi_input_names(abi_element)
174
139
 
140
+ if set(argument_names).intersection(abi_arg_names) == set(argument_names):
141
+ abis_with_matching_args.append(abi_element)
142
+ except TypeError:
143
+ # fallback or receive functions do not have arguments
144
+ # proceed to next ABIElement
145
+ continue
175
146
 
176
- def filter_by_argument_count(
177
- num_arguments: int, contract_abi: ABI
178
- ) -> List[Union[ABIFunction, ABIEvent]]:
179
- return [abi for abi in contract_abi if len(abi["inputs"]) == num_arguments]
147
+ return abis_with_matching_args
180
148
 
181
149
 
182
- def filter_by_argument_name(
183
- argument_names: Collection[str], contract_abi: ABI
184
- ) -> List[Union[ABIFunction, ABIEvent]]:
185
- return [
186
- abi
187
- for abi in contract_abi
188
- if set(argument_names).intersection(get_abi_input_names(abi))
189
- == set(argument_names)
190
- ]
191
-
192
-
193
- # type ignored because subclassing encoding.AddressEncoder which has type Any
194
- class AddressEncoder(encoding.AddressEncoder): # type: ignore[misc]
150
+ class AddressEncoder(encoding.AddressEncoder):
195
151
  @classmethod
196
152
  def validate_value(cls, value: Any) -> None:
197
153
  if is_ens_name(value):
198
154
  return
199
155
 
200
- super().validate_value(value)
156
+ super().validate_value(value) # type: ignore[no-untyped-call]
201
157
 
202
158
 
203
- # type ignored because subclassing encoding.BytesEncoder which has type Any
204
- class AcceptsHexStrEncoder(encoding.BaseEncoder): # type: ignore[misc]
159
+ class AcceptsHexStrEncoder(encoding.BaseEncoder):
205
160
  subencoder_cls: Type[encoding.BaseEncoder] = None
206
161
  is_strict: bool = None
207
162
  is_big_endian: bool = False
@@ -213,7 +168,7 @@ class AcceptsHexStrEncoder(encoding.BaseEncoder): # type: ignore[misc]
213
168
  subencoder: encoding.BaseEncoder,
214
169
  **kwargs: Dict[str, Any],
215
170
  ) -> None:
216
- super().__init__(**kwargs)
171
+ super().__init__(**kwargs) # type: ignore[no-untyped-call]
217
172
  self.subencoder = subencoder
218
173
  self.is_dynamic = subencoder.is_dynamic
219
174
 
@@ -225,7 +180,7 @@ class AcceptsHexStrEncoder(encoding.BaseEncoder): # type: ignore[misc]
225
180
  # cast b/c expects BaseCoder but `from_type_string`
226
181
  # restricted to BaseEncoder subclasses
227
182
  subencoder = cast(
228
- encoding.BaseEncoder, subencoder_cls.from_type_str(abi_type, registry)
183
+ encoding.BaseEncoder, subencoder_cls.from_type_str(abi_type, registry) # type: ignore[no-untyped-call] # noqa: E501
229
184
  )
230
185
  return cls(subencoder)
231
186
 
@@ -290,7 +245,7 @@ class ExactLengthBytesEncoder(BytesEncoder):
290
245
  is_strict = True
291
246
 
292
247
  def validate(self) -> None:
293
- super().validate()
248
+ super().validate() # type: ignore[no-untyped-call]
294
249
  if self.value_bit_size is None:
295
250
  raise Web3ValueError("`value_bit_size` may not be none")
296
251
  if self.data_byte_size is None:
@@ -307,16 +262,22 @@ class ExactLengthBytesEncoder(BytesEncoder):
307
262
  if self.value_bit_size > self.data_byte_size * 8:
308
263
  raise Web3ValueError("Value byte size exceeds data size")
309
264
 
310
- @parse_type_str("bytes")
265
+ @parse_type_str("bytes") # type: ignore[no-untyped-call]
311
266
  def from_type_str(
312
267
  cls, abi_type: BasicType, registry: ABIRegistry
313
268
  ) -> "ExactLengthBytesEncoder":
314
269
  subencoder_cls = cls.get_subencoder_class()
315
- subencoder = subencoder_cls.from_type_str(abi_type.to_type_str(), registry)
316
- return cls(
317
- subencoder,
318
- value_bit_size=abi_type.sub * 8,
319
- data_byte_size=abi_type.sub,
270
+ subencoder = subencoder_cls.from_type_str(abi_type.to_type_str(), registry) # type: ignore[no-untyped-call] # noqa: E501
271
+ return cast(
272
+ ExactLengthBytesEncoder,
273
+ # type ignored b/c mypy thinks the __call__ is from BaseEncoder, but it's
274
+ # from ExactLengthBytesEncoder, which does have value_bit_size and
275
+ # data_byte_size attributes
276
+ cls( # type: ignore[call-arg]
277
+ subencoder,
278
+ value_bit_size=abi_type.sub * 8,
279
+ data_byte_size=abi_type.sub,
280
+ ),
320
281
  )
321
282
 
322
283
 
@@ -330,8 +291,7 @@ class StrictByteStringEncoder(AcceptsHexStrEncoder):
330
291
  is_strict = True
331
292
 
332
293
 
333
- # type ignored because subclassing encoding.TextStringEncoder which has type Any
334
- class TextStringEncoder(encoding.TextStringEncoder): # type: ignore[misc]
294
+ class TextStringEncoder(encoding.TextStringEncoder):
335
295
  @classmethod
336
296
  def validate_value(cls, value: Any) -> None:
337
297
  if is_bytes(value):
@@ -343,110 +303,7 @@ class TextStringEncoder(encoding.TextStringEncoder): # type: ignore[misc]
343
303
  msg="not decodable as unicode string",
344
304
  )
345
305
 
346
- super().validate_value(value)
347
-
348
-
349
- def filter_by_encodability(
350
- abi_codec: codec.ABIEncoder,
351
- args: Sequence[Any],
352
- kwargs: Dict[str, Any],
353
- contract_abi: ABI,
354
- ) -> List[ABIFunction]:
355
- return [
356
- cast(ABIFunction, function_abi)
357
- for function_abi in contract_abi
358
- if check_if_arguments_can_be_encoded(
359
- cast(ABIFunction, function_abi), abi_codec, args, kwargs
360
- )
361
- ]
362
-
363
-
364
- def check_if_arguments_can_be_encoded(
365
- function_abi: ABIFunction,
366
- abi_codec: codec.ABIEncoder,
367
- args: Sequence[Any],
368
- kwargs: Dict[str, Any],
369
- ) -> bool:
370
- try:
371
- arguments = merge_args_and_kwargs(function_abi, args, kwargs)
372
- except TypeError:
373
- return False
374
-
375
- if len(function_abi.get("inputs", [])) != len(arguments):
376
- return False
377
-
378
- try:
379
- types, aligned_args = get_aligned_abi_inputs(function_abi, arguments)
380
- except TypeError:
381
- return False
382
-
383
- return all(
384
- abi_codec.is_encodable(_type, arg) for _type, arg in zip(types, aligned_args)
385
- )
386
-
387
-
388
- def merge_args_and_kwargs(
389
- function_abi: ABIFunction, args: Sequence[Any], kwargs: Dict[str, Any]
390
- ) -> Tuple[Any, ...]:
391
- """
392
- Takes a list of positional args (``args``) and a dict of keyword args
393
- (``kwargs``) defining values to be passed to a call to the contract function
394
- described by ``function_abi``. Checks to ensure that the correct number of
395
- args were given, no duplicate args were given, and no unknown args were
396
- given. Returns a list of argument values aligned to the order of inputs
397
- defined in ``function_abi``.
398
- """
399
- # Ensure the function is being applied to the correct number of args
400
- if len(args) + len(kwargs) != len(function_abi.get("inputs", [])):
401
- raise Web3TypeError(
402
- f"Incorrect argument count. Expected '{len(function_abi['inputs'])}'"
403
- f". Got '{len(args) + len(kwargs)}'"
404
- )
405
-
406
- # If no keyword args were given, we don't need to align them
407
- if not kwargs:
408
- return cast(Tuple[Any, ...], args)
409
-
410
- kwarg_names = set(kwargs.keys())
411
- sorted_arg_names = tuple(arg_abi["name"] for arg_abi in function_abi["inputs"])
412
- args_as_kwargs = dict(zip(sorted_arg_names, args))
413
-
414
- # Check for duplicate args
415
- duplicate_args = kwarg_names.intersection(args_as_kwargs.keys())
416
- if duplicate_args:
417
- raise Web3TypeError(
418
- f"{function_abi.get('name')}() got multiple values for argument(s) "
419
- f"'{', '.join(duplicate_args)}'"
420
- )
421
-
422
- # Check for unknown args
423
- unknown_args = kwarg_names.difference(sorted_arg_names)
424
- if unknown_args:
425
- if function_abi.get("name"):
426
- raise Web3TypeError(
427
- f"{function_abi.get('name')}() got unexpected keyword argument(s)"
428
- f" '{', '.join(unknown_args)}'"
429
- )
430
- raise Web3TypeError(
431
- f"Type: '{function_abi.get('type')}' got unexpected keyword argument(s)"
432
- f" '{', '.join(unknown_args)}'"
433
- )
434
-
435
- # Sort args according to their position in the ABI and unzip them from their
436
- # names
437
- sorted_args = tuple(
438
- zip(
439
- *sorted(
440
- itertools.chain(kwargs.items(), args_as_kwargs.items()),
441
- key=lambda kv: sorted_arg_names.index(kv[0]),
442
- )
443
- )
444
- )
445
-
446
- if sorted_args:
447
- return sorted_args[1]
448
- else:
449
- return tuple()
306
+ super().validate_value(value) # type: ignore[no-untyped-call]
450
307
 
451
308
 
452
309
  TUPLE_TYPE_STR_RE = re.compile(r"^(tuple)((\[([1-9]\d*\b)?])*)??$")
@@ -468,7 +325,9 @@ def get_tuple_type_str_parts(s: str) -> Optional[Tuple[str, Optional[str]]]:
468
325
  return None
469
326
 
470
327
 
471
- def _align_abi_input(arg_abi: ABIFunctionParams, arg: Any) -> Tuple[Any, ...]:
328
+ def _align_abi_input(
329
+ arg_abi: Union[ABIComponent, ABIComponentIndexed], arg: Any
330
+ ) -> Tuple[Any, ...]:
472
331
  """
473
332
  Aligns the values of any mapping at any level of nesting in ``arg``
474
333
  according to the layout of the corresponding abi spec.
@@ -492,7 +351,7 @@ def _align_abi_input(arg_abi: ABIFunctionParams, arg: Any) -> Tuple[Any, ...]:
492
351
  new_abi = copy.copy(arg_abi)
493
352
  new_abi["type"] = tuple_prefix + "[]" * (num_dims - 1)
494
353
 
495
- sub_abis = itertools.repeat(new_abi) # type: ignore
354
+ sub_abis = [cast(ABIComponent, abi) for abi in itertools.repeat(new_abi)]
496
355
 
497
356
  if isinstance(arg, abc.Mapping):
498
357
  # Arg is mapping. Align values according to abi order.
@@ -515,29 +374,14 @@ def _align_abi_input(arg_abi: ABIFunctionParams, arg: Any) -> Tuple[Any, ...]:
515
374
  )
516
375
 
517
376
 
518
- def get_aligned_abi_inputs(
519
- abi: ABIFunction, args: Union[Tuple[Any, ...], Mapping[Any, Any]]
520
- ) -> Tuple[Tuple[Any, ...], Tuple[Any, ...]]:
521
- """
522
- Takes a function ABI (``abi``) and a sequence or mapping of args (``args``).
523
- Returns a list of type strings for the function's inputs and a list of
524
- arguments which have been aligned to the layout of those types. The args
525
- contained in ``args`` may contain nested mappings or sequences corresponding
526
- to tuple-encoded values in ``abi``.
377
+ def find_constructor_abi_element_by_type(contract_abi: ABI) -> ABIConstructor:
527
378
  """
528
- input_abis = abi.get("inputs", [])
529
-
530
- if isinstance(args, abc.Mapping):
531
- # `args` is mapping. Align values according to abi order.
532
- args = tuple(args[abi["name"]] for abi in input_abis)
533
-
534
- return (
535
- tuple(collapse_if_tuple(abi) for abi in input_abis),
536
- type(args)(_align_abi_input(abi, arg) for abi, arg in zip(input_abis, args)),
537
- )
538
-
379
+ Find the constructor ABI element in the contract ABI.
539
380
 
540
- def get_constructor_abi(contract_abi: ABI) -> ABIFunction:
381
+ This function is often used in place of `web3.utils.abi.get_abi_element` to find
382
+ a constructor without considering it's argument types. This is used prior to
383
+ encoding the abi, since the argument types are not known at that time.
384
+ """
541
385
  candidates = [abi for abi in contract_abi if abi["type"] == "constructor"]
542
386
  if len(candidates) == 1:
543
387
  return candidates[0]
@@ -671,8 +515,8 @@ def is_probably_enum(abi_type: TypeStr) -> bool:
671
515
 
672
516
  @to_tuple
673
517
  def normalize_event_input_types(
674
- abi_args: Collection[Union[ABIFunction, ABIEvent]]
675
- ) -> Iterable[Union[ABIFunction, ABIEvent, Dict[TypeStr, Any]]]:
518
+ abi_args: Collection[ABIEvent],
519
+ ) -> Iterable[Union[ABIEvent, Dict[TypeStr, Any]]]:
676
520
  for arg in abi_args:
677
521
  if is_recognized_type(arg["type"]):
678
522
  yield arg
@@ -682,17 +526,6 @@ def normalize_event_input_types(
682
526
  yield arg
683
527
 
684
528
 
685
- def abi_to_signature(abi: Union[ABIFunction, ABIEvent]) -> str:
686
- function_signature = "{fn_name}({fn_input_types})".format(
687
- fn_name=abi["name"],
688
- fn_input_types=",".join(
689
- collapse_if_tuple(dict(arg))
690
- for arg in normalize_event_input_types(abi.get("inputs", []))
691
- ),
692
- )
693
- return function_signature
694
-
695
-
696
529
  ########################################################
697
530
  #
698
531
  # Conditionally modifying data, tagged with ABI Types
@@ -843,7 +676,7 @@ def strip_abi_type(elements: Any) -> Any:
843
676
  def build_non_strict_registry() -> ABIRegistry:
844
677
  # We make a copy here just to make sure that eth-abi's default registry is not
845
678
  # affected by our custom encoder subclasses
846
- registry = default_registry.copy()
679
+ registry = default_registry.copy() # type: ignore[no-untyped-call]
847
680
 
848
681
  registry.unregister("address")
849
682
  registry.unregister("bytes<M>")
@@ -851,25 +684,25 @@ def build_non_strict_registry() -> ABIRegistry:
851
684
  registry.unregister("string")
852
685
 
853
686
  registry.register(
854
- BaseEquals("address"),
687
+ BaseEquals("address"), # type: ignore[no-untyped-call]
855
688
  AddressEncoder,
856
689
  decoding.AddressDecoder,
857
690
  label="address",
858
691
  )
859
692
  registry.register(
860
- BaseEquals("bytes", with_sub=True),
693
+ BaseEquals("bytes", with_sub=True), # type: ignore[no-untyped-call]
861
694
  BytesEncoder,
862
695
  decoding.BytesDecoder,
863
696
  label="bytes<M>",
864
697
  )
865
698
  registry.register(
866
- BaseEquals("bytes", with_sub=False),
699
+ BaseEquals("bytes", with_sub=False), # type: ignore[no-untyped-call]
867
700
  ByteStringEncoder,
868
701
  decoding.ByteStringDecoder,
869
702
  label="bytes",
870
703
  )
871
704
  registry.register(
872
- BaseEquals("string"),
705
+ BaseEquals("string"), # type: ignore[no-untyped-call]
873
706
  TextStringEncoder,
874
707
  decoding.StringDecoder,
875
708
  label="string",
@@ -878,7 +711,7 @@ def build_non_strict_registry() -> ABIRegistry:
878
711
 
879
712
 
880
713
  def build_strict_registry() -> ABIRegistry:
881
- registry = default_registry.copy()
714
+ registry = default_registry.copy() # type: ignore[no-untyped-call]
882
715
 
883
716
  registry.unregister("address")
884
717
  registry.unregister("bytes<M>")
@@ -886,25 +719,25 @@ def build_strict_registry() -> ABIRegistry:
886
719
  registry.unregister("string")
887
720
 
888
721
  registry.register(
889
- BaseEquals("address"),
722
+ BaseEquals("address"), # type: ignore[no-untyped-call]
890
723
  AddressEncoder,
891
724
  decoding.AddressDecoder,
892
725
  label="address",
893
726
  )
894
727
  registry.register(
895
- BaseEquals("bytes", with_sub=True),
728
+ BaseEquals("bytes", with_sub=True), # type: ignore[no-untyped-call]
896
729
  ExactLengthBytesEncoder,
897
730
  decoding.BytesDecoder,
898
731
  label="bytes<M>",
899
732
  )
900
733
  registry.register(
901
- BaseEquals("bytes", with_sub=False),
734
+ BaseEquals("bytes", with_sub=False), # type: ignore[no-untyped-call]
902
735
  StrictByteStringEncoder,
903
736
  decoding.ByteStringDecoder,
904
737
  label="bytes",
905
738
  )
906
739
  registry.register(
907
- BaseEquals("string"),
740
+ BaseEquals("string"), # type: ignore[no-untyped-call]
908
741
  encoding.TextStringEncoder,
909
742
  decoding.StringDecoder,
910
743
  label="string",
@@ -913,7 +746,11 @@ def build_strict_registry() -> ABIRegistry:
913
746
 
914
747
 
915
748
  def named_tree(
916
- abi: Iterable[Union[ABIFunctionParams, ABIFunction, ABIEvent, Dict[TypeStr, Any]]],
749
+ abi: Iterable[
750
+ Union[
751
+ ABIComponent, ABIComponentIndexed, ABIFunction, ABIEvent, Dict[TypeStr, Any]
752
+ ]
753
+ ],
917
754
  data: Iterable[Tuple[Any, ...]],
918
755
  ) -> Dict[str, Any]:
919
756
  """
@@ -926,10 +763,12 @@ def named_tree(
926
763
 
927
764
 
928
765
  def _named_subtree(
929
- abi: Union[ABIFunctionParams, ABIFunction, ABIEvent, Dict[TypeStr, Any]],
766
+ abi: Union[
767
+ ABIComponent, ABIComponentIndexed, ABIFunction, ABIEvent, Dict[TypeStr, Any]
768
+ ],
930
769
  data: Tuple[Any, ...],
931
770
  ) -> Union[Dict[str, Any], Tuple[Any, ...], List[Any]]:
932
- abi_type = parse(collapse_if_tuple(dict(abi)))
771
+ abi_type = parse(collapse_if_tuple(cast(Dict[str, Any], abi)))
933
772
 
934
773
  if abi_type.is_array:
935
774
  item_type = abi_type.item_type.to_type_str()
@@ -938,7 +777,11 @@ def _named_subtree(
938
777
  return items
939
778
 
940
779
  elif isinstance(abi_type, TupleType):
941
- abi = cast(ABIFunctionParams, abi)
780
+ if abi.get("indexed"):
781
+ abi = cast(ABIComponentIndexed, abi)
782
+ else:
783
+ abi = cast(ABIComponent, abi)
784
+
942
785
  names = [item["name"] for item in abi["components"]]
943
786
  items = [_named_subtree(*item) for item in zip(abi["components"], data)]
944
787
 
@@ -12,4 +12,5 @@ from typing_extensions import (
12
12
  NotRequired, # py311
13
13
  Self, # py311
14
14
  Unpack, # py311
15
+ TypeAlias, # py310
15
16
  )