Add to_key_val_lists to avoid repetition.
authorIan Cordasco <graffatcolmingov@gmail.com>
Mon, 6 Aug 2012 03:28:19 +0000 (23:28 -0400)
committerIan Cordasco <graffatcolmingov@gmail.com>
Mon, 6 Aug 2012 03:29:10 +0000 (23:29 -0400)
It uses the same logic whenever we're trying to use a list of key values and
avoid what I had started doing -- using the same pattern everywhere.

proxies, and headers should both be covered by this commit.

requests/models.py
requests/sessions.py
requests/utils.py

index 514bcb4..cdcdee8 100644 (file)
@@ -29,7 +29,7 @@ from .exceptions import (
 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)
@@ -317,15 +317,8 @@ class Request(object):
         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,
@@ -339,20 +332,8 @@ class Request(object):
         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
index ee47a01..32d39fc 100644 (file)
@@ -15,7 +15,7 @@ from .cookies import cookiejar_from_dict, remove_cookie_by_name
 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
 
 
@@ -38,14 +38,7 @@ def merge_kwargs(local_kwarg, default_kwarg):
     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()
@@ -79,12 +72,12 @@ class Session(object):
         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
@@ -157,10 +150,10 @@ class Session(object):
         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
 
@@ -170,8 +163,10 @@ class Session(object):
 
         # 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,
@@ -185,7 +180,7 @@ class Session(object):
             hooks=hooks,
             timeout=timeout,
             allow_redirects=allow_redirects,
-            proxies=proxies,
+            proxies=to_key_val_list(proxies),
             config=config,
             prefetch=prefetch,
             verify=verify,
index ce08ba7..53bb80f 100644 (file)
@@ -112,6 +112,33 @@ def guess_filename(obj):
         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.