web3 7.0.0b1__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 (261) hide show
  1. ens/__init__.py +13 -2
  2. ens/_normalization.py +4 -4
  3. ens/async_ens.py +31 -21
  4. ens/base_ens.py +3 -1
  5. ens/contract_data.py +2 -2
  6. ens/ens.py +14 -11
  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 +33 -41
  11. web3/__init__.py +23 -12
  12. web3/_utils/abi.py +162 -274
  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 +56 -41
  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 -43
  89. web3/manager.py +368 -101
  90. web3/method.py +43 -15
  91. web3/middleware/__init__.py +26 -8
  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 +62 -26
  100. web3/providers/__init__.py +21 -0
  101. web3/providers/async_base.py +93 -38
  102. web3/providers/base.py +85 -40
  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 +57 -35
  106. web3/providers/eth_tester/middleware.py +16 -17
  107. web3/providers/ipc.py +42 -18
  108. web3/providers/legacy_websocket.py +27 -2
  109. web3/providers/persistent/__init__.py +7 -0
  110. web3/providers/persistent/async_ipc.py +61 -121
  111. web3/providers/persistent/persistent.py +324 -17
  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.0b1.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.0b1.dist-info → web3-7.7.0.dist-info}/WHEEL +1 -1
  137. {web3-7.0.0b1.dist-info → web3-7.7.0.dist-info}/top_level.txt +0 -1
  138. ethpm/__init__.py +0 -20
  139. ethpm/_utils/__init__.py +0 -0
  140. ethpm/_utils/backend.py +0 -93
  141. ethpm/_utils/cache.py +0 -44
  142. ethpm/_utils/chains.py +0 -119
  143. ethpm/_utils/contract.py +0 -35
  144. ethpm/_utils/deployments.py +0 -145
  145. ethpm/_utils/ipfs.py +0 -116
  146. ethpm/_utils/protobuf/__init__.py +0 -0
  147. ethpm/_utils/protobuf/ipfs_file_pb2.py +0 -33
  148. ethpm/_utils/registry.py +0 -29
  149. ethpm/assets/__init__.py +0 -0
  150. ethpm/assets/ens/v3.json +0 -1
  151. ethpm/assets/escrow/with_bytecode_v3.json +0 -1
  152. ethpm/assets/ipfs_file.proto +0 -32
  153. ethpm/assets/owned/output_v3.json +0 -1
  154. ethpm/assets/owned/with_contract_type_v3.json +0 -1
  155. ethpm/assets/registry/contracts/Authority.sol +0 -156
  156. ethpm/assets/registry/contracts/IndexedOrderedSetLib.sol +0 -106
  157. ethpm/assets/registry/contracts/PackageDB.sol +0 -225
  158. ethpm/assets/registry/contracts/PackageRegistry.sol +0 -361
  159. ethpm/assets/registry/contracts/PackageRegistryInterface.sol +0 -97
  160. ethpm/assets/registry/contracts/ReleaseDB.sol +0 -309
  161. ethpm/assets/registry/contracts/ReleaseValidator.sol +0 -152
  162. ethpm/assets/registry/solc_input.json +0 -1
  163. ethpm/assets/registry/solc_output.json +0 -1
  164. ethpm/assets/registry/v3.json +0 -1
  165. ethpm/assets/safe-math-lib/v3-strict-no-deployments.json +0 -1
  166. ethpm/assets/simple-registry/contracts/Ownable.sol +0 -63
  167. ethpm/assets/simple-registry/contracts/PackageRegistry.sol +0 -373
  168. ethpm/assets/simple-registry/contracts/PackageRegistryInterface.sol +0 -96
  169. ethpm/assets/simple-registry/solc_input.json +0 -33
  170. ethpm/assets/simple-registry/solc_output.json +0 -1
  171. ethpm/assets/simple-registry/v3.json +0 -1
  172. ethpm/assets/standard-token/output_v3.json +0 -1
  173. ethpm/assets/standard-token/with_bytecode_v3.json +0 -1
  174. ethpm/assets/vyper_registry/0.1.0.json +0 -1
  175. ethpm/assets/vyper_registry/registry.vy +0 -216
  176. ethpm/assets/vyper_registry/registry_with_delete.vy +0 -244
  177. ethpm/backends/__init__.py +0 -0
  178. ethpm/backends/base.py +0 -43
  179. ethpm/backends/http.py +0 -108
  180. ethpm/backends/ipfs.py +0 -219
  181. ethpm/backends/registry.py +0 -154
  182. ethpm/constants.py +0 -17
  183. ethpm/contract.py +0 -187
  184. ethpm/dependencies.py +0 -58
  185. ethpm/deployments.py +0 -80
  186. ethpm/ethpm-spec/examples/escrow/1.0.0-pretty.json +0 -146
  187. ethpm/ethpm-spec/examples/escrow/1.0.0.json +0 -1
  188. ethpm/ethpm-spec/examples/escrow/contracts/Escrow.sol +0 -32
  189. ethpm/ethpm-spec/examples/escrow/contracts/SafeSendLib.sol +0 -20
  190. ethpm/ethpm-spec/examples/escrow/v3-pretty.json +0 -171
  191. ethpm/ethpm-spec/examples/escrow/v3.json +0 -1
  192. ethpm/ethpm-spec/examples/owned/1.0.0-pretty.json +0 -21
  193. ethpm/ethpm-spec/examples/owned/1.0.0.json +0 -1
  194. ethpm/ethpm-spec/examples/owned/contracts/Owned.sol +0 -12
  195. ethpm/ethpm-spec/examples/owned/v3-pretty.json +0 -27
  196. ethpm/ethpm-spec/examples/owned/v3.json +0 -1
  197. ethpm/ethpm-spec/examples/piper-coin/1.0.0-pretty.json +0 -31
  198. ethpm/ethpm-spec/examples/piper-coin/1.0.0.json +0 -1
  199. ethpm/ethpm-spec/examples/piper-coin/v3-pretty.json +0 -21
  200. ethpm/ethpm-spec/examples/piper-coin/v3.json +0 -1
  201. ethpm/ethpm-spec/examples/safe-math-lib/1.0.0-pretty.json +0 -85
  202. ethpm/ethpm-spec/examples/safe-math-lib/1.0.0.json +0 -1
  203. ethpm/ethpm-spec/examples/safe-math-lib/contracts/SafeMathLib.sol +0 -24
  204. ethpm/ethpm-spec/examples/safe-math-lib/v3-pretty.json +0 -117
  205. ethpm/ethpm-spec/examples/safe-math-lib/v3.json +0 -1
  206. ethpm/ethpm-spec/examples/standard-token/1.0.0-pretty.json +0 -55
  207. ethpm/ethpm-spec/examples/standard-token/1.0.0.json +0 -1
  208. ethpm/ethpm-spec/examples/standard-token/contracts/AbstractToken.sol +0 -20
  209. ethpm/ethpm-spec/examples/standard-token/contracts/StandardToken.sol +0 -84
  210. ethpm/ethpm-spec/examples/standard-token/v3-pretty.json +0 -460
  211. ethpm/ethpm-spec/examples/standard-token/v3.json +0 -1
  212. ethpm/ethpm-spec/examples/transferable/1.0.0-pretty.json +0 -21
  213. ethpm/ethpm-spec/examples/transferable/1.0.0.json +0 -1
  214. ethpm/ethpm-spec/examples/transferable/contracts/Transferable.sol +0 -14
  215. ethpm/ethpm-spec/examples/transferable/v3-pretty.json +0 -27
  216. ethpm/ethpm-spec/examples/transferable/v3.json +0 -1
  217. ethpm/ethpm-spec/examples/wallet/1.0.0-pretty.json +0 -120
  218. ethpm/ethpm-spec/examples/wallet/1.0.0.json +0 -1
  219. ethpm/ethpm-spec/examples/wallet/contracts/Wallet.sol +0 -41
  220. ethpm/ethpm-spec/examples/wallet/v3-pretty.json +0 -181
  221. ethpm/ethpm-spec/examples/wallet/v3.json +0 -1
  222. ethpm/ethpm-spec/examples/wallet-with-send/1.0.0-pretty.json +0 -135
  223. ethpm/ethpm-spec/examples/wallet-with-send/1.0.0.json +0 -1
  224. ethpm/ethpm-spec/examples/wallet-with-send/contracts/WalletWithSend.sol +0 -18
  225. ethpm/ethpm-spec/examples/wallet-with-send/v3-pretty.json +0 -207
  226. ethpm/ethpm-spec/examples/wallet-with-send/v3.json +0 -1
  227. ethpm/ethpm-spec/spec/package.spec.json +0 -379
  228. ethpm/ethpm-spec/spec/v3.spec.json +0 -483
  229. ethpm/exceptions.py +0 -68
  230. ethpm/package.py +0 -438
  231. ethpm/tools/__init__.py +0 -4
  232. ethpm/tools/builder.py +0 -930
  233. ethpm/tools/checker.py +0 -312
  234. ethpm/tools/get_manifest.py +0 -19
  235. ethpm/uri.py +0 -141
  236. ethpm/validation/__init__.py +0 -0
  237. ethpm/validation/manifest.py +0 -146
  238. ethpm/validation/misc.py +0 -39
  239. ethpm/validation/package.py +0 -80
  240. ethpm/validation/uri.py +0 -163
  241. web3/_utils/caching.py +0 -155
  242. web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
  243. web3/_utils/module_testing/go_ethereum_personal_module.py +0 -300
  244. web3/_utils/request.py +0 -265
  245. web3/pm.py +0 -602
  246. web3/tools/__init__.py +0 -4
  247. web3/tools/benchmark/__init__.py +0 -0
  248. web3/tools/benchmark/main.py +0 -185
  249. web3/tools/benchmark/node.py +0 -126
  250. web3/tools/benchmark/reporting.py +0 -39
  251. web3/tools/benchmark/utils.py +0 -69
  252. web3/tools/pytest_ethereum/__init__.py +0 -0
  253. web3/tools/pytest_ethereum/_utils.py +0 -145
  254. web3/tools/pytest_ethereum/deployer.py +0 -48
  255. web3/tools/pytest_ethereum/exceptions.py +0 -22
  256. web3/tools/pytest_ethereum/linker.py +0 -128
  257. web3/tools/pytest_ethereum/plugins.py +0 -33
  258. web3-7.0.0b1.dist-info/METADATA +0 -114
  259. web3-7.0.0b1.dist-info/RECORD +0 -280
  260. web3-7.0.0b1.dist-info/entry_points.txt +0 -2
  261. /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +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,12 +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 (
54
- combomethod,
62
+ collapse_if_tuple,
55
63
  decode_hex,
64
+ filter_abi_by_type,
65
+ get_abi_input_names,
66
+ get_abi_input_types,
56
67
  is_bytes,
57
68
  is_list_like,
58
69
  is_string,
@@ -60,15 +71,16 @@ from eth_utils import (
60
71
  to_text,
61
72
  to_tuple,
62
73
  )
63
- from eth_utils.abi import (
64
- collapse_if_tuple,
65
- )
66
74
  from eth_utils.toolz import (
67
75
  curry,
68
76
  partial,
69
77
  pipe,
70
78
  )
71
79
 
80
+ from web3._utils.abi_element_identifiers import (
81
+ FallbackFn,
82
+ ReceiveFn,
83
+ )
72
84
  from web3._utils.decorators import (
73
85
  reject_recursive_repeats,
74
86
  )
@@ -79,20 +91,15 @@ from web3._utils.formatters import (
79
91
  recursive_map,
80
92
  )
81
93
  from web3.exceptions import (
82
- FallbackNotFound,
83
94
  MismatchedABI,
95
+ Web3AttributeError,
96
+ Web3TypeError,
97
+ Web3ValueError,
84
98
  )
85
99
  from web3.types import (
86
- ABI,
87
- ABIEvent,
88
- ABIEventParams,
89
- ABIFunction,
90
- ABIFunctionParams,
100
+ ABIElementIdentifier,
91
101
  TReturn,
92
102
  )
93
- from web3.utils import ( # public utils module
94
- get_abi_input_names,
95
- )
96
103
 
97
104
  if TYPE_CHECKING:
98
105
  from web3 import ( # noqa: F401
@@ -100,92 +107,94 @@ if TYPE_CHECKING:
100
107
  )
101
108
 
102
109
 
103
- def filter_by_type(_type: str, contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
104
- return [abi for abi in contract_abi if abi["type"] == _type]
105
-
106
-
107
- def filter_by_name(name: str, contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
108
- return [
109
- abi
110
- for abi in contract_abi
111
- if (
112
- abi["type"] not in ("fallback", "constructor", "receive")
113
- and abi["name"] == name
114
- )
115
- ]
116
-
117
-
118
- def get_abi_input_types(abi: ABIFunction) -> List[str]:
119
- if "inputs" not in abi and (abi["type"] == "fallback" or abi["type"] == "receive"):
120
- return []
121
- else:
122
- return [collapse_if_tuple(cast(Dict[str, Any], arg)) for arg in abi["inputs"]]
123
-
124
-
125
- def get_abi_output_types(abi: ABIFunction) -> List[str]:
126
- if abi["type"] == "fallback":
127
- return []
128
- else:
129
- return [collapse_if_tuple(cast(Dict[str, Any], arg)) for arg in abi["outputs"]]
110
+ def fallback_func_abi_exists(contract_abi: ABI) -> Sequence[ABIFallback]:
111
+ return filter_abi_by_type("fallback", contract_abi)
130
112
 
131
113
 
132
- def get_receive_func_abi(contract_abi: ABI) -> ABIFunction:
133
- receive_abis = filter_by_type("receive", contract_abi)
134
- if receive_abis:
135
- return cast(ABIFunction, receive_abis[0])
136
- else:
137
- raise FallbackNotFound("No receive function was found in the contract ABI.")
114
+ def receive_func_abi_exists(contract_abi: ABI) -> Sequence[ABIReceive]:
115
+ return filter_abi_by_type("receive", contract_abi)
138
116
 
139
117
 
140
- def get_fallback_func_abi(contract_abi: ABI) -> ABIFunction:
141
- fallback_abis = filter_by_type("fallback", contract_abi)
142
- if fallback_abis:
143
- return cast(ABIFunction, fallback_abis[0])
144
- else:
145
- raise FallbackNotFound("No fallback function was found in the contract ABI.")
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]
146
120
 
147
121
 
148
- def fallback_func_abi_exists(contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
149
- return filter_by_type("fallback", contract_abi)
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]
150
124
 
151
125
 
152
- def receive_func_abi_exists(contract_abi: ABI) -> List[Union[ABIFunction, ABIEvent]]:
153
- return filter_by_type("receive", contract_abi)
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]
154
128
 
155
129
 
156
- def get_indexed_event_inputs(event_abi: ABIEvent) -> List[ABIEventParams]:
157
- return [arg for arg in event_abi["inputs"] if arg["indexed"] is True]
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)
158
141
 
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
159
148
 
