Index: Python-2.6.9/Lib/test/test_urlparse.py
===================================================================
--- Python-2.6.9.orig/Lib/test/test_urlparse.py	2013-10-29 16:04:38.000000000 +0100
+++ Python-2.6.9/Lib/test/test_urlparse.py	2014-05-02 15:05:57.154299247 +0200
@@ -292,6 +292,40 @@
         #self.checkJoin(RFC3986_BASE, 'http:g','http:g') # strict parser
         self.checkJoin(RFC3986_BASE, 'http:g','http://a/b/c/g') #relaxed parser
 
+    def test_RFC2732(self):
+        for url, hostname, port in [
+            ('http://Test.python.org:5432/foo/', 'test.python.org', 5432),
+            ('http://12.34.56.78:5432/foo/', '12.34.56.78', 5432),
+            ('http://[::1]:5432/foo/', '::1', 5432),
+            ('http://[dead:beef::1]:5432/foo/', 'dead:beef::1', 5432),
+            ('http://[dead:beef::]:5432/foo/', 'dead:beef::', 5432),
+            ('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]:5432/foo/',
+             'dead:beef:cafe:5417:affe:8fa3:deaf:feed', 5432),
+            ('http://[::12.34.56.78]:5432/foo/', '::12.34.56.78', 5432),
+            ('http://[::ffff:12.34.56.78]:5432/foo/',
+             '::ffff:12.34.56.78', 5432),
+            ('http://Test.python.org/foo/', 'test.python.org', None),
+            ('http://12.34.56.78/foo/', '12.34.56.78', None),
+            ('http://[::1]/foo/', '::1', None),
+            ('http://[dead:beef::1]/foo/', 'dead:beef::1', None),
+            ('http://[dead:beef::]/foo/', 'dead:beef::', None),
+            ('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/',
+             'dead:beef:cafe:5417:affe:8fa3:deaf:feed', None),
+            ('http://[::12.34.56.78]/foo/', '::12.34.56.78', None),
+            ('http://[::ffff:12.34.56.78]/foo/',
+             '::ffff:12.34.56.78', None),
+            ]:
+            urlparsed = urlparse.urlparse(url)
+            self.assertEqual((urlparsed.hostname, urlparsed.port) , (hostname, port))
+
+        for invalid_url in [
+                'http://::12.34.56.78]/',
+                'http://[::1/foo/',
+                'http://[::1/foo/bad]/bad',
+                'http://[::ffff:12.34.56.78']:
+            self.assertRaises(ValueError, lambda : urlparse.urlparse(invalid_url).hostname)
+            self.assertRaises(ValueError, lambda : urlparse.urlparse(invalid_url))
+
     def test_urljoins(self):
         self.checkJoin(SIMPLE_BASE, 'g:h','g:h')
         self.checkJoin(SIMPLE_BASE, 'http:g','http://a/b/c/g')
Index: Python-2.6.9/Lib/urlparse.py
===================================================================
--- Python-2.6.9.orig/Lib/urlparse.py	2013-10-29 16:04:38.000000000 +0100
+++ Python-2.6.9/Lib/urlparse.py	2014-05-02 15:05:57.154299247 +0200
@@ -85,22 +85,24 @@
 
     @property
     def hostname(self):
-        netloc = self.netloc
-        if "@" in netloc:
-            netloc = netloc.rsplit("@", 1)[1]
-        if ":" in netloc:
-            netloc = netloc.split(":", 1)[0]
-        return netloc.lower() or None
+        netloc = self.netloc.split('@')[-1]
+        if '[' in netloc and ']' in netloc:
+            return netloc.split(']')[0][1:].lower()
+        elif ':' in netloc:
+            return netloc.split(':')[0].lower()
+        elif netloc == '':
+            return None
+        else:
+            return netloc.lower()
 
     @property
     def port(self):
-        netloc = self.netloc
-        if "@" in netloc:
-            netloc = netloc.rsplit("@", 1)[1]
-        if ":" in netloc:
-            port = netloc.split(":", 1)[1]
+        netloc = self.netloc.split('@')[-1].split(']')[-1]
+        if ':' in netloc:
+            port = netloc.split(':')[1]
             return int(port, 10)
-        return None
+        else:
+            return None
 
 from collections import namedtuple
 
@@ -172,6 +174,10 @@
             url = url[i+1:]
             if url[:2] == '//':
                 netloc, url = _splitnetloc(url, 2)
+                if '[' in netloc :
+                    if not ']' in netloc: raise ValueError("Invalid IPv6 URL")
+                if ']' in netloc:
+                    if not '[' in netloc: raise ValueError("Invalid IPv6 URL")
             if allow_fragments and '#' in url:
                 url, fragment = url.split('#', 1)
             if '?' in url:
@@ -187,6 +193,10 @@
 
     if url[:2] == '//':
         netloc, url = _splitnetloc(url, 2)
+        if '[' in netloc:
+            if not ']' in netloc: raise ValueError("Invalid IPv6 URL")
+        if ']' in netloc:
+            if not '[' in netloc: raise ValueError("Invalid IPv6 URL")
     if allow_fragments and scheme in uses_fragment and '#' in url:
         url, fragment = url.split('#', 1)
     if scheme in uses_query and '?' in url:
