eventsourcing 9.4.0b2__py3-none-any.whl → 9.4.0b4__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.

Potentially problematic release.


This version of eventsourcing might be problematic. Click here for more details.

@@ -72,8 +72,7 @@ def project_aggregate(
72
72
  aggregate: TMutableOrImmutableAggregate | None,
73
73
  domain_events: Iterable[DomainEventProtocol],
74
74
  ) -> TMutableOrImmutableAggregate | None:
75
- """
76
- Projector function for aggregate projections, which works
75
+ """Projector function for aggregate projections, which works
77
76
  by successively calling aggregate mutator function mutate()
78
77
  on each of the given list of domain events in turn.
79
78
  """
@@ -102,8 +101,7 @@ class Cache(Generic[S, T]):
102
101
 
103
102
 
104
103
  class LRUCache(Cache[S, T]):
105
- """
106
- Size limited caching that tracks accesses by recency.
104
+ """Size limited caching that tracks accesses by recency.
107
105
 
108
106
  This is basically copied from functools.lru_cache. But
109
107
  we need to know when there was a cache hit, so we can
@@ -205,7 +203,8 @@ class Repository:
205
203
  """Reconstructs aggregates from events in an
206
204
  :class:`~eventsourcing.persistence.EventStore`,
207
205
  possibly using snapshot store to avoid replaying
208
- all events."""
206
+ all events.
207
+ """
209
208
 
210
209
  FASTFORWARD_LOCKS_CACHE_MAXSIZE = 50
211
210
 
@@ -219,8 +218,7 @@ class Repository:
219
218
  fastforward_skipping: bool = False,
220
219
  deepcopy_from_cache: bool = True,
221
220
  ):
222
- """
223
- Initialises repository with given event store (an
221
+ """Initialises repository with given event store (an
224
222
  :class:`~eventsourcing.persistence.EventStore` for aggregate
225
223
  :class:`~eventsourcing.domain.AggregateEvent` objects)
226
224
  and optionally a snapshot store (an
@@ -258,15 +256,14 @@ class Repository:
258
256
  fastforward_skipping: bool = False,
259
257
  deepcopy_from_cache: bool = True,
260
258
  ) -> TMutableOrImmutableAggregate:
261
- """
262
- Reconstructs an :class:`~eventsourcing.domain.Aggregate` for a
259
+ """Reconstructs an :class:`~eventsourcing.domain.Aggregate` for a
263
260
  given ID from stored events, optionally at a particular version.
264
261
  """
265
262
  if self.cache and version is None:
266
263
  try:
267
264
  # Look for aggregate in the cache.
268
265
  aggregate = cast(
269
- TMutableOrImmutableAggregate, self.cache.get(aggregate_id)
266
+ "TMutableOrImmutableAggregate", self.cache.get(aggregate_id)
270
267
  )
271
268
  except KeyError:
272
269
  # Reconstruct aggregate from stored events.
@@ -287,7 +284,11 @@ class Repository:
287
284
  originator_id=aggregate_id, gt=aggregate.version
288
285
  )
289
286
  _aggregate = projector_func(
290
- aggregate, cast(Iterable[TDomainEvent], new_events)
287
+ aggregate,
288
+ cast(
289
+ "Iterable[TDomainEvent]",
290
+ new_events,
291
+ ),
291
292
  )
292
293
  if _aggregate is None:
293
294
  raise AggregateNotFoundError(aggregate_id)
@@ -342,8 +343,8 @@ class Repository:
342
343
  aggregate = projector_func(
343
344
  initial,
344
345
  chain(
345
- cast(Iterable[TDomainEvent], snapshots),
346
- cast(Iterable[TDomainEvent], aggregate_events),
346
+ cast("Iterable[TDomainEvent]", snapshots),
347
+ cast("Iterable[TDomainEvent]", aggregate_events),
347
348
  ),
348
349
  )
349
350
 
@@ -379,9 +380,7 @@ class Repository:
379
380
  self._fastforward_locks_inuse[aggregate_id] = (lock_, num_users)
380
381
 
381
382
  def __contains__(self, item: UUID) -> bool:
382
- """
383
- Tests to see if an aggregate exists in the repository.
384
- """
383
+ """Tests to see if an aggregate exists in the repository."""
385
384
  try:
386
385
  self.get(aggregate_id=item)
387
386
  except AggregateNotFoundError:
@@ -392,8 +391,7 @@ class Repository:
392
391
 
393
392
  @dataclass(frozen=True)
394
393
  class Section:
395
- """
396
- Frozen dataclass that represents a section from a :class:`NotificationLog`.
394
+ """Frozen dataclass that represents a section from a :class:`NotificationLog`.
397
395
  The :data:`items` attribute contains a list of
398
396
  :class:`~eventsourcing.persistence.Notification` objects.
399
397
  The :data:`id` attribute is the section ID, two integers
@@ -416,14 +414,11 @@ class Section:
416
414
 
417
415
 
418
416
  class NotificationLog(ABC):
419
- """
420
- Abstract base class for notification logs.
421
- """
417
+ """Abstract base class for notification logs."""
422
418
 
423
419
  @abstractmethod
424
420
  def __getitem__(self, section_id: str) -> Section:
425
- """
426
- Returns a :class:`Section` of
421
+ """Returns a :class:`Section` of
427
422
  :class:`~eventsourcing.persistence.Notification` objects
428
423
  from the notification log.
429
424
  """