160
- def exclude_indexed_event_inputs(event_abi: ABIEvent) -> List[ABIEventParams]:
161
- return [arg for arg in event_abi["inputs"] if arg["indexed"] is False]
149
+ return abis_with_matching_args
162
150
 
163
151
 
164
- 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]:
165
155
  """
166
- Return the normalized type for the abi argument provided.
167
- In order to account for tuple argument types, this abstraction
168
- makes use of `collapse_if_tuple()` to collapse the appropriate component
169
- types within a tuple type, if present.
156
+ Return a list of each ``ABIElement`` which contain arguments matching provided
157
+ types.
170
158
  """
171
- 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")
172
185
 
173
186
 
174
- def filter_by_argument_count(
175
- num_arguments: int, contract_abi: ABI
176
- ) -> List[Union[ABIFunction, ABIEvent]]:
177
- 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 [])
178
193
 
194
+ if element_name in ["fallback", "receive"]:
195
+ return element_name
179
196
 
180
- def filter_by_argument_name(
181
- argument_names: Collection[str], contract_abi: ABI
182
- ) -> List[Union[ABIFunction, ABIEvent]]:
183
- return [
184
- abi
185
- for abi in contract_abi
186
- if set(argument_names).intersection(get_abi_input_names(abi))
187
- == set(argument_names)
188
- ]
197
+ return f"{element_name}({argument_types})"
189
198
 
