From: Daniele Varrazzo Date: Tue, 1 Aug 2023 11:34:01 +0000 (+0100) Subject: fix: raise an error instead of a warning using nextset in pipeline mode X-Git-Tag: pool-3.2.0~74^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=98f344f0b50a0ae1575cbe277411cea082e63b0b;p=thirdparty%2Fpsycopg.git fix: raise an error instead of a warning using nextset in pipeline mode Note: the tests, intentionally, don't pass, because they expects execute() results to clobber the previous ones rather than accumulating. This behaviour is to be changed in a further commit. See #604. --- diff --git a/docs/news.rst b/docs/news.rst index 5a7a2afe8..e3e4b09e3 100644 --- a/docs/news.rst +++ b/docs/news.rst @@ -15,6 +15,9 @@ Psycopg 3.2 (unreleased) - Add support for libpq functions to close prepared statements and portals introduced in libpq v17 (:ticket:`#603`). +- Disable receiving more than one result on the same cursor in pipeline mode, + to iterate through `~Cursor.nextset()`. The behaviour was different than + in non-pipeline mode and not totally reliable (:ticket:`#604`). Psycopg 3.1.10 (unreleased) diff --git a/psycopg/psycopg/cursor.py b/psycopg/psycopg/cursor.py index 3b7182a25..356e94018 100644 --- a/psycopg/psycopg/cursor.py +++ b/psycopg/psycopg/cursor.py @@ -9,7 +9,6 @@ from types import TracebackType from typing import Any, Generic, Iterable, Iterator, List from typing import Optional, NoReturn, Sequence, Tuple, Type, TypeVar from typing import overload, TYPE_CHECKING -from warnings import warn from contextlib import contextmanager from . import pq @@ -157,16 +156,17 @@ class BaseCursor(Generic[ConnectionType, Row]): Return `!True` if a new result is available, which will be the one methods `!fetch*()` will operate on. """ - # Raise a warning if people is calling nextset() in pipeline mode - # after a sequence of execute() in pipeline mode. Pipeline accumulating - # execute() results in the cursor is an unintended difference w.r.t. - # non-pipeline mode. + # Python 3.1 would accumulate execute() results in the cursor, but it + # was an undesired difference with non-pipeline mode, so it was + # deprecated in 3.1.10; in 3.2 we moved to clobber previous execute() + # results and, because running multiple statements in the same + # execute() is not supported in pipeline mode, there is no reason to + # support nextset(). This error replaces the previous warning. if self._execmany_returning is None and self._conn._pipeline: - warn( + raise e.NotSupportedError( "using nextset() in pipeline mode for several execute() is" - " deprecated and will be dropped in 3.2; please use different" - " cursors to receive more than one result", - DeprecationWarning, + " not supported. Please use several cursors to receive more" + " than one result" ) if self._iresult < len(self._results) - 1: diff --git a/tests/test_pipeline.py b/tests/test_pipeline.py index 12180bdeb..77c3c6f7c 100644 --- a/tests/test_pipeline.py +++ b/tests/test_pipeline.py @@ -595,7 +595,7 @@ def test_concurrency(conn): assert after > before -def test_execute_nextset_warning(conn): +def test_execute_nextset_error(conn): cur = conn.cursor() cur.execute("select 1") cur.execute("select 2") @@ -608,8 +608,6 @@ def test_execute_nextset_warning(conn): cur.execute("select 1") cur.execute("select 2") - # WARNING: this behavior is unintentional and will be changed in 3.2 - assert cur.fetchall() == [(1,)] - with pytest.warns(DeprecationWarning, match="nextset"): - assert cur.nextset() assert cur.fetchall() == [(2,)] + with pytest.raises(psycopg.NotSupportedError, match="nextset"): + assert cur.nextset() diff --git a/tests/test_pipeline_async.py b/tests/test_pipeline_async.py index 484cce4dc..c578618fd 100644 --- a/tests/test_pipeline_async.py +++ b/tests/test_pipeline_async.py @@ -603,7 +603,7 @@ async def test_concurrency(aconn): assert after > before -async def test_execute_nextset_warning(aconn): +async def test_execute_nextset_error(aconn): cur = aconn.cursor() await cur.execute("select 1") await cur.execute("select 2") @@ -616,8 +616,6 @@ async def test_execute_nextset_warning(aconn): await cur.execute("select 1") await cur.execute("select 2") - # WARNING: this behavior is unintentional and will be changed in 3.2 - assert (await cur.fetchall()) == [(1,)] - with pytest.warns(DeprecationWarning, match="nextset"): - assert cur.nextset() assert (await cur.fetchall()) == [(2,)] + with pytest.raises(psycopg.NotSupportedError, match="nextset"): + assert cur.nextset()