Dropped quirks in connection arguments handling

Now connect() raises an exception instead of swallowing keyword arguments
when a connection string is specified as well

Closes ticket #131.
This commit is contained in:
Daniele Varrazzo 2012-09-25 23:46:46 +01:00
parent 59151886a0
commit cd316a94f1
3 changed files with 36 additions and 26 deletions

2
NEWS
View File

@ -13,6 +13,8 @@ What's new in psycopg 2.4.6
Thanks to Manu Cupcic for the report (ticket #110). Thanks to Manu Cupcic for the report (ticket #110).
- 'register_hstore()', 'register_composite()', 'tpc_recover()' work with - 'register_hstore()', 'register_composite()', 'tpc_recover()' work with
RealDictConnection and Cursor (ticket #114). RealDictConnection and Cursor (ticket #114).
- connect() raises an exception instead of swallowing keyword arguments
when a connection string is specified as well (ticket #131).
- 'errorcodes' map updated to PostgreSQL 9.2. - 'errorcodes' map updated to PostgreSQL 9.2.

View File

@ -146,13 +146,9 @@ def connect(dsn=None,
Using *async*=True an asynchronous connection will be created. Using *async*=True an asynchronous connection will be created.
Any other keyword parameter will be passed to the underlying client Any other keyword parameter will be passed to the underlying client
library: the list of supported parameter depends on the library version. library: the list of supported parameters depends on the library version.
""" """
if dsn is None:
# Note: reproducing the behaviour of the previous C implementation:
# keyword are silently swallowed if a DSN is specified. I would have
# raised an exception. File under "histerical raisins".
items = [] items = []
if database is not None: if database is not None:
items.append(('dbname', database)) items.append(('dbname', database))
@ -162,21 +158,25 @@ def connect(dsn=None,
items.append(('password', password)) items.append(('password', password))
if host is not None: if host is not None:
items.append(('host', host)) items.append(('host', host))
# Reproducing the previous C implementation behaviour: swallow a if port is not None:
# negative port. The libpq would raise an exception for it.
if port is not None and int(port) > 0:
items.append(('port', port)) items.append(('port', port))
items.extend( items.extend([(k, v) for (k, v) in kwargs.iteritems() if v is not None])
[(k, v) for (k, v) in kwargs.iteritems() if v is not None])
if dsn is not None and items:
raise InterfaceError(
"you cannot specify keyword arguments (%s)"
" together with a connection string"
% ", ".join([k for k, v in items]))
if dsn is None:
if not items:
raise InterfaceError('missing dsn and no parameters')
else:
dsn = " ".join(["%s=%s" % (k, _param_escape(str(v))) dsn = " ".join(["%s=%s" % (k, _param_escape(str(v)))
for (k, v) in items]) for (k, v) in items])
if not dsn: return _connect(dsn, connection_factory=connection_factory, async=async)
raise InterfaceError('missing dsn and no parameters')
return _connect(dsn,
connection_factory=connection_factory, async=async)
__all__ = filter(lambda k: not k.startswith('_'), locals().keys()) __all__ = filter(lambda k: not k.startswith('_'), locals().keys())

View File

@ -127,6 +127,14 @@ class ConnectTestCase(unittest.TestCase):
psycopg2.connect(database=r"\every thing'") psycopg2.connect(database=r"\every thing'")
self.assertEqual(self.args[0], r"dbname='\\every thing\''") self.assertEqual(self.args[0], r"dbname='\\every thing\''")
def test_no_kwargs_swallow(self):
self.assertRaises(psycopg2.InterfaceError,
psycopg2.connect, 'dbname=foo', database='foo')
self.assertRaises(psycopg2.InterfaceError,
psycopg2.connect, 'dbname=foo', user='postgres')
self.assertRaises(psycopg2.InterfaceError,
psycopg2.connect, 'dbname=foo', no_such_param='meh')
class ExceptionsTestCase(unittest.TestCase): class ExceptionsTestCase(unittest.TestCase):
def setUp(self): def setUp(self):