190
199
 
191
200
  class AddressEncoder(encoding.AddressEncoder):
@@ -194,7 +203,7 @@ class AddressEncoder(encoding.AddressEncoder):
194
203
  if is_ens_name(value):
195
204
  return
196
205
 
197
- super().validate_value(value)
206
+ super().validate_value(value) # type: ignore[no-untyped-call]
198
207
 
199
208
 
200
209
  class AcceptsHexStrEncoder(encoding.BaseEncoder):
@@ -209,12 +218,9 @@ class AcceptsHexStrEncoder(encoding.BaseEncoder):
209
218
  subencoder: encoding.BaseEncoder,
210
219
  **kwargs: Dict[str, Any],
211
220
  ) -> None:
212
- super().__init__(**kwargs)
221
+ super().__init__(**kwargs) # type: ignore[no-untyped-call]
213
222
  self.subencoder = subencoder
214
-
215
- @property
216
- def is_dynamic(self) -> bool:
217
- return self.subencoder.is_dynamic
223
+ self.is_dynamic = subencoder.is_dynamic
218
224
 
219
225
  @classmethod
220
226
  def from_type_str(
@@ -224,20 +230,19 @@ class AcceptsHexStrEncoder(encoding.BaseEncoder):
224
230
  # cast b/c expects BaseCoder but `from_type_string`
225
231
  # restricted to BaseEncoder subclasses
226
232
  subencoder = cast(
227
- 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
228
234
  )
229
235
  return cls(subencoder)
230
236
 
231
237
  @classmethod
232
238
  def get_subencoder_class(cls) -> Type[encoding.BaseEncoder]:
233
239
  if cls.subencoder_cls is None:
234
- raise AttributeError(f"No subencoder class is set. {cls.__name__}")
240
+ raise Web3AttributeError(f"No subencoder class is set. {cls.__name__}")
235
241
  return cls.subencoder_cls
236
242
 
237
- @combomethod
238
243
  def validate_value(self, value: Any) -> None:
239
244
  normalized_value = self.validate_and_normalize(value)
240
- return self.subencoder.validate_value(normalized_value)
245
+ self.subencoder.validate_value(normalized_value)
241
246
 
242
247
  def encode(self, value: Any) -> bytes:
243
248
  normalized_value = self.validate_and_normalize(value)
@@ -290,36 +295,39 @@ class ExactLengthBytesEncoder(BytesEncoder):
290
295
  is_strict = True
291
296
 
292
297
  def validate(self) -> None:
293
- super().validate()
298
+ super().validate() # type: ignore[no-untyped-call]
294
299
  if self.value_bit_size is None:
295
- raise ValueError("`value_bit_size` may not be none")
300
+ raise Web3ValueError("`value_bit_size` may not be none")
296
301
  if self.data_byte_size is None:
297
- raise ValueError("`data_byte_size` may not be none")
302
+ raise Web3ValueError("`data_byte_size` may not be none")
298
303
  if self.is_big_endian is None:
299
- raise ValueError("`is_big_endian` may not be none")
304
+ raise Web3ValueError("`is_big_endian` may not be none")
300
305
 
301
306
  if self.value_bit_size % 8 != 0:
302
- raise ValueError(
307
+ raise Web3ValueError(
303
308
  f"Invalid value bit size: {self.value_bit_size}. "
304
309
  "Must be a multiple of 8"
305
310
  )
306
311
 
307
312
  if self.value_bit_size > self.data_byte_size * 8:
308
- raise ValueError("Value byte size exceeds data size")
313
+ raise Web3ValueError("Value byte size exceeds data size")
309
314
 
310
- @parse_type_str("bytes")
311
- def from_type_str(cls, abi_type: BasicType, registry: ABIRegistry) -> bytes:
315
+ @parse_type_str("bytes") # type: ignore[no-untyped-call]
316
+ def from_type_str(
317
+ cls, abi_type: BasicType, registry: ABIRegistry
318
+ ) -> "ExactLengthBytesEncoder":
312
319
  subencoder_cls = cls.get_subencoder_class()
313
- # cast b/c expects BaseCoder but `from_type_string`
314
- # restricted to BaseEncoder subclasses
315
- subencoder = cast(
316
- encoding.BaseEncoder,
317
- subencoder_cls.from_type_str(abi_type.to_type_str(), registry),
318
- )
319
- return cls(
320
- subencoder,
321
- value_bit_size=abi_type.sub * 8,
322
- 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
+ ),
323
331
  )
324
332
 
325
333
 
@@ -345,110 +353,7 @@ class TextStringEncoder(encoding.TextStringEncoder):
345
353
  msg="not decodable as unicode string",
346
354
  )