@@ -438,16 +433,14 @@ class NotificationLog(ABC):
438
433
  *,
439
434
  inclusive_of_start: bool = True,
440
435
  ) -> list[Notification]:
441
- """
442
- Returns a selection of
436
+ """Returns a selection of
443
437
  :class:`~eventsourcing.persistence.Notification` objects
444
438
  from the notification log.
445
439
  """
446
440
 
447
441
 
448
442
  class LocalNotificationLog(NotificationLog):
449
- """
450
- Notification log that presents sections of event notifications
443
+ """Notification log that presents sections of event notifications
451
444
  retrieved from an :class:`~eventsourcing.persistence.ApplicationRecorder`.
452
445
  """
453
446
 
@@ -458,8 +451,7 @@ class LocalNotificationLog(NotificationLog):
458
451
  recorder: ApplicationRecorder,
459
452
  section_size: int = DEFAULT_SECTION_SIZE,
460
453
  ):
461
- """
462
- Initialises a local notification object with given
454
+ """Initialises a local notification object with given
463
455
  :class:`~eventsourcing.persistence.ApplicationRecorder`
464
456
  and an optional section size.
465
457
 
@@ -474,8 +466,7 @@ class LocalNotificationLog(NotificationLog):
474
466
  self.section_size = section_size
475
467
 
476
468
  def __getitem__(self, requested_section_id: str) -> Section:
477
- """
478
- Returns a :class:`Section` of event notifications
469
+ """Returns a :class:`Section` of event notifications
479
470
  based on the requested section ID. The section ID of
480
471
  the returned section will describe the event
481
472
  notifications that are actually contained in
@@ -528,8 +519,7 @@ class LocalNotificationLog(NotificationLog):
528
519
  *,
529
520
  inclusive_of_start: bool = True,
530
521
  ) -> list[Notification]:
531
- """
532
- Returns a selection of
522
+ """Returns a selection of
533
523
  :class:`~eventsourcing.persistence.Notification` objects
534
524
  from the notification log.
535
525
  """
@@ -552,17 +542,14 @@ class LocalNotificationLog(NotificationLog):
552
542
 
553
543
 
554
544
  class ProcessingEvent:
555
- """
556
- Keeps together a :class:`~eventsourcing.persistence.Tracking`
545
+ """Keeps together a :class:`~eventsourcing.persistence.Tracking`
557
546
  object, which represents the position of a domain event notification
558
547
  in the notification log of a particular application, and the
559
548
  new domain events that result from processing that notification.
560
549
  """
561
550
 
562
551
  def __init__(self, tracking: Tracking | None = None):
563
- """
564
- Initialises the process event with the given tracking object.
565
- """
552
+ """Initialises the process event with the given tracking object."""
566
553
  self.tracking = tracking
567
554
  self.events: list[DomainEventProtocol] = []
568
555
  self.aggregates: dict[UUID, MutableOrImmutableAggregate] = {}
@@ -573,9 +560,7 @@ class ProcessingEvent:
573
560
  *objs: MutableOrImmutableAggregate | DomainEventProtocol | None,
574
561
  **kwargs: Any,
575
562
  ) -> None:
