Merge pull request #3088 from drnextgis/quote_via
quote_via urlencode argument
| | |
| | | - Fang-Pen Lin, 2017/05/22 |
| | | |
| | | - Volker Diels-Grabsch, 2017/06/09 |
| | | |
| | | - Denis Rykov, 2017/06/15 |
| | |
| | | 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) |
| | |
| | | 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 |
| | |
| | | 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) |
| | |
| | | ) |
| | | |
| | | 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)]) |
| | |
| | | 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 |