eventsourcing 9.4.0a5__tar.gz → 9.4.0a6__tar.gz

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.

Files changed (26) hide show
  1. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/PKG-INFO +2 -4
  2. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/application.py +21 -27
  3. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/domain.py +49 -51
  4. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/interface.py +5 -2
  5. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/persistence.py +29 -36
  6. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/popo.py +17 -16
  7. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/postgres.py +18 -17
  8. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/projection.py +8 -17
  9. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/sqlite.py +18 -17
  10. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/system.py +49 -62
  11. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/tests/application.py +3 -3
  12. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/tests/persistence.py +12 -12
  13. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/utils.py +8 -20
  14. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/pyproject.toml +6 -12
  15. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/AUTHORS +0 -0
  16. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/LICENSE +0 -0
  17. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/README.md +0 -0
  18. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/__init__.py +0 -0
  19. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/cipher.py +0 -0
  20. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/compressor.py +0 -0
  21. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/cryptography.py +0 -0
  22. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/dispatch.py +0 -0
  23. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/py.typed +0 -0
  24. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/tests/__init__.py +0 -0
  25. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/tests/domain.py +0 -0
  26. {eventsourcing-9.4.0a5 → eventsourcing-9.4.0a6}/eventsourcing/tests/postgres_utils.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: eventsourcing
3
- Version: 9.4.0a5
3
+ Version: 9.4.0a6
4
4
  Summary: Event sourcing in Python
5
5
  License: BSD 3-Clause
6
6
  Keywords: event sourcing,event store,domain driven design,domain-driven design,ddd,cqrs,cqs
7
7
  Author: John Bywater
8
8
  Author-email: john.bywater@appropriatesoftware.net
9
- Requires-Python: >=3.8, !=2.7.*, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*, !=3.7.*
9
+ Requires-Python: >=3.9, !=2.7.*, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*, !=3.7.*, !=3.8.*
10
10
  Classifier: Development Status :: 3 - Alpha
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: Intended Audience :: Education
@@ -16,7 +16,6 @@ Classifier: License :: Other/Proprietary License
16
16
  Classifier: Operating System :: OS Independent
17
17
  Classifier: Programming Language :: Python
18
18
  Classifier: Programming Language :: Python :: 3
19
- Classifier: Programming Language :: Python :: 3.8
20
19
  Classifier: Programming Language :: Python :: 3.10
21
20
  Classifier: Programming Language :: Python :: 3.11
22
21
  Classifier: Programming Language :: Python :: 3.12
@@ -26,7 +25,6 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
25
  Provides-Extra: crypto
27
26
  Provides-Extra: cryptography
28
27
  Provides-Extra: postgres
29
- Requires-Dist: backports.zoneinfo ; python_version < "3.9"
30
28
  Requires-Dist: cryptography (>=44.0,<44.1) ; extra == "cryptography"
31
29
  Requires-Dist: psycopg[pool] (<=3.2.99999) ; extra == "postgres"
32
30
  Requires-Dist: pycryptodome (>=3.22,<3.23) ; extra == "crypto"
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import os
4
4
  from abc import ABC, abstractmethod
5
+ from collections.abc import Iterable, Iterator, Sequence
5
6
  from copy import deepcopy
6
7
  from dataclasses import dataclass
7
8
  from itertools import chain
@@ -11,15 +12,8 @@ from typing import (
11
12
  Any,
12
13
  Callable,
13
14
  ClassVar,
14
- Dict,
15
15
  Generic,
16
- Iterable,
17
- Iterator,
18
- List,
19
16
  Optional,
20
- Sequence,
21
- Tuple,
22
- Type,
23
17
  TypeVar,
24
18
  cast,
25
19
  )
@@ -96,7 +90,7 @@ T = TypeVar("T")
96
90
 
97
91
  class Cache(Generic[S, T]):
98
92
  def __init__(self) -> None:
99
- self.cache: Dict[S, Any] = {}
93
+ self.cache: dict[S, Any] = {}
100
94
 
101
95
  def get(self, key: S, *, evict: bool = False) -> T:
102
96
  if evict:
@@ -127,7 +121,7 @@ class LRUCache(Cache[S, T]):
127
121
  self.maxsize = maxsize
128
122
  self.full = False
129
123
  self.lock = Lock() # because linkedlist updates aren't threadsafe
