From 3a049e22f1cf183ed416bb2b68873e0acea6e09f Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Wed, 29 Oct 2025 14:31:25 -0400 Subject: [PATCH 1/4] [TASK]-[PYTHON-5623]: Change with_transaction callback return type to Awaitable (#2594) Co-authored-by: Logan Pulley (cherry picked from commit 5f00966f9ce591cbff982bea56df888875b80fb7) --- doc/changelog.rst | 16 ++++++++++++++++ pymongo/asynchronous/client_session.py | 4 ++-- test/asynchronous/test_transactions.py | 12 ++++++++++++ test/test_transactions.py | 12 ++++++++++++ tools/synchro.py | 8 ++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index bde6125c44..a9917d211e 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -1,6 +1,22 @@ Changelog ========= +Changes in Version 4.15.4 (2025/11/11) +-------------------------------------- + +Version 4.15.4 is a bug fix release. + +- Relaxed the callback type of :meth:`~pymongo.asynchronous.client_session.AsyncClientSession.with_transaction` to allow the broader Awaitable type rather than only Coroutine objects. +- Added the missing Python 3.14 trove classifier to the package metadata. + +Issues Resolved +............... + +See the `PyMongo 4.15.4 release notes in JIRA`_ for the list of resolved issues +in this release. + +.. _PyMongo 4.15.4 release notes in JIRA: https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=10004&version=47237 + Changes in Version 4.15.3 (2025/10/07) -------------------------------------- diff --git a/pymongo/asynchronous/client_session.py b/pymongo/asynchronous/client_session.py index be02295cea..ce2d7667f5 100644 --- a/pymongo/asynchronous/client_session.py +++ b/pymongo/asynchronous/client_session.py @@ -143,8 +143,8 @@ TYPE_CHECKING, Any, AsyncContextManager, + Awaitable, Callable, - Coroutine, Mapping, MutableMapping, NoReturn, @@ -600,7 +600,7 @@ def _inherit_option(self, name: str, val: _T) -> _T: async def with_transaction( self, - callback: Callable[[AsyncClientSession], Coroutine[Any, Any, _T]], + callback: Callable[[AsyncClientSession], Awaitable[_T]], read_concern: Optional[ReadConcern] = None, write_concern: Optional[WriteConcern] = None, read_preference: Optional[_ServerMode] = None, diff --git a/test/asynchronous/test_transactions.py b/test/asynchronous/test_transactions.py index 5c2a4f6fae..6849da9896 100644 --- a/test/asynchronous/test_transactions.py +++ b/test/asynchronous/test_transactions.py @@ -15,6 +15,7 @@ """Execute Transactions Spec tests.""" from __future__ import annotations +import asyncio import sys from io import BytesIO from test.asynchronous.utils_spec_runner import AsyncSpecRunner @@ -469,6 +470,17 @@ async def callback2(session): async with self.client.start_session() as s: self.assertEqual(await s.with_transaction(callback2), "Foo") + @async_client_context.require_transactions + @async_client_context.require_async + async def test_callback_awaitable_no_coroutine(self): + def callback(_): + future = asyncio.Future() + future.set_result("Foo") + return future + + async with self.client.start_session() as s: + self.assertEqual(await s.with_transaction(callback), "Foo") + @async_client_context.require_transactions async def test_callback_not_retried_after_timeout(self): listener = OvertCommandListener() diff --git a/test/test_transactions.py b/test/test_transactions.py index f4578deddb..0c5bd42d7d 100644 --- a/test/test_transactions.py +++ b/test/test_transactions.py @@ -15,6 +15,7 @@ """Execute Transactions Spec tests.""" from __future__ import annotations +import asyncio import sys from io import BytesIO from test.utils_spec_runner import SpecRunner @@ -461,6 +462,17 @@ def callback2(session): with self.client.start_session() as s: self.assertEqual(s.with_transaction(callback2), "Foo") + @client_context.require_transactions + @client_context.require_async + def test_callback_awaitable_no_coroutine(self): + def callback(_): + future = asyncio.Future() + future.set_result("Foo") + return future + + with self.client.start_session() as s: + self.assertEqual(s.with_transaction(callback), "Foo") + @client_context.require_transactions def test_callback_not_retried_after_timeout(self): listener = OvertCommandListener() diff --git a/tools/synchro.py b/tools/synchro.py index e502f96281..17dac3f21f 100644 --- a/tools/synchro.py +++ b/tools/synchro.py @@ -322,6 +322,14 @@ def translate_coroutine_types(lines: list[str]) -> list[str]: index = lines.index(type) new = type.replace(old, res.group(3)) lines[index] = new + coroutine_types = [line for line in lines if "Awaitable[" in line] + for type in coroutine_types: + res = re.search(r"Awaitable\[([A-z]+)\]", type) + if res: + old = res[0] + index = lines.index(type) + new = type.replace(old, res.group(1)) + lines[index] = new return lines From e12646a353c4f3d0129299f7d78a14027277b261 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 11 Nov 2025 12:30:01 -0600 Subject: [PATCH 2/4] move to supported macos on GHA --- .github/workflows/dist.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml index f9b61d73e5..3f0379bf19 100644 --- a/.github/workflows/dist.yml +++ b/.github/workflows/dist.yml @@ -100,7 +100,7 @@ jobs: make_sdist: name: Make SDist - runs-on: macos-13 + runs-on: macos-14 steps: - uses: actions/checkout@v5 with: From 461076cc474665be89193fb7370b090ba62d6baa Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Mon, 27 Oct 2025 11:41:14 -0400 Subject: [PATCH 3/4] PYTHON-5628 - Update the link for help in the documentation (#2602) (cherry picked from commit fd025503491e2bc939d8272770623c47dbaa3fd7) --- doc/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.rst b/doc/index.rst index 85812d1b14..1714836fef 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -22,7 +22,7 @@ work with MongoDB from Python. Getting Help ------------ If you're having trouble or have questions about PyMongo, ask your question on -our `MongoDB Community Forum `_. +one of the platforms listed on `Technical Support `_. You may also want to consider a `commercial support subscription `_. Once you get an answer, it'd be great if you could work it back into this From 20f060da4b6029604be4198baaed4bb5f3deadb3 Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Fri, 24 Oct 2025 15:26:46 -0400 Subject: [PATCH 4/4] PYTHON-5627 - Update feedback link (#2601) (cherry picked from commit 0c8a22b87d40d2afcec65de08c5f76505fa03091) --- doc/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.rst b/doc/index.rst index 1714836fef..17b12e51a8 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -37,7 +37,7 @@ project. Feature Requests / Feedback --------------------------- -Use our `feedback engine `_ +Use our `feedback engine `_ to send us feature requests and general feedback about PyMongo. Contributing