576
- """
577
- Collects pending domain events from the given aggregate.
578
- """
563
+ """Collects pending domain events from the given aggregate."""
579
564
  for obj in objs:
580
565
  if obj is None:
581
566
  continue
@@ -604,9 +589,7 @@ class ProcessingEvent:
604
589
 
605
590
 
606
591
  class Application:
607
- """
608
- Base class for event-sourced applications.
609
- """
592
+ """Base class for event-sourced applications."""
610
593
 
611
594
  name = "Application"
612
595
  env: ClassVar[dict[str, str]] = {}
@@ -629,8 +612,7 @@ class Application:
629
612
  cls.name = cls.__name__
630
613
 
631
614
  def __init__(self, env: EnvType | None = None) -> None:
632
- """
633
- Initialises an application with an
615
+ """Initialises an application with an
634
616
  :class:`~eventsourcing.persistence.InfrastructureFactory`,
635
617
  a :class:`~eventsourcing.persistence.Mapper`,
636
618
  an :class:`~eventsourcing.persistence.ApplicationRecorder`,
@@ -652,15 +634,12 @@ class Application:
652
634
 
653
635
  @property
654
636
  def repository(self) -> Repository:
655
- """
656
- An application's repository reconstructs aggregates from stored events.
657
- """
637
+ """An application's repository reconstructs aggregates from stored events."""
658
638
  return self._repository
659
639
 
660
640
  @property
661
641
  def notification_log(self) -> LocalNotificationLog:
662
- """
663
- An application's notification log presents all the aggregate events
642
+ """An application's notification log presents all the aggregate events
664
643
  of an application in the order they were recorded as a sequence of event
665
644
  notifications.
666
645
  """
@@ -676,9 +655,7 @@ class Application:
676
655
  return self._notification_log
677
656
 
678
657
  def construct_env(self, name: str, env: EnvType | None = None) -> Environment:
679
- """
680
- Constructs environment from which application will be configured.
681
- """
658
+ """Constructs environment from which application will be configured."""
682
659
  _env = dict(type(self).env)
683
660
  if type(self).is_snapshotting_enabled or type(self).snapshotting_intervals:
684
661
  _env["IS_SNAPSHOTTING_ENABLED"] = "y"
@@ -688,22 +665,19 @@ class Application:
688
665
  return Environment(name, _env)
689
666
 
690
667
  def construct_factory(self, env: Environment) -> InfrastructureFactory:
691
- """
692
- Constructs an :class:`~eventsourcing.persistence.InfrastructureFactory`
668
+ """Constructs an :class:`~eventsourcing.persistence.InfrastructureFactory`
693
669
  for use by the application.
694
670
  """
695
671
  return InfrastructureFactory.construct(env)
696
672
 
697
673
  def construct_mapper(self) -> Mapper:
698
- """
699
- Constructs a :class:`~eventsourcing.persistence.Mapper`
674
+ """Constructs a :class:`~eventsourcing.persistence.Mapper`
700
675
  for use by the application.
701
676
  """
702
677
  return self.factory.mapper(transcoder=self.construct_transcoder())
703
678
 
704
679
  def construct_transcoder(self) -> Transcoder:
705
- """
706
- Constructs a :class:`~eventsourcing.persistence.Transcoder`
680
+ """Constructs a :class:`~eventsourcing.persistence.Transcoder`
707
681
  for use by the application.
708
682
  """
709
683
  transcoder = self.factory.transcoder()
@@ -712,8 +686,7 @@ class Application:
712
686
  return transcoder
713
687
 
714
688
  def register_transcodings(self, transcoder: JSONTranscoder) -> None:
715
- """
716
- Registers :class:`~eventsourcing.persistence.Transcoding`
689
+ """Registers :class:`~eventsourcing.persistence.Transcoding`
717
690
  objects on given :class:`~eventsourcing.persistence.JSONTranscoder`.
718
691
  """
719
692
  transcoder.register(UUIDAsHex())
@@ -721,15 +694,13 @@ class Application:
721
694
  transcoder.register(DatetimeAsISO())
722
695
 
723
696
  def construct_recorder(self) -> ApplicationRecorder:
724
- """
725
- Constructs an :class:`~eventsourcing.persistence.ApplicationRecorder`
697
+ """Constructs an :class:`~eventsourcing.persistence.ApplicationRecorder`
726
698
  for use by the application.
727
699
  """