130
- self.root: List[Any] = [] # root of the circular doubly linked list
124
+ self.root: list[Any] = [] # root of the circular doubly linked list
131
125
  self.clear()
132
126
 
133
127
  def clear(self) -> None:
@@ -253,7 +247,7 @@ class Repository:
253
247
  self._fastforward_locks_cache: LRUCache[UUID, Lock] = LRUCache(
254
248
  maxsize=self.FASTFORWARD_LOCKS_CACHE_MAXSIZE
255
249
  )
256
- self._fastforward_locks_inuse: Dict[UUID, Tuple[Lock, int]] = {}
250
+ self._fastforward_locks_inuse: dict[UUID, tuple[Lock, int]] = {}
257
251
 
258
252
  def get(
259
253
  self,
@@ -415,12 +409,12 @@ class Section:
415
409
  Constructor arguments:
416
410
 
417
411
  :param Optional[str] id: section ID of this section e.g. "1,10"
418
- :param List[Notification] items: a list of event notifications
412
+ :param list[Notification] items: a list of event notifications
419
413
  :param Optional[str] next_id: section ID of the following section
420
414
  """
421
415
 
422
416
  id: str | None
423
- items: List[Notification]
417
+ items: list[Notification]
424
418
  next_id: str | None
425
419
 
426
420
 
@@ -446,7 +440,7 @@ class NotificationLog(ABC):
446
440
  topics: Sequence[str] = (),
447
441
  *,
448
442
  inclusive_of_start: bool = True,
449
- ) -> List[Notification]:
443
+ ) -> list[Notification]:
450
444
  """
451
445
  Returns a selection of
452
446
  :class:`~eventsourcing.persistence.Notification` objects
@@ -536,7 +530,7 @@ class LocalNotificationLog(NotificationLog):
536
530
  topics: Sequence[str] = (),
537
531
  *,
538
532
  inclusive_of_start: bool = True,
539
- ) -> List[Notification]:
533
+ ) -> list[Notification]:
540
534
  """
541
535
  Returns a selection of
542
536
  :class:`~eventsourcing.persistence.Notification` objects
@@ -573,9 +567,9 @@ class ProcessingEvent:
573
567
  Initialises the process event with the given tracking object.
574
568
  """
575
569
  self.tracking = tracking
576
- self.events: List[DomainEventProtocol] = []
577
- self.aggregates: Dict[UUID, MutableOrImmutableAggregate] = {}
578
- self.saved_kwargs: Dict[Any, Any] = {}
570
+ self.events: list[DomainEventProtocol] = []
571
+ self.aggregates: dict[UUID, MutableOrImmutableAggregate] = {}
572
+ self.saved_kwargs: dict[Any, Any] = {}
579
573
 
