]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Remove the pgresult structure from the cursor on close
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 25 Oct 2021 08:59:09 +0000 (09:59 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 25 Oct 2021 10:57:52 +0000 (11:57 +0100)
This is what the dbapi demands and helps with make the cursor
unavailable after close.

psycopg/psycopg/cursor.py
tests/test_cursor.py
tests/test_cursor_async.py
tests/test_server_cursor.py
tests/test_server_cursor_async.py

index 36d50fd0ff1243b04f5c90171c25e1f17e5c631f..cbc1dda9700746f924945c3813d741c9f177a88d 100644 (file)
@@ -73,13 +73,15 @@ class BaseCursor(Generic[ConnectionType, Row]):
         self._last_query: Optional[Query] = None
         self._reset()
 
-    def _reset(self) -> None:
+    def _reset(self, reset_query: bool = True) -> None:
         self._results: List["PGresult"] = []
         self.pgresult: Optional["PGresult"] = None
         self._pos = 0
         self._iresult = 0
         self._rowcount = -1
-        self._query: Optional[PostgresQuery] = None
+        self._query: Optional[PostgresQuery]
+        if reset_query:
+            self._query = None
 
     def __repr__(self) -> str:
         cls = f"{self.__class__.__module__}.{self.__class__.__qualname__}"
@@ -490,6 +492,10 @@ class BaseCursor(Generic[ConnectionType, Row]):
         self._pos = newpos
 
     def _close(self) -> None:
+        """Non-blocking part of closing. Common to sync/async."""
+        # Don't reset the query because it may be useful to investigate after
+        # an error.
+        self._reset(reset_query=False)
         self._closed = True
 
 
index eab60206facf4eed9dc54c53b192c4307d466563..a72b617fec43d979d3e0cf07f85e25e649116dca 100644 (file)
@@ -42,6 +42,14 @@ def test_weakref(conn):
     assert w() is None
 
 
+def test_pgresult(conn):
+    cur = conn.cursor()
+    cur.execute("select 1")
+    assert cur.pgresult
+    cur.close()
+    assert not cur.pgresult
+
+
 def test_statusmessage(conn):
     cur = conn.cursor()
     assert cur.statusmessage is None
@@ -274,9 +282,6 @@ def test_rowcount(conn):
     )
     assert cur.rowcount == 42
 
-    cur.close()
-    assert cur.rowcount == 42
-
 
 def test_rownumber(conn):
     cur = conn.cursor()
index 3aaa4356049b5f2c17e441d28d3552819b292aaf..7f297ab5490c585ebb9a6e7cf2aef1738bb9ee8f 100644 (file)
@@ -42,6 +42,14 @@ async def test_weakref(aconn):
     assert w() is None
 
 
+async def test_pgresult(aconn):
+    cur = aconn.cursor()
+    await cur.execute("select 1")
+    assert cur.pgresult
+    await cur.close()
+    assert not cur.pgresult
+
+
 async def test_statusmessage(aconn):
     cur = aconn.cursor()
     assert cur.statusmessage is None
@@ -276,9 +284,6 @@ async def test_rowcount(aconn):
     )
     assert cur.rowcount == 42
 
-    await cur.close()
-    assert cur.rowcount == 42
-
 
 async def test_rownumber(aconn):
     cur = aconn.cursor()
index 132fa1a93e1cd106584c3a731bb8d444f1447d9e..6686621d66f61d49c515c29cfd31929ed18d474f 100644 (file)
@@ -138,6 +138,14 @@ def test_close_on_error(conn):
     cur.close()
 
 
+def test_pgresult(conn):
+    cur = conn.cursor()
+    cur.execute("select 1")
+    assert cur.pgresult
+    cur.close()
+    assert not cur.pgresult
+
+
 def test_context(conn, recwarn, retries):
     for retry in retries:
         with retry:
index d240ac39d3ccfa76fe2df220de99bbde184f556f..a2b5486e1e03c036d11774264c0e24a2b7d4a335 100644 (file)
@@ -145,6 +145,14 @@ async def test_close_on_error(aconn):
     await cur.close()
 
 
+async def test_pgresult(aconn):
+    cur = aconn.cursor()
+    await cur.execute("select 1")
+    assert cur.pgresult
+    await cur.close()
+    assert not cur.pgresult
+
+
 async def test_context(aconn, recwarn, retries):
     async for retry in retries:
         with retry: