This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: parse_qsl fails on empty query argument without =
Type: behavior Stage: resolved
Components: Versions: Python 3.2, Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: David.Pizzuto, r.david.murray
Priority: normal Keywords:

Created on 2013-12-11 18:11 by David.Pizzuto, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (2)
msg205911 - (view) Author: David Pizzuto (David.Pizzuto) Date: 2013-12-11 18:11
Using an empty query argument with no = fails in urlparse.parse_qsl. Chrome and Firefox accept it without the =, so a navigation to google.com/search?q=foo&bar appears in the address bar as google.com/search?q=foo&bar=. Neither RFC 1738 nor RFC 3986 define the format of query strings. Wikipedia is similarly silent.

I can reproduce in 2.7.3 and 3.2.3, as shown below. I'm told this is also true of 3.3 but don't have easy access to a 3.3 interpreter to confirm.

The obvious workaround is to simply set strict_parsing=False, but I don't know what other checks that's disabling. Would it be reasonable to change parse_qsl to add the = if it's not present?

$ python
Python 2.7.3 (default, Sep 26 2013, 20:03:06) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import urlparse
>>> query = 'foo&bar=baz'
>>> urlparse.parse_qs(query, strict_parsing=True, keep_blank_values=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/urlparse.py", line 353, in parse_qs
    for name, value in parse_qsl(qs, keep_blank_values, strict_parsing):
  File "/usr/lib/python2.7/urlparse.py", line 387, in parse_qsl
    raise ValueError, "bad query field: %r" % (name_value,)
ValueError: bad query field: 'foo'

$ python3
Python 3.2.3 (default, Sep 25 2013, 18:22:43) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import urllib.parse
>>> query = 'foo&bar=baz'
>>> urllib.parse.parse_qs(query, strict_parsing=True, keep_blank_values=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.2/urllib/parse.py", line 556, in parse_qs
    encoding=encoding, errors=errors)
  File "/usr/lib/python3.2/urllib/parse.py", line 596, in parse_qsl
    raise ValueError("bad query field: %r" % (name_value,))
ValueError: bad query field: 'foo'
msg205913 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-12-11 18:43
I did some research on this for a previous issue, and every description of query strings I could find agreed that the format was '<name>=<value>'.  That is, that the '=' is not optional, even though some servers (note, *not* browsers, they just transmit or display the URI provided by the user or server) will accept parameters without the '=' and treat them as if they had one.

So I think this being rejected by strict_parsing is correct.  I'm closing this as invalid.

As for what strict_parsing, controls, you can check the source.  It looks like this and empty arguments (ie: &&) are the only things it controls.
History
Date User Action Args
2022-04-11 14:57:55adminsetgithub: 64150
2013-12-11 18:43:06r.david.murraysetstatus: open -> closed

type: behavior

nosy: + r.david.murray
messages: + msg205913
resolution: not a bug
stage: resolved
2013-12-11 18:11:45David.Pizzutocreate