diff --git a/NEWS b/NEWS index 616b3276..1c6b4398 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ What's new in psycopg 2.7.5 (:ticket:`#677`). - Maybe fixed building on MSYS2 (as reported in :ticket:`#658`). - Allow string subclasses in connection and other places (:ticket:`#679`). +- Don't raise an exception closing an unused named cursor (:ticket:`#716`). What's new in psycopg 2.7.4 diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c index b7fd1870..d73bc3a4 100644 --- a/psycopg/cursor_type.c +++ b/psycopg/cursor_type.c @@ -59,6 +59,11 @@ psyco_curs_close(cursorObject *self) char buffer[128]; PGTransactionStatusType status; + if (!self->query) { + Dprintf("skipping named cursor close because unused"); + goto close; + } + if (self->conn) { status = PQtransactionStatus(self->conn->pgconn); } @@ -66,17 +71,18 @@ psyco_curs_close(cursorObject *self) status = PQTRANS_UNKNOWN; } - if (!(status == PQTRANS_UNKNOWN || status == PQTRANS_INERROR)) { - EXC_IF_NO_MARK(self); - PyOS_snprintf(buffer, 127, "CLOSE %s", self->qname); - if (pq_execute(self, buffer, 0, 0, 1) == -1) return NULL; - } - else { + if (status == PQTRANS_UNKNOWN || status == PQTRANS_INERROR) { Dprintf("skipping named curs close because tx status %d", (int)status); + goto close; } + + EXC_IF_NO_MARK(self); + PyOS_snprintf(buffer, 127, "CLOSE %s", self->qname); + if (pq_execute(self, buffer, 0, 0, 1) == -1) return NULL; } +close: self->closed = 1; Dprintf("psyco_curs_close: cursor at %p closed", self); diff --git a/tests/test_cursor.py b/tests/test_cursor.py index 76646160..d9dea0c5 100755 --- a/tests/test_cursor.py +++ b/tests/test_cursor.py @@ -443,6 +443,11 @@ class CursorTests(ConnectingTestCase): self.assertEqual([(2,), (3,), (4,)], cur2.fetchmany(3)) self.assertEqual([(5,), (6,), (7,)], cur2.fetchall()) + @skip_before_postgres(8, 0) + def test_named_noop_close(self): + cur = self.conn.cursor('test') + cur.close() + @skip_before_postgres(8, 0) def test_scroll(self): cur = self.conn.cursor() diff --git a/tests/test_with.py b/tests/test_with.py index e5c0bc23..29b7e860 100755 --- a/tests/test_with.py +++ b/tests/test_with.py @@ -28,7 +28,7 @@ from __future__ import with_statement import psycopg2 import psycopg2.extensions as ext -from testutils import unittest, ConnectingTestCase +from testutils import unittest, ConnectingTestCase, skip_before_postgres class WithTestCase(ConnectingTestCase): @@ -217,6 +217,11 @@ class WithCursorTestCase(WithTestCase): else: self.fail("where is my exception?") + @skip_before_postgres(8, 0) + def test_named_with_noop(self): + with self.conn.cursor('named') as cur: + pass + def test_suite(): return unittest.TestLoader().loadTestsFromName(__name__)