diff --git a/NEWS b/NEWS index d5f1686f..928eedeb 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,8 @@ What's new in psycopg 2.5.3 Chris Withers (:ticket:`#193`). - Avoid blocking async connections on connect (:ticket:`#194`). Thanks to Adam Petrovich for the bug report and diagnosis. +- Fixed handling of dsn and closed attributes in connection subclasses + failing to connect (from :ticket:`#192` discussion). - Don't segfault using poorly defined cursor subclasses which forgot to call the superclass init (:ticket:`#195`). - Fixed debug build on Windows, thanks to James Emerton. diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index c48dc811..aea2841c 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -629,14 +629,23 @@ _conn_async_connect(connectionObject *self) int conn_connect(connectionObject *self, long int async) { - if (async == 1) { + int rv; + + if (async == 1) { Dprintf("con_connect: connecting in ASYNC mode"); - return _conn_async_connect(self); + rv = _conn_async_connect(self); } else { Dprintf("con_connect: connecting in SYNC mode"); - return _conn_sync_connect(self); + rv = _conn_sync_connect(self); } + + if (rv != 0) { + /* connection failed, so let's close ourselves */ + self->closed = 2; + } + + return rv; } diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index b3d4aa63..80ce7fe2 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -1099,6 +1099,7 @@ connection_setup(connectionObject *self, const char *dsn, long int async) res = 0; } +exit: /* here we obfuscate the password even if there was a connection error */ pos = strstr(self->dsn, "password"); if (pos != NULL) { @@ -1106,7 +1107,6 @@ connection_setup(connectionObject *self, const char *dsn, long int async) *pos = 'x'; } -exit: return res; } diff --git a/tests/test_connection.py b/tests/test_connection.py index 26ad9329..b2c51977 100755 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -249,6 +249,18 @@ class ConnectionTests(ConnectingTestCase): cur.execute("select 1 as a") self.assertRaises(TypeError, (lambda r: r['a']), cur.fetchone()) + def test_failed_init_status(self): + class SubConnection(psycopg2.extensions.connection): + def __init__(self, dsn): + try: + super(SubConnection, self).__init__(dsn) + except Exception: + pass + + c = SubConnection("dbname=thereisnosuchdatabasemate password=foobar") + self.assert_(c.closed, "connection failed so it must be closed") + self.assert_('foobar' not in c.dsn, "password was not obscured") + pass class IsolationLevelsTestCase(ConnectingTestCase):