From 34322bd928c825feeff507afa1a9c29228456404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20L=C3=B3pez?= Date: Fri, 25 Jul 2025 13:11:54 -0600 Subject: [PATCH 1/5] async signals with blinker async signals --- mongoengine_plus/aio/async_document.py | 11 ++++++- mongoengine_plus/aio/async_signals.py | 6 ++++ mongoengine_plus/version.py | 2 +- tests/aio/test_async_signals.py | 43 ++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 mongoengine_plus/aio/async_signals.py create mode 100644 tests/aio/test_async_signals.py diff --git a/mongoengine_plus/aio/async_document.py b/mongoengine_plus/aio/async_document.py index abe8a9d..30c241f 100644 --- a/mongoengine_plus/aio/async_document.py +++ b/mongoengine_plus/aio/async_document.py @@ -1,6 +1,7 @@ from mongoengine import Document from .async_query_set import AsyncQuerySet +from .async_signals import post_save, pre_save from .utils import create_awaitable @@ -11,7 +12,15 @@ class AsyncDocument(Document): ) async def async_save(self, *args, **kwargs): - return await create_awaitable(self.save, *args, **kwargs) + signal_kwargs = kwargs.pop("signal_kwargs", {}) + await pre_save.send_async( + self.__class__, document=self, **signal_kwargs + ) + result = await create_awaitable(self.save, *args, **kwargs) + await post_save.send_async( + self.__class__, document=self, **signal_kwargs + ) + return result async def async_reload(self, *fields, **kwargs): return await create_awaitable(self.reload, *fields, **kwargs) diff --git a/mongoengine_plus/aio/async_signals.py b/mongoengine_plus/aio/async_signals.py new file mode 100644 index 0000000..8b59d96 --- /dev/null +++ b/mongoengine_plus/aio/async_signals.py @@ -0,0 +1,6 @@ +from mongoengine.signals import Namespace + +async_signals = Namespace() + +pre_save = async_signals.signal("pre_save") +post_save = async_signals.signal("post_save") diff --git a/mongoengine_plus/version.py b/mongoengine_plus/version.py index 1a72d32..a7977e0 100644 --- a/mongoengine_plus/version.py +++ b/mongoengine_plus/version.py @@ -1 +1 @@ -__version__ = '1.1.0' +__version__ = '1.2.0.devb1' diff --git a/tests/aio/test_async_signals.py b/tests/aio/test_async_signals.py new file mode 100644 index 0000000..29ee745 --- /dev/null +++ b/tests/aio/test_async_signals.py @@ -0,0 +1,43 @@ +import pytest +from mongoengine import StringField + +from mongoengine_plus.aio.async_document import AsyncDocument +from mongoengine_plus.aio.async_signals import post_save, pre_save +from mongoengine_plus.models.event_handlers import handler + + +@pytest.mark.asyncio +async def test_async_signal_handler_on_asyncdocument(): + pre_calls = [] + post_calls = [] + + @handler(pre_save) + async def my_async_pre_handler(cls, document, **kwargs): + pre_calls.append((document.name, getattr(document, "updated", False))) + + @handler(post_save) + async def my_async_post_handler(cls, document, **kwargs): + post_calls.append((document.name, getattr(document, "updated", False))) + + @my_async_pre_handler.apply + @my_async_post_handler.apply + class User(AsyncDocument): + name = StringField(required=True) + updated = StringField() + + user = User(name="Jane") + await user.async_save() + assert pre_calls[-1][0] == "Jane" + assert post_calls[-1][0] == "Jane" + + user.name = "John" + user.updated = "yes" + await user.async_save() + + # The handlers should have been called again with updated data + assert pre_calls[-1][0] == "John" + assert pre_calls[-1][1] == "yes" + assert post_calls[-1][0] == "John" + assert post_calls[-1][1] == "yes" + assert len(pre_calls) == 2 + assert len(post_calls) == 2 From 6f53d83a79fe5c46d6cad2cc0929d337e327be5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20L=C3=B3pez?= Date: Fri, 25 Jul 2025 13:23:04 -0600 Subject: [PATCH 2/5] version test --- mongoengine_plus/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoengine_plus/version.py b/mongoengine_plus/version.py index a7977e0..df61be1 100644 --- a/mongoengine_plus/version.py +++ b/mongoengine_plus/version.py @@ -1 +1 @@ -__version__ = '1.2.0.devb1' +__version__ = '1.2.0.dev+asyncsignals' From 706910f6cffd9ef01d820e77646b83e146c55512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20L=C3=B3pez?= Date: Fri, 25 Jul 2025 13:26:53 -0600 Subject: [PATCH 3/5] version test --- mongoengine_plus/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoengine_plus/version.py b/mongoengine_plus/version.py index df61be1..778e9e8 100644 --- a/mongoengine_plus/version.py +++ b/mongoengine_plus/version.py @@ -1 +1 @@ -__version__ = '1.2.0.dev+asyncsignals' +__version__ = '1.2.0.dev1+asyncsignals' From 75f377bd9cdc5086f1bf1ac8fa38b1f8a9dad6d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20L=C3=B3pez?= Date: Fri, 25 Jul 2025 13:29:41 -0600 Subject: [PATCH 4/5] version test --- mongoengine_plus/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mongoengine_plus/version.py b/mongoengine_plus/version.py index 778e9e8..78dc420 100644 --- a/mongoengine_plus/version.py +++ b/mongoengine_plus/version.py @@ -1 +1 @@ -__version__ = '1.2.0.dev1+asyncsignals' +__version__ = '1.2.0.dev101' From 92a6f41793d5b555d9ea695c73d4fccbfd7aabd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20L=C3=B3pez?= Date: Tue, 29 Jul 2025 17:03:33 -0600 Subject: [PATCH 5/5] version --- mongoengine_plus/version.py | 2 +- setup.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mongoengine_plus/version.py b/mongoengine_plus/version.py index 78dc420..58d478a 100644 --- a/mongoengine_plus/version.py +++ b/mongoengine_plus/version.py @@ -1 +1 @@ -__version__ = '1.2.0.dev101' +__version__ = '1.2.0' diff --git a/setup.py b/setup.py index abc9678..a339550 100644 --- a/setup.py +++ b/setup.py @@ -30,6 +30,7 @@ 'pymongo>=3.13.0,<4.0.0', 'pymongocrypt>=1.12.2,<2.0.0', 'boto3>=1.34.106,<2.0.0', + 'blinker>=1.9.0,<2.0.0', ], classifiers=[ 'Programming Language :: Python :: 3.9',