mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-22 17:06:33 +03:00
Don't try to close the server cursor in error state
`close()` is implicitly called by `__exit__()`, so an exit on error would run a query on a inerr connection, causing another exception hiding the original one. The fix is on `close()`, not on `__exit__()`, because the semantic of the latter is simply to call the former. Closes #262.
This commit is contained in:
parent
d6688b6689
commit
e3c6b46416
7
NEWS
7
NEWS
|
@ -1,6 +1,13 @@
|
||||||
Current release
|
Current release
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
What's new in psycopg 2.5.5
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
- Named cursors used as context manager don't swallow the exception on exit
|
||||||
|
(:ticket:`#262`).
|
||||||
|
|
||||||
|
|
||||||
What's new in psycopg 2.5.4
|
What's new in psycopg 2.5.4
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -57,11 +57,25 @@ psyco_curs_close(cursorObject *self)
|
||||||
|
|
||||||
if (self->name != NULL) {
|
if (self->name != NULL) {
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
|
PGTransactionStatusType status;
|
||||||
|
|
||||||
|
if (self->conn) {
|
||||||
|
status = PQtransactionStatus(self->conn->pgconn);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
status = PQTRANS_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(status == PQTRANS_UNKNOWN || status == PQTRANS_INERROR)) {
|
||||||
EXC_IF_NO_MARK(self);
|
EXC_IF_NO_MARK(self);
|
||||||
PyOS_snprintf(buffer, 127, "CLOSE \"%s\"", self->name);
|
PyOS_snprintf(buffer, 127, "CLOSE \"%s\"", self->name);
|
||||||
if (pq_execute(self, buffer, 0, 0, 1) == -1) return NULL;
|
if (pq_execute(self, buffer, 0, 0, 1) == -1) return NULL;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Dprintf("skipping named curs close because tx status %d",
|
||||||
|
(int)status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self->closed = 1;
|
self->closed = 1;
|
||||||
Dprintf("psyco_curs_close: cursor at %p closed", self);
|
Dprintf("psyco_curs_close: cursor at %p closed", self);
|
||||||
|
|
|
@ -200,6 +200,18 @@ class WithCursorTestCase(WithTestCase):
|
||||||
self.assert_(curs.closed)
|
self.assert_(curs.closed)
|
||||||
self.assert_(closes)
|
self.assert_(closes)
|
||||||
|
|
||||||
|
def test_exception_swallow(self):
|
||||||
|
# bug #262: __exit__ calls cur.close() that hides the exception
|
||||||
|
# with another error.
|
||||||
|
try:
|
||||||
|
with self.conn as conn:
|
||||||
|
with conn.cursor('named') as cur:
|
||||||
|
cur.execute("select 1/0")
|
||||||
|
except psycopg2.DataError, e:
|
||||||
|
self.assertEqual(e.pgcode, '22012')
|
||||||
|
else:
|
||||||
|
self.fail("where is my exception?")
|
||||||
|
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user