python-cq 0.20.0__tar.gz → 0.21.1__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.
- {python_cq-0.20.0 → python_cq-0.21.1}/PKG-INFO +2 -2
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/__init__.py +12 -14
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/cq.py +13 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/dispatchers/bus.py +1 -1
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/handler.py +14 -1
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/related_events.py +1 -1
- {python_cq-0.20.0 → python_cq-0.21.1}/pyproject.toml +2 -2
- {python_cq-0.20.0 → python_cq-0.21.1}/.gitignore +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/LICENSE +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/__init__.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/common/__init__.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/common/typing.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/di.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/dispatchers/__init__.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/dispatchers/abc.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/dispatchers/lazy.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/dispatchers/pipe.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/message.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/middleware.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/middlewares/__init__.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/middlewares/scope.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/pipetools.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/pump.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/queues/__init__.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/queues/abc.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/_core/queues/memory.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/exceptions.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/ext/__init__.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/ext/injection.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/middlewares/__init__.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/middlewares/exc.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/middlewares/retry.py +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/cq/py.typed +0 -0
- {python_cq-0.20.0 → python_cq-0.21.1}/docs/index.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-cq
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.21.1
|
|
4
4
|
Summary: CQRS library for async Python projects.
|
|
5
5
|
Project-URL: Documentation, https://python-cq.remimd.dev
|
|
6
6
|
Project-URL: Repository, https://github.com/100nm/python-cq
|
|
@@ -22,7 +22,7 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
22
22
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
23
23
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
24
|
Classifier: Typing :: Typed
|
|
25
|
-
Requires-Python: <3.
|
|
25
|
+
Requires-Python: <3.16,>=3.12
|
|
26
26
|
Requires-Dist: anyio
|
|
27
27
|
Requires-Dist: type-analyzer
|
|
28
28
|
Provides-Extra: injection
|
|
@@ -21,6 +21,7 @@ from ._core.queues.memory import MemoryQueue
|
|
|
21
21
|
from ._core.related_events import AnyIORelatedEvents, RelatedEvents
|
|
22
22
|
|
|
23
23
|
__all__ = (
|
|
24
|
+
"__cq__",
|
|
24
25
|
"AnyCommandBus",
|
|
25
26
|
"AnyIORelatedEvents",
|
|
26
27
|
"Bus",
|
|
@@ -55,30 +56,27 @@ __all__ = (
|
|
|
55
56
|
)
|
|
56
57
|
|
|
57
58
|
try:
|
|
58
|
-
from
|
|
59
|
+
from .ext.injection import InjectionAdapter as _InjectionAdapter
|
|
59
60
|
|
|
60
61
|
except ImportError: # pragma: no cover
|
|
61
|
-
|
|
62
|
+
__cq__ = CQ(_NoDI())
|
|
62
63
|
|
|
63
64
|
else:
|
|
64
|
-
|
|
65
|
+
__cq__ = CQ(_InjectionAdapter())
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
__cq__.register_defaults()
|
|
67
68
|
|
|
68
|
-
command_handler =
|
|
69
|
-
event_handler =
|
|
70
|
-
query_handler =
|
|
69
|
+
command_handler = __cq__.command_handler
|
|
70
|
+
event_handler = __cq__.event_handler
|
|
71
|
+
query_handler = __cq__.query_handler
|
|
71
72
|
|
|
72
|
-
new_command_bus =
|
|
73
|
-
new_event_bus =
|
|
74
|
-
new_query_bus =
|
|
73
|
+
new_command_bus = __cq__.new_command_bus
|
|
74
|
+
new_event_bus = __cq__.new_event_bus
|
|
75
|
+
new_query_bus = __cq__.new_query_bus
|
|
75
76
|
|
|
76
77
|
|
|
77
78
|
class ContextCommandPipeline[C: Command](_ContextCommandPipeline[C]):
|
|
78
79
|
__slots__ = ()
|
|
79
80
|
|
|
80
|
-
def __init__(self, di: DIAdapter =
|
|
81
|
+
def __init__(self, di: DIAdapter = __cq__.di) -> None:
|
|
81
82
|
super().__init__(di)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
del _default
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from collections.abc import KeysView
|
|
1
2
|
from typing import Any, Self
|
|
2
3
|
|
|
3
4
|
from cq._core.di import DIAdapter
|
|
@@ -34,14 +35,26 @@ class CQ:
|
|
|
34
35
|
def command_handler(self) -> HandlerDecorator[Command, Any]:
|
|
35
36
|
return HandlerDecorator(self.__command_registry, self.__di)
|
|
36
37
|
|
|
38
|
+
@property
|
|
39
|
+
def command_types(self) -> KeysView[type[Command]]:
|
|
40
|
+
return self.__command_registry.message_types
|
|
41
|
+
|
|
37
42
|
@property
|
|
38
43
|
def event_handler(self) -> HandlerDecorator[Event, Any]:
|
|
39
44
|
return HandlerDecorator(self.__event_registry, self.__di)
|
|
40
45
|
|
|
46
|
+
@property
|
|
47
|
+
def event_types(self) -> KeysView[type[Event]]:
|
|
48
|
+
return self.__event_registry.message_types
|
|
49
|
+
|
|
41
50
|
@property
|
|
42
51
|
def query_handler(self) -> HandlerDecorator[Query, Any]:
|
|
43
52
|
return HandlerDecorator(self.__query_registry, self.__di)
|
|
44
53
|
|
|
54
|
+
@property
|
|
55
|
+
def query_types(self) -> KeysView[type[Query]]:
|
|
56
|
+
return self.__query_registry.message_types
|
|
57
|
+
|
|
45
58
|
def new_command_bus(self) -> Bus[Command, Any]:
|
|
46
59
|
bus = SimpleBus(self.__command_registry)
|
|
47
60
|
command_middleware = CommandDispatchScopeMiddleware(self.__di)
|
|
@@ -69,7 +69,7 @@ class BaseBus[I, O](BaseDispatcher[I, O], Bus[I, O], ABC):
|
|
|
69
69
|
|
|
70
70
|
def _trigger_listeners(self, message: I, /, task_group: TaskGroup) -> None:
|
|
71
71
|
for listener in self.__listeners:
|
|
72
|
-
task_group.start_soon(listener, message)
|
|
72
|
+
task_group.start_soon(listener, message) # type: ignore[arg-type]
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
class SimpleBus[I, O](BaseBus[I, O]):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from abc import abstractmethod
|
|
2
2
|
from collections import defaultdict
|
|
3
|
-
from collections.abc import Awaitable, Callable, Iterator
|
|
3
|
+
from collections.abc import Awaitable, Callable, Iterator, KeysView
|
|
4
4
|
from dataclasses import dataclass, field
|
|
5
5
|
from functools import partial
|
|
6
6
|
from inspect import Parameter, isclass, unwrap
|
|
@@ -49,6 +49,11 @@ class HandleFunction[**P, T]:
|
|
|
49
49
|
class HandlerRegistry[I, O](Protocol):
|
|
50
50
|
__slots__ = ()
|
|
51
51
|
|
|
52
|
+
@property
|
|
53
|
+
@abstractmethod
|
|
54
|
+
def message_types(self) -> KeysView[type[I]]:
|
|
55
|
+
raise NotImplementedError
|
|
56
|
+
|
|
52
57
|
@abstractmethod
|
|
53
58
|
def handlers_from(self, message_type: type[I]) -> Iterator[HandleFunction[[I], O]]:
|
|
54
59
|
raise NotImplementedError
|
|
@@ -71,6 +76,10 @@ class MultipleHandlerRegistry[I, O](HandlerRegistry[I, O]):
|
|
|
71
76
|
init=False,
|
|
72
77
|
)
|
|
73
78
|
|
|
79
|
+
@property
|
|
80
|
+
def message_types(self) -> KeysView[type[I]]:
|
|
81
|
+
return self.__values.keys()
|
|
82
|
+
|
|
74
83
|
def handlers_from(self, message_type: type[I]) -> Iterator[HandleFunction[[I], O]]:
|
|
75
84
|
for key_type in _iter_key_types(message_type):
|
|
76
85
|
yield from self.__values.get(key_type, ())
|
|
@@ -97,6 +106,10 @@ class SingleHandlerRegistry[I, O](HandlerRegistry[I, O]):
|
|
|
97
106
|
init=False,
|
|
98
107
|
)
|
|
99
108
|
|
|
109
|
+
@property
|
|
110
|
+
def message_types(self) -> KeysView[type[I]]:
|
|
111
|
+
return self.__values.keys()
|
|
112
|
+
|
|
100
113
|
def handlers_from(self, message_type: type[I]) -> Iterator[HandleFunction[[I], O]]:
|
|
101
114
|
for key_type in _iter_key_types(message_type):
|
|
102
115
|
function = self.__values.get(key_type, None)
|
|
@@ -20,12 +20,12 @@ test = [
|
|
|
20
20
|
|
|
21
21
|
[project]
|
|
22
22
|
name = "python-cq"
|
|
23
|
-
version = "0.
|
|
23
|
+
version = "0.21.1"
|
|
24
24
|
description = "CQRS library for async Python projects."
|
|
25
25
|
license = "MIT"
|
|
26
26
|
license-files = ["LICENSE"]
|
|
27
27
|
readme = "docs/index.md"
|
|
28
|
-
requires-python = ">=3.12, <3.
|
|
28
|
+
requires-python = ">=3.12, <3.16"
|
|
29
29
|
authors = [{ name = "remimd" }]
|
|
30
30
|
keywords = ["cqrs"]
|
|
31
31
|
classifiers = [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|