- 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)
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
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:
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")
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()
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")
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()