diff -r 6446fc0a0a99 Lib/test/test_urlparse.py --- a/Lib/test/test_urlparse.py Sat Jul 16 23:56:45 2011 +0200 +++ b/Lib/test/test_urlparse.py Sun Jul 17 21:14:37 2011 -0700 @@ -94,7 +94,10 @@ for orig, expect in parse_qsl_test_cases: result = urllib.parse.parse_qsl(orig, keep_blank_values=True) self.assertEqual(result, expect, "Error parsing %s" % repr(orig)) - + expect_without_blanks = [v for v in expect if len(v[1])] + result = urllib.parse.parse_qsl(orig, keep_blank_values=False) + self.assertEqual(result, expect_without_blanks, + "Error parsing %s" % repr(orig)) def test_roundtrips(self): str_cases = [ @@ -365,6 +368,9 @@ self.checkJoin(SIMPLE_BASE, 'http:?y','http://a/b/c/d?y') self.checkJoin(SIMPLE_BASE, 'http:g?y','http://a/b/c/g?y') self.checkJoin(SIMPLE_BASE, 'http:g?y/./x','http://a/b/c/g?y/./x') + self.checkJoin('http:///', '..','http:///') + self.checkJoin('', 'http://a/b/c/g?y/./x','http://a/b/c/g?y/./x') + self.checkJoin('', 'http://a/./g', 'http://a/./g') def test_RFC2732(self): str_cases = [ @@ -719,6 +725,69 @@ errors="ignore") self.assertEqual(result, [('key', '\u0141-')]) + def test_splitnport(self): + result = urllib.parse.splitnport('parrot:88') + self.assertEqual(result, ('parrot', 88)) + result = urllib.parse.splitnport('parrot') + self.assertEqual(result, ('parrot', -1)) + result = urllib.parse.splitnport('parrot', 55) + self.assertEqual(result, ('parrot', 55)) + result = urllib.parse.splitnport('parrot:') + self.assertEqual(result, ('parrot', None)) + + def test_splitquery(self): + result = urllib.parse.splitquery('http://python.org/fake?foo=bar') + self.assertEqual(result, ('http://python.org/fake', 'foo=bar')) + result = urllib.parse.splitquery('http://python.org/fake?foo=bar?') + self.assertEqual(result, ('http://python.org/fake?foo=bar', '')) + result = urllib.parse.splitquery('http://python.org/fake') + self.assertEqual(result, ('http://python.org/fake', None)) + + def test_splitvalue(self): + result = urllib.parse.splitvalue('foo=bar') + self.assertEqual(result, ('foo', 'bar')) + result = urllib.parse.splitvalue('foo=') + self.assertEqual(result, ('foo', '')) + result = urllib.parse.splitvalue('foobar') + self.assertEqual(result, ('foobar', None)) + + def test_to_bytes(self): + result = urllib.parse.to_bytes('http://www.python.org') + self.assertEqual(result, 'http://www.python.org') + self.assertRaises(UnicodeError, urllib.parse.to_bytes, + 'http://www.python.org/mediƦval') + + def test_urlencode_sequences(self): + result = urllib.parse.urlencode({'a': [1, 2], 'b': (3, 4, 5)}, True) + self.assertEqual(result, 'a=1&a=2&b=3&b=4&b=5') + class Trivial(object): + def __str__(self): + return 'trivial' + result = urllib.parse.urlencode({'a': Trivial()}, True) + self.assertEqual(result, 'a=trivial') + + def test_quote_from_bytes(self): + self.assertRaises(TypeError, urllib.parse.quote_from_bytes, 'foo') + result = urllib.parse.quote_from_bytes(b'archaeological arcana') + self.assertEqual(result, 'archaeological%20arcana') + result = urllib.parse.quote_from_bytes(b'') + self.assertEqual(result, '') + + def test_unquote_to_bytes(self): + result = urllib.parse.unquote_to_bytes('abc%20def') + self.assertEqual(result, b'abc def') + result = urllib.parse.unquote_to_bytes('') + self.assertEqual(result, b'') + + def test_quote_errors(self): + self.assertRaises(TypeError, urllib.parse.quote, b'foo', + encoding='utf-8') + self.assertRaises(TypeError, urllib.parse.quote, b'foo', errors='strict') + + def test_quoter_repr(self): + quoter = urllib.parse.Quoter(b'') + result = repr(quoter) + self.assertEqual(result, '') def test_main(): diff -r 6446fc0a0a99 Lib/urllib/parse.py --- a/Lib/urllib/parse.py Sat Jul 16 23:56:45 2011 +0200 +++ b/Lib/urllib/parse.py Sun Jul 17 21:14:37 2011 -0700 @@ -790,21 +790,16 @@ v = quote_plus(v, safe, encoding, errors) l.append(k + '=' + v) else: - try: - # Is this a sufficient test for sequence-ness? - x = len(v) - except TypeError: - # not a sequence - v = quote_plus(str(v), safe, encoding, errors) - l.append(k + '=' + v) - else: - # loop over the sequence + if isinstance(v, collections.Iterable): for elt in v: if isinstance(elt, bytes): elt = quote_plus(elt, safe) else: elt = quote_plus(str(elt), safe, encoding, errors) l.append(k + '=' + elt) + else: + v = quote_plus(str(v), safe, encoding, errors) + l.append(k + '=' + v) return '&'.join(l) # Utilities to parse URLs (most of these return None for missing parts):