From c8226f69e13b9a076f725965e2ed462216c2f4c3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 4 Mar 2014 16:27:13 -0500 Subject: [PATCH 1/3] Add documentation about decode_unicode. --- requests/models.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/requests/models.py b/requests/models.py index cd232e68..682cd9e1 100644 --- a/requests/models.py +++ b/requests/models.py @@ -617,6 +617,9 @@ class Response(object): large responses. The chunk size is the number of bytes it should read into memory. This is not necessarily the length of each item returned as decoding can take place. + + If decode_unicode is True, content will be decoded using the best + available encoding based on the response. """ if self._content_consumed: # simulate reading small chunks of the content From d289eb22f164e0bc71c81b191c1f00bdd08fe669 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 4 Mar 2014 16:33:40 -0500 Subject: [PATCH 2/3] Always honor decode_unicode, even when _content is present. --HG-- extra : amend_source : 25977a1227b163d49bf2e1aec6aa448e5cd3be8a --- requests/models.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/requests/models.py b/requests/models.py index 682cd9e1..c55e6ea7 100644 --- a/requests/models.py +++ b/requests/models.py @@ -621,10 +621,6 @@ class Response(object): If decode_unicode is True, content will be decoded using the best available encoding based on the response. """ - if self._content_consumed: - # simulate reading small chunks of the content - return iter_slices(self._content, chunk_size) - def generate(): try: # Special case for urllib3. @@ -645,12 +641,17 @@ class Response(object): self._content_consumed = True - gen = generate() + # simulate reading small chunks of the content + reused_chunks = iter_slices(self._content, chunk_size) + + stream_chunks = generate() + + chunks = reused_chunks if self._content_consumed else stream_chunks if decode_unicode: - gen = stream_decode_response_unicode(gen, self) + chunks = stream_decode_response_unicode(chunks, self) - return gen + return chunks def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None): """Iterates over the response data, one line at a time. When From 7b378cb74266ccea308a83c5b0f7129cb4962567 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 4 Mar 2014 17:46:58 -0500 Subject: [PATCH 3/3] Add tests for decode_unicode --- test_requests.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test_requests.py b/test_requests.py index 17de8491..65eb571c 100755 --- a/test_requests.py +++ b/test_requests.py @@ -9,6 +9,7 @@ import os import pickle import unittest +import io import requests import pytest from requests.adapters import HTTPAdapter @@ -690,6 +691,26 @@ class RequestsTestCase(unittest.TestCase): assert next(iter(r)) io.close() + def test_response_decode_unicode(self): + """ + When called with decode_unicode, Response.iter_content should always + return unicode. + """ + r = requests.Response() + r._content_consumed = True + r._content = b'the content' + r.encoding = 'ascii' + + chunks = r.iter_content(decode_unicode=True) + assert all(isinstance(chunk, str) for chunk in chunks) + + # also for streaming + r = requests.Response() + r.raw = io.BytesIO(b'the content') + r.encoding = 'ascii' + chunks = r.iter_content(decode_unicode=True) + assert all(isinstance(chunk, str) for chunk in chunks) + def test_request_and_response_are_pickleable(self): r = requests.get(httpbin('get'))