Skip to content

bpo-42967: Fix urllib.parse docs and make logic clearer #24536

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions Doc/library/urllib.parse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ or on combining URL components into a URL string.
read. If set, then throws a :exc:`ValueError` if there are more than
*max_num_fields* fields read.

The optional argument *separator* is the symbol to use for separating the query arguments. It defaults to `&`.
The optional argument *separator* is the symbol to use for separating the
query arguments. It defaults to ``&``.

Use the :func:`urllib.parse.urlencode` function (with the ``doseq``
parameter set to ``True``) to convert such dictionaries into query
Expand All @@ -204,8 +205,10 @@ or on combining URL components into a URL string.
Added *max_num_fields* parameter.

.. versionchanged:: 3.10
Added *separator* parameter with the default value of `&`. Python versions earlier than Python 3.10 allowed using both ";" and "&" as
query parameter separator. This has been changed to allow only a single separator key, with "&" as the default separator.
Added *separator* parameter with the default value of ``&``. Python
versions earlier than Python 3.10 allowed using both ``;`` and ``&`` as
query parameter separator. This has been changed to allow only a single
separator key, with ``&`` as the default separator.


.. function:: parse_qsl(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&')
Expand All @@ -232,7 +235,8 @@ or on combining URL components into a URL string.
read. If set, then throws a :exc:`ValueError` if there are more than
*max_num_fields* fields read.

The optional argument *separator* is the symbol to use for separating the query arguments. It defaults to `&`.
The optional argument *separator* is the symbol to use for separating the
query arguments. It defaults to ``&``.

Use the :func:`urllib.parse.urlencode` function to convert such lists of pairs into
query strings.
Expand All @@ -244,8 +248,10 @@ or on combining URL components into a URL string.
Added *max_num_fields* parameter.

.. versionchanged:: 3.10
Added *separator* parameter with the default value of `&`. Python versions earlier than Python 3.10 allowed using both ";" and "&" as
query parameter separator. This has been changed to allow only a single separator key, with "&" as the default separator.
Added *separator* parameter with the default value of ``&``. Python
versions earlier than Python 3.10 allowed using both ``;`` and ``&`` as
query parameter separator. This has been changed to allow only a single
separator key, with ``&`` as the default separator.


.. function:: urlunparse(parts)
Expand Down
4 changes: 2 additions & 2 deletions Doc/whatsnew/3.6.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2447,11 +2447,11 @@ details, see the documentation for ``loop.create_datagram_endpoint()``.
Notable changes in Python 3.6.13
================================

Earlier Python versions allowed using both ";" and "&" as
Earlier Python versions allowed using both ``;`` and ``&`` as
query parameter separators in :func:`urllib.parse.parse_qs` and
:func:`urllib.parse.parse_qsl`. Due to security concerns, and to conform with
newer W3C recommendations, this has been changed to allow only a single
separator key, with "&" as the default. This change also affects
separator key, with ``&`` as the default. This change also affects
:func:`cgi.parse` and :func:`cgi.parse_multipart` as they use the affected
functions internally. For more details, please see their respective
documentation.
Expand Down
4 changes: 2 additions & 2 deletions Doc/whatsnew/3.8.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2238,11 +2238,11 @@ details, see the documentation for ``loop.create_datagram_endpoint()``.
Notable changes in Python 3.8.8
===============================

Earlier Python versions allowed using both ";" and "&" as
Earlier Python versions allowed using both ``;`` and ``&`` as
query parameter separators in :func:`urllib.parse.parse_qs` and
:func:`urllib.parse.parse_qsl`. Due to security concerns, and to conform with
newer W3C recommendations, this has been changed to allow only a single
separator key, with "&" as the default. This change also affects
separator key, with ``&`` as the default. This change also affects
:func:`cgi.parse` and :func:`cgi.parse_multipart` as they use the affected
functions internally. For more details, please see their respective
documentation.
Expand Down
4 changes: 2 additions & 2 deletions Doc/whatsnew/3.9.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1520,11 +1520,11 @@ become a :exc:`TypeError` in Python 3.10.
urllib.parse
------------

Earlier Python versions allowed using both ";" and "&" as
Earlier Python versions allowed using both ``;`` and ``&`` as
query parameter separators in :func:`urllib.parse.parse_qs` and
:func:`urllib.parse.parse_qsl`. Due to security concerns, and to conform with
newer W3C recommendations, this has been changed to allow only a single
separator key, with "&" as the default. This change also affects
separator key, with ``&`` as the default. This change also affects
:func:`cgi.parse` and :func:`cgi.parse_multipart` as they use the affected
functions internally. For more details, please see their respective
documentation.
Expand Down
3 changes: 1 addition & 2 deletions Lib/urllib/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,8 +734,7 @@ def parse_qsl(qs, keep_blank_values=False, strict_parsing=False,
"""
qs, _coerce_result = _coerce_args(qs)

if not separator or (not isinstance(separator, str)
and not isinstance(separator, bytes)):
if not separator or (not isinstance(separator, (str, bytes))):
raise ValueError("Separator must be of type string or bytes.")

# If max_num_fields is defined then check that the number of fields
Expand Down