diff options
author | R David Murray <rdmurray@bitdance.com> | 2015-05-18 00:44:50 (GMT) |
---|---|---|
committer | R David Murray <rdmurray@bitdance.com> | 2015-05-18 00:44:50 (GMT) |
commit | c17686f071c6f5b5d20366ae32188327a36e282e (patch) | |
tree | 70c6482b2a224313d4771917aff6f9b810e00fb8 /Lib | |
parent | 1dbee9460e6a242bfbdd701ce328f11f7dd69019 (diff) | |
download | cpython-c17686f071c6f5b5d20366ae32188327a36e282e.zip cpython-c17686f071c6f5b5d20366ae32188327a36e282e.tar.gz cpython-c17686f071c6f5b5d20366ae32188327a36e282e.tar.bz2 |
Issue #13866: add *quote_via* argument to urlencode.
Patch by samwyse, completed by Arnon Yaari, and reviewed by
Martin Panter.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_urlparse.py | 10 | ||||
-rw-r--r-- | Lib/urllib/parse.py | 29 |
2 files changed, 25 insertions, 14 deletions
diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 156ccf5..4fa3dc6 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -785,6 +785,16 @@ class UrlParseTestCase(unittest.TestCase): result = urllib.parse.urlencode({'a': Trivial()}, True) self.assertEqual(result, 'a=trivial') + def test_urlencode_quote_via(self): + result = urllib.parse.urlencode({'a': 'some value'}) + self.assertEqual(result, "a=some+value") + result = urllib.parse.urlencode({'a': 'some value/another'}, + quote_via=urllib.parse.quote) + self.assertEqual(result, "a=some%20value%2Fanother") + result = urllib.parse.urlencode({'a': 'some value/another'}, + safe='/', quote_via=urllib.parse.quote) + self.assertEqual(result, "a=some%20value/another") + def test_quote_from_bytes(self): self.assertRaises(TypeError, urllib.parse.quote_from_bytes, 'foo') result = urllib.parse.quote_from_bytes(b'archaeological arcana') diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index e313371..01c9e58 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -750,7 +750,8 @@ def quote_from_bytes(bs, safe='/'): _safe_quoters[safe] = quoter = Quoter(safe).__getitem__ return ''.join([quoter(char) for char in bs]) -def urlencode(query, doseq=False, safe='', encoding=None, errors=None): +def urlencode(query, doseq=False, safe='', encoding=None, errors=None, + quote_via=quote_plus): """Encode a dict or sequence of two-element tuples into a URL query string. If any values in the query arg are sequences and doseq is true, each @@ -762,8 +763,8 @@ def urlencode(query, doseq=False, safe='', encoding=None, errors=None): The components of a query arg may each be either a string or a bytes type. - The safe, encoding, and errors parameters are passed down to quote_plus() - (encoding and errors only if a component is a str). + The safe, encoding, and errors parameters are passed down to the function + specified by quote_via (encoding and errors only if a component is a str). """ if hasattr(query, "items"): @@ -789,27 +790,27 @@ def urlencode(query, doseq=False, safe='', encoding=None, errors=None): if not doseq: for k, v in query: if isinstance(k, bytes): - k = quote_plus(k, safe) + k = quote_via(k, safe) else: - k = quote_plus(str(k), safe, encoding, errors) + k = quote_via(str(k), safe, encoding, errors) if isinstance(v, bytes): - v = quote_plus(v, safe) + v = quote_via(v, safe) else: - v = quote_plus(str(v), safe, encoding, errors) + v = quote_via(str(v), safe, encoding, errors) l.append(k + '=' + v) else: for k, v in query: if isinstance(k, bytes): - k = quote_plus(k, safe) + k = quote_via(k, safe) else: - k = quote_plus(str(k), safe, encoding, errors) + k = quote_via(str(k), safe, encoding, errors) if isinstance(v, bytes): - v = quote_plus(v, safe) + v = quote_via(v, safe) l.append(k + '=' + v) elif isinstance(v, str): - v = quote_plus(v, safe, encoding, errors) + v = quote_via(v, safe, encoding, errors) l.append(k + '=' + v) else: try: @@ -817,15 +818,15 @@ def urlencode(query, doseq=False, safe='', encoding=None, errors=None): x = len(v) except TypeError: # not a sequence - v = quote_plus(str(v), safe, encoding, errors) + v = quote_via(str(v), safe, encoding, errors) l.append(k + '=' + v) else: # loop over the sequence for elt in v: if isinstance(elt, bytes): - elt = quote_plus(elt, safe) + elt = quote_via(elt, safe) else: - elt = quote_plus(str(elt), safe, encoding, errors) + elt = quote_via(str(elt), safe, encoding, errors) l.append(k + '=' + elt) return '&'.join(l) |