347
355
 
348
- super().validate_value(value)
349
-
350
-
351
- def filter_by_encodability(
352
- abi_codec: codec.ABIEncoder,
353
- args: Sequence[Any],
354
- kwargs: Dict[str, Any],
355
- contract_abi: ABI,
356
- ) -> List[ABIFunction]:
357
- return [
358
- cast(ABIFunction, function_abi)
359
- for function_abi in contract_abi
360
- if check_if_arguments_can_be_encoded(
361
- cast(ABIFunction, function_abi), abi_codec, args, kwargs
362
- )
363
- ]
364
-
365
-
366
- def check_if_arguments_can_be_encoded(
367
- function_abi: ABIFunction,
368
- abi_codec: codec.ABIEncoder,
369
- args: Sequence[Any],
370
- kwargs: Dict[str, Any],
371
- ) -> bool:
372
- try:
373
- arguments = merge_args_and_kwargs(function_abi, args, kwargs)
374
- except TypeError:
375
- return False
376
-
377
- if len(function_abi.get("inputs", [])) != len(arguments):
378
- return False
379
-
380
- try:
381
- types, aligned_args = get_aligned_abi_inputs(function_abi, arguments)
382
- except TypeError:
383
- return False
384
-
385
- return all(
386
- abi_codec.is_encodable(_type, arg) for _type, arg in zip(types, aligned_args)
387
- )
388
-
389
-
390
- def merge_args_and_kwargs(
391
- function_abi: ABIFunction, args: Sequence[Any], kwargs: Dict[str, Any]
392
- ) -> Tuple[Any, ...]:
393
- """
394
- Takes a list of positional args (``args``) and a dict of keyword args
395
- (``kwargs``) defining values to be passed to a call to the contract function
396
- described by ``function_abi``. Checks to ensure that the correct number of
397
- args were given, no duplicate args were given, and no unknown args were
398
- given. Returns a list of argument values aligned to the order of inputs
399
- defined in ``function_abi``.
400
- """
401
- # Ensure the function is being applied to the correct number of args
402
- if len(args) + len(kwargs) != len(function_abi.get("inputs", [])):
403
- raise TypeError(
404
- f"Incorrect argument count. Expected '{len(function_abi['inputs'])}'"
405
- f". Got '{len(args) + len(kwargs)}'"
406
- )
407
-
408
- # If no keyword args were given, we don't need to align them
409
- if not kwargs:
410
- return cast(Tuple[Any, ...], args)
411
-
412
- kwarg_names = set(kwargs.keys())
413
- sorted_arg_names = tuple(arg_abi["name"] for arg_abi in function_abi["inputs"])
414
- args_as_kwargs = dict(zip(sorted_arg_names, args))
415
-
416
- # Check for duplicate args
417
- duplicate_args = kwarg_names.intersection(args_as_kwargs.keys())
418
- if duplicate_args:
419
- raise TypeError(
420
- f"{function_abi.get('name')}() got multiple values for argument(s) "
421
- f"'{', '.join(duplicate_args)}'"
422
- )
423
-
424
- # Check for unknown args
425
- unknown_args = kwarg_names.difference(sorted_arg_names)
426
- if unknown_args:
427
- if function_abi.get("name"):
428
- raise TypeError(
429
- f"{function_abi.get('name')}() got unexpected keyword argument(s)"
430
- f" '{', '.join(unknown_args)}'"
431
- )
432
- raise TypeError(
433
- f"Type: '{function_abi.get('type')}' got unexpected keyword argument(s)"
434
- f" '{', '.join(unknown_args)}'"
435
- )
436
-
437
- # Sort args according to their position in the ABI and unzip them from their
438
- # names
439
- sorted_args = tuple(
440
- zip(
441
- *sorted(
442
- itertools.chain(kwargs.items(), args_as_kwargs.items()),
443
- key=lambda kv: sorted_arg_names.index(kv[0]),
444
- )
445
- )
446
- )
447
-
448
- if sorted_args:
449
- return sorted_args[1]
450
- else:
451
- return tuple()
356
+ super().validate_value(value) # type: ignore[no-untyped-call]
452
357
 