728
700
  return self.factory.application_recorder()
729
701
 
730
702
  def construct_event_store(self) -> EventStore:
731
- """
732
- Constructs an :class:`~eventsourcing.persistence.EventStore`
703
+ """Constructs an :class:`~eventsourcing.persistence.EventStore`
733
704
  for use by the application to store and retrieve aggregate
734
705
  :class:`~eventsourcing.domain.AggregateEvent` objects.
735
706
  """
@@ -739,8 +710,7 @@ class Application:
739
710
  )
740
711
 
741
712
  def construct_snapshot_store(self) -> EventStore:
742
- """
743
- Constructs an :class:`~eventsourcing.persistence.EventStore`
713
+ """Constructs an :class:`~eventsourcing.persistence.EventStore`
744
714
  for use by the application to store and retrieve aggregate
745
715
  :class:`~eventsourcing.domain.Snapshot` objects.
746
716
  """
@@ -751,9 +721,7 @@ class Application:
751
721
  )
752
722
 
753
723
  def construct_repository(self) -> Repository:
754
- """
755
- Constructs a :class:`Repository` for use by the application.
756
- """
724
+ """Constructs a :class:`Repository` for use by the application."""
757
725
  cache_maxsize_envvar = self.env.get(self.AGGREGATE_CACHE_MAXSIZE)
758
726
  cache_maxsize = int(cache_maxsize_envvar) if cache_maxsize_envvar else None
759
727
  return Repository(
@@ -770,9 +738,7 @@ class Application:
770
738
  )
771
739
 
772
740
  def construct_notification_log(self) -> LocalNotificationLog:
773
- """
774
- Constructs a :class:`LocalNotificationLog` for use by the application.
775
- """
741
+ """Constructs a :class:`LocalNotificationLog` for use by the application."""
776
742
  return LocalNotificationLog(self.recorder, section_size=self.log_section_size)
777
743
 
778
744
  def save(
@@ -780,8 +746,7 @@ class Application:
780
746
  *objs: MutableOrImmutableAggregate | DomainEventProtocol | None,
781
747
  **kwargs: Any,
782
748
  ) -> list[Recording]:
783
- """
784
- Collects pending events from given aggregates and
749
+ """Collects pending events from given aggregates and
785
750
  puts them in the application's event store.
786
751
  """
787
752
  processing_event = ProcessingEvent()
@@ -793,9 +758,7 @@ class Application:
793
758
  return recordings
794
759
 
795
760
  def _record(self, processing_event: ProcessingEvent) -> list[Recording]:
796
- """
797
- Records given process event in the application's recorder.
798
- """
761
+ """Records given process event in the application's recorder."""
799
762
  recordings = self.events.put(
800
763
  processing_event.events,
801
764
  tracking=processing_event.tracking,
@@ -849,8 +812,7 @@ class Application:
849
812
  TMutableOrImmutableAggregate, TDomainEvent
850
813
  ] = project_aggregate,
851
814
  ) -> None:
852
- """
853
- Takes a snapshot of the recorded state of the aggregate,
815
+ """Takes a snapshot of the recorded state of the aggregate,
854
816
  and puts the snapshot in the snapshot store.
855
817
  """
856
818
  if self.snapshots is None:
@@ -870,8 +832,7 @@ class Application:
870
832
  self.snapshots.put([snapshot])
871
833
 
872
834
  def notify(self, new_events: list[DomainEventProtocol]) -> None:
873
- """
874
- Deprecated.
835
+ """Deprecated.
875
836
 
876
837
  Called after new aggregate events have been saved. This
877
838
  method on this class doesn't actually do anything,
@@ -880,8 +841,7 @@ class Application:
880
841
  """
881
842
 
882
843
  def _notify(self, recordings: list[Recording]) -> None:
883
- """
884
- Called after new aggregate events have been saved. This
844
+ """Called after new aggregate events have been saved. This
885
845
  method on this class doesn't actually do anything,
886
846
  but this method may be implemented by subclasses that
887
847
  need to take action when new domain events have been saved.
@@ -896,15 +856,13 @@ TApplication = TypeVar("TApplication", bound=Application)
896
856
 
897
857
 
898
858
  class AggregateNotFoundError(EventSourcingError):
