summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS.txt2
-rw-r--r--pyramid/encode.py45
-rw-r--r--pyramid/tests/test_encode.py11
3 files changed, 36 insertions, 22 deletions
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 445536e9e..32c0833b4 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -304,3 +304,5 @@ Contributors
- Fang-Pen Lin, 2017/05/22
- Volker Diels-Grabsch, 2017/06/09
+
+- Denis Rykov, 2017/06/15
diff --git a/pyramid/encode.py b/pyramid/encode.py
index 0be0107b3..73ff14e62 100644
--- a/pyramid/encode.py
+++ b/pyramid/encode.py
@@ -14,13 +14,21 @@ def url_quote(val, safe=''): # bw compat api
val = str(val).encode('utf-8')
return _url_quote(val, safe=safe)
-def urlencode(query, doseq=True):
+# bw compat api (dnr)
+def quote_plus(val, safe=''):
+ cls = val.__class__
+ if cls is text_type:
+ val = val.encode('utf-8')
+ elif cls is not binary_type:
+ val = str(val).encode('utf-8')
+ return _quote_plus(val, safe=safe)
+
+def urlencode(query, doseq=True, quote_via=quote_plus):
"""
- An alternate implementation of Python's stdlib `urllib.urlencode
- function <http://docs.python.org/library/urllib.html>`_ which
- accepts unicode keys and values within the ``query``
- dict/sequence; all Unicode keys and values are first converted to
- UTF-8 before being used to compose the query string.
+ An alternate implementation of Python's stdlib
+ :func:`urllib.parse.urlencode` function which accepts unicode keys and
+ values within the ``query`` dict/sequence; all Unicode keys and values are
+ first converted to UTF-8 before being used to compose the query string.
The value of ``query`` must be a sequence of two-tuples
representing key/value pairs *or* an object (often a dictionary)
@@ -35,12 +43,18 @@ def urlencode(query, doseq=True):
the ``doseq=True`` mode, no matter what the value of the second
argument.
- See the Python stdlib documentation for ``urllib.urlencode`` for
- more information.
+ Both the key and value are encoded using the ``quote_via`` function which
+ by default is using a similar algorithm to :func:`urllib.parse.quote_plus`
+ which converts spaces into '+' characters and '/' into '%2F'.
.. versionchanged:: 1.5
In a key/value pair, if the value is ``None`` then it will be
dropped from the resulting output.
+
+ .. versionchanged:: 1.9
+ Added the ``quote_via`` argument to allow alternate quoting algorithms
+ to be used.
+
"""
try:
# presumed to be a dictionary
@@ -52,28 +66,19 @@ def urlencode(query, doseq=True):
prefix = ''
for (k, v) in query:
- k = quote_plus(k)
+ k = quote_via(k)
if is_nonstr_iter(v):
for x in v:
- x = quote_plus(x)
+ x = quote_via(x)
result += '%s%s=%s' % (prefix, k, x)
prefix = '&'
elif v is None:
result += '%s%s=' % (prefix, k)
else:
- v = quote_plus(v)
+ v = quote_via(v)
result += '%s%s=%s' % (prefix, k, v)
prefix = '&'
return result
-
-# bw compat api (dnr)
-def quote_plus(val, safe=''):
- cls = val.__class__
- if cls is text_type:
- val = val.encode('utf-8')
- elif cls is not binary_type:
- val = str(val).encode('utf-8')
- return _quote_plus(val, safe=safe)
diff --git a/pyramid/tests/test_encode.py b/pyramid/tests/test_encode.py
index 8fb766d88..d3a9f7095 100644
--- a/pyramid/tests/test_encode.py
+++ b/pyramid/tests/test_encode.py
@@ -5,9 +5,9 @@ from pyramid.compat import (
)
class UrlEncodeTests(unittest.TestCase):
- def _callFUT(self, query, doseq=False):
+ def _callFUT(self, query, doseq=False, **kw):
from pyramid.encode import urlencode
- return urlencode(query, doseq)
+ return urlencode(query, doseq, **kw)
def test_ascii_only(self):
result = self._callFUT([('a',1), ('b',2)])
@@ -53,6 +53,13 @@ class UrlEncodeTests(unittest.TestCase):
result = self._callFUT([('a', '1'), ('b', None), ('c', None)])
self.assertEqual(result, 'a=1&b=&c=')
+ def test_quote_via(self):
+ def my_quoter(value):
+ return 'xxx' + value
+ result = self._callFUT([('a', '1'), ('b', None), ('c', None)],
+ quote_via=my_quoter)
+ self.assertEqual(result, 'xxxa=xxx1&xxxb=&xxxc=')
+
class URLQuoteTests(unittest.TestCase):
def _callFUT(self, val, safe=''):
from pyramid.encode import url_quote