web3 7.7.0__py3-none-any.whl → 7.8.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.
@@ -14,7 +14,6 @@ from typing import (
14
14
 
15
15
  from eth_typing import (
16
16
  ABI,
17
- ABIFunction,
18
17
  ChecksumAddress,
19
18
  )
20
19
  from eth_utils import (
@@ -22,7 +21,6 @@ from eth_utils import (
22
21
  )
23
22
  from eth_utils.abi import (
24
23
  abi_to_signature,
25
- filter_abi_by_type,
26
24
  get_abi_input_names,
27
25
  )
28
26
  from eth_utils.toolz import (
@@ -34,7 +32,6 @@ from hexbytes import (
34
32
 
35
33
  from web3._utils.abi import (
36
34
  fallback_func_abi_exists,
37
- get_name_from_abi_element_identifier,
38
35
  receive_func_abi_exists,
39
36
  )
40
37
  from web3._utils.abi_element_identifiers import (
@@ -49,8 +46,6 @@ from web3._utils.compat import (
49
46
  )
50
47
  from web3._utils.contracts import (
51
48
  async_parse_block_identifier,
52
- copy_contract_event,
53
- copy_contract_function,
54
49
  )
55
50
  from web3._utils.datatypes import (
56
51
  PropertyCheckingFactory,
@@ -89,12 +84,6 @@ from web3.contract.utils import (
89
84
  get_function_by_identifier,
90
85
  )
91
86
  from web3.exceptions import (
92
- ABIEventNotFound,
93
- ABIFunctionNotFound,
94
- MismatchedABI,
95
- NoABIEventsFound,
96
- NoABIFound,
97
- NoABIFunctionsFound,
98
87
  Web3AttributeError,
99
88
  Web3TypeError,
100
89
  Web3ValidationError,
@@ -106,12 +95,6 @@ from web3.types import (
106
95
  StateOverride,
107
96
  TxParams,
108
97
  )
109
- from web3.utils.abi import (
110
- _filter_by_argument_count,
111
- _get_any_abi_signature_with_name,
112
- _mismatched_abi_error_diagnosis,
113
- get_abi_element,
114
- )
115
98
 
116
99
  if TYPE_CHECKING:
117
100
  from ens import AsyncENS # noqa: F401
@@ -122,9 +105,6 @@ class AsyncContractEvent(BaseContractEvent):
122
105
  # mypy types
123
106
  w3: "AsyncWeb3"
124
107
 
125
- def __call__(self, *args: Any, **kwargs: Any) -> "AsyncContractEvent":
126
- return copy_contract_event(self, *args, **kwargs)
127
-
128
108
  @combomethod
129
109
  async def get_logs(
130
110
  self,
@@ -255,162 +235,18 @@ class AsyncContractEvent(BaseContractEvent):
255
235
  builder.address = self.address
256
236
  return builder
257
237
 
258
- @classmethod
259
- def factory(cls, class_name: str, **kwargs: Any) -> Self:
260
- return PropertyCheckingFactory(class_name, (cls,), kwargs)()
261
238
 
262
-
263
- class AsyncContractEvents(BaseContractEvents):
239
+ class AsyncContractEvents(BaseContractEvents[AsyncContractEvent]):
264
240
  def __init__(
265
241
  self, abi: ABI, w3: "AsyncWeb3", address: Optional[ChecksumAddress] = None
266
242
  ) -> None:
267
243
  super().__init__(abi, w3, AsyncContractEvent, address)
268
244
 
269
- def __iter__(self) -> Iterable["AsyncContractEvent"]:
270
- if not hasattr(self, "_events") or not self._events:
271
- return
272
-
273
- for event in self._events:
274
- yield self[abi_to_signature(event)]
275
-
276
- def __getattr__(self, event_name: str) -> "AsyncContractEvent":
277
- if super().__getattribute__("abi") is None:
278
- raise NoABIFound(
279
- "There is no ABI found for this contract.",
280
- )
281
- elif "_events" not in self.__dict__ or len(self._events) == 0:
282
- raise NoABIEventsFound(
283
- "The abi for this contract contains no event definitions. ",
284
- "Are you sure you provided the correct contract abi?",
285
- )
286
- elif get_name_from_abi_element_identifier(event_name) not in [
287
- get_name_from_abi_element_identifier(event["name"])
288
- for event in self._events
289
- ]:
290
- raise ABIEventNotFound(
291
- f"The event '{event_name}' was not found in this contract's abi. ",
292
- "Are you sure you provided the correct contract abi?",
293
- )
294
-
295
- if "(" not in event_name:
296
- event_name = _get_any_abi_signature_with_name(event_name, self._events)
297
- else:
298
- event_name = f"_{event_name}"
299
-
300
- return super().__getattribute__(event_name)
301
-
302
- def __getitem__(self, event_name: str) -> "AsyncContractEvent":
303
- return getattr(self, event_name)
304
-
305
245
 
306
246
  class AsyncContractFunction(BaseContractFunction):
307
247
  # mypy types
308
248
  w3: "AsyncWeb3"
309
249
 
310
- def __call__(self, *args: Any, **kwargs: Any) -> "AsyncContractFunction":
311
- # When a function is called, check arguments to obtain the correct function
312
- # in the contract. self will be used if all args and kwargs are
313
- # encodable to self.abi, otherwise the correct function is obtained from
314
- # the contract.
315
- if (
316
- self.abi_element_identifier in [FallbackFn, ReceiveFn]
317
- or self.abi_element_identifier == "constructor"
318
- ):
319
- return copy_contract_function(self, *args, **kwargs)
320
-
321
- all_functions = cast(
322
- List[ABIFunction],
323
- filter_abi_by_type(
324
- "function",
325
- self.contract_abi,
326
- ),
327
- )
328
- # Filter functions by name to obtain function signatures
329
- function_name = get_name_from_abi_element_identifier(
330
- self.abi_element_identifier
331
- )
332
- function_abis = [
333
- function for function in all_functions if function["name"] == function_name
334
- ]
335
- num_args = len(args) + len(kwargs)
336
- function_abis_with_arg_count = cast(
337
- List[ABIFunction],
338
- _filter_by_argument_count(
339
- num_args,
340
- function_abis,
341
- ),
342
- )
343
-
344
- if not len(function_abis_with_arg_count):
345
- # Build an ABI without arguments to determine if one exists
346
- function_abis_with_arg_count = [
347
- ABIFunction({"type": "function", "name": function_name})
348
- ]
349
-
350
- # Check that arguments in call match a function ABI
351
- num_attempts = 0
352
- function_abi_matches = []
353
- contract_function = None
354
- for abi in function_abis_with_arg_count:
355
- try:
356
- num_attempts += 1
357
-
358
- # Search for a function ABI that matches the arguments used
359
- function_abi_matches.append(
360
- cast(
361
- ABIFunction,
362
- get_abi_element(
363
- function_abis,
364
- abi_to_signature(abi),
365
- *args,
366
- abi_codec=self.w3.codec,
367
- **kwargs,
368
- ),
369
- )
370
- )
371
- except MismatchedABI:
372
- # ignore exceptions
373
- continue
374
-
375
- if len(function_abi_matches) == 1:
376
- function_abi = function_abi_matches[0]
377
- if abi_to_signature(self.abi) == abi_to_signature(function_abi):
378
- contract_function = self
379
- else:
380
- # Found a match that is not self
381
- contract_function = AsyncContractFunction.factory(
382
- abi_to_signature(function_abi),
383
- w3=self.w3,
384
- contract_abi=self.contract_abi,
385
- address=self.address,
386
- abi_element_identifier=abi_to_signature(function_abi),
387
- abi=function_abi,
388
- )
389
- else:
390
- for abi in function_abi_matches:
391
- if abi_to_signature(self.abi) == abi_to_signature(abi):
392
- contract_function = self
393
- break
394
- else:
395
- # Raise exception if multiple found
396
- raise MismatchedABI(
397
- _mismatched_abi_error_diagnosis(
398
- function_name,
399
- self.contract_abi,
400
- len(function_abi_matches),
401
- num_args,
402
- *args,
403
- abi_codec=self.w3.codec,
404
- **kwargs,
405
- )
406
- )
407
-
408
- return copy_contract_function(contract_function, *args, **kwargs)
409
-
410
- @classmethod
411
- def factory(cls, class_name: str, **kwargs: Any) -> Self:
412
- return PropertyCheckingFactory(class_name, (cls,), kwargs)()
413
-
414
250
  async def call(
415
251
  self,
416
252
  transaction: Optional[TxParams] = None,
@@ -551,7 +387,7 @@ class AsyncContractFunction(BaseContractFunction):
551
387
  return cast(AsyncContractFunction, NonExistentReceiveFunction())
552
388
 
553
389
 
554
- class AsyncContractFunctions(BaseContractFunctions):
390
+ class AsyncContractFunctions(BaseContractFunctions[AsyncContractFunction]):
555
391
  def __init__(
556
392
  self,
557
393
  abi: ABI,
@@ -561,46 +397,6 @@ class AsyncContractFunctions(BaseContractFunctions):
561
397
  ) -> None:
562
398
  super().__init__(abi, w3, AsyncContractFunction, address, decode_tuples)
563
399
 
564
- def __iter__(self) -> Iterable["AsyncContractFunction"]:
565
- if not hasattr(self, "_functions") or not self._functions:
566
- return
567
-
568
- for func in self._functions:
569
- yield self[abi_to_signature(func)]
570
-
571
- def __getattr__(self, function_name: str) -> "AsyncContractFunction":
572
- if super().__getattribute__("abi") is None:
573
- raise NoABIFound(
574
- "There is no ABI found for this contract.",
575
- )
576
- elif "_functions" not in self.__dict__ or len(self._functions) == 0:
577
- raise NoABIFunctionsFound(
578
- "The abi for this contract contains no function definitions. ",
579
- "Are you sure you provided the correct contract abi?",
580
- )
581
- elif get_name_from_abi_element_identifier(function_name) not in [
582
- get_name_from_abi_element_identifier(function["name"])
583
- for function in self._functions
584
- ]:
585
- raise ABIFunctionNotFound(
586
- f"The function '{function_name}' was not found in this ",
587
- "contract's abi.",
588
- )
589
-
590
- if "(" not in function_name:
591
- function_name = _get_any_abi_signature_with_name(
592
- function_name, self._functions
593
- )
594
- else:
595
- function_name = f"_{function_name}"
596
-
597
- return super().__getattribute__(
598
- function_name,
599
- )
600
-
601
- def __getitem__(self, function_name: str) -> "AsyncContractFunction":
602
- return getattr(self, function_name)
603
-
604
400
 
605
401
  class AsyncContract(BaseContract):
606
402
  functions: AsyncContractFunctions = None
@@ -4,6 +4,7 @@ from typing import (
4
4
  Callable,
5
5
  Collection,
6
6
  Dict,
7
+ Generic,
7
8
  Iterable,
8
9
  List,
9
10
  NoReturn,
@@ -58,7 +59,12 @@ from web3._utils.abi_element_identifiers import (
58
59
  FallbackFn,
59
60
  ReceiveFn,
60
61
  )
62
+ from web3._utils.compat import (
63
+ Self,
64
+ )
61
65
  from web3._utils.contracts import (
66
+ copy_contract_event,
67
+ copy_contract_function,
62
68
  decode_transaction_data,
63
69
  encode_abi,
64
70
  prepare_transaction,
@@ -98,6 +104,7 @@ from web3.exceptions import (
98
104
  InvalidEventABI,
99
105
  LogTopicError,
100
106
  MismatchedABI,
107
+ NoABIEventsFound,
101
108
  NoABIFound,
102
109
  NoABIFunctionsFound,
103
110
  Web3AttributeError,
@@ -118,12 +125,16 @@ from web3.types import (
118
125
  EventData,
119
126
  FilterParams,
120
127
  LogReceipt,
128
+ StateOverride,
129
+ TContractEvent,
121
130
  TContractFn,
122
131
  TxParams,
123
132
  TxReceipt,
124
133
  )
125
134
  from web3.utils.abi import (
135
+ _filter_by_argument_count,
126
136
  _get_any_abi_signature_with_name,
137
+ _mismatched_abi_error_diagnosis,
127
138
  check_if_arguments_can_be_encoded,
128
139
  get_abi_element,
129
140
  get_abi_element_info,
@@ -189,6 +200,9 @@ class BaseContractEvent:
189
200
  return f"<Event {abi_to_signature(self.abi)}>"
190
201
  return f"<Event {get_abi_element_signature(self.abi_element_identifier)}>"
191
202
 
203
+ def __call__(self, *args: Any, **kwargs: Any) -> Self:
204
+ return copy_contract_event(self, *args, **kwargs)
205
+
192
206
  @property
193
207
  def topic(self) -> HexStr:
194
208
  if self._topic is None:
@@ -310,9 +324,7 @@ class BaseContractEvent:
310
324
  return event_filter_params
311
325
 
312
326
  @classmethod
313
- def factory(
314
- cls, class_name: str, **kwargs: Any
315
- ) -> Union["ContractEvent", "AsyncContractEvent"]:
327
+ def factory(cls, class_name: str, **kwargs: Any) -> Self:
316
328
  return PropertyCheckingFactory(class_name, (cls,), kwargs)()
317
329
 
318
330
  @staticmethod
@@ -440,7 +452,7 @@ class BaseContractEvent:
440
452
  filter_builder.args[arg].match_single(value)
441
453
 
442
454
 
443
- class BaseContractEvents:
455
+ class BaseContractEvents(Generic[TContractEvent]):
444
456
  """
445
457
  Class containing contract event objects
446
458
 
@@ -466,12 +478,13 @@ class BaseContractEvents:
466
478
  self,
467
479
  abi: ABI,
468
480
  w3: Union["Web3", "AsyncWeb3"],
469
- contract_event_type: Union[Type["ContractEvent"], Type["AsyncContractEvent"]],
481
+ contract_event_type: Type[TContractEvent],
470
482
  address: Optional[ChecksumAddress] = None,
471
483
  ) -> None:
472
484
  self.abi = abi
473
485
  self.w3 = w3
474
486
  self.address = address
487
+ self.contract_event_type = contract_event_type
475
488
  _events: Sequence[ABIEvent] = None
476
489
 
477
490
  if self.abi:
@@ -506,6 +519,42 @@ class BaseContractEvents:
506
519
  except ABIEventNotFound:
507
520
  return False
508
521
 
522
+ def __getattr__(self, event_name: str) -> TContractEvent:
523
+ if super().__getattribute__("abi") is None:
524
+ raise NoABIFound(
525
+ "There is no ABI found for this contract.",
526
+ )
527
+ elif "_events" not in self.__dict__ or len(self._events) == 0:
528
+ raise NoABIEventsFound(
529
+ "The abi for this contract contains no event definitions. ",
530
+ "Are you sure you provided the correct contract abi?",
531
+ )
532
+ elif get_name_from_abi_element_identifier(event_name) not in [
533
+ get_name_from_abi_element_identifier(event["name"])
534
+ for event in self._events
535
+ ]:
536
+ raise ABIEventNotFound(
537
+ f"The event '{event_name}' was not found in this contract's abi. ",
538
+ "Are you sure you provided the correct contract abi?",
539
+ )
540
+
541
+ if "(" not in event_name:
542
+ event_name = _get_any_abi_signature_with_name(event_name, self._events)
543
+ else:
544
+ event_name = f"_{event_name}"
545
+
546
+ return super().__getattribute__(event_name)
547
+
548
+ def __getitem__(self, event_name: str) -> TContractEvent:
549
+ return getattr(self, event_name)
550
+
551
+ def __iter__(self) -> Iterable[TContractEvent]:
552
+ if not hasattr(self, "_events") or not self._events:
553
+ return
554
+
555
+ for event in self._events:
556
+ yield self[abi_to_signature(event)]
557
+
509
558
 
510
559
  class BaseContractFunction:
511
560
  """
@@ -721,14 +770,123 @@ class BaseContractFunction:
721
770
  return _repr + ">"
722
771
  return f"<Function {get_abi_element_signature(self.abi_element_identifier)}>"
723
772
 
773
+ def __call__(self, *args: Any, **kwargs: Any) -> Self:
774
+ # When a function is called, check arguments to obtain the correct function
775
+ # in the contract. self will be used if all args and kwargs are
776
+ # encodable to self.abi, otherwise the correct function is obtained from
777
+ # the contract.
778
+ if (
779
+ self.abi_element_identifier in [FallbackFn, ReceiveFn]
780
+ or self.abi_element_identifier == "constructor"
781
+ ):
782
+ return copy_contract_function(self, *args, **kwargs)
783
+
784
+ all_functions = cast(
785
+ List[ABIFunction],
786
+ filter_abi_by_type(
787
+ "function",
788
+ self.contract_abi,
789
+ ),
790
+ )
791
+ # Filter functions by name to obtain function signatures
792
+ function_name = get_name_from_abi_element_identifier(
793
+ self.abi_element_identifier
794
+ )
795
+ function_abis = [
796
+ function for function in all_functions if function["name"] == function_name
797
+ ]
798
+ num_args = len(args) + len(kwargs)
799
+ function_abis_with_arg_count = cast(
800
+ List[ABIFunction],
801
+ _filter_by_argument_count(
802
+ num_args,
803
+ function_abis,
804
+ ),
805
+ )
806
+
807
+ if not len(function_abis_with_arg_count):
808
+ # Build an ABI without arguments to determine if one exists
809
+ function_abis_with_arg_count = [
810
+ ABIFunction({"type": "function", "name": function_name})
811
+ ]
812
+
813
+ function_abi_matches = []
814
+ contract_function = None
815
+ for abi in function_abis_with_arg_count:
816
+ try:
817
+ # Search for a function ABI that matches the arguments used
818
+ function_abi_matches.append(
819
+ cast(
820
+ ABIFunction,
821
+ get_abi_element(
822
+ function_abis,
823
+ abi_to_signature(abi),
824
+ *args,
825
+ abi_codec=self.w3.codec,
826
+ **kwargs,
827
+ ),
828
+ )
829
+ )
830
+ except MismatchedABI:
831
+ # ignore exceptions
832
+ continue
833
+
834
+ if len(function_abi_matches) == 1:
835
+ function_abi = function_abi_matches[0]
836
+ if abi_to_signature(self.abi) == abi_to_signature(function_abi):
837
+ contract_function = self
838
+ else:
839
+ # Found a match that is not self
840
+ contract_function = self.__class__.factory(
841
+ abi_to_signature(function_abi),
842
+ w3=self.w3,
843
+ contract_abi=self.contract_abi,
844
+ address=self.address,
845
+ abi_element_identifier=abi_to_signature(function_abi),
846
+ abi=function_abi,
847
+ )
848
+ else:
849
+ for abi in function_abi_matches:
850
+ if abi_to_signature(self.abi) == abi_to_signature(abi):
851
+ contract_function = self
852
+ break
853
+ else:
854
+ # Raise exception if multiple found
855
+ raise MismatchedABI(
856
+ _mismatched_abi_error_diagnosis(
857
+ function_name,
858
+ self.contract_abi,
859
+ len(function_abi_matches),
860
+ num_args,
861
+ *args,
862
+ abi_codec=self.w3.codec,
863
+ **kwargs,
864
+ )
865
+ )
866
+
867
+ return copy_contract_function(contract_function, *args, **kwargs)
868
+
724
869
  @classmethod
725
- def factory(
726
- cls, class_name: str, **kwargs: Any
727
- ) -> Union["ContractFunction", "AsyncContractFunction"]:
870
+ def factory(cls, class_name: str, **kwargs: Any) -> Self:
728
871
  return PropertyCheckingFactory(class_name, (cls,), kwargs)()
729
872
 
873
+ def call(
874
+ self,
875
+ transaction: Optional[TxParams] = None,
876
+ block_identifier: Optional[BlockIdentifier] = None,
877
+ state_override: Optional[StateOverride] = None,
878
+ ccip_read_enabled: Optional[bool] = None,
879
+ ) -> Any:
880
+ """
881
+ Implementation of ``call`` should create a callable contract function
882
+ and execute it using the `eth_call` interface.
883
+ """
884
+ raise NotImplementedError(
885
+ "This method should be implemented in the inherited class"
886
+ )
730
887
 
731
- class BaseContractFunctions:
888
+
889
+ class BaseContractFunctions(Generic[TContractFn]):
732
890
  """Class containing contract function objects"""
733
891
 
734
892
  _functions: Sequence[ABIFunction] = None
@@ -737,9 +895,7 @@ class BaseContractFunctions:
737
895
  self,
738
896
  abi: ABI,
739
897
  w3: Union["Web3", "AsyncWeb3"],
740
- contract_function_class: Union[
741
- Type["ContractFunction"], Type["AsyncContractFunction"]
742
- ],
898
+ contract_function_class: Type[TContractFn],
743
899
  address: Optional[ChecksumAddress] = None,
744
900
  decode_tuples: Optional[bool] = False,
745
901
  ) -> None:
@@ -785,6 +941,46 @@ class BaseContractFunctions:
785
941
  except ABIFunctionNotFound:
786
942
  return False
787
943
 
944
+ def __iter__(self) -> Iterable[TContractFn]:
945
+ if not hasattr(self, "_functions") or not self._functions:
946
+ return
947
+
948
+ for func in self._functions:
949
+ yield self[abi_to_signature(func)]
950
+
951
+ def __getattr__(self, function_name: str) -> TContractFn:
952
+ if super().__getattribute__("abi") is None:
953
+ raise NoABIFound(
954
+ "There is no ABI found for this contract.",
955
+ )
956
+ elif "_functions" not in self.__dict__ or len(self._functions) == 0:
957
+ raise NoABIFunctionsFound(
958
+ "The abi for this contract contains no function definitions. ",
959
+ "Are you sure you provided the correct contract abi?",
960
+ )
961
+ elif get_name_from_abi_element_identifier(function_name) not in [
962
+ get_name_from_abi_element_identifier(function["name"])
963
+ for function in self._functions
964
+ ]:
965
+ raise ABIFunctionNotFound(
966
+ f"The function '{function_name}' was not found in this ",
967
+ "contract's abi.",
968
+ )
969
+
970
+ if "(" not in function_name:
971
+ function_name = _get_any_abi_signature_with_name(
972
+ function_name, self._functions
973
+ )
974
+ else:
975
+ function_name = f"_{function_name}"
976
+
977
+ return super().__getattribute__(
978
+ function_name,
979
+ )
980
+
981
+ def __getitem__(self, function_name: str) -> TContractFn:
982
+ return getattr(self, function_name)
983
+
788
984
 
789
985
  class BaseContract:
790
986
  """