899
- """
900
- Raised when an :class:`~eventsourcing.domain.Aggregate`
859
+ """Raised when an :class:`~eventsourcing.domain.Aggregate`
901
860
  object is not found in a :class:`Repository`.
902
861
  """
903
862
 
904
863
 
905
864
  class EventSourcedLog(Generic[TDomainEvent]):
906
- """
907
- Constructs a sequence of domain events, like an aggregate.
865
+ """Constructs a sequence of domain events, like an aggregate.
908
866
  But unlike an aggregate the events can be triggered
909
867
  and selected for use in an application without
910
868
  reconstructing a current state from all the events.
@@ -932,9 +890,7 @@ class EventSourcedLog(Generic[TDomainEvent]):
932
890
  next_originator_version: int | None = None,
933
891
  **kwargs: Any,
934
892
  ) -> TDomainEvent:
935
- """
936
- Constructs and returns a new log event.
937
- """
893
+ """Constructs and returns a new log event."""
938
894
  return self._trigger_event(
939
895
  logged_cls=self.logged_cls,
940
896
  next_originator_version=next_originator_version,
@@ -947,9 +903,7 @@ class EventSourcedLog(Generic[TDomainEvent]):
947
903
  next_originator_version: int | None = None,
948
904
  **kwargs: Any,
949
905
  ) -> SDomainEvent:
950
- """
951
- Constructs and returns a new log event.
952
- """
906
+ """Constructs and returns a new log event."""
953
907
  if next_originator_version is None:
954
908
  last_logged = self.get_last()
955
909
  if last_logged is None:
@@ -965,18 +919,14 @@ class EventSourcedLog(Generic[TDomainEvent]):
965
919
  )
966
920
 
967
921
  def get_first(self) -> TDomainEvent | None:
968
- """
969
- Selects the first logged event.
970
- """
922
+ """Selects the first logged event."""
971
923
  try:
972
924
  return next(self.get(limit=1))
973
925
  except StopIteration:
974
926
  return None
975
927
 
976
928
  def get_last(self) -> TDomainEvent | None:
977
- """
978
- Selects the last logged event.
979
- """
929
+ """Selects the last logged event."""
980
930
  try:
981
931
  return next(self.get(desc=True, limit=1))
982
932
  except StopIteration:
@@ -990,12 +940,11 @@ class EventSourcedLog(Generic[TDomainEvent]):
990
940
  desc: bool = False,
991
941
  limit: int | None = None,
992
942
  ) -> Iterator[TDomainEvent]:
993
- """
994
- Selects a range of logged events with limit,
943
+ """Selects a range of logged events with limit,
995
944
  with ascending or descending order.
996
945
  """
