Commit aad2ee01 authored by Stein Karlsen's avatar Stein Karlsen Committed by Tal Einat

bpo-32498: urllib.parse.unquote also accepts bytes (GH-7768)

parent 9cb51f4e
...@@ -571,7 +571,7 @@ task isn't already covered by the URL parsing functions above. ...@@ -571,7 +571,7 @@ task isn't already covered by the URL parsing functions above.
percent-encoded sequences into Unicode characters, as accepted by the percent-encoded sequences into Unicode characters, as accepted by the
:meth:`bytes.decode` method. :meth:`bytes.decode` method.
*string* must be a :class:`str`. *string* may be either a :class:`str` or a :class:`bytes`.
*encoding* defaults to ``'utf-8'``. *encoding* defaults to ``'utf-8'``.
*errors* defaults to ``'replace'``, meaning invalid sequences are replaced *errors* defaults to ``'replace'``, meaning invalid sequences are replaced
...@@ -579,6 +579,11 @@ task isn't already covered by the URL parsing functions above. ...@@ -579,6 +579,11 @@ task isn't already covered by the URL parsing functions above.
Example: ``unquote('/El%20Ni%C3%B1o/')`` yields ``'/El Niño/'``. Example: ``unquote('/El%20Ni%C3%B1o/')`` yields ``'/El Niño/'``.
.. versionchanged:: 3.9
*string* parameter supports bytes and str objects (previously only str).
.. function:: unquote_plus(string, encoding='utf-8', errors='replace') .. function:: unquote_plus(string, encoding='utf-8', errors='replace')
......
...@@ -1049,8 +1049,6 @@ class UnquotingTests(unittest.TestCase): ...@@ -1049,8 +1049,6 @@ class UnquotingTests(unittest.TestCase):
"%s" % result) "%s" % result)
self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, None) self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, None)
self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, ()) self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, ())
with support.check_warnings(('', BytesWarning), quiet=True):
self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, b'')
def test_unquoting_badpercent(self): def test_unquoting_badpercent(self):
# Test unquoting on bad percent-escapes # Test unquoting on bad percent-escapes
...@@ -1210,6 +1208,29 @@ class UnquotingTests(unittest.TestCase): ...@@ -1210,6 +1208,29 @@ class UnquotingTests(unittest.TestCase):
self.assertEqual(expect, result, self.assertEqual(expect, result,
"using unquote(): %r != %r" % (expect, result)) "using unquote(): %r != %r" % (expect, result))
def test_unquoting_with_bytes_input(self):
# ASCII characters decoded to a string
given = b'blueberryjam'
expect = 'blueberryjam'
result = urllib.parse.unquote(given)
self.assertEqual(expect, result,
"using unquote(): %r != %r" % (expect, result))
# A mix of non-ASCII hex-encoded characters and ASCII characters
given = b'bl\xc3\xa5b\xc3\xa6rsyltet\xc3\xb8y'
expect = 'bl\u00e5b\u00e6rsyltet\u00f8y'
result = urllib.parse.unquote(given)
self.assertEqual(expect, result,
"using unquote(): %r != %r" % (expect, result))
# A mix of non-ASCII percent-encoded characters and ASCII characters
given = b'bl%c3%a5b%c3%a6rsyltet%c3%b8j'
expect = 'bl\u00e5b\u00e6rsyltet\u00f8j'
result = urllib.parse.unquote(given)
self.assertEqual(expect, result,
"using unquote(): %r != %r" % (expect, result))
class urlencode_Tests(unittest.TestCase): class urlencode_Tests(unittest.TestCase):
"""Tests for urlencode()""" """Tests for urlencode()"""
......
...@@ -631,6 +631,8 @@ def unquote(string, encoding='utf-8', errors='replace'): ...@@ -631,6 +631,8 @@ def unquote(string, encoding='utf-8', errors='replace'):
unquote('abc%20def') -> 'abc def'. unquote('abc%20def') -> 'abc def'.
""" """
if isinstance(string, bytes):
return unquote_to_bytes(string).decode(encoding, errors)
if '%' not in string: if '%' not in string:
string.split string.split
return string return string
......
Made :func:`urllib.parse.unquote()` accept bytes in addition to strings.
Patch by Stein Karlsen.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment