summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-10-23 15:02:36 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2013-10-23 15:02:36 -0400
commit382cd56772efd92a9fe5ce46623029a04163c8cf (patch)
treec7f50d1add74e1b87f6e608be93f8a4047b5139c
parent0e7a82304a15e15f2d9de5202aea6b554af76991 (diff)
downloadsqlalchemy-382cd56772efd92a9fe5ce46623029a04163c8cf.tar.gz
- The regexp used by the :func:`.url.make_url` function now parses
ipv6 addresses, e.g. surrounded by brackets. [ticket:2851]
-rw-r--r--doc/build/changelog/changelog_07.rst8
-rw-r--r--lib/sqlalchemy/engine/url.py13
-rw-r--r--test/engine/test_parseconnect.py31
3 files changed, 38 insertions, 14 deletions
diff --git a/doc/build/changelog/changelog_07.rst b/doc/build/changelog/changelog_07.rst
index 3a46580db..f658a7d87 100644
--- a/doc/build/changelog/changelog_07.rst
+++ b/doc/build/changelog/changelog_07.rst
@@ -7,6 +7,14 @@
:version: 0.7.11
.. change::
+ :tags: bug, engine
+ :tickets: 2851
+ :versions: 0.8.3, 0.9.0
+
+ The regexp used by the :func:`.url.make_url` function now parses
+ ipv6 addresses, e.g. surrounded by brackets.
+
+ .. change::
:tags: bug, orm
:tickets: 2807
:versions: 0.8.3, 0.9.0
diff --git a/lib/sqlalchemy/engine/url.py b/lib/sqlalchemy/engine/url.py
index 1f192ae7f..74584b787 100644
--- a/lib/sqlalchemy/engine/url.py
+++ b/lib/sqlalchemy/engine/url.py
@@ -71,7 +71,10 @@ class URL(object):
else util.quote_plus(self.password))
s += "@"
if self.host is not None:
- s += self.host
+ if ':' in self.host:
+ s += "[%s]" % self.host
+ else:
+ s += self.host
if self.port is not None:
s += ':' + str(self.port)
if self.database is not None:
@@ -170,7 +173,10 @@ def _parse_rfc1738_args(name):
(?::(?P<password>[^/]*))?
@)?
(?:
- (?P<host>[^/:]*)
+ (?:
+ \[(?P<ipv6host>[^/]+)\] |
+ (?P<ipv4host>[^/:]+)
+ )?
(?::(?P<port>[^/]*))?
)?
(?:/(?P<database>.*))?
@@ -193,6 +199,9 @@ def _parse_rfc1738_args(name):
components['password'] = \
util.unquote_plus(components['password'])
+ ipv4host = components.pop('ipv4host')
+ ipv6host = components.pop('ipv6host')
+ components['host'] = ipv4host or ipv6host
name = components.pop('name')
return URL(name, **components)
else:
diff --git a/test/engine/test_parseconnect.py b/test/engine/test_parseconnect.py
index f56c844f0..07ce96d5e 100644
--- a/test/engine/test_parseconnect.py
+++ b/test/engine/test_parseconnect.py
@@ -15,6 +15,7 @@ class ParseConnectTest(fixtures.TestBase):
for text in (
'dbtype://username:password@hostspec:110//usr/db_file.db',
'dbtype://username:password@hostspec/database',
+ 'dbtype+apitype://username:password@hostspec/database',
'dbtype://username:password@hostspec',
'dbtype://username:password@/database',
'dbtype://username@hostspec',
@@ -22,25 +23,31 @@ class ParseConnectTest(fixtures.TestBase):
'dbtype://hostspec/database',
'dbtype://hostspec',
'dbtype://hostspec/?arg1=val1&arg2=val2',
- 'dbtype:///database',
+ 'dbtype+apitype:///database',
'dbtype:///:memory:',
'dbtype:///foo/bar/im/a/file',
'dbtype:///E:/work/src/LEM/db/hello.db',
'dbtype:///E:/work/src/LEM/db/hello.db?foo=bar&hoho=lala',
'dbtype://',
- 'dbtype://username:password@/db',
- 'dbtype:////usr/local/mailman/lists/_xtest@example.com/memb'
- 'ers.db',
- 'dbtype://username:apples%2Foranges@hostspec/mydatabase',
+ 'dbtype://username:password@/database',
+ 'dbtype:////usr/local/_xtest@example.com/members.db',
+ 'dbtype://username:apples%2Foranges@hostspec/database',
+ 'dbtype://username:password@[2001:da8:2004:1000:202:116:160:90]/database?foo=bar',
+ 'dbtype://username:password@[2001:da8:2004:1000:202:116:160:90]:80/database?foo=bar'
):
u = url.make_url(text)
- assert u.drivername == 'dbtype'
- assert u.username == 'username' or u.username is None
- assert u.password == 'password' or u.password \
- == 'apples/oranges' or u.password is None
- assert u.host == 'hostspec' or u.host == '127.0.0.1' \
- or not u.host
- assert str(u) == text
+
+ assert u.drivername in ('dbtype', 'dbtype+apitype')
+ assert u.username in ('username', None)
+ assert u.password in ('password', 'apples/oranges', None)
+ assert u.host in ('hostspec', '127.0.0.1',
+ '2001:da8:2004:1000:202:116:160:90', '', None), u.host
+ assert u.database in ('database',
+ '/usr/local/_xtest@example.com/members.db',
+ '/usr/db_file.db', ':memory:', '',
+ 'foo/bar/im/a/file',
+ 'E:/work/src/LEM/db/hello.db', None), u.database
+ eq_(str(u), text)
class DialectImportTest(fixtures.TestBase):
def test_import_base_dialects(self):