Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-psycopg-pool for 
openSUSE:Factory checked in at 2026-10-20 12:40:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-psycopg-pool (Old)
 and      /work/SRC/openSUSE:Factory/.python-psycopg-pool.new.3698736 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-psycopg-pool"

Tue Oct 20 12:40:15 2026 rev:6 rq:1386238 version:3.3.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-psycopg-pool/python-psycopg-pool.changes  
2026-01-28 15:15:57.980022191 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-psycopg-pool.new.3698736/python-psycopg-pool.changes
     2026-10-20 12:41:42.098975380 +0200
@@ -1,0 +2,20 @@
+Sat Oct 17 15:32:56 UTC 2026 - Andrea Manzini <[email protected]>
+
+- Update to 3.3.3:
+  * Fix sync pool workers terminating after 24 hours with no task
+    to run (ticket #1419).
+- Changes from 3.3.2:
+  * Propagate cancellation and other base exceptions raised in
+    connection check (ticket #1401).
+  * Declare compatibility with Python 3.15.
+- Changes from 3.3.1:
+  * Fix residual race condition catching asyncio.CancelledError on
+    connection (ticket #1275).
+  * Fix race condition constructing the lock that makes sync
+    ConnectionPool.open() thread-safe (ticket #1300).
+  * Raise PoolClosed instead of generic OperationalError on pool
+    reopening attempt (ticket #1295).
+- Bump python-setuptools BuildRequires minimum version to 80.3.1
+  to match upstream pyproject.toml.
+
+-------------------------------------------------------------------

Old:
----
  psycopg_pool-3.3.0.tar.gz

New:
----
  psycopg_pool-3.3.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-psycopg-pool.spec ++++++
--- /var/tmp/diff_new_pack.Sop9Tj/_old  2026-10-20 12:41:43.008013425 +0200
+++ /var/tmp/diff_new_pack.Sop9Tj/_new  2026-10-20 12:41:43.012013593 +0200
@@ -18,14 +18,14 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-psycopg-pool
-Version:        3.3.0
+Version:        3.3.3
 Release:        0
 Summary:        Connection Pool for Psycopg
 License:        LGPL-3.0-only
 URL:            https://psycopg.org/psycopg3/
-Source:         
https://files.pythonhosted.org/packages/source/p/psycopg-pool/psycopg_pool-%{version}.tar.gz
+Source:         
https://files.pythonhosted.org/packages/source/p/psycopg_pool/psycopg_pool-%{version}.tar.gz
 BuildRequires:  %{python_module pip}
-BuildRequires:  %{python_module setuptools >= 49.2.0}
+BuildRequires:  %{python_module setuptools >= 80.3.1}
 BuildRequires:  %{python_module wheel >= 0.37}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros

++++++ psycopg_pool-3.3.0.tar.gz -> psycopg_pool-3.3.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg_pool-3.3.0/PKG-INFO 
new/psycopg_pool-3.3.3/PKG-INFO
--- old/psycopg_pool-3.3.0/PKG-INFO     2025-12-01 04:37:42.109674700 +0100
+++ new/psycopg_pool-3.3.3/PKG-INFO     2026-09-22 17:50:41.969243800 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: psycopg-pool
-Version: 3.3.0
+Version: 3.3.3
 Summary: Connection Pool for Psycopg
 Author-email: Daniele Varrazzo <[email protected]>
 License-Expression: LGPL-3.0-only
@@ -21,6 +21,7 @@
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
 Classifier: Programming Language :: Python :: 3.14
+Classifier: Programming Language :: Python :: 3.15
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Topic :: Database
@@ -33,7 +34,7 @@
 Requires-Dist: typing-extensions>=4.6
 Provides-Extra: test
 Requires-Dist: anyio>=4.0; extra == "test"
-Requires-Dist: mypy>=1.14; extra == "test"
+Requires-Dist: mypy>=2.1.0; extra == "test"
 Requires-Dist: pproxy>=2.7; extra == "test"
 Requires-Dist: pytest>=6.2.5; extra == "test"
 Requires-Dist: pytest-cov>=3.0; extra == "test"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg_pool-3.3.0/psycopg_pool/_acompat.py 
new/psycopg_pool-3.3.3/psycopg_pool/_acompat.py
--- old/psycopg_pool-3.3.0/psycopg_pool/_acompat.py     2025-12-01 
04:37:38.000000000 +0100
+++ new/psycopg_pool-3.3.3/psycopg_pool/_acompat.py     2026-09-22 
17:50:38.591066800 +0200
@@ -50,11 +50,19 @@
     A Queue subclass with an interruptible get() method.
     """
 
+    # Time to spend in a single wait. Expposed for testing purpose,
+    # in order to inject a timeout.
+    _WAIT_INTERVAL = 10.0 * 60.0
+
     def get(self, block: bool = True, timeout: float | None = None) -> T:
-        # Always specify a timeout to make the wait interruptible.
-        if timeout is None:
-            timeout = 24.0 * 60.0 * 60.0
-        return super().get(block, timeout)
+        if not block or timeout is not None:
+            return super().get(block, timeout)
+
+        while True:
+            try:
+                return super().get(True, self._WAIT_INTERVAL)
+            except queue.Empty:
+                pass
 
 
 class AEvent(asyncio.Event):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg_pool-3.3.0/psycopg_pool/base.py 
new/psycopg_pool-3.3.3/psycopg_pool/base.py
--- old/psycopg_pool-3.3.0/psycopg_pool/base.py 2025-12-01 04:37:38.000000000 
+0100
+++ new/psycopg_pool-3.3.3/psycopg_pool/base.py 2026-09-22 17:50:38.591066800 
+0200
@@ -11,8 +11,6 @@
 from typing import TYPE_CHECKING, Any
 from collections import Counter, deque
 
-from psycopg import errors as e
-
 from .errors import PoolClosed
 
 if TYPE_CHECKING:
@@ -126,15 +124,13 @@
         if max_size < min_size:
             raise ValueError("max_size must be greater or equal than min_size")
         if min_size == max_size == 0:
-            raise ValueError("if min_size is 0 max_size must be greater or 
than 0")
+            raise ValueError("if min_size is 0 max_size must be greater than 
0")
 
         return min_size, max_size
 
     def _check_open(self) -> None:
         if self._closed and self._opened:
-            raise e.OperationalError(
-                "pool has already been opened/closed and cannot be reused"
-            )
+            raise PoolClosed("pool has already been opened/closed and cannot 
be reused")
 
     def _check_open_getconn(self) -> None:
         if self._closed:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg_pool-3.3.0/psycopg_pool/pool.py 
new/psycopg_pool-3.3.3/psycopg_pool/pool.py
--- old/psycopg_pool-3.3.0/psycopg_pool/pool.py 2025-12-01 04:37:38.000000000 
+0100
+++ new/psycopg_pool-3.3.3/psycopg_pool/pool.py 2026-09-22 17:50:38.591066800 
+0200
@@ -16,7 +16,7 @@
 from types import TracebackType
 from typing import Any, Generic, cast
 from weakref import ref
-from contextlib import contextmanager
+from contextlib import contextmanager, suppress
 from collections import deque
 from collections.abc import Iterator
 
@@ -105,6 +105,10 @@
             num_workers=num_workers,
         )
 
+        # Construct the lock during single-threaded `__init__` so that
+        # threads concurrently calling `open()` can't race on it.
+        self._lock = Lock()
+
         if open is None:
             open = self._open_implicit = True
 
@@ -222,8 +226,13 @@
             conn = self._getconn_unchecked(deadline - monotonic())
             try:
                 self._check_connection(conn)
-            except CLIENT_EXCEPTIONS:
+            except Exception:
                 self._putconn(conn, from_getconn=True)
+            except BaseException:
+                # Cancellation, KeyboardInterrupt etc.: don't lose the
+                # connection, but don't try again either.
+                self._putconn(conn, from_getconn=True)
+                raise
             else:
                 logger.info("connection given by %r", self.name)
                 return conn
@@ -261,6 +270,8 @@
             try:
                 conn = pos.wait(timeout=timeout)
             except CLIENT_EXCEPTIONS:
+                if pos.conn:
+                    self.run_task(ReturnConnection(self, pos.conn, 
from_getconn=True))
                 self._stats[self._REQUESTS_ERRORS] += 1
                 raise
             finally:
@@ -378,8 +389,6 @@
         because the pool was initialized with *open* = `!True`) but you cannot
         currently re-open a closed pool.
         """
-        # Make sure the lock is created after there is an event loop
-        self._ensure_lock()
 
         with self._lock:
             self._open()
@@ -393,9 +402,6 @@
 
         self._check_open()
 
-        # A lock has been most likely, but not necessarily, created in 
`open()`.
-        self._ensure_lock()
-
         # Create these objects now to attach them to the right loop.
         # See #219
         self._tasks = Queue()
@@ -407,17 +413,6 @@
         self._start_workers()
         self._start_initial_tasks()
 
-    def _ensure_lock(self) -> None:
-        """Make sure the pool lock is created.
-
-        In async code, also make sure that the loop is running.
-        """
-
-        try:
-            self._lock
-        except AttributeError:
-            self._lock = Lock()
-
     def _start_workers(self) -> None:
         self._sched_runner = spawn(self._sched.run, 
name=f"{self.name}-scheduler")
         assert not self._workers
@@ -573,7 +568,9 @@
             try:
                 conn.execute("")
             finally:
-                conn.autocommit = False
+                # Avoid clobbering an exception if the connection is closed
+                with suppress(Exception):
+                    conn.autocommit = False
 
     def reconnect_failed(self) -> None:
         """
@@ -894,11 +891,11 @@
                 except CLIENT_EXCEPTIONS as ex:
                     self.error = ex
 
-        if self.conn:
-            return self.conn
-        else:
-            assert self.error
+        if self.error:
             raise self.error
+        else:
+            assert self.conn
+            return self.conn
 
     def set(self, conn: CT) -> bool:
         """Signal the client waiting that a connection is ready.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg_pool-3.3.0/psycopg_pool/pool_async.py 
new/psycopg_pool-3.3.3/psycopg_pool/pool_async.py
--- old/psycopg_pool-3.3.0/psycopg_pool/pool_async.py   2025-12-01 
04:37:38.000000000 +0100
+++ new/psycopg_pool-3.3.3/psycopg_pool/pool_async.py   2026-09-22 
17:50:38.591236000 +0200
@@ -13,7 +13,7 @@
 from types import TracebackType
 from typing import Any, Generic, cast
 from weakref import ref
-from contextlib import asynccontextmanager
+from contextlib import asynccontextmanager, suppress
 from collections import deque
 from collections.abc import AsyncIterator
 
@@ -117,6 +117,10 @@
         if True:  # ASYNC
             if open:
                 self._warn_open_async()
+        else:
+            # Construct the lock during single-threaded `__init__` so that
+            # threads concurrently calling `open()` can't race on it.
+            self._lock = ALock()
 
         if open is None:
             open = self._open_implicit = True
@@ -259,8 +263,13 @@
             conn = await self._getconn_unchecked(deadline - monotonic())
             try:
                 await self._check_connection(conn)
-            except CLIENT_EXCEPTIONS:
+            except Exception:
                 await self._putconn(conn, from_getconn=True)
+            except BaseException:
+                # Cancellation, KeyboardInterrupt etc.: don't lose the
+                # connection, but don't try again either.
+                await self._putconn(conn, from_getconn=True)
+                raise
             else:
                 logger.info("connection given by %r", self.name)
                 return conn
@@ -298,6 +307,8 @@
             try:
                 conn = await pos.wait(timeout=timeout)
             except CLIENT_EXCEPTIONS:
+                if pos.conn:
+                    self.run_task(ReturnConnection(self, pos.conn, 
from_getconn=True))
                 self._stats[self._REQUESTS_ERRORS] += 1
                 raise
             finally:
@@ -416,8 +427,9 @@
         because the pool was initialized with *open* = `!True`) but you cannot
         currently re-open a closed pool.
         """
-        # Make sure the lock is created after there is an event loop
-        self._ensure_lock()
+        if True:  # ASYNC
+            # Make sure the lock is created after there is an event loop
+            self._ensure_lock()
 
         async with self._lock:
             self._open()
@@ -431,8 +443,10 @@
 
         self._check_open()
 
-        # A lock has been most likely, but not necessarily, created in 
`open()`.
-        self._ensure_lock()
+        if True:  # ASYNC
+            # A lock has been most likely, but not necessarily, created
+            # in `open()`. The sync pool creates it in `__init__()`.
+            self._ensure_lock()
 
         # Create these objects now to attach them to the right loop.
         # See #219
@@ -445,12 +459,16 @@
         self._start_workers()
         self._start_initial_tasks()
 
-    def _ensure_lock(self) -> None:
-        """Make sure the pool lock is created.
+    if True:  # ASYNC
+
+        def _ensure_lock(self) -> None:
+            """Make sure the pool lock is created and the loop is running."""
+            try:
+                self._lock
+                return
+            except AttributeError:
+                pass
 
-        In async code, also make sure that the loop is running.
-        """
-        if True:  # ASYNC
             try:
                 asyncio.get_running_loop()
             except RuntimeError:
@@ -458,9 +476,6 @@
                     f"{type(self).__name__} open with no running loop"
                 ) from None
 
-        try:
-            self._lock
-        except AttributeError:
             self._lock = ALock()
 
     def _start_workers(self) -> None:
@@ -622,13 +637,17 @@
                 try:
                     await conn.execute("")
                 finally:
-                    await conn.set_autocommit(False)
+                    # Avoid clobbering an exception if the connection is closed
+                    with suppress(Exception):
+                        await conn.set_autocommit(False)
             else:
                 conn.autocommit = True
                 try:
                     conn.execute("")
                 finally:
-                    conn.autocommit = False
+                    # Avoid clobbering an exception if the connection is closed
+                    with suppress(Exception):
+                        conn.autocommit = False
 
     async def reconnect_failed(self) -> None:
         """
@@ -957,11 +976,11 @@
                 except CLIENT_EXCEPTIONS as ex:
                     self.error = ex
 
-        if self.conn:
-            return self.conn
-        else:
-            assert self.error
+        if self.error:
             raise self.error
+        else:
+            assert self.conn
+            return self.conn
 
     async def set(self, conn: ACT) -> bool:
         """Signal the client waiting that a connection is ready.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg_pool-3.3.0/psycopg_pool.egg-info/PKG-INFO 
new/psycopg_pool-3.3.3/psycopg_pool.egg-info/PKG-INFO
--- old/psycopg_pool-3.3.0/psycopg_pool.egg-info/PKG-INFO       2025-12-01 
04:37:42.000000000 +0100
+++ new/psycopg_pool-3.3.3/psycopg_pool.egg-info/PKG-INFO       2026-09-22 
17:50:41.952676500 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: psycopg-pool
-Version: 3.3.0
+Version: 3.3.3
 Summary: Connection Pool for Psycopg
 Author-email: Daniele Varrazzo <[email protected]>
 License-Expression: LGPL-3.0-only
@@ -21,6 +21,7 @@
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
 Classifier: Programming Language :: Python :: 3.14
+Classifier: Programming Language :: Python :: 3.15
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: Topic :: Database
@@ -33,7 +34,7 @@
 Requires-Dist: typing-extensions>=4.6
 Provides-Extra: test
 Requires-Dist: anyio>=4.0; extra == "test"
-Requires-Dist: mypy>=1.14; extra == "test"
+Requires-Dist: mypy>=2.1.0; extra == "test"
 Requires-Dist: pproxy>=2.7; extra == "test"
 Requires-Dist: pytest>=6.2.5; extra == "test"
 Requires-Dist: pytest-cov>=3.0; extra == "test"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/psycopg_pool-3.3.0/psycopg_pool.egg-info/requires.txt 
new/psycopg_pool-3.3.3/psycopg_pool.egg-info/requires.txt
--- old/psycopg_pool-3.3.0/psycopg_pool.egg-info/requires.txt   2025-12-01 
04:37:42.000000000 +0100
+++ new/psycopg_pool-3.3.3/psycopg_pool.egg-info/requires.txt   2026-09-22 
17:50:41.953518600 +0200
@@ -2,7 +2,7 @@
 
 [test]
 anyio>=4.0
-mypy>=1.14
+mypy>=2.1.0
 pproxy>=2.7
 pytest>=6.2.5
 pytest-cov>=3.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/psycopg_pool-3.3.0/pyproject.toml 
new/psycopg_pool-3.3.3/pyproject.toml
--- old/psycopg_pool-3.3.0/pyproject.toml       2025-12-01 04:37:38.000000000 
+0100
+++ new/psycopg_pool-3.3.3/pyproject.toml       2026-09-22 17:50:38.591236000 
+0200
@@ -7,7 +7,7 @@
 description = "Connection Pool for Psycopg"
 
 # STOP AND READ! if you change:
-version = "3.3.0"
+version = "3.3.3"
 # also change:
 # - `docs/news_pool.rst` to declare this version current or unreleased
 
@@ -25,6 +25,7 @@
     "Programming Language :: Python :: 3.12",
     "Programming Language :: Python :: 3.13",
     "Programming Language :: Python :: 3.14",
+    "Programming Language :: Python :: 3.15",
     "Programming Language :: Python :: Implementation :: CPython",
     "Programming Language :: Python :: Implementation :: PyPy",
     "Topic :: Database",
@@ -56,7 +57,7 @@
 [project.optional-dependencies]
 test = [
     "anyio >= 4.0",
-    "mypy >= 1.14",
+    "mypy >= 2.1.0",
     "pproxy >= 2.7",
     "pytest >= 6.2.5",
     "pytest-cov >= 3.0",

Reply via email to