453
358
 
454
359
  TUPLE_TYPE_STR_RE = re.compile(r"^(tuple)((\[([1-9]\d*\b)?])*)??$")
@@ -470,7 +375,9 @@ def get_tuple_type_str_parts(s: str) -> Optional[Tuple[str, Optional[str]]]:
470
375
  return None
471
376
 
472
377
 
473
- 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, ...]:
474
381
  """
475
382
  Aligns the values of any mapping at any level of nesting in ``arg``
476
383
  according to the layout of the corresponding abi spec.
@@ -494,7 +401,7 @@ def _align_abi_input(arg_abi: ABIFunctionParams, arg: Any) -> Tuple[Any, ...]:
494
401
  new_abi = copy.copy(arg_abi)
495
402
  new_abi["type"] = tuple_prefix + "[]" * (num_dims - 1)
496
403
 
497
- sub_abis = itertools.repeat(new_abi) # type: ignore
404
+ sub_abis = [cast(ABIComponent, abi) for abi in itertools.repeat(new_abi)]
498
405
 
499
406
  if isinstance(arg, abc.Mapping):
500
407
  # Arg is mapping. Align values according to abi order.
@@ -503,7 +410,7 @@ def _align_abi_input(arg_abi: ABIFunctionParams, arg: Any) -> Tuple[Any, ...]:
503
410
  aligned_arg = arg
504
411
 
505
412
  if not is_list_like(aligned_arg):
506
- raise TypeError(
413
+ raise Web3TypeError(
507
414
  f'Expected non-string sequence for "{arg_abi.get("type")}" '
508
415
  f"component type: got {aligned_arg}"
509
416
  )
@@ -517,38 +424,21 @@ def _align_abi_input(arg_abi: ABIFunctionParams, arg: Any) -> Tuple[Any, ...]:
517
424
  )
518
425
 
519
426
 
520
- def get_aligned_abi_inputs(
521
- abi: ABIFunction, args: Union[Tuple[Any, ...], Mapping[Any, Any]]
522
- ) -> Tuple[Tuple[Any, ...], Tuple[Any, ...]]:
523
- """
524
- Takes a function ABI (``abi``) and a sequence or mapping of args (``args``).
525
- Returns a list of type strings for the function's inputs and a list of
526
- arguments which have been aligned to the layout of those types. The args
527
- contained in ``args`` may contain nested mappings or sequences corresponding
528
- to tuple-encoded values in ``abi``.
427
+ def find_constructor_abi_element_by_type(contract_abi: ABI) -> ABIConstructor:
529
428
  """
530
- input_abis = abi.get("inputs", [])
531
-
532
- if isinstance(args, abc.Mapping):
533
- # `args` is mapping. Align values according to abi order.
534
- args = tuple(args[abi["name"]] for abi in input_abis)
535
-
536
- return (
537
- # typed dict cannot be used w/ a normal Dict
538
- # https://github.com/python/mypy/issues/4976
539
- tuple(collapse_if_tuple(abi) for abi in input_abis), # type: ignore
540
- type(args)(_align_abi_input(abi, arg) for abi, arg in zip(input_abis, args)),
541
- )
429
+ Find the constructor ABI element in the contract ABI.
542
430
 
543
-
544
- 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
+ """
545
435
  candidates = [abi for abi in contract_abi if abi["type"] == "constructor"]
