Fixes #817.
authorIan Cordasco <graffatcolmingov@gmail.com>
Mon, 3 Sep 2012 03:09:43 +0000 (23:09 -0400)
committerIan Cordasco <graffatcolmingov@gmail.com>
Mon, 3 Sep 2012 03:10:28 +0000 (23:10 -0400)
Use dicts and lists where necessary but accept both dicts and lists of
2-tuples everywhere.

requests/compat.py
requests/models.py
requests/sessions.py
requests/structures.py
requests/utils.py

index 1d4f4a9..351b7c6 100644 (file)
@@ -93,6 +93,7 @@ if is_py2:
         import cchardet as chardet
     except ImportError:
         from .packages import chardet
+    from .packages.urllib3.packages.ordered_dict import OrderedDict
 
     builtin_str = str
     bytes = str
@@ -109,6 +110,7 @@ elif is_py3:
     from http.cookies import Morsel
     from io import StringIO
     from .packages import chardet2 as chardet
+    from collections import OrderedDict
 
     builtin_str = str
     str = str
index 1159ad5..b02739f 100644 (file)
@@ -34,7 +34,7 @@ from .utils import (
     to_key_val_list, DEFAULT_CA_BUNDLE_PATH, parse_header_links, iter_slices)
 from .compat import (
     cookielib, urlparse, urlunparse, urljoin, urlsplit, urlencode, str, bytes,
-    StringIO, is_py2, chardet, json, builtin_str, numeric_types)
+    StringIO, is_py2, chardet, json, builtin_str)
 
 REDIRECT_STATI = (codes.moved, codes.found, codes.other, codes.temporary_moved)
 CONTENT_CHUNK_SIZE = 10 * 1024
index 1f46688..f0d4f3c 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, to_key_val_list
+from .utils import header_expand, from_key_val_list
 from .packages.urllib3.poolmanager import PoolManager
 
 
@@ -34,27 +34,19 @@ def merge_kwargs(local_kwarg, default_kwarg):
     if local_kwarg is None:
         return default_kwarg
 
-    kwargs = default_kwarg
-    # If default_kwargs is a list rather than a dictionary attempt to convert
-    # to dictionary.  If the check fails, return local_kwargs.
-    if isinstance(default_kwarg, list):
-        try:
-            kwargs = dict(kwargs)
-        except ValueError:
-            return local_kwarg
-
     # Bypass if not a dictionary (e.g. timeout)
-    if not hasattr(kwargs, 'items'):
+    if not hasattr(default_kwarg, 'items'):
         return local_kwarg
 
-    local_kwarg = to_key_val_list(local_kwarg)
+    default_kwarg = from_key_val_list(default_kwarg)
+    local_kwarg = from_key_val_list(local_kwarg)
 
     # Update new values.
-    kwargs = kwargs.copy()
+    kwargs = default_kwarg.copy()
     kwargs.update(local_kwarg)
 
     # Remove keys that are set to None.
-    for (k, v) in local_kwarg:
+    for (k, v) in local_kwarg.items():
         if v is None:
             del kwargs[k]
 
@@ -81,14 +73,13 @@ class Session(object):
         verify=True,
         cert=None):
 
-        #self.headers = to_key_val_list(headers or [])
-        self.headers = headers or {}
+        self.headers = from_key_val_list(headers or [])
         self.auth = auth
         self.timeout = timeout
-        self.proxies = to_key_val_list(proxies or [])
-        self.hooks = hooks or {}
-        self.params = to_key_val_list(params or [])
-        self.config = config or {}
+        self.proxies = from_key_val_list(proxies or [])
+        self.hooks = from_key_val_list(hooks or {})
+        self.params = from_key_val_list(params or [])
+        self.config = from_key_val_list(config or {})
         self.prefetch = prefetch
         self.verify = verify
         self.cert = cert
@@ -171,7 +162,7 @@ class Session(object):
         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
+        params = {} if params is None else params
         hooks = {} if hooks is None else hooks
         prefetch = prefetch if prefetch is not None else self.prefetch
 
@@ -181,25 +172,23 @@ class Session(object):
 
         # Expand header values.
         if headers:
-            #e = [(k, header_expand(v)) for k, v in to_key_val_list(headers)]
-            #headers = e
-            for k, v in list(headers.items()) or {}:
+            for k, v in list(headers.items() or {}):
                 headers[k] = header_expand(v)
 
         args = dict(
             method=method,
             url=url,
             data=data,
-            params=params,
-            headers=headers,
+            params=from_key_val_list(params),
+            headers=from_key_val_list(headers),
             cookies=cookies,
             files=files,
             auth=auth,
-            hooks=hooks,
+            hooks=from_key_val_list(hooks),
             timeout=timeout,
             allow_redirects=allow_redirects,
-            proxies=to_key_val_list(proxies),
-            config=config,
+            proxies=from_key_val_list(proxies),
+            config=from_key_val_list(config),
             prefetch=prefetch,
             verify=verify,
             cert=cert,
index 7969c7e..3fda984 100644 (file)
@@ -8,6 +8,7 @@ Data structures that power Requests.
 
 """
 
+
 class CaseInsensitiveDict(dict):
     """Case-insensitive Dictionary
 
index 3639b8f..eb14600 100644 (file)
@@ -20,7 +20,7 @@ from netrc import netrc, NetrcParseError
 
 from . import __version__
 from .compat import parse_http_list as _parse_list_header
-from .compat import quote, urlparse, basestring, bytes, str
+from .compat import quote, urlparse, basestring, bytes, str, OrderedDict
 from .cookies import RequestsCookieJar, cookiejar_from_dict
 
 _hush_pyflakes = (RequestsCookieJar,)
@@ -114,28 +114,49 @@ def guess_filename(obj):
         return name
 
 
+def from_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 an
+    OrderedDict, e.g.,
+
+    ::
+
+        >>> from_key_val_list([('key', 'val')])
+        OrderedDict([('key', 'val')])
+        >>> from_key_val_list('string')
+        ValueError: need more than 1 value to unpack
+        >>> from_key_val_list({'key': 'val'})
+        OrderedDict([('key', 'val')])
+    """
+    if value is None:
+        return None
+
+    if isinstance(value, (str, bytes, bool, int)):
+        raise ValueError('cannot encode objects that are not 2-tuples')
+
+    return OrderedDict(value)
+
+
 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')]
+    dictionary. If it can be, return a list of tuples, e.g.,
+
+    ::
+
+        >>> to_key_val_list([('key', 'val')])
+        [('key', 'val')]
+        >>> to_key_val_list({'key': 'val'})
+        [('key', 'val')]
+        >>> to_key_val_list('string')
+        ValueError: cannot encode objects that are not 2-tuples.
     """
     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, (str, bytes, bool, int)):
+        raise ValueError('cannot encode objects that are not 2-tuples')
 
-    if isinstance(value, dict) or hasattr(value, 'items'):
+    if isinstance(value, dict):
         value = value.items()
 
     return list(value)
@@ -531,7 +552,7 @@ def parse_header_links(value):
     i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg"
 
     """
-    
+
     links = []
 
     replace_chars = " '\""
@@ -551,7 +572,7 @@ def parse_header_links(value):
                 key,value = param.split("=")
             except ValueError:
                 break
-            
+
             link[key.strip(replace_chars)] = value.strip(replace_chars)
 
         links.append(link)