Skip to content

Commit

Permalink
pythongh-116764: Fix regressions in urllib.parse.parse_qsl() (pythonG…
Browse files Browse the repository at this point in the history
…H-116801)

* Restore support of None and other false values.
* Raise TypeError for non-zero integers and non-empty sequences.

The regressions were introduced in pythongh-74668
(bdba8ef).
(cherry picked from commit 1069a46)

Co-authored-by: Serhiy Storchaka <[email protected]>
  • Loading branch information
serhiy-storchaka authored and miss-islington committed Mar 16, 2024
1 parent d16519a commit 808742b
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
24 changes: 24 additions & 0 deletions Lib/test/test_urlparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,30 @@ def test_parse_qsl_separator(self):
result_bytes = urllib.parse.parse_qsl(orig, separator=b';')
self.assertEqual(result_bytes, expect, "Error parsing %r" % orig)

def test_parse_qsl_bytes(self):
self.assertEqual(urllib.parse.parse_qsl(b'a=b'), [(b'a', b'b')])
self.assertEqual(urllib.parse.parse_qsl(bytearray(b'a=b')), [(b'a', b'b')])
self.assertEqual(urllib.parse.parse_qsl(memoryview(b'a=b')), [(b'a', b'b')])

def test_parse_qsl_false_value(self):
kwargs = dict(keep_blank_values=True, strict_parsing=True)
for x in '', b'', None, 0, 0.0, [], {}, memoryview(b''):
self.assertEqual(urllib.parse.parse_qsl(x, **kwargs), [])
self.assertRaises(ValueError, urllib.parse.parse_qsl, x, separator=1)

def test_parse_qsl_errors(self):
self.assertRaises(TypeError, urllib.parse.parse_qsl, list(b'a=b'))
self.assertRaises(TypeError, urllib.parse.parse_qsl, iter(b'a=b'))
self.assertRaises(TypeError, urllib.parse.parse_qsl, 1)
self.assertRaises(TypeError, urllib.parse.parse_qsl, object())

for separator in '', b'', None, 0, 1, 0.0, 1.5:
with self.assertRaises(ValueError):
urllib.parse.parse_qsl('a=b', separator=separator)
with self.assertRaises(UnicodeEncodeError):
urllib.parse.parse_qsl(b'a=b', separator='\xa6')
with self.assertRaises(UnicodeDecodeError):
urllib.parse.parse_qsl('a=b', separator=b'\xa6')

def test_urlencode_sequences(self):
# Other tests incidentally urlencode things; test non-covered cases:
Expand Down
6 changes: 5 additions & 1 deletion Lib/urllib/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,11 @@ def parse_qsl(qs, keep_blank_values=False, strict_parsing=False,
def _unquote(s):
return unquote_plus(s, encoding=encoding, errors=errors)
else:
qs = bytes(qs)
if not qs:
return []
# Use memoryview() to reject integers and iterables,
# acceptable by the bytes constructor.
qs = bytes(memoryview(qs))
if isinstance(separator, str):
separator = bytes(separator, 'ascii')
eq = b'='
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Restore support of ``None`` and other false values in :mod:`urllib.parse`
functions :func:`~urllib.parse.parse_qs` and
:func:`~urllib.parse.parse_qsl`. Also, they now raise a TypeError for
non-zero integers and non-empty sequences.

0 comments on commit 808742b

Please sign in to comment.