546
436
  if len(candidates) == 1:
547
437
  return candidates[0]
548
438
  elif len(candidates) == 0:
549
439
  return None
550
440
  elif len(candidates) > 1:
551
- raise ValueError("Found multiple constructors.")
441
+ raise Web3ValueError("Found multiple constructors.")
552
442
  return None
553
443
 
554
444
 
@@ -570,7 +460,7 @@ STATIC_TYPES = list(
570
460
  )
571
461
 
572
462
  BASE_TYPE_REGEX = "|".join(
573
- (_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)
574
464
  )
575
465
 
576
466
  SUB_TYPE_REGEX = r"\[" "[0-9]*" r"\]"
@@ -636,14 +526,14 @@ END_BRACKETS_OF_ARRAY_TYPE_REGEX = r"\[[^]]*\]$"
636
526
 
637
527
  def sub_type_of_array_type(abi_type: TypeStr) -> str:
638
528
  if not is_array_type(abi_type):
639
- 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}")
640
530
 
641
- 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)
642
532
 
643
533
 
644
534
  def length_of_array_type(abi_type: TypeStr) -> int:
645
535
  if not is_array_type(abi_type):
646
- 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}")
647
537
 
648
538
  inner_brackets = (
649
539
  re.search(END_BRACKETS_OF_ARRAY_TYPE_REGEX, abi_type).group(0).strip("[]")
@@ -675,8 +565,8 @@ def is_probably_enum(abi_type: TypeStr) -> bool:
675
565
 
676
566
  @to_tuple
677
567
  def normalize_event_input_types(
678
- abi_args: Collection[Union[ABIFunction, ABIEvent]]
679
- ) -> Iterable[Union[ABIFunction, ABIEvent, Dict[TypeStr, Any]]]:
568
+ abi_args: Collection[ABIEvent],
569
+ ) -> Iterable[Union[ABIEvent, Dict[TypeStr, Any]]]:
680
570
  for arg in abi_args:
