From c4da939909ea9bef99bcdef805b68dca6131eac0 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Sun, 20 May 2018 13:56:59 +0100 Subject: [PATCH] Don't raise an exception closing an unused named cursor Close #716 --- NEWS | 1 + psycopg/cursor_type.c | 18 ++++++++++++------ tests/test_cursor.py | 5 +++++ tests/test_with.py | 7 ++++++- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 5dc4ae04..cb1b5813 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,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 cc8db0f4..b3e03d9b 100755 --- a/tests/test_cursor.py +++ b/tests/test_cursor.py @@ -435,6 +435,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 1392d85f..f26f8f9c 100755 --- a/tests/test_with.py +++ b/tests/test_with.py @@ -26,7 +26,7 @@ import psycopg2 import psycopg2.extensions as ext import unittest -from .testutils import ConnectingTestCase +from .testutils import ConnectingTestCase, skip_before_postgres class WithTestCase(ConnectingTestCase): @@ -215,6 +215,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__)