eventsourcing 9.3.0a1__py3-none-any.whl → 9.3.0b1__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.
- eventsourcing/domain.py +87 -88
- eventsourcing/tests/domain_tests/test_aggregate.py +14 -0
- {eventsourcing-9.3.0a1.dist-info → eventsourcing-9.3.0b1.dist-info}/METADATA +2 -2
- {eventsourcing-9.3.0a1.dist-info → eventsourcing-9.3.0b1.dist-info}/RECORD +6 -6
- {eventsourcing-9.3.0a1.dist-info → eventsourcing-9.3.0b1.dist-info}/LICENSE +0 -0
- {eventsourcing-9.3.0a1.dist-info → eventsourcing-9.3.0b1.dist-info}/WHEEL +0 -0
eventsourcing/domain.py
CHANGED
|
@@ -941,6 +941,7 @@ class MetaAggregate(type, Generic[TAggregate]):
|
|
|
941
941
|
setattr(cls, base_event_name, base_event_cls)
|
|
942
942
|
|
|
943
943
|
# Make sure all events defined on aggregate subclass the base event class.
|
|
944
|
+
created_event_classes: Dict[str, Type[CanInitAggregate]] = {}
|
|
944
945
|
for name, value in tuple(cls.__dict__.items()):
|
|
945
946
|
if name == base_event_name:
|
|
946
947
|
# Don't subclass the base event class again.
|
|
@@ -955,31 +956,20 @@ class MetaAggregate(type, Generic[TAggregate]):
|
|
|
955
956
|
):
|
|
956
957
|
sub_class = cls._define_event_class(name, (value, base_event_cls), None)
|
|
957
958
|
setattr(cls, name, sub_class)
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
# Has the "created" event class been indicated with '_created_event_class'.
|
|
963
|
-
if "_created_event_class" in cls.__dict__:
|
|
964
|
-
created_event_class = cls.__dict__["_created_event_class"]
|
|
965
|
-
if isinstance(created_event_class, type) and issubclass(
|
|
966
|
-
created_event_class, CanInitAggregate
|
|
967
|
-
):
|
|
968
|
-
# We just subclassed the event classes, so reassign this.
|
|
969
|
-
created_event_class = getattr(cls, created_event_class.__name__)
|
|
970
|
-
assert created_event_class
|
|
971
|
-
cls._created_event_class = created_event_class
|
|
972
|
-
else:
|
|
973
|
-
msg = (
|
|
974
|
-
f"{created_event_class} not subclass of {CanInitAggregate.__name__}"
|
|
975
|
-
)
|
|
976
|
-
raise TypeError(msg)
|
|
959
|
+
for name, value in tuple(cls.__dict__.items()):
|
|
960
|
+
if isinstance(value, type) and issubclass(value, CanInitAggregate):
|
|
961
|
+
created_event_classes[name] = value
|
|
977
962
|
|
|
978
963
|
# Disallow using both '_created_event_class' and 'created_event_name'.
|
|
964
|
+
created_event_class: Type[CanInitAggregate] | None = cls.__dict__.get(
|
|
965
|
+
"_created_event_class"
|
|
966
|
+
)
|
|
979
967
|
if created_event_class and created_event_name:
|
|
980
968
|
msg = "Can't use both '_created_event_class' and 'created_event_name'"
|
|
981
969
|
raise TypeError(msg)
|
|
982
970
|
|
|
971
|
+
# Identify or define the aggregate's "created" event class.
|
|
972
|
+
|
|
983
973
|
# Is the init method decorated with a CommandMethodDecorator?
|
|
984
974
|
if isinstance(cls.__dict__.get("__init__"), CommandMethodDecorator):
|
|
985
975
|
init_decorator: CommandMethodDecorator = cls.__dict__["__init__"]
|
|
@@ -987,31 +977,20 @@ class MetaAggregate(type, Generic[TAggregate]):
|
|
|
987
977
|
# Set the original method on the class (un-decorate __init__).
|
|
988
978
|
cls.__init__ = init_decorator.decorated_method # type: ignore
|
|
989
979
|
|
|
990
|
-
# Disallow using both 'created_event_name' and
|
|
980
|
+
# Disallow using both 'created_event_name' and decorator on __init__.
|
|
991
981
|
if created_event_name:
|
|
992
982
|
msg = "Can't use both 'created_event_name' and decorator on __init__"
|
|
993
983
|
raise TypeError(msg)
|
|
984
|
+
# Disallow using both '_created_event_class' and decorator on __init__.
|
|
994
985
|
if created_event_class:
|
|
995
986
|
msg = "Can't use both '_created_event_class' and decorator on __init__"
|
|
996
987
|
raise TypeError(msg)
|
|
997
988
|
|
|
998
|
-
# Does the decorator specify a "
|
|
989
|
+
# Does the decorator specify a "created" event class?
|
|
999
990
|
if init_decorator.given_event_cls:
|
|
1000
|
-
created_event_class =
|
|
1001
|
-
|
|
991
|
+
created_event_class = cast(
|
|
992
|
+
Type[CanInitAggregate], init_decorator.given_event_cls
|
|
1002
993
|
)
|
|
1003
|
-
if isinstance(created_event_class, type) and issubclass(
|
|
1004
|
-
created_event_class, CanInitAggregate
|
|
1005
|
-
):
|
|
1006
|
-
assert created_event_class
|
|
1007
|
-
cls._created_event_class = created_event_class
|
|
1008
|
-
else:
|
|
1009
|
-
msg = (
|
|
1010
|
-
f"{created_event_class} not subclass of "
|
|
1011
|
-
f"{CanInitAggregate.__name__}"
|
|
1012
|
-
)
|
|
1013
|
-
raise TypeError(msg)
|
|
1014
|
-
|
|
1015
994
|
# Does the decorator specify a "created" event name?
|
|
1016
995
|
elif init_decorator.event_cls_name:
|
|
1017
996
|
created_event_name = init_decorator.event_cls_name
|
|
@@ -1028,65 +1007,85 @@ class MetaAggregate(type, Generic[TAggregate]):
|
|
|
1028
1007
|
_init_mentions_id.add(cls)
|
|
1029
1008
|
break
|
|
1030
1009
|
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1010
|
+
if created_event_class:
|
|
1011
|
+
# Check specified "created" event class can init aggregate.
|
|
1012
|
+
if not issubclass(created_event_class, CanInitAggregate):
|
|
1013
|
+
msg = (
|
|
1014
|
+
f"{created_event_class} not subclass of {CanInitAggregate.__name__}"
|
|
1015
|
+
)
|
|
1016
|
+
raise TypeError(msg)
|
|
1017
|
+
|
|
1018
|
+
for sub_class in created_event_classes.values():
|
|
1019
|
+
if issubclass(sub_class, created_event_class):
|
|
1020
|
+
# We just subclassed the created event class, so reassign it.
|
|
1021
|
+
created_event_class = sub_class
|
|
1022
|
+
|
|
1023
|
+
# Is a "created" event class already defined that matches the name?
|
|
1024
|
+
elif created_event_name and created_event_name in created_event_classes:
|
|
1025
|
+
created_event_class = created_event_classes[created_event_name]
|
|
1026
|
+
|
|
1027
|
+
# If there is only one class defined, then use it.
|
|
1028
|
+
elif len(created_event_classes) == 1 and not created_event_name:
|
|
1029
|
+
created_event_class = next(iter(created_event_classes.values()))
|
|
1030
|
+
|
|
1031
|
+
# If there are no "created" event classes already defined, or a name is
|
|
1032
|
+
# specified that hasn't matched, then define a "created" event class.
|
|
1033
|
+
elif len(created_event_classes) == 0 or created_event_name:
|
|
1034
|
+
|
|
1035
|
+
# Decide the base classes for the new "created" event class.
|
|
1036
|
+
if created_event_name and len(created_event_classes) == 1:
|
|
1037
|
+
base_created_event_cls = next(iter(created_event_classes.values()))
|
|
1038
|
+
else:
|
|
1039
|
+
for base_cls in cls.__mro__:
|
|
1040
|
+
if base_cls is cls:
|
|
1041
|
+
continue
|
|
1042
|
+
base_created_event_cls = base_cls.__dict__.get(
|
|
1043
|
+
"_created_event_class",
|
|
1044
|
+
base_cls.__dict__.get("Created"),
|
|
1045
|
+
)
|
|
1046
|
+
if base_created_event_cls:
|
|
1047
|
+
break
|
|
1048
|
+
else: # pragma: no cover
|
|
1049
|
+
msg = "Can't decide base class for new 'created' event class"
|
|
1050
|
+
raise TypeError(msg)
|
|
1051
|
+
|
|
1052
|
+
if not created_event_name:
|
|
1053
|
+
created_event_name = base_created_event_cls.__name__
|
|
1054
|
+
|
|
1055
|
+
# Disallow init method from having variable params if
|
|
1056
|
+
# we are using it to define a "created" event class.
|
|
1057
|
+
try:
|
|
1058
|
+
init_method = cls.__dict__["__init__"]
|
|
1059
|
+
except KeyError:
|
|
1060
|
+
init_method = None
|
|
1061
|
+
else:
|
|
1057
1062
|
try:
|
|
1058
|
-
init_method
|
|
1059
|
-
except
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
else:
|
|
1072
|
-
bases = (cls.Created, base_event_cls)
|
|
1073
|
-
event_cls = cls._define_event_class(
|
|
1063
|
+
_check_no_variable_params(init_method)
|
|
1064
|
+
except TypeError:
|
|
1065
|
+
raise
|
|
1066
|
+
|
|
1067
|
+
# Define a "created" event class for this aggregate.
|
|
1068
|
+
if issubclass(base_created_event_cls, base_event_cls):
|
|
1069
|
+
# Don't subclass from base event class twice.
|
|
1070
|
+
bases: Tuple[Type[CanMutateAggregate], ...] = (base_created_event_cls,)
|
|
1071
|
+
else:
|
|
1072
|
+
bases = (base_created_event_cls, base_event_cls)
|
|
1073
|
+
created_event_class = cast(
|
|
1074
|
+
Type[CanInitAggregate],
|
|
1075
|
+
cls._define_event_class(
|
|
1074
1076
|
created_event_name,
|
|
1075
1077
|
bases,
|
|
1076
1078
|
init_method,
|
|
1077
|
-
)
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
# Remember which is the "created" event class.
|
|
1083
|
-
cls._created_event_class = cast(Type[AggregateCreated], event_cls)
|
|
1079
|
+
),
|
|
1080
|
+
)
|
|
1081
|
+
# Set the event class as an attribute of the aggregate class.
|
|
1082
|
+
setattr(cls, created_event_name, created_event_class)
|
|
1084
1083
|
|
|
1084
|
+
if created_event_class:
|
|
1085
|
+
cls._created_event_class = created_event_class
|
|
1086
|
+
else:
|
|
1085
1087
|
# Prepare to disallow ambiguity of choice between created event classes.
|
|
1086
|
-
|
|
1087
|
-
aggregate_has_many_created_event_classes[cls] = list(
|
|
1088
|
-
created_event_classes
|
|
1089
|
-
)
|
|
1088
|
+
aggregate_has_many_created_event_classes[cls] = list(created_event_classes)
|
|
1090
1089
|
|
|
1091
1090
|
# Prepare the subsequent event classes.
|
|
1092
1091
|
for attr_name, attr_value in tuple(cls.__dict__.items()):
|
|
@@ -730,6 +730,7 @@ class TestAggregateCreation(TestCase):
|
|
|
730
730
|
order = Order("name")
|
|
731
731
|
pending = order.collect_events()
|
|
732
732
|
self.assertEqual(type(pending[0]).__name__, "Started")
|
|
733
|
+
self.assertTrue(isinstance(pending[0], Order.Created))
|
|
733
734
|
|
|
734
735
|
def test_raises_when_given_created_event_name_conflicts_with_created_event_class(
|
|
735
736
|
self,
|
|
@@ -1098,6 +1099,19 @@ class TestAggregateEventsAreSubclassed(TestCase):
|
|
|
1098
1099
|
MySubclass.Ended.__qualname__,
|
|
1099
1100
|
)
|
|
1100
1101
|
|
|
1102
|
+
self.assertTrue(
|
|
1103
|
+
MySubclass._created_event_class.__qualname__.endswith("MySubclass.Opened")
|
|
1104
|
+
)
|
|
1105
|
+
|
|
1106
|
+
class MySubSubClass(MySubclass):
|
|
1107
|
+
pass
|
|
1108
|
+
|
|
1109
|
+
self.assertTrue(
|
|
1110
|
+
MySubSubClass._created_event_class.__qualname__.endswith(
|
|
1111
|
+
"MySubSubClass.Opened"
|
|
1112
|
+
)
|
|
1113
|
+
)
|
|
1114
|
+
|
|
1101
1115
|
|
|
1102
1116
|
class TestBankAccount(TestCase):
|
|
1103
1117
|
def test_subclass_bank_account(self):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: eventsourcing
|
|
3
|
-
Version: 9.3.
|
|
3
|
+
Version: 9.3.0b1
|
|
4
4
|
Summary: Event sourcing in Python
|
|
5
5
|
Home-page: https://github.com/pyeventsourcing/eventsourcing
|
|
6
6
|
License: BSD 3-Clause
|
|
@@ -8,7 +8,7 @@ Keywords: event sourcing,event store,domain driven design,domain-driven design,d
|
|
|
8
8
|
Author: John Bywater
|
|
9
9
|
Author-email: john.bywater@appropriatesoftware.net
|
|
10
10
|
Requires-Python: >=3.8,<4.0
|
|
11
|
-
Classifier: Development Status ::
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
12
|
Classifier: Intended Audience :: Developers
|
|
13
13
|
Classifier: Intended Audience :: Education
|
|
14
14
|
Classifier: Intended Audience :: Science/Research
|
|
@@ -3,7 +3,7 @@ eventsourcing/application.py,sha256=ZTsk-qTieT13Jesf44Xh6htF8Y_CP753bmdoDOKSVW4,
|
|
|
3
3
|
eventsourcing/cipher.py,sha256=NJcVfZdSlCER6xryM4zVoY3cmKstF-iSSniB4jmpaKg,3200
|
|
4
4
|
eventsourcing/compressor.py,sha256=IdvrJUB9B2td871oifInv4lGXmHwYL9d69MbHHCr7uI,421
|
|
5
5
|
eventsourcing/dispatch.py,sha256=yYSpT-jqc6l_wTdqEnfPJJfvsZN2Ta8g2anrVPWIcqQ,1412
|
|
6
|
-
eventsourcing/domain.py,sha256=
|
|
6
|
+
eventsourcing/domain.py,sha256=rvm4Sv2MmLcha8_5wqJ13AjmqyWvuzkquYsexUaePIg,57264
|
|
7
7
|
eventsourcing/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
eventsourcing/examples/aggregate1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
eventsourcing/examples/aggregate1/application.py,sha256=LPle9YoAu85EQFrp-lUk0I8DKuSdQOSUyJ__38JHSvE,766
|
|
@@ -114,7 +114,7 @@ eventsourcing/tests/docs_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5
|
|
|
114
114
|
eventsourcing/tests/docs_tests/test_docs.py,sha256=Yt--RMe_tcG9zERBJmaAVkZ0qgMWnlgbFzRPktRUVGk,10777
|
|
115
115
|
eventsourcing/tests/domain.py,sha256=lHSlY6jIoSeqlcPSbrrozEPUJGvJ8bgPrznlmzTxn2w,3254
|
|
116
116
|
eventsourcing/tests/domain_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
117
|
-
eventsourcing/tests/domain_tests/test_aggregate.py,sha256=
|
|
117
|
+
eventsourcing/tests/domain_tests/test_aggregate.py,sha256=tH61bA69MzNF9VVt5USayWoB8tZ2lnLIaqyE5MTEgUI,38255
|
|
118
118
|
eventsourcing/tests/domain_tests/test_aggregate_decorators.py,sha256=zky6jmqblM0GKgdhCJjYdSxtEE9MwRcemYaZhqxL1AE,50256
|
|
119
119
|
eventsourcing/tests/domain_tests/test_domainevent.py,sha256=3EGLKnla1aWfKPzMfLCNmh7UtVAztk_ne_Oi0cP7jPU,2782
|
|
120
120
|
eventsourcing/tests/interface_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -138,7 +138,7 @@ eventsourcing/tests/system_tests/test_system.py,sha256=xi-nCPTWeB5Rqasyn4-rP213F
|
|
|
138
138
|
eventsourcing/tests/utils_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
139
139
|
eventsourcing/tests/utils_tests/test_utils.py,sha256=8HcTk_0_lXyoT307fEmd2utwmOUS_joToUPGFeFnKW8,6486
|
|
140
140
|
eventsourcing/utils.py,sha256=PIWDvoGiKCXsNbR5DirkoJ_svopg80SoH37bqxOcjkU,8247
|
|
141
|
-
eventsourcing-9.3.
|
|
142
|
-
eventsourcing-9.3.
|
|
143
|
-
eventsourcing-9.3.
|
|
144
|
-
eventsourcing-9.3.
|
|
141
|
+
eventsourcing-9.3.0b1.dist-info/LICENSE,sha256=bSE_F-T6cQPmMY5LuJC27km_pGB1XCVuUFx1uY0Nueg,1512
|
|
142
|
+
eventsourcing-9.3.0b1.dist-info/METADATA,sha256=bNaX2a3mE4_9aGXlStw7M2EK_VijO5w8Z-GdTe4Rmmg,9890
|
|
143
|
+
eventsourcing-9.3.0b1.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
|
|
144
|
+
eventsourcing-9.3.0b1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|