681
571
  if is_recognized_type(arg["type"]):
682
572
  yield arg
@@ -686,17 +576,6 @@ def normalize_event_input_types(
686
576
  yield arg
687
577
 
688
578
 
689
- def abi_to_signature(abi: Union[ABIFunction, ABIEvent]) -> str:
690
- function_signature = "{fn_name}({fn_input_types})".format(
691
- fn_name=abi["name"],
692
- fn_input_types=",".join(
693
- collapse_if_tuple(dict(arg))
694
- for arg in normalize_event_input_types(abi.get("inputs", []))
695
- ),
696
- )
697
- return function_signature
698
-
699
-
700
579
  ########################################################
701
580
  #
702
581
  # Conditionally modifying data, tagged with ABI Types
@@ -711,8 +590,8 @@ def map_abi_data(
711
590
  data: Sequence[Any],
712
591
  ) -> Any:
713
592
  """
714
- This function will apply normalizers to your data, in the
715
- 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:
716
595
 
717
596
  def normalizer(datatype, data):
718
597
  # Conditionally modify data
@@ -778,7 +657,7 @@ def data_tree_map(
778
657
 
779
658
  class ABITypedData(namedtuple("ABITypedData", "abi_type, data")):
780
659
  """
781
- This class marks data as having a certain ABI-type.
660
+ Marks data as having a certain ABI-type.
782
661
 
783
662
  >>> a1 = ABITypedData(['address', addr1])
784
663
  >>> a2 = ABITypedData(['address', addr2])
@@ -847,7 +726,7 @@ def strip_abi_type(elements: Any) -> Any:
847
726
  def build_non_strict_registry() -> ABIRegistry:
848
727
  # We make a copy here just to make sure that eth-abi's default registry is not
849
728
  # affected by our custom encoder subclasses
850
- registry = default_registry.copy()
729
+ registry = default_registry.copy() # type: ignore[no-untyped-call]
851
730
 
852
731
  registry.unregister("address")
853
732
  registry.unregister("bytes<M>")
@@ -855,25 +734,25 @@ def build_non_strict_registry() -> ABIRegistry:
855
734
  registry.unregister("string")
856
735
 
857
736
  registry.register(
858
- BaseEquals("address"),
737
+ BaseEquals("address"), # type: ignore[no-untyped-call]
859
738
  AddressEncoder,
860
739
  decoding.AddressDecoder,
861
740
  label="address",
862
741
  )
863
742
  registry.register(
864
- BaseEquals("bytes", with_sub=True),
743
+ BaseEquals("bytes", with_sub=True), # type: ignore[no-untyped-call]
865
744
  BytesEncoder,
866
745
  decoding.BytesDecoder,
867
746
  label="bytes<M>",
868
747
  )
869
748
  registry.register(
870
- BaseEquals("bytes", with_sub=False),
749
+ BaseEquals("bytes", with_sub=False), # type: ignore[no-untyped-call]
871
750
  ByteStringEncoder,
872
751
  decoding.ByteStringDecoder,
873
752
  label="bytes",
874
753
  )
875
754
  registry.register(
876
- BaseEquals("string"),
755
+ BaseEquals("string"), # type: ignore[no-untyped-call]
877
756
  TextStringEncoder,
878
757
  decoding.StringDecoder,
879
758
  label="string",
@@ -882,7 +761,7 @@ def build_non_strict_registry() -> ABIRegistry:
882
761
 
883
762
 
884
763
  def build_strict_registry() -> ABIRegistry:
885
- registry = default_registry.copy()
764
+ registry = default_registry.copy() # type: ignore[no-untyped-call]
886
765
 
887
766
  registry.unregister("address")
888
767
  registry.unregister("bytes<M>")
@@ -890,25 +769,25 @@ def build_strict_registry() -> ABIRegistry:
890
769
  registry.unregister("string")
891
770
 
892
771
  registry.register(
893
- BaseEquals("address"),
772
+ BaseEquals("address"), # type: ignore[no-untyped-call]
894
773
  AddressEncoder,
895
774
  decoding.AddressDecoder,
896
775
  label="address",
897
776
  )
898
777
  registry.register(
899
- BaseEquals("bytes", with_sub=True),
778
+ BaseEquals("bytes", with_sub=True), # type: ignore[no-untyped-call]
900
779
  ExactLengthBytesEncoder,
901
780
  decoding.BytesDecoder,
902
781
  label="bytes<M>",
903
782
  )
904
783
  registry.register(
905
- BaseEquals("bytes", with_sub=False),
784
+ BaseEquals("bytes", with_sub=False), # type: ignore[no-untyped-call]
906
785
  StrictByteStringEncoder,
907
786
  decoding.ByteStringDecoder,
908
787
  label="bytes",
909
788
  )
910
789
  registry.register(
911
- BaseEquals("string"),
790
+ BaseEquals("string"), # type: ignore[no-untyped-call]
912
791
  encoding.TextStringEncoder,
913
792
  decoding.StringDecoder,
914
793
  label="string",
@@ -917,7 +796,11 @@ def build_strict_registry() -> ABIRegistry:
917
796
 
918
797
 
919
798
  def named_tree(
920
- abi: Iterable[Union[ABIFunctionParams, ABIFunction, ABIEvent, Dict[TypeStr, Any]]],
799
+ abi: Iterable[
800
+ Union[
801
+ ABIComponent, ABIComponentIndexed, ABIFunction, ABIEvent, Dict[TypeStr, Any]
802
+ ]
803
+ ],
921
804
  data: Iterable[Tuple[Any, ...]],
922
805
  ) -> Dict[str, Any]:
923
806
  """
@@ -930,10 +813,12 @@ def named_tree(
930
813
 
931
814
 
932
815
  def _named_subtree(
933
- abi: Union[ABIFunctionParams, ABIFunction, ABIEvent, Dict[TypeStr, Any]],
816
+ abi: Union[
817
+ ABIComponent, ABIComponentIndexed, ABIFunction, ABIEvent, Dict[TypeStr, Any]
818
+ ],
934
819
  data: Tuple[Any, ...],
935
820
  ) -> Union[Dict[str, Any], Tuple[Any, ...], List[Any]]:
936
- abi_type = parse(collapse_if_tuple(dict(abi)))
821
+ abi_type = parse(collapse_if_tuple(cast(Dict[str, Any], abi)))
937
822
 
938
823
  if abi_type.is_array:
939
824
  item_type = abi_type.item_type.to_type_str()
@@ -942,7 +827,11 @@ def _named_subtree(
942
827
  return items
943
828
 
944
829
  elif isinstance(abi_type, TupleType):
945
- abi = cast(ABIFunctionParams, abi)
830
+ if abi.get("indexed"):
831
+ abi = cast(ABIComponentIndexed, abi)
832
+ else:
833
+ abi = cast(ABIComponent, abi)
834
+
946
835
  names = [item["name"] for item in abi["components"]]
947
836
  items = [_named_subtree(*item) for item in zip(abi["components"], data)]
948
837
 
@@ -1035,7 +924,6 @@ async def async_map_if_collection(
1035
924
  Apply an awaitable method to each element of a collection or value of a dictionary.
1036
925
  If the value is not a collection, return it unmodified.
1037
926
  """
1038
-
1039
927
  datatype = type(value)
1040
928
  if isinstance(value, Mapping):
1041
929
  return datatype({key: await func(val) for key, val in value.values()})