Skip to content

Commit aad2ee0

Browse files
stein-ktaleinat
authored andcommitted
bpo-32498: urllib.parse.unquote also accepts bytes (GH-7768)
1 parent 9cb51f4 commit aad2ee0

File tree

4 files changed

+33
-3
lines changed

4 files changed

+33
-3
lines changed

Doc/library/urllib.parse.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,14 +571,19 @@ task isn't already covered by the URL parsing functions above.
571571
percent-encoded sequences into Unicode characters, as accepted by the
572572
:meth:`bytes.decode` method.
573573

574-
*string* must be a :class:`str`.
574+
*string* may be either a :class:`str` or a :class:`bytes`.
575575

576576
*encoding* defaults to ``'utf-8'``.
577577
*errors* defaults to ``'replace'``, meaning invalid sequences are replaced
578578
by a placeholder character.
579579

580580
Example: ``unquote('/El%20Ni%C3%B1o/')`` yields ``'/El Niño/'``.
581581

582+
.. versionchanged:: 3.9
583+
*string* parameter supports bytes and str objects (previously only str).
584+
585+
586+
582587

583588
.. function:: unquote_plus(string, encoding='utf-8', errors='replace')
584589

Lib/test/test_urllib.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,8 +1049,6 @@ def test_unquoting(self):
10491049
"%s" % result)
10501050
self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, None)
10511051
self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, ())
1052-
with support.check_warnings(('', BytesWarning), quiet=True):
1053-
self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, b'')
10541052

10551053
def test_unquoting_badpercent(self):
10561054
# Test unquoting on bad percent-escapes
@@ -1210,6 +1208,29 @@ def test_unquote_with_unicode(self):
12101208
self.assertEqual(expect, result,
12111209
"using unquote(): %r != %r" % (expect, result))
12121210

1211+
def test_unquoting_with_bytes_input(self):
1212+
# ASCII characters decoded to a string
1213+
given = b'blueberryjam'
1214+
expect = 'blueberryjam'
1215+
result = urllib.parse.unquote(given)
1216+
self.assertEqual(expect, result,
1217+
"using unquote(): %r != %r" % (expect, result))
1218+
1219+
# A mix of non-ASCII hex-encoded characters and ASCII characters
1220+
given = b'bl\xc3\xa5b\xc3\xa6rsyltet\xc3\xb8y'
1221+
expect = 'bl\u00e5b\u00e6rsyltet\u00f8y'
1222+
result = urllib.parse.unquote(given)
1223+
self.assertEqual(expect, result,
1224+
"using unquote(): %r != %r" % (expect, result))
1225+
1226+
# A mix of non-ASCII percent-encoded characters and ASCII characters
1227+
given = b'bl%c3%a5b%c3%a6rsyltet%c3%b8j'
1228+
expect = 'bl\u00e5b\u00e6rsyltet\u00f8j'
1229+
result = urllib.parse.unquote(given)
1230+
self.assertEqual(expect, result,
1231+
"using unquote(): %r != %r" % (expect, result))
1232+
1233+
12131234
class urlencode_Tests(unittest.TestCase):
12141235
"""Tests for urlencode()"""
12151236

Lib/urllib/parse.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,8 @@ def unquote(string, encoding='utf-8', errors='replace'):
631631
632632
unquote('abc%20def') -> 'abc def'.
633633
"""
634+
if isinstance(string, bytes):
635+
return unquote_to_bytes(string).decode(encoding, errors)
634636
if '%' not in string:
635637
string.split
636638
return string
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Made :func:`urllib.parse.unquote()` accept bytes in addition to strings.
2+
Patch by Stein Karlsen.

0 commit comments

Comments
 (0)