close() methods don't raise errors if called on closed objects

This commit is contained in:
Daniele Varrazzo 2012-03-04 05:03:15 +00:00
parent 2cbedbee45
commit 84f2a370f6
6 changed files with 26 additions and 7 deletions

2
NEWS
View File

@ -1,6 +1,8 @@
What's new in psycopg 2.4.5
---------------------------
- The close() methods on connections and cursors don't raise exceptions
if called on already closed objects.
- Fixed fetchmany() with no argument in cursor subclasses
(ticket #84).
- Use lo_creat() instead of lo_create() when possible for better

View File

@ -906,6 +906,10 @@ conn_poll(connectionObject *self)
void
conn_close(connectionObject *self)
{
if (self->closed) {
return;
}
/* sets this connection as closed even for other threads; also note that
we need to check the value of pgconn, because we get called even when
the connection fails! */
@ -922,14 +926,13 @@ conn_close(connectionObject *self)
* closed only in status CONN_STATUS_READY.
*/
if (self->closed == 0)
self->closed = 1;
self->closed = 1;
if (self->pgconn) {
PQfinish(self->pgconn);
PQfreeCancel(self->cancel);
Dprintf("conn_close: PQfinish called");
self->pgconn = NULL;
Dprintf("conn_close: PQfinish called");
PQfreeCancel(self->cancel);
self->cancel = NULL;
}

View File

@ -122,8 +122,6 @@ psyco_conn_cursor(connectionObject *self, PyObject *args, PyObject *keywds)
static PyObject *
psyco_conn_close(connectionObject *self, PyObject *args)
{
EXC_IF_CONN_CLOSED(self);
Dprintf("psyco_conn_close: closing connection at %p", self);
conn_close(self);
Dprintf("psyco_conn_close: connection at %p closed", self);

View File

@ -52,9 +52,12 @@ extern PyObject *pyPsycopgTzFixedOffsetTimezone;
static PyObject *
psyco_curs_close(cursorObject *self, PyObject *args)
{
EXC_IF_CURS_CLOSED(self);
EXC_IF_ASYNC_IN_PROGRESS(self, close);
if (self->closed) {
goto exit;
}
if (self->name != NULL) {
char buffer[128];
@ -66,6 +69,7 @@ psyco_curs_close(cursorObject *self, PyObject *args)
self->closed = 1;
Dprintf("psyco_curs_close: cursor at %p closed", self);
exit:
Py_INCREF(Py_None);
return Py_None;
}

View File

@ -48,6 +48,12 @@ class ConnectionTests(unittest.TestCase):
conn.close()
self.assertEqual(conn.closed, True)
def test_close_idempotent(self):
conn = self.conn
conn.close()
conn.close()
self.assert_(conn.closed)
def test_cursor_closed_attribute(self):
conn = self.conn
curs = conn.cursor()

View File

@ -37,6 +37,12 @@ class CursorTests(unittest.TestCase):
def tearDown(self):
self.conn.close()
def test_close_idempotent(self):
cur = self.conn.cursor()
cur.close()
cur.close()
self.assert_(cur.closed)
def test_empty_query(self):
cur = self.conn.cursor()
self.assertRaises(psycopg2.ProgrammingError, cur.execute, "")