diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index e7a75ce4a6b..01ac4444449 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -116,7 +116,7 @@ or on combining URL components into a URL string. Added IPv6 URL parsing capabilities. -.. function:: parse_qs(qs, keep_blank_values=False, strict_parsing=False) +.. function:: parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace') Parse a query string given as a string argument (data of type :mimetype:`application/x-www-form-urlencoded`). Data are returned as a @@ -133,11 +133,15 @@ or on combining URL components into a URL string. parsing errors. If false (the default), errors are silently ignored. If true, errors raise a :exc:`ValueError` exception. + The optional *encoding* and *errors* parameters specify how to decode + percent-encoded sequences into Unicode characters, as accepted by the + :meth:`bytes.decode` method. + Use the :func:`urllib.parse.urlencode` function to convert such dictionaries into query strings. -.. function:: parse_qsl(qs, keep_blank_values=False, strict_parsing=False) +.. function:: parse_qsl(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace') Parse a query string given as a string argument (data of type :mimetype:`application/x-www-form-urlencoded`). Data are returned as a list of @@ -153,6 +157,10 @@ or on combining URL components into a URL string. parsing errors. If false (the default), errors are silently ignored. If true, errors raise a :exc:`ValueError` exception. + The optional *encoding* and *errors* parameters specify how to decode + percent-encoded sequences into Unicode characters, as accepted by the + :meth:`bytes.decode` method. + Use the :func:`urllib.parse.urlencode` function to convert such lists of pairs into query strings. diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 42f81936828..9a3e42ee786 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -523,7 +523,8 @@ def unquote(string, encoding='utf-8', errors='replace'): string += pct_sequence.decode(encoding, errors) return string -def parse_qs(qs, keep_blank_values=False, strict_parsing=False): +def parse_qs(qs, keep_blank_values=False, strict_parsing=False, + encoding='utf-8', errors='replace'): """Parse a query given as a string argument. Arguments: @@ -540,16 +541,22 @@ def parse_qs(qs, keep_blank_values=False, strict_parsing=False): strict_parsing: flag indicating what to do with parsing errors. If false (the default), errors are silently ignored. If true, errors raise a ValueError exception. + + encoding and errors: specify how to decode percent-encoded sequences + into Unicode characters, as accepted by the bytes.decode() method. """ dict = {} - for name, value in parse_qsl(qs, keep_blank_values, strict_parsing): + pairs = parse_qsl(qs, keep_blank_values, strict_parsing, + encoding=encoding, errors=errors) + for name, value in pairs: if name in dict: dict[name].append(value) else: dict[name] = [value] return dict -def parse_qsl(qs, keep_blank_values=False, strict_parsing=False): +def parse_qsl(qs, keep_blank_values=False, strict_parsing=False, + encoding='utf-8', errors='replace'): """Parse a query given as a string argument. Arguments: @@ -566,6 +573,9 @@ def parse_qsl(qs, keep_blank_values=False, strict_parsing=False): false (the default), errors are silently ignored. If true, errors raise a ValueError exception. + encoding and errors: specify how to decode percent-encoded sequences + into Unicode characters, as accepted by the bytes.decode() method. + Returns a list, as G-d intended. """ qs, _coerce_result = _coerce_args(qs) @@ -584,8 +594,12 @@ def parse_qsl(qs, keep_blank_values=False, strict_parsing=False): else: continue if len(nv[1]) or keep_blank_values: - name = _coerce_result(unquote(nv[0].replace('+', ' '))) - value = _coerce_result(unquote(nv[1].replace('+', ' '))) + name = nv[0].replace('+', ' ') + name = unquote(name, encoding=encoding, errors=errors) + name = _coerce_result(name) + value = nv[1].replace('+', ' ') + value = unquote(value, encoding=encoding, errors=errors) + value = _coerce_result(value) r.append((name, value)) return r diff --git a/Misc/NEWS b/Misc/NEWS index 3ff1326aae2..3b0e81389fd 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -43,6 +43,8 @@ Core and Builtins Library ------- +- Add encoding and errors arguments to urllib.parse_qs() and urllib.parse_qsl() + - Issue #10899: No function type annotations in the standard library. Removed function type annotations from _pyio.py.