From ccf4ca8929ec88e84616ecbc0176a26b3042f0bd Mon Sep 17 00:00:00 2001 From: Russell Davis Date: Sat, 3 Nov 2012 12:58:04 -0700 Subject: [PATCH] Fix a bug in _encode_params - it wasn't utf-8 encoding strings in values that are iterable but not a list. --- requests/models.py | 6 ++++-- tests/test_requests.py | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/requests/models.py b/requests/models.py index f3d7d76..16d1dd8 100644 --- a/requests/models.py +++ b/requests/models.py @@ -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, diff --git a/tests/test_requests.py b/tests/test_requests.py index 80709d5..6615678 100755 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -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: -- 2.34.1