Michael Merickel
2018-10-26 572e03c1e47385f093ffb701e21c226f99247837
commit | author | age
0c1c39 1 from pyramid.compat import (
CM 2     text_type,
3     binary_type,
4     is_nonstr_iter,
5     url_quote as _url_quote,
e967a9 6     url_quote_plus as _quote_plus,
0c29cf 7 )
8e606d 8
0c29cf 9
MM 10 def url_quote(val, safe=''):  # bw compat api
22f0eb 11     cls = val.__class__
MM 12     if cls is text_type:
13         val = val.encode('utf-8')
14     elif cls is not binary_type:
15         val = str(val).encode('utf-8')
16     return _url_quote(val, safe=safe)
0c29cf 17
eb9fbf 18
804232 19 # bw compat api (dnr)
D 20 def quote_plus(val, safe=''):
21     cls = val.__class__
22     if cls is text_type:
23         val = val.encode('utf-8')
24     elif cls is not binary_type:
25         val = str(val).encode('utf-8')
26     return _quote_plus(val, safe=safe)
27
0c29cf 28
804232 29 def urlencode(query, doseq=True, quote_via=quote_plus):
eb9fbf 30     """
6f43b6 31     An alternate implementation of Python's stdlib
MM 32     :func:`urllib.parse.urlencode` function which accepts unicode keys and
33     values within the ``query`` dict/sequence; all Unicode keys and values are
34     first converted to UTF-8 before being used to compose the query string.
eb9fbf 35
CM 36     The value of ``query`` must be a sequence of two-tuples
37     representing key/value pairs *or* an object (often a dictionary)
38     with an ``.items()`` method that returns a sequence of two-tuples
39     representing key/value pairs.
40
41     For minimal calling convention backwards compatibility, this
42     version of urlencode accepts *but ignores* a second argument
43     conventionally named ``doseq``.  The Python stdlib version behaves
44     differently when ``doseq`` is False and when a sequence is
45     presented as one of the values.  This version always behaves in
46     the ``doseq=True`` mode, no matter what the value of the second
47     argument.
48
6f43b6 49     Both the key and value are encoded using the ``quote_via`` function which
MM 50     by default is using a similar algorithm to :func:`urllib.parse.quote_plus`
51     which converts spaces into '+' characters and '/' into '%2F'.
af5fa0 52
MM 53     .. versionchanged:: 1.5
54        In a key/value pair, if the value is ``None`` then it will be
55        dropped from the resulting output.
6f43b6 56
MM 57     .. versionchanged:: 1.9
58        Added the ``quote_via`` argument to allow alternate quoting algorithms
59        to be used.
60
eb9fbf 61     """
CM 62     try:
63         # presumed to be a dictionary
64         query = query.items()
65     except AttributeError:
66         pass
67
68     result = ''
69     prefix = ''
70
71     for (k, v) in query:
804232 72         k = quote_via(k)
a84e17 73
8e606d 74         if is_nonstr_iter(v):
eb9fbf 75             for x in v:
804232 76                 x = quote_via(x)
eb9fbf 77                 result += '%s%s=%s' % (prefix, k, x)
CM 78                 prefix = '&'
af5fa0 79         elif v is None:
15afe5 80             result += '%s%s=' % (prefix, k)
eb9fbf 81         else:
804232 82             v = quote_via(v)
eb9fbf 83             result += '%s%s=%s' % (prefix, k, v)
a84e17 84
eb9fbf 85         prefix = '&'
CM 86
87     return result