from .utils import (
get_encoding_from_headers, stream_untransfer, guess_filename, requote_uri,
stream_decode_response_unicode, get_netrc_auth, get_environ_proxies,
- DEFAULT_CA_BUNDLE_PATH)
+ to_key_val_list, DEFAULT_CA_BUNDLE_PATH)
from .compat import (
cookielib, urlparse, urlunparse, urljoin, urlsplit, urlencode, str, bytes,
StringIO, is_py2, chardet, json, builtin_str)
elif hasattr(data, 'read'):
return data
elif hasattr(data, '__iter__'):
- try:
- dict(data)
- except ValueError:
- raise ValueError('Unable to encode lists with elements that '
- 'are not 2-tuples.')
-
- params = list(data.items() if isinstance(data, dict) else data)
result = []
- for k, vs in params:
+ for k, vs in to_key_val_list(data):
for v in isinstance(vs, list) and vs or [vs]:
result.append(
(k.encode('utf-8') if isinstance(k, str) else k,
if (not files) or isinstance(self.data, str):
return None
- try:
- fields = list(self.data.items())
- except AttributeError:
- dict(self.data)
- fields = list(self.data)
-
- try:
- dict(files)
- except ValueError:
- raise ValueError('Unable to encode lists with elements that '
- 'are not 2-tuples.')
-
- if isinstance(files, dict):
- files = files.items()
+ fields = to_key_val_list(self.data)
+ files = to_key_val_list(files)
for (k, v) in files:
# support for explicit filename
from .defaults import defaults
from .models import Request
from .hooks import dispatch_hook
-from .utils import header_expand
+from .utils import header_expand, to_key_val_list
from .packages.urllib3.poolmanager import PoolManager
if not hasattr(default_kwarg, 'items'):
return local_kwarg
- try:
- dict(local_kwarg)
- except ValueError:
- raise ValueError('Unable to encode lists with elements that are not '
- '2-tuples.')
-
- if hasattr(local_kwarg, 'items'):
- local_kwarg = list(local_kwarg.items())
+ local_kwarg = to_key_val_list(local_kwarg)
# Update new values.
kwargs = default_kwarg.copy()
verify=True,
cert=None):
- self.headers = headers or {}
+ self.headers = to_key_val_list(headers or [])
self.auth = auth
self.timeout = timeout
- self.proxies = proxies or {}
+ self.proxies = to_key_val_list(proxies or [])
self.hooks = hooks or {}
- self.params = params or {}
+ self.params = to_key_val_list(params or [])
self.config = config or {}
self.prefetch = prefetch
self.verify = verify
method = str(method).upper()
# Default empty dicts for dict params.
- data = {} if data is None else data
- files = {} if files is None else files
- headers = {} if headers is None else headers
- params = {} if params is None else params
+ data = [] if data is None else data
+ files = [] if files is None else files
+ headers = [] if headers is None else headers
+ params = [] if params is None else params
hooks = {} if hooks is None else hooks
prefetch = self.prefetch or prefetch
# Expand header values.
if headers:
- for k, v in list(headers.items()) or {}:
- headers[k] = header_expand(v)
+ expanded = []
+ for k, v in to_key_val_list(headers):
+ expanded.append((k, header_expand(v)))
+ headers = expanded
args = dict(
method=method,
hooks=hooks,
timeout=timeout,
allow_redirects=allow_redirects,
- proxies=proxies,
+ proxies=to_key_val_list(proxies),
config=config,
prefetch=prefetch,
verify=verify,
return name
+def to_key_val_list(value):
+ """Take an object and test to see if it can be represented as a
+ dictionary. Unless it can not be represented as such, return a list of
+ tuples, e.g.,:
+
+ >>> to_key_val_list([('key', 'val')])
+ [('key', 'val')]
+ >>> to_key_val_list('string')
+ ValueError: ...
+ >>> to_key_val_list({'key': 'val'})
+ [('key', 'val')]
+ """
+ if value is None:
+ return None
+
+ try:
+ dict(value)
+ except ValueError:
+ raise ValueError('Unable to encode lists with elements that are not '
+ '2-tuples.')
+
+ if isinstance(value, dict) or hasattr(value, 'items'):
+ value = value.items()
+
+ return list(value)
+
+
# From mitsuhiko/werkzeug (used with permission).
def parse_list_header(value):
"""Parse lists as described by RFC 2068 Section 2.