997
946
  return cast(
998
- Iterator[TDomainEvent],
947
+ "Iterator[TDomainEvent]",
999
948
  self.events.get(
1000
949
  originator_id=self.originator_id,
1001
950
  gt=gt,
eventsourcing/cipher.py CHANGED
@@ -17,8 +17,7 @@ if TYPE_CHECKING:
17
17
 
18
18
 
19
19
  class AESCipher(Cipher):
20
- """
21
- Cipher strategy that uses AES cipher (in GCM mode)
20
+ """Cipher strategy that uses AES cipher (in GCM mode)
22
21
  from the Python pycryptodome package.
23
22
  """
24
23
 
@@ -27,8 +26,7 @@ class AESCipher(Cipher):
27
26
 
28
27
  @staticmethod
29
28
  def create_key(num_bytes: int) -> str:
30
- """
31
- Creates AES cipher key, with length num_bytes.
29
+ """Creates AES cipher key, with length num_bytes.
32
30
 
33
31
  :param num_bytes: An int value, either 16, 24, or 32.
34
32
 
@@ -47,8 +45,7 @@ class AESCipher(Cipher):
47
45
  return os.urandom(num_bytes)
48
46
 
49
47
  def __init__(self, environment: Environment):
50
- """
51
- Initialises AES cipher with ``cipher_key``.
48
+ """Initialises AES cipher with ``cipher_key``.
52
49
 
53
50
  :param str cipher_key: 16, 24, or 32 bytes encoded as base64
54
51
  """
@@ -62,7 +59,6 @@ class AESCipher(Cipher):
62
59
 
63
60
  def encrypt(self, plaintext: bytes) -> bytes:
64
61
  """Return ciphertext for given plaintext."""
65
-
66
62
  # Construct AES-GCM cipher, with 96-bit nonce.
67
63
  nonce = AESCipher.random_bytes(12)
68
64
  cipher = self.construct_cipher(nonce)
@@ -87,7 +83,6 @@ class AESCipher(Cipher):
87
83
 
88
84
  def decrypt(self, ciphertext: bytes) -> bytes:
89
85
  """Return plaintext for given ciphertext."""
90
-
91
86
  # Split out the nonce, tag, and encrypted data.
92
87
  nonce = ciphertext[:12]
93
88
  if len(nonce) != 12:
@@ -7,13 +7,9 @@ from eventsourcing.persistence import Compressor
7
7
 
8
8
  class ZlibCompressor(Compressor):
9
9
  def compress(self, data: bytes) -> bytes:
10
- """
11
- Compress bytes using zlib.
12
- """
10
+ """Compress bytes using zlib."""
13
11
  return zlib.compress(data)
14
12
 
15
13
  def decompress(self, data: bytes) -> bytes:
16
- """
17
- Decompress bytes using zlib.
18
- """
14
+ """Decompress bytes using zlib."""
19
15
  return zlib.decompress(data)
@@ -14,8 +14,7 @@ if TYPE_CHECKING:
14
14
 
15
15
 
16
16
  class AESCipher(Cipher):
17
- """
18
- Cipher strategy that uses AES cipher (in GCM mode)
17
+ """Cipher strategy that uses AES cipher (in GCM mode)
19
18
  from the Python cryptography package.
20
19
  """
21
20
 
@@ -24,8 +23,7 @@ class AESCipher(Cipher):
24
23
 
25
24
  @staticmethod
26
25
  def create_key(num_bytes: int) -> str:
27
- """
28
- Creates AES cipher key, with length num_bytes.
26
+ """Creates AES cipher key, with length num_bytes.
29
27
 
30
28
  :param num_bytes: An int value, either 16, 24, or 32.
31
29
 
@@ -45,8 +43,7 @@ class AESCipher(Cipher):
45
43
  return os.urandom(num_bytes)
46
44
 
47
45
  def __init__(self, environment: Environment):
48
- """
49
- Initialises AES cipher with ``cipher_key``.
46
+ """Initialises AES cipher with ``cipher_key``.
50
47
 
51
48
  :param str cipher_key: 16, 24, or 32 bytes encoded as base64
52
49
  """
@@ -60,7 +57,6 @@ class AESCipher(Cipher):
60
57
 
61
58
  def encrypt(self, plaintext: bytes) -> bytes:
62
59
  """Return ciphertext for given plaintext."""
63
-
64
60
  # Construct AES-GCM cipher, with 96-bit nonce.
65
61
  aesgcm = AESGCM(self.key)
66
62
  nonce = AESCipher.random_bytes(12)
@@ -72,7 +68,6 @@ class AESCipher(Cipher):
72
68
 
73
69
  def decrypt(self, ciphertext: bytes) -> bytes:
74
70
  """Return plaintext for given ciphertext."""
75
-
76
71
  # Split out the nonce, tag, and encrypted data.
77
72
  nonce = ciphertext[:12]
78
73
  if len(nonce) != 12:
eventsourcing/dispatch.py CHANGED
@@ -62,7 +62,7 @@ class singledispatchmethod(_singledispatchmethod[_T]): # noqa: N801
62
62
  # cls.__wrapped__ = cls.__func__
63
63
 
64
64
  try:
65
- return self.dispatcher.register(cast(type[Any], cls), func=method)
65
+ return self.dispatcher.register(cast("type[Any]", cls), func=method)
66
66
  except NameError:
67
67
  self.deferred_registrations.append(
68
68
  (cls, method) # pyright: ignore [reportArgumentType]
@@ -73,7 +73,7 @@ class singledispatchmethod(_singledispatchmethod[_T]): # noqa: N801
73
73
  def __get__(self, obj: _S, cls: type[_S] | None = None) -> Callable[..., _T]:
74
74
  for registered_cls, registered_method in self.deferred_registrations:
75
75
  self.dispatcher.register(
76
- cast(type[Any], registered_cls), func=registered_method
76
+ cast("type[Any]", registered_cls), func=registered_method
77
77
  )
78
78
  self.deferred_registrations = []
79
79
  return super().__get__(obj, cls=cls)