Fix a bug in _encode_params - it wasn't utf-8 encoding strings in values that
authorRussell Davis <russell.davis@gmail.com>
Sat, 3 Nov 2012 19:58:04 +0000 (12:58 -0700)
committerRussell Davis <russell.davis@gmail.com>
Sat, 3 Nov 2012 19:58:04 +0000 (12:58 -0700)
are iterable but not a list.

requests/models.py
tests/test_requests.py

index f3d7d7682bb0bde2c29661a207fdc24074adb216..16d1dd821a18d3056b7f93d98c9ac1ef1418d33f 100644 (file)
@@ -35,7 +35,7 @@ from .utils import (
     guess_json_utf)
 from .compat import (
     cookielib, urlparse, urlunparse, urljoin, urlsplit, urlencode, str, bytes,
-    StringIO, is_py2, chardet, json, builtin_str, urldefrag)
+    StringIO, is_py2, chardet, json, builtin_str, urldefrag, basestring)
 
 REDIRECT_STATI = (codes.moved, codes.found, codes.other, codes.temporary_moved)
 CONTENT_CHUNK_SIZE = 10 * 1024
@@ -334,7 +334,9 @@ class Request(object):
         elif hasattr(data, '__iter__'):
             result = []
             for k, vs in to_key_val_list(data):
-                for v in isinstance(vs, list) and vs or [vs]:
+                if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
+                    vs = [vs]
+                for v in vs:
                     if v is not None:
                         result.append(
                             (k.encode('utf-8') if isinstance(k, str) else k,
index 80709d5a344fa602d1aac9dedb7380566f65dbf8..6615678ff4518c2a05787b19d4d9af85f1393895 100755 (executable)
@@ -647,6 +647,30 @@ class RequestsTestSuite(TestSetup, TestBaseMixin, unittest.TestCase):
             self.assertEqual(rbody.get('form'), dict(test2='foobar', test3=['foo', 'baz']))
             self.assertEqual(rbody.get('data'), '')
 
+    def test_multivalued_data_encoding(self):
+        """
+        Make sure data encoding works on a value that is an iterable but not
+        a list
+        """
+        for service in SERVICES:
+            # Can't have unicode literals in Python3, so avoid them.
+            # TODO: fixup when moving to Python 3.3
+            if (sys.version_info[0] == 2):
+                nonascii = '\xc3\xa9'.decode('utf-8')
+            else:
+                nonascii = '\xe9'
+
+            r = post(
+                service('post'),
+                data=dict(test=('foo', nonascii)))
+
+            self.assertEqual(r.status_code, 200)
+            self.assertEqual(r.headers['content-type'], 'application/json')
+
+            rbody = json.loads(r.text)
+            self.assertEqual(rbody.get('form'),
+                             dict(test=['foo', nonascii]))
+
     def test_GET_no_redirect(self):
 
         for service in SERVICES: