Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-pymongo for openSUSE:Factory checked in at 2025-12-29 15:16:57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pymongo (Old) and /work/SRC/openSUSE:Factory/.python-pymongo.new.1928 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pymongo" Mon Dec 29 15:16:57 2025 rev:48 rq:1324601 version:4.15.5 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pymongo/python-pymongo.changes 2025-11-07 18:24:41.925094698 +0100 +++ /work/SRC/openSUSE:Factory/.python-pymongo.new.1928/python-pymongo.changes 2025-12-29 15:17:51.253599207 +0100 @@ -1,0 +2,13 @@ +Sun Dec 28 21:13:50 UTC 2025 - Dirk Müller <[email protected]> + +- update to 4.15.5: + * Fixed a bug that could cause AutoReconnect("connection pool + paused") errors when cursors fetched more documents from the + database after SDAM heartbeat failures. + * Relaxed the callback type of :meth:`~pymongo.asynchronous.cli + ent_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. + +------------------------------------------------------------------- Old: ---- pymongo-4.15.3.tar.gz New: ---- pymongo-4.15.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pymongo.spec ++++++ --- /var/tmp/diff_new_pack.RrCnkl/_old 2025-12-29 15:17:52.341643929 +0100 +++ /var/tmp/diff_new_pack.RrCnkl/_new 2025-12-29 15:17:52.345644093 +0100 @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-pymongo -Version: 4.15.3 +Version: 4.15.5 Release: 0 Summary: Python driver for MongoDB License: Apache-2.0 ++++++ pymongo-4.15.3.tar.gz -> pymongo-4.15.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymongo-4.15.3/.github/workflows/dist.yml new/pymongo-4.15.5/.github/workflows/dist.yml --- old/pymongo-4.15.3/.github/workflows/dist.yml 2020-02-02 01:00:00.000000000 +0100 +++ new/pymongo-4.15.5/.github/workflows/dist.yml 2020-02-02 01:00:00.000000000 +0100 @@ -100,7 +100,7 @@ make_sdist: name: Make SDist - runs-on: macos-13 + runs-on: macos-14 steps: - uses: actions/checkout@v5 with: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymongo-4.15.3/PKG-INFO new/pymongo-4.15.5/PKG-INFO --- old/pymongo-4.15.3/PKG-INFO 2020-02-02 01:00:00.000000000 +0100 +++ new/pymongo-4.15.5/PKG-INFO 2020-02-02 01:00:00.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: pymongo -Version: 4.15.3 +Version: 4.15.5 Summary: PyMongo - the Official MongoDB Python driver Project-URL: Homepage, https://www.mongodb.org Project-URL: Documentation, https://www.mongodb.com/docs/languages/python/pymongo-driver/current/ @@ -223,6 +223,7 @@ Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Database diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymongo-4.15.3/doc/changelog.rst new/pymongo-4.15.5/doc/changelog.rst --- old/pymongo-4.15.3/doc/changelog.rst 2020-02-02 01:00:00.000000000 +0100 +++ new/pymongo-4.15.5/doc/changelog.rst 2020-02-02 01:00:00.000000000 +0100 @@ -1,6 +1,37 @@ Changelog ========= +Changes in Version 4.15.5 (2025/12/02) +-------------------------------------- + +Version 4.15.5 is a bug fix release. + +- Fixed a bug that could cause ``AutoReconnect("connection pool paused")`` errors when cursors fetched more documents from the database after SDAM heartbeat failures. + +Issues Resolved +............... + +See the `PyMongo 4.15.5 release notes in JIRA`_ for the list of resolved issues +in this release. + +.. _PyMongo 4.15.5 release notes in JIRA: https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=10004&version=47640 + +Changes in Version 4.15.4 (2025/10/21) +-------------------------------------- + +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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymongo-4.15.3/doc/index.rst new/pymongo-4.15.5/doc/index.rst --- old/pymongo-4.15.3/doc/index.rst 2020-02-02 01:00:00.000000000 +0100 +++ new/pymongo-4.15.5/doc/index.rst 2020-02-02 01:00:00.000000000 +0100 @@ -22,7 +22,7 @@ Getting Help ------------ If you're having trouble or have questions about PyMongo, ask your question on -our `MongoDB Community Forum <https://www.mongodb.com/community/forums/tag/python>`_. +one of the platforms listed on `Technical Support <https://www.mongodb.com/docs/manual/support/>`_. You may also want to consider a `commercial support subscription <https://support.mongodb.com/welcome>`_. Once you get an answer, it'd be great if you could work it back into this @@ -37,7 +37,7 @@ Feature Requests / Feedback --------------------------- -Use our `feedback engine <https://feedback.mongodb.com/forums/924286-drivers>`_ +Use our `feedback engine <https://feedback.mongodb.com/?category=7548141816650747033>`_ to send us feature requests and general feedback about PyMongo. Contributing diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymongo-4.15.3/pymongo/_version.py new/pymongo-4.15.5/pymongo/_version.py --- old/pymongo-4.15.3/pymongo/_version.py 2020-02-02 01:00:00.000000000 +0100 +++ new/pymongo-4.15.5/pymongo/_version.py 2020-02-02 01:00:00.000000000 +0100 @@ -18,7 +18,7 @@ import re from typing import List, Tuple, Union -__version__ = "4.15.3" +__version__ = "4.15.5" def get_version_tuple(version: str) -> Tuple[Union[int, str], ...]: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymongo-4.15.3/pymongo/asynchronous/client_session.py new/pymongo-4.15.5/pymongo/asynchronous/client_session.py --- old/pymongo-4.15.3/pymongo/asynchronous/client_session.py 2020-02-02 01:00:00.000000000 +0100 +++ new/pymongo-4.15.5/pymongo/asynchronous/client_session.py 2020-02-02 01:00:00.000000000 +0100 @@ -143,8 +143,8 @@ TYPE_CHECKING, Any, AsyncContextManager, + Awaitable, Callable, - Coroutine, Mapping, MutableMapping, NoReturn, @@ -600,7 +600,7 @@ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymongo-4.15.3/pymongo/topology_description.py new/pymongo-4.15.5/pymongo/topology_description.py --- old/pymongo-4.15.3/pymongo/topology_description.py 2020-02-02 01:00:00.000000000 +0100 +++ new/pymongo-4.15.5/pymongo/topology_description.py 2020-02-02 01:00:00.000000000 +0100 @@ -322,7 +322,7 @@ if address: # Ignore selectors when explicit address is requested. description = self.server_descriptions().get(address) - return [description] if description else [] + return [description] if description and description.is_server_type_known else [] # Primary selection fast path. if self.topology_type == TOPOLOGY_TYPE.ReplicaSetWithPrimary and type(selector) is Primary: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymongo-4.15.3/pyproject.toml new/pymongo-4.15.5/pyproject.toml --- old/pymongo-4.15.3/pyproject.toml 2020-02-02 01:00:00.000000000 +0100 +++ new/pymongo-4.15.5/pyproject.toml 2020-02-02 01:00:00.000000000 +0100 @@ -35,6 +35,7 @@ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Database", "Typing :: Typed", ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymongo-4.15.3/test/asynchronous/test_server_selection.py new/pymongo-4.15.5/test/asynchronous/test_server_selection.py --- old/pymongo-4.15.3/test/asynchronous/test_server_selection.py 2020-02-02 01:00:00.000000000 +0100 +++ new/pymongo-4.15.5/test/asynchronous/test_server_selection.py 2020-02-02 01:00:00.000000000 +0100 @@ -17,9 +17,10 @@ import os import sys +import time from pathlib import Path -from pymongo import AsyncMongoClient, ReadPreference +from pymongo import AsyncMongoClient, ReadPreference, monitoring from pymongo.asynchronous.settings import TopologySettings from pymongo.asynchronous.topology import Topology from pymongo.errors import ServerSelectionTimeoutError @@ -30,7 +31,7 @@ sys.path[0:0] = [""] -from test.asynchronous import AsyncIntegrationTest, async_client_context, unittest +from test.asynchronous import AsyncIntegrationTest, async_client_context, client_knobs, unittest from test.asynchronous.utils import async_wait_until from test.asynchronous.utils_selection_tests import ( create_selection_tests, @@ -42,6 +43,7 @@ ) from test.utils_shared import ( FunctionCallRecorder, + HeartbeatEventListener, OvertCommandListener, ) @@ -207,6 +209,40 @@ ) self.assertEqual(selector.call_count, 0) + @async_client_context.require_replica_set + @async_client_context.require_failCommand_appName + async def test_server_selection_getMore_blocks(self): + hb_listener = HeartbeatEventListener() + client = await self.async_rs_client( + event_listeners=[hb_listener], heartbeatFrequencyMS=500, appName="heartbeatFailedClient" + ) + coll = client.db.test + await coll.drop() + docs = [{"x": 1} for _ in range(5)] + await coll.insert_many(docs) + + fail_heartbeat = { + "configureFailPoint": "failCommand", + "mode": {"times": 4}, + "data": { + "failCommands": [HelloCompat.LEGACY_CMD, "hello"], + "closeConnection": True, + "appName": "heartbeatFailedClient", + }, + } + + def hb_failed(event): + return isinstance(event, monitoring.ServerHeartbeatFailedEvent) + + cursor = coll.find({}, batch_size=1) + await cursor.next() # force initial query that will pin the address for the getMore + + async with self.fail_point(fail_heartbeat): + await async_wait_until( + lambda: hb_listener.matching(hb_failed), "published failed event" + ) + self.assertEqual(len(await cursor.to_list()), 4) + if __name__ == "__main__": unittest.main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymongo-4.15.3/test/asynchronous/test_transactions.py new/pymongo-4.15.5/test/asynchronous/test_transactions.py --- old/pymongo-4.15.3/test/asynchronous/test_transactions.py 2020-02-02 01:00:00.000000000 +0100 +++ new/pymongo-4.15.5/test/asynchronous/test_transactions.py 2020-02-02 01:00:00.000000000 +0100 @@ -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 @@ -470,6 +471,17 @@ 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() client = await self.async_rs_client(event_listeners=[listener]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymongo-4.15.3/test/test_server_selection.py new/pymongo-4.15.5/test/test_server_selection.py --- old/pymongo-4.15.3/test/test_server_selection.py 2020-02-02 01:00:00.000000000 +0100 +++ new/pymongo-4.15.5/test/test_server_selection.py 2020-02-02 01:00:00.000000000 +0100 @@ -17,9 +17,10 @@ import os import sys +import time from pathlib import Path -from pymongo import MongoClient, ReadPreference +from pymongo import MongoClient, ReadPreference, monitoring from pymongo.errors import ServerSelectionTimeoutError from pymongo.hello import HelloCompat from pymongo.operations import _Op @@ -30,7 +31,7 @@ sys.path[0:0] = [""] -from test import IntegrationTest, client_context, unittest +from test import IntegrationTest, client_context, client_knobs, unittest from test.utils import wait_until from test.utils_selection_tests import ( create_selection_tests, @@ -42,6 +43,7 @@ ) from test.utils_shared import ( FunctionCallRecorder, + HeartbeatEventListener, OvertCommandListener, ) @@ -205,6 +207,38 @@ topology.select_server(writable_server_selector, _Op.TEST, server_selection_timeout=0.1) self.assertEqual(selector.call_count, 0) + @client_context.require_replica_set + @client_context.require_failCommand_appName + def test_server_selection_getMore_blocks(self): + hb_listener = HeartbeatEventListener() + client = self.rs_client( + event_listeners=[hb_listener], heartbeatFrequencyMS=500, appName="heartbeatFailedClient" + ) + coll = client.db.test + coll.drop() + docs = [{"x": 1} for _ in range(5)] + coll.insert_many(docs) + + fail_heartbeat = { + "configureFailPoint": "failCommand", + "mode": {"times": 4}, + "data": { + "failCommands": [HelloCompat.LEGACY_CMD, "hello"], + "closeConnection": True, + "appName": "heartbeatFailedClient", + }, + } + + def hb_failed(event): + return isinstance(event, monitoring.ServerHeartbeatFailedEvent) + + cursor = coll.find({}, batch_size=1) + cursor.next() # force initial query that will pin the address for the getMore + + with self.fail_point(fail_heartbeat): + wait_until(lambda: hb_listener.matching(hb_failed), "published failed event") + self.assertEqual(len(cursor.to_list()), 4) + if __name__ == "__main__": unittest.main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymongo-4.15.3/test/test_transactions.py new/pymongo-4.15.5/test/test_transactions.py --- old/pymongo-4.15.3/test/test_transactions.py 2020-02-02 01:00:00.000000000 +0100 +++ new/pymongo-4.15.5/test/test_transactions.py 2020-02-02 01:00:00.000000000 +0100 @@ -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 @@ -462,6 +463,17 @@ 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() client = self.rs_client(event_listeners=[listener]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pymongo-4.15.3/tools/synchro.py new/pymongo-4.15.5/tools/synchro.py --- old/pymongo-4.15.3/tools/synchro.py 2020-02-02 01:00:00.000000000 +0100 +++ new/pymongo-4.15.5/tools/synchro.py 2020-02-02 01:00:00.000000000 +0100 @@ -322,6 +322,14 @@ 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