580
574
  def collect_events(
581
575
  self,
@@ -618,15 +612,15 @@ class Application:
618
612
  """
619
613
 
620
614
  name = "Application"
621
- env: ClassVar[Dict[str, str]] = {}
615
+ env: ClassVar[dict[str, str]] = {}
622
616
  is_snapshotting_enabled: bool = False
623
617
  snapshotting_intervals: ClassVar[
624
- Dict[Type[MutableOrImmutableAggregate], int] | None
618
+ dict[type[MutableOrImmutableAggregate], int] | None
625
619
  ] = None
626
620
  snapshotting_projectors: ClassVar[
627
- Dict[Type[MutableOrImmutableAggregate], ProjectorFunction[Any, Any]] | None
621
+ dict[type[MutableOrImmutableAggregate], ProjectorFunction[Any, Any]] | None
628
622
  ] = None
629
- snapshot_class: Type[SnapshotProtocol] = Snapshot
623
+ snapshot_class: type[SnapshotProtocol] = Snapshot
630
624
  log_section_size = 10
631
625
  notify_topics: Sequence[str] = []
632
626
 
@@ -792,7 +786,7 @@ class Application:
792
786
  self,
793
787
  *objs: MutableOrImmutableAggregate | DomainEventProtocol | None,
794
788
  **kwargs: Any,
795
- ) -> List[Recording]:
789
+ ) -> list[Recording]:
796
790
  """
797
791
  Collects pending events from given aggregates and
798
792
  puts them in the application's event store.
@@ -805,7 +799,7 @@ class Application:
805
799
  self.notify(processing_event.events) # Deprecated.
806
800
  return recordings
807
801
 
808
- def _record(self, processing_event: ProcessingEvent) -> List[Recording]:
802
+ def _record(self, processing_event: ProcessingEvent) -> list[Recording]:
809
803
  """
810
804
  Records given process event in the application's recorder.
811
805
  """
@@ -885,7 +879,7 @@ class Application:
885
879
  snapshot = snapshot_class.take(aggregate)
886
880
  self.snapshots.put([snapshot])
887
881
 
888
- def notify(self, new_events: List[DomainEventProtocol]) -> None:
882
+ def notify(self, new_events: list[DomainEventProtocol]) -> None:
889
883
  """
890
884
  Deprecated.
891
885
 
@@ -895,7 +889,7 @@ class Application:
895
889
  need to take action when new domain events have been saved.
896
890
  """
897
891
 
898
- def _notify(self, recordings: List[Recording]) -> None:
892
+ def _notify(self, recordings: list[Recording]) -> None:
899
893
  """
900
894
  Called after new aggregate events have been saved. This
901
895
  method on this class doesn't actually do anything,
@@ -944,7 +938,7 @@ class EventSourcedLog(Generic[TDomainEvent]):
944
938
  self,
945
939
  events: EventStore,
946
940
  originator_id: UUID,
947
- logged_cls: Type[TDomainEvent], # TODO: Rename to 'event_class' in v10.
941
+ logged_cls: type[TDomainEvent], # TODO: Rename to 'event_class' in v10.
948
942
  ):
949
943
  self.events = events
950
944
  self.originator_id = originator_id
@@ -966,7 +960,7 @@ class EventSourcedLog(Generic[TDomainEvent]):
966
960
 
967
961
  def _trigger_event(
968
962
  self,
969
- logged_cls: Type[T] | None,
963
+ logged_cls: type[T] | None,
970
964
  next_originator_version: int | None = None,
971
965
  **kwargs: Any,
972
966
  ) -> T:
@@ -4,20 +4,14 @@ import inspect
4
4
  import os
5
5
  from dataclasses import dataclass
6
6
  from datetime import datetime, tzinfo
7
- from functools import lru_cache
7
+ from functools import cache
8
8
  from types import FunctionType, WrapperDescriptorType
9
9
  from typing import (
10
10
  TYPE_CHECKING,
11
11
  Any,
12
12
  Callable,
13
- Dict,
14
13
  Generic,
15
- Iterable,
16
- List,
17
14
  Protocol,
18
- Sequence,
19
- Tuple,
20
- Type,
21
15
  TypeVar,
22
16
  Union,
23
17
  cast,
@@ -29,6 +23,10 @@ from warnings import warn
29
23
 
30
24
  from eventsourcing.utils import get_method_name, get_topic, resolve_topic
31
25
 
26
+ if TYPE_CHECKING:
27
+ from collections.abc import Iterable, Sequence
28
+
29
+
32
30
  TZINFO: tzinfo = resolve_topic(os.getenv("TZINFO_TOPIC", "datetime:timezone.utc"))
33
31
  """
34
32
  A Python :py:obj:`tzinfo` object that defaults to UTC (:py:obj:`timezone.utc`). Used
@@ -294,7 +292,7 @@ class CanInitAggregate(CanMutateAggregate):
294
292
  assert aggregate is None
295
293
 
296
294
  # Resolve originator topic.
297
- aggregate_class: Type[TAggregate] = resolve_topic(self.originator_topic)
295
+ aggregate_class: type[TAggregate] = resolve_topic(self.originator_topic)
298
296
 
299
297
  # Construct an aggregate object (a "shell" of the correct object type).
300
298
  agg = aggregate_class.__new__(aggregate_class)
@@ -333,10 +331,10 @@ class MetaDomainEvent(type):
333
331
  """
334
332
 
335
333
  def __new__(
336
- cls, name: str, bases: Tuple[Type[TDomainEvent], ...], cls_dict: Dict[str, Any]
337
- ) -> Type[TDomainEvent]:
334
+ cls, name: str, bases: tuple[type[TDomainEvent], ...], cls_dict: dict[str, Any]
335
+ ) -> type[TDomainEvent]:
338
336
  event_cls = cast(
339
- Type[TDomainEvent], super().__new__(cls, name, bases, cls_dict)
337
+ type[TDomainEvent], super().__new__(cls, name, bases, cls_dict)
340
338
  )
341
339
  event_cls = dataclass(frozen=True)(event_cls)
342
340
  event_cls.__signature__ = inspect.signature(event_cls.__init__) # type: ignore
@@ -398,20 +396,20 @@ TLogEvent = TypeVar("TLogEvent", bound=DomainEventProtocol)
398
396
 
399
397
 
400
398
  def _filter_kwargs_for_method_params(
401
- kwargs: Dict[str, Any], method: Callable[..., Any]
402
- ) -> Dict[str, Any]:
399
+ kwargs: dict[str, Any], method: Callable[..., Any]
400
+ ) -> dict[str, Any]:
403
401
  names = _spec_filter_kwargs_for_method_params(method)
404
402
  return {k: v for k, v in kwargs.items() if k in names}
405
403
 
406
404
 
407
- @lru_cache(maxsize=None)
405
+ @cache
408
406
  def _spec_filter_kwargs_for_method_params(method: Callable[..., Any]) -> set[str]:
409
407
  method_signature = inspect.signature(method)
410
408
  return set(method_signature.parameters)
411
409
 
412
410
 
413
411
  if TYPE_CHECKING:
414
- EventSpecType = Union[str, Type[CanMutateAggregate]]
412
+ EventSpecType = Union[str, type[CanMutateAggregate]]
415
413
 
416
414
  CommandMethod = Callable[..., None]
417
415
  DecoratedObjType = Union[CommandMethod, property]
@@ -425,7 +423,7 @@ class CommandMethodDecorator:
425
423
  decorated_obj: DecoratedObjType,
426
424
  ):
427
425
  self.is_name_inferred_from_method = False
428
- self.given_event_cls: Type[CanMutateAggregate] | None = None
426
+ self.given_event_cls: type[CanMutateAggregate] | None = None
429
427
  self.event_cls_name: str | None = None
430
428
  self.decorated_property: property | None = None
431
429
  self.is_property_setter = False
@@ -740,12 +738,12 @@ class BoundCommandMethodDecorator:
740
738
 
741
739
 
742
740
  given_event_classes: set[type] = set()
743
- decorated_methods: Dict[type, CommandMethod] = {}
744
- aggregate_has_many_created_event_classes: Dict[type, List[str]] = {}
741
+ decorated_methods: dict[type, CommandMethod] = {}
742
+ aggregate_has_many_created_event_classes: dict[type, list[str]] = {}
745
743
 
746
744
 
747
- decorated_event_classes: Dict[
748
- CommandMethodDecorator, Type[MetaAggregate.DecoratedEvent]
745
+ decorated_event_classes: dict[
746
+ CommandMethodDecorator, type[MetaAggregate.DecoratedEvent]
749
747
  ] = {}
750
748
 
751
749
 
@@ -767,10 +765,10 @@ def _check_no_variable_params(method: FunctionType) -> None:
767
765
  def _coerce_args_to_kwargs(
768
766
  method: FunctionType | WrapperDescriptorType,
769
767
  args: Iterable[Any],
770
- kwargs: Dict[str, Any],
768
+ kwargs: dict[str, Any],
771
769
  *,
772
770
  expects_id: bool = False,
773
- ) -> Dict[str, Any]:
771
+ ) -> dict[str, Any]:
774
772
  assert isinstance(method, (FunctionType, WrapperDescriptorType))
775
773
 
776
774
  args = tuple(args)
@@ -789,14 +787,14 @@ def _coerce_args_to_kwargs(
789
787
  return copy_kwargs
790
788
 
791
789
 
792
- @lru_cache(maxsize=None)
790
+ @cache
793
791
  def _spec_coerce_args_to_kwargs(
794
792
  method: FunctionType | WrapperDescriptorType,
795
793
  len_args: int,
796
- kwargs_keys: Tuple[str],
794
+ kwargs_keys: tuple[str],
797
795
  *,
798
796
  expects_id: bool,
799
- ) -> Tuple[Tuple[Tuple[int, str], ...], Tuple[Tuple[str, Any], ...]]:
797
+ ) -> tuple[tuple[tuple[int, str], ...], tuple[tuple[str, Any], ...]]:
800
798
  method_signature = inspect.signature(method)
801
799
  positional_names = []
802
800
  keyword_defaults = {}
@@ -874,7 +872,7 @@ def _spec_coerce_args_to_kwargs(
874
872
  return enumerated_args_names, keyword_defaults_items
875
873
 
876
874
 
877
- def _raise_missing_names_type_error(missing_names: List[str], msg: str) -> None:
875
+ def _raise_missing_names_type_error(missing_names: list[str], msg: str) -> None:
878
876
  msg += missing_names[0]
879
877
  if len(missing_names) == 2:
880
878
  msg += f" and {missing_names[1]}"
@@ -920,7 +918,7 @@ class MetaAggregate(type, Generic[TAggregate]):
920
918
  # Call the original method with event attribute values.
921
919
  decorated_method(aggregate, **kwargs)
922
920
 
923
- _created_event_class: Type[CanInitAggregate]
921
+ _created_event_class: type[CanInitAggregate]
924
922
 
925
923
  def __new__(cls, *args: Any, **_: Any) -> MetaAggregate[Aggregate]:
926
924
  """
@@ -957,7 +955,7 @@ class MetaAggregate(type, Generic[TAggregate]):
957
955
 
958
956
  # Identify or define a base event class for this aggregate.
959
957
  base_event_name = "Event"
960
- base_event_cls: Type[CanMutateAggregate]
958
+ base_event_cls: type[CanMutateAggregate]
961
959
  try:
962
960
  base_event_cls = cls.__dict__[base_event_name]
963
961
  except KeyError:
@@ -967,7 +965,7 @@ class MetaAggregate(type, Generic[TAggregate]):
967
965
  setattr(cls, base_event_name, base_event_cls)
968
966
 
969
967
  # Make sure all events defined on aggregate subclass the base event class.
970
- created_event_classes: Dict[str, Type[CanInitAggregate]] = {}
968
+ created_event_classes: dict[str, type[CanInitAggregate]] = {}
971
969
  for name, value in tuple(cls.__dict__.items()):
972
970
  if name == base_event_name:
973
971
  # Don't subclass the base event class again.
@@ -987,7 +985,7 @@ class MetaAggregate(type, Generic[TAggregate]):
987
985
  created_event_classes[name] = value
988
986
 
989
987
  # Disallow using both '_created_event_class' and 'created_event_name'.
990
- created_event_class: Type[CanInitAggregate] | None = cls.__dict__.get(
988
+ created_event_class: type[CanInitAggregate] | None = cls.__dict__.get(
991
989
  "_created_event_class"
992
990
  )
993
991
  if created_event_class and created_event_name:
@@ -1015,7 +1013,7 @@ class MetaAggregate(type, Generic[TAggregate]):
1015
1013
  # Does the decorator specify a "created" event class?
1016
1014
  if init_decorator.given_event_cls:
1017
1015
  created_event_class = cast(
1018
- Type[CanInitAggregate], init_decorator.given_event_cls
1016
+ type[CanInitAggregate], init_decorator.given_event_cls
1019
1017
  )
1020
1018
  # Does the decorator specify a "created" event name?
1021
1019
  elif init_decorator.event_cls_name:
@@ -1093,11 +1091,11 @@ class MetaAggregate(type, Generic[TAggregate]):
1093
1091
  # Define a "created" event class for this aggregate.
1094
1092
  if issubclass(base_created_event_cls, base_event_cls):
1095
1093
  # Don't subclass from base event class twice.
1096
- bases: Tuple[Type[CanMutateAggregate], ...] = (base_created_event_cls,)
1094
+ bases: tuple[type[CanMutateAggregate], ...] = (base_created_event_cls,)
1097
1095
  else:
1098
1096
  bases = (base_created_event_cls, base_event_cls)
1099
1097
  created_event_class = cast(
1100
- Type[CanInitAggregate],
1098
+ type[CanInitAggregate],
1101
1099
  cls._define_event_class(
1102
1100
  created_event_name,
1103
1101
  bases,
@@ -1160,7 +1158,7 @@ class MetaAggregate(type, Generic[TAggregate]):
1160
1158
 
1161
1159
  # Define event class as subclass of given class.
1162
1160
  given_subclass = cast(
1163
- Type[CanMutateAggregate],
1161
+ type[CanMutateAggregate],
1164
1162
  getattr(cls, event_decorator.given_event_cls.__name__),
1165
1163
  )
1166
1164
  event_cls = cls._define_event_class(
@@ -1194,7 +1192,7 @@ class MetaAggregate(type, Generic[TAggregate]):
1194
1192
 
1195
1193
  # Remember which event class to trigger.
1196
1194
  decorated_event_classes[event_decorator] = cast(
1197
- Type[MetaAggregate.DecoratedEvent], event_cls
1195
+ type[MetaAggregate.DecoratedEvent], event_cls
1198
1196
  )
1199
1197
 
1200
1198
  # Check any create_id method defined on this class is static or class method.
@@ -1208,7 +1206,7 @@ class MetaAggregate(type, Generic[TAggregate]):
1208
1206
  raise TypeError(msg)
1209
1207
 
1210
1208
  # Get the parameters of the create_id method that will be used by this class.
1211
- cls._create_id_param_names: List[str] = []
1209
+ cls._create_id_param_names: list[str] = []
1212
1210
  for name, param in inspect.signature(cls.create_id).parameters.items():
1213
1211
  if param.kind in [param.KEYWORD_ONLY, param.POSITIONAL_OR_KEYWORD]:
1214
1212
  cls._create_id_param_names.append(name)
@@ -1230,9 +1228,9 @@ class MetaAggregate(type, Generic[TAggregate]):
1230
1228
  def _define_event_class(
1231
1229
  cls,
1232
1230
  name: str,
1233
- bases: Tuple[Type[CanMutateAggregate], ...],
1231
+ bases: tuple[type[CanMutateAggregate], ...],
1234
1232
  apply_method: CommandMethod | None,
1235
- ) -> Type[CanMutateAggregate]:
1233
+ ) -> type[CanMutateAggregate]:
1236
1234
  # Define annotations for the event class (specs the init method).
1237
1235
  annotations = {}
1238
1236
  if apply_method is not None:
@@ -1256,7 +1254,7 @@ class MetaAggregate(type, Generic[TAggregate]):
1256
1254
  }
1257
1255
 
1258
1256
  # Create the event class object.
1259
- return cast(Type[CanMutateAggregate], type(name, bases, event_cls_dict))
1257
+ return cast(type[CanMutateAggregate], type(name, bases, event_cls_dict))
1260
1258
 
1261
1259
  def __call__(
1262
1260
  cls: MetaAggregate[TAggregate], *args: Any, **kwargs: Any
@@ -1286,7 +1284,7 @@ class MetaAggregate(type, Generic[TAggregate]):
1286
1284
 
1287
1285
  def _create(
1288
1286
  cls: MetaAggregate[TAggregate],
1289
- event_class: Type[CanInitAggregate],
1287
+ event_class: type[CanInitAggregate],
1290
1288
  **kwargs: Any,
1291
1289
  ) -> TAggregate:
1292
1290
  raise NotImplementedError # pragma: no cover
@@ -1308,8 +1306,8 @@ class Aggregate(metaclass=MetaAggregate):
1308
1306
 
1309
1307
  @classmethod
1310
1308
  def _create(
1311
- cls: Type[TAggregate],
1312
- event_class: Type[CanInitAggregate],
1309
+ cls: type[TAggregate],
1310
+ event_class: type[CanInitAggregate],
1313
1311
  *,
1314
1312
  id: UUID | None = None, # noqa: A002
1315
1313
  **kwargs: Any,
@@ -1359,7 +1357,7 @@ class Aggregate(metaclass=MetaAggregate):
1359
1357
  self._version = originator_version
1360
1358
  self._created_on = timestamp
1361
1359
  self._modified_on = timestamp
1362
- self._pending_events: List[CanMutateAggregate] = []
1360
+ self._pending_events: list[CanMutateAggregate] = []
1363
1361
 
1364
1362
  @property
1365
1363
  def id(self) -> UUID:
@@ -1398,7 +1396,7 @@ class Aggregate(metaclass=MetaAggregate):
1398
1396
  self._modified_on = modified_on
1399
1397
 
1400
1398
  @property
1401
- def pending_events(self) -> List[CanMutateAggregate]:
1399
+ def pending_events(self) -> list[CanMutateAggregate]:
1402
1400
  """
1403
1401
  A list of pending events.
1404
1402
  """
@@ -1423,7 +1421,7 @@ class Aggregate(metaclass=MetaAggregate):
1423
1421
 
1424
1422
  def trigger_event(
1425
1423
  self,
1426
- event_class: Type[CanMutateAggregate],
1424
+ event_class: type[CanMutateAggregate],
1427
1425
  **kwargs: Any,
1428
1426
  ) -> None:
1429
1427
  """
@@ -1480,7 +1478,7 @@ def aggregate(
1480
1478
  cls: Any | None = None,
1481
1479
  *,
1482
1480
  created_event_name: str = "",
1483
- ) -> Type[Aggregate] | Callable[[Any], Type[Aggregate]]:
1481
+ ) -> type[Aggregate] | Callable[[Any], type[Aggregate]]:
1484
1482
  """
1485
1483
  Converts the class that was passed in to inherit from Aggregate.
1486
1484
 
@@ -1498,7 +1496,7 @@ def aggregate(
1498
1496
  pass
1499
1497
  """
1500
1498
 
1501
- def decorator(cls_: Any) -> Type[Aggregate]:
1499
+ def decorator(cls_: Any) -> type[Aggregate]:
1502
1500
  if issubclass(cls_, Aggregate):
1503
1501
  msg = f"{cls_.__qualname__} is already an Aggregate"
1504
1502
  raise TypeError(msg)
@@ -1553,7 +1551,7 @@ class VersionError(OriginatorVersionError):
1553
1551
 
1554
1552
  class SnapshotProtocol(DomainEventProtocol, Protocol):
1555
1553
  @property
1556
- def state(self) -> Dict[str, Any]:
1554
+ def state(self) -> dict[str, Any]:
1557
1555
  """
1558
1556
  Snapshots have a read-only 'state'.
1559
1557
  """
@@ -1575,7 +1573,7 @@ class CanSnapshotAggregate(HasOriginatorIDVersion, CanCreateTimestamp):
1575
1573
 
1576
1574
  @classmethod
1577
1575
  def take(
1578
- cls: Type[TCanSnapshotAggregate],
1576
+ cls: type[TCanSnapshotAggregate],
1579
1577
  aggregate: MutableOrImmutableAggregate,
1580
1578
  ) -> TCanSnapshotAggregate:
1581
1579
  """
@@ -1601,7 +1599,7 @@ class CanSnapshotAggregate(HasOriginatorIDVersion, CanCreateTimestamp):
1601
1599
  """
1602
1600
  Reconstructs the snapshotted :class:`Aggregate` object.
1603
1601
  """
1604
- cls = cast(Type[Aggregate], resolve_topic(self.topic))
1602
+ cls = cast(type[Aggregate], resolve_topic(self.topic))
1605
1603
  aggregate_state = dict(self.state)
1606
1604
  from_version = aggregate_state.pop("class_version", 1)
1607
1605
  class_version = getattr(cls, "class_version", 1)
@@ -1634,4 +1632,4 @@ class Snapshot(CanSnapshotAggregate, DomainEvent):
1634
1632
  """
1635
1633
 
1636
1634
  topic: str
1637
- state: Dict[str, Any]
1635
+ state: dict[str, Any]
@@ -3,12 +3,15 @@ from __future__ import annotations
3
3
  import json
4
4
  from abc import ABC, abstractmethod
5
5
  from base64 import b64decode, b64encode
6
- from typing import Generic, List, Sequence
6
+ from typing import TYPE_CHECKING, Generic
7
7
  from uuid import UUID
8
8
 
9
9
  from eventsourcing.application import NotificationLog, Section, TApplication
10
10
  from eventsourcing.persistence import Notification
11
11
 
12
+ if TYPE_CHECKING:
13
+ from collections.abc import Sequence
14
+
12
15
 
13
16
  class NotificationLogInterface(ABC):
14
17
  """
@@ -142,7 +145,7 @@ class NotificationLogJSONClient(NotificationLog):
142
145
  topics: Sequence[str] = (),
143
146
  *,
144
147
  inclusive_of_start: bool = True,
145
- ) -> List[Notification]:
148
+ ) -> list[Notification]:
146
149
  """
147
150
  Returns a selection of
148
151
  :class:`~eventsourcing.persistence.Notification` objects