web3 7.5.0__py3-none-any.whl → 7.6.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.
@@ -48,7 +48,10 @@ from hexbytes import (
48
48
 
49
49
  from web3._utils.abi import (
50
50
  fallback_func_abi_exists,
51
+ filter_by_types,
51
52
  find_constructor_abi_element_by_type,
53
+ get_abi_element_signature,
54
+ get_name_from_abi_element_identifier,
52
55
  is_array_type,
53
56
  receive_func_abi_exists,
54
57
  )
@@ -96,7 +99,6 @@ from web3.exceptions import (
96
99
  InvalidEventABI,
97
100
  LogTopicError,
98
101
  MismatchedABI,
99
- NoABIEventsFound,
100
102
  NoABIFound,
101
103
  NoABIFunctionsFound,
102
104
  Web3AttributeError,
@@ -121,10 +123,10 @@ from web3.types import (
121
123
  TxReceipt,
122
124
  )
123
125
  from web3.utils.abi import (
126
+ _get_any_abi_signature_with_name,
124
127
  check_if_arguments_can_be_encoded,
125
128
  get_abi_element,
126
129
  get_abi_element_info,
127
- get_event_abi,
128
130
  )
129
131
 
130
132
  if TYPE_CHECKING:
@@ -153,13 +155,20 @@ class BaseContractEvent:
153
155
 
154
156
  address: ChecksumAddress = None
155
157
  event_name: str = None
158
+ abi_element_identifier: ABIElementIdentifier = None
156
159
  w3: Union["Web3", "AsyncWeb3"] = None
157
160
  contract_abi: ABI = None
158
161
  abi: ABIEvent = None
162
+ argument_types: Tuple[str] = None
163
+ args: Any = None
164
+ kwargs: Any = None
159
165
 
160
- def __init__(self, *argument_names: Tuple[str], abi: ABIEvent) -> None:
166
+ def __init__(self, *argument_names: Tuple[str]) -> None:
167
+ self.event_name = get_name_from_abi_element_identifier(type(self).__name__)
168
+ self.abi_element_identifier = type(self).__name__
169
+ abi = self._get_event_abi()
170
+ self.name = abi_to_signature(abi)
161
171
  self.abi = abi
162
- self.name = type(self).__name__
163
172
 
164
173
  if argument_names is None:
165
174
  # https://github.com/python/mypy/issues/6283
@@ -168,11 +177,26 @@ class BaseContractEvent:
168
177
  self.argument_names = argument_names
169
178
 
170
179
  def __repr__(self) -> str:
171
- return f"<Event {abi_to_signature(self.abi)}>"
180
+ if self.abi:
181
+ return f"<Event {abi_to_signature(self.abi)}>"
182
+ return f"<Event {get_abi_element_signature(self.abi_element_identifier)}>"
172
183
 
173
- @classmethod
184
+ @combomethod
174
185
  def _get_event_abi(cls) -> ABIEvent:
175
- return get_event_abi(cls.contract_abi, event_name=cls.event_name)
186
+ if cls.abi:
187
+ return cls.abi
188
+
189
+ return cast(
190
+ ABIEvent,
191
+ get_abi_element(
192
+ filter_abi_by_type("event", cls.contract_abi),
193
+ cls.abi_element_identifier,
194
+ abi_codec=cls.w3.codec,
195
+ ),
196
+ )
197
+
198
+ def _set_event_info(self) -> None:
199
+ self.abi = self._get_event_abi()
176
200
 
177
201
  @combomethod
178
202
  def process_receipt(
@@ -275,9 +299,7 @@ class BaseContractEvent:
275
299
  def factory(
276
300
  cls, class_name: str, **kwargs: Any
277
301
  ) -> Union["ContractEvent", "AsyncContractEvent"]:
278
- return PropertyCheckingFactory(class_name, (cls,), kwargs)(
279
- abi=kwargs.get("abi")
280
- )
302
+ return PropertyCheckingFactory(class_name, (cls,), kwargs)()
281
303
 
282
304
  @staticmethod
283
305
  def check_for_forbidden_api_filter_arguments(
@@ -367,12 +389,10 @@ class BaseContractEvent:
367
389
 
368
390
  _filters = dict(**argument_filters)
369
391
 
370
- event_abi = self._get_event_abi()
371
-
372
- self.check_for_forbidden_api_filter_arguments(event_abi, _filters)
392
+ self.check_for_forbidden_api_filter_arguments(self.abi, _filters)
373
393
 
374
394
  _, event_filter_params = construct_event_filter_params(
375
- self._get_event_abi(),
395
+ self.abi,
376
396
  self.w3.codec,
377
397
  contract_address=self.address,
378
398
  argument_filters=_filters,
@@ -435,48 +455,26 @@ class BaseContractEvents:
435
455
  contract_event_type: Union[Type["ContractEvent"], Type["AsyncContractEvent"]],
436
456
  address: Optional[ChecksumAddress] = None,
437
457
  ) -> None:
438
- if abi:
439
- self.abi = abi
440
- self._events = filter_abi_by_type("event", self.abi)
441
- for event in self._events:
442
- setattr(
443
- self,
444
- event["name"],
445
- contract_event_type.factory(
446
- event["name"],
447
- w3=w3,
448
- contract_abi=self.abi,
449
- address=address,
450
- event_name=event["name"],
451
- abi=event,
452
- ),
453
- )
454
-
455
- def __getattr__(self, event_name: str) -> Type["BaseContractEvent"]:
456
- if "_events" not in self.__dict__:
457
- raise NoABIEventsFound(
458
- "The abi for this contract contains no event definitions. ",
459
- "Are you sure you provided the correct contract abi?",
460
- )
461
- elif event_name not in self.__dict__["_events"]:
462
- raise ABIEventNotFound(
463
- f"The event '{event_name}' was not found in this contract's abi. ",
464
- "Are you sure you provided the correct contract abi?",
465
- )
466
- else:
467
- return super().__getattribute__(event_name)
468
-
469
- def __getitem__(self, event_name: str) -> Type["BaseContractEvent"]:
470
- return getattr(self, event_name)
458
+ self.abi = abi
459
+ self.w3 = w3
460
+ self.address = address
461
+ _events: Sequence[ABIEvent] = None
471
462
 
472
- def __iter__(self) -> Iterable[Type["BaseContractEvent"]]:
473
- """
474
- Iterate over supported
463
+ if self.abi:
464
+ _events = filter_abi_by_type("event", abi)
465
+ for event in _events:
466
+ abi_signature = abi_to_signature(event)
467
+ event_factory = contract_event_type.factory(
468
+ abi_signature,
469
+ w3=self.w3,
470
+ contract_abi=self.abi,
471
+ address=self.address,
472
+ event_name=event["name"],
473
+ )
474
+ setattr(self, abi_signature, event_factory)
475
475
 
476
- :return: Iterable of :class:`ContractEvent`
477
- """
478
- for event in self._events:
479
- yield self[event["name"]]
476
+ if _events:
477
+ self._events = _events
480
478
 
481
479
  def __hasattr__(self, event_name: str) -> bool:
482
480
  try:
@@ -494,52 +492,80 @@ class BaseContractFunction:
494
492
  """
495
493
 
496
494
  address: ChecksumAddress = None
495
+ fn_name: str = None
496
+ name: str = None
497
497
  abi_element_identifier: ABIElementIdentifier = None
498
498
  w3: Union["Web3", "AsyncWeb3"] = None
499
499
  contract_abi: ABI = None
500
500
  abi: ABIFunction = None
501
501
  transaction: TxParams = None
502
502
  arguments: Tuple[Any, ...] = None
503
- decode_tuples: Optional[bool] = False
503
+ decode_tuples: Optional[bool] = None
504
504
  args: Any = None
505
505
  kwargs: Any = None
506
506
 
507
507
  def __init__(self, abi: Optional[ABIFunction] = None) -> None:
508
- self.abi = abi
509
- self.fn_name = type(self).__name__
508
+ if not self.abi_element_identifier:
509
+ self.abi_element_identifier = type(self).__name__
510
+
511
+ self.fn_name = get_name_from_abi_element_identifier(self.abi_element_identifier)
512
+ self.abi = cast(
513
+ ABIFunction,
514
+ get_abi_element(
515
+ filter_by_types(
516
+ ["function", "constructor", "fallback", "receive"],
517
+ self.contract_abi,
518
+ ),
519
+ self.abi_element_identifier,
520
+ ),
521
+ )
522
+ self.name = abi_to_signature(self.abi)
510
523
 
511
- def _set_function_info(self) -> None:
512
- if not self.abi:
513
- self.abi = cast(
524
+ @combomethod
525
+ def _get_abi(cls) -> ABIFunction:
526
+ if not cls.args and not cls.kwargs:
527
+ # If no args or kwargs are provided, get the ABI element by name
528
+ return cast(
514
529
  ABIFunction,
515
530
  get_abi_element(
516
- self.contract_abi,
517
- self.abi_element_identifier,
518
- *self.args,
519
- abi_codec=self.w3.codec,
520
- **self.kwargs,
531
+ cls.contract_abi,
532
+ get_abi_element_signature(cls.abi_element_identifier),
533
+ abi_codec=cls.w3.codec,
521
534
  ),
522
535
  )
523
536
 
524
- if self.abi_element_identifier in [
525
- FallbackFn,
526
- ReceiveFn,
527
- ]:
528
- self.selector = encode_hex(b"")
529
- elif is_text(self.abi_element_identifier):
530
- self.selector = encode_hex(function_abi_to_4byte_selector(self.abi))
531
- else:
532
- raise Web3TypeError("Unsupported function identifier")
537
+ return cast(
538
+ ABIFunction,
539
+ get_abi_element(
540
+ cls.contract_abi,
541
+ get_name_from_abi_element_identifier(cls.abi_element_identifier),
542
+ *cls.args,
543
+ abi_codec=cls.w3.codec,
544
+ **cls.kwargs,
545
+ ),
546
+ )
533
547
 
548
+ def _set_function_info(self) -> None:
549
+ self.selector = encode_hex(b"")
534
550
  if self.abi_element_identifier in [
551
+ "fallback",
552
+ "receive",
535
553
  FallbackFn,
536
554
  ReceiveFn,
537
555
  ]:
556
+ self.abi = self._get_abi()
557
+
558
+ self.selector = encode_hex(function_abi_to_4byte_selector(self.abi))
538
559
  self.arguments = None
539
- else:
560
+ elif is_text(self.abi_element_identifier):
561
+ self.abi = self._get_abi()
562
+
563
+ self.selector = encode_hex(function_abi_to_4byte_selector(self.abi))
540
564
  self.arguments = get_normalized_abi_inputs(
541
565
  self.abi, *self.args, **self.kwargs
542
566
  )
567
+ else:
568
+ raise Web3TypeError("Unsupported function identifier")
543
569
 
544
570
  def _get_call_txparams(self, transaction: Optional[TxParams] = None) -> TxParams:
545
571
  if transaction is None:
@@ -671,20 +697,20 @@ class BaseContractFunction:
671
697
  if self.arguments is not None:
672
698
  _repr += f" bound to {self.arguments!r}"
673
699
  return _repr + ">"
674
- return f"<Function {self.fn_name}>"
700
+ return f"<Function {get_abi_element_signature(self.abi_element_identifier)}>"
675
701
 
676
702
  @classmethod
677
703
  def factory(
678
704
  cls, class_name: str, **kwargs: Any
679
705
  ) -> Union["ContractFunction", "AsyncContractFunction"]:
680
- return PropertyCheckingFactory(class_name, (cls,), kwargs)(
681
- abi=kwargs.get("abi")
682
- )
706
+ return PropertyCheckingFactory(class_name, (cls,), kwargs)()
683
707
 
684
708
 
685
709
  class BaseContractFunctions:
686
710
  """Class containing contract function objects"""
687
711
 
712
+ _functions: Sequence[ABIFunction] = None
713
+
688
714
  def __init__(
689
715
  self,
690
716
  abi: ABI,
@@ -698,32 +724,26 @@ class BaseContractFunctions:
698
724
  self.abi = abi
699
725
  self.w3 = w3
700
726
  self.address = address
727
+ _functions: Sequence[ABIFunction] = None
701
728
 
702
729
  if self.abi:
703
- self._functions = filter_abi_by_type("function", self.abi)
704
- for func in self._functions:
730
+ _functions = filter_abi_by_type("function", self.abi)
731
+ for func in _functions:
732
+ abi_signature = abi_to_signature(func)
705
733
  setattr(
706
734
  self,
707
- func["name"],
735
+ abi_signature,
708
736
  contract_function_class.factory(
709
- func["name"],
737
+ abi_signature,
710
738
  w3=self.w3,
711
739
  contract_abi=self.abi,
712
740
  address=self.address,
713
741
  decode_tuples=decode_tuples,
714
- abi_element_identifier=func["name"],
715
742
  ),
716
743
  )
717
744
 
718
- def __iter__(self) -> Iterable["ABIFunction"]:
719
- if not hasattr(self, "_functions") or not self._functions:
720
- return
721
-
722
- for func in self._functions:
723
- yield self[func["name"]]
724
-
725
- def __getitem__(self, function_name: str) -> ABIFunction:
726
- return getattr(self, function_name)
745
+ if _functions:
746
+ self._functions = _functions
727
747
 
728
748
  def __hasattr__(self, function_name: str) -> bool:
729
749
  try:
@@ -813,7 +833,7 @@ class BaseContract:
813
833
  @combomethod
814
834
  def all_functions(
815
835
  self,
816
- ) -> "BaseContractFunction":
836
+ ) -> List["BaseContractFunction"]:
817
837
  """
818
838
  Return all functions in the contract.
819
839
  """
@@ -843,7 +863,7 @@ class BaseContract:
843
863
  return self.get_function_by_identifier(fns, "signature")
844
864
 
845
865
  @combomethod
846
- def find_functions_by_name(self, fn_name: str) -> "BaseContractFunction":
866
+ def find_functions_by_name(self, fn_name: str) -> List["BaseContractFunction"]:
847
867
  """
848
868
  Return all functions with matching name.
849
869
  Raises a Web3ValueError if there is no match or more than one is found.
@@ -1138,6 +1158,9 @@ class BaseContract:
1138
1158
  *args: Sequence[Any],
1139
1159
  **kwargs: Dict[str, Any],
1140
1160
  ) -> ABIElement:
1161
+ if not args and not kwargs:
1162
+ fn_identifier = get_abi_element_signature(fn_identifier)
1163
+
1141
1164
  return get_abi_element(
1142
1165
  cls.abi,
1143
1166
  fn_identifier,
@@ -1152,8 +1175,13 @@ class BaseContract:
1152
1175
  event_name: Optional[str] = None,
1153
1176
  argument_names: Optional[Sequence[str]] = None,
1154
1177
  ) -> ABIEvent:
1155
- return get_event_abi(
1156
- abi=cls.abi, event_name=event_name, argument_names=argument_names
1178
+ return cast(
1179
+ ABIEvent,
1180
+ get_abi_element(
1181
+ abi=cls.abi,
1182
+ abi_element_identifier=event_name,
1183
+ argument_names=argument_names,
1184
+ ),
1157
1185
  )
1158
1186
 
1159
1187
  @combomethod
@@ -1219,7 +1247,9 @@ class BaseContractCaller:
1219
1247
 
1220
1248
  def __getattr__(self, function_name: str) -> Any:
1221
1249
  function_names = [
1222
- fn["name"] for fn in self._functions if fn.get("type") == "function"
1250
+ get_name_from_abi_element_identifier(fn["name"])
1251
+ for fn in self._functions
1252
+ if fn.get("type") == "function"
1223
1253
  ]
1224
1254
  if self.abi is None:
1225
1255
  raise NoABIFound(
@@ -1230,7 +1260,7 @@ class BaseContractCaller:
1230
1260
  "The ABI for this contract contains no function definitions. ",
1231
1261
  "Are you sure you provided the correct contract ABI?",
1232
1262
  )
1233
- elif function_name not in function_names:
1263
+ elif get_name_from_abi_element_identifier(function_name) not in function_names:
1234
1264
  functions_available = ", ".join(function_names)
1235
1265
  raise ABIFunctionNotFound(
1236
1266
  f"The function '{function_name}' was not found in this contract's ABI.",
@@ -1239,11 +1269,17 @@ class BaseContractCaller:
1239
1269
  "Did you mean to call one of those functions?",
1240
1270
  )
1241
1271
  else:
1242
- return super().__getattribute__(function_name)
1272
+ function_identifier = function_name
1243
1273
 
1244
- def __hasattr__(self, event_name: str) -> bool:
1274
+ if "(" not in function_name:
1275
+ function_identifier = _get_any_abi_signature_with_name(
1276
+ function_name, self._functions
1277
+ )
1278
+ return super().__getattribute__(function_identifier)
1279
+
1280
+ def __hasattr__(self, function_name: str) -> bool:
1245
1281
  try:
1246
- return event_name in self.__dict__["_events"]
1282
+ return function_name in self.__dict__["_functions"]
1247
1283
  except ABIFunctionNotFound:
1248
1284
  return False
1249
1285