Fixed #13222 -- Made HttpResponse iterable once
response.content can be accessed many times as desired, and always returns the same result. iter(response) works only once and consumes the iterator.
This commit is contained in:
parent
495a8b8107
commit
82b3e6ffcb
|
@ -283,7 +283,8 @@ class HttpResponse(HttpResponseBase):
|
|||
'deprecated. Use `StreamingHttpResponse` instead '
|
||||
'if you need the streaming behavior.',
|
||||
PendingDeprecationWarning, stacklevel=2)
|
||||
self._iterator = iter(self._container)
|
||||
if not hasattr(self, '_iterator'):
|
||||
self._iterator = iter(self._container)
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
|
@ -303,7 +304,7 @@ class HttpResponse(HttpResponseBase):
|
|||
|
||||
def tell(self):
|
||||
self._consume_content()
|
||||
return sum(len(chunk) for chunk in self)
|
||||
return len(self.content)
|
||||
|
||||
|
||||
class StreamingHttpResponse(HttpResponseBase):
|
||||
|
|
|
@ -596,7 +596,11 @@ class TransactionTestCase(SimpleTestCase):
|
|||
msg_prefix + "Couldn't retrieve content: Response code was %d"
|
||||
" (expected %d)" % (response.status_code, status_code))
|
||||
text = force_text(text, encoding=response._charset)
|
||||
content = b''.join(response).decode(response._charset)
|
||||
if response.streaming:
|
||||
content = b''.join(response.streaming_content)
|
||||
else:
|
||||
content = response.content
|
||||
content = content.decode(response._charset)
|
||||
# Avoid ResourceWarning about unclosed files.
|
||||
response.close()
|
||||
if html:
|
||||
|
|
|
@ -337,15 +337,36 @@ class HttpResponseTests(unittest.TestCase):
|
|||
self.assertRaises(UnicodeEncodeError,
|
||||
getattr, r, 'content')
|
||||
|
||||
# content can safely be accessed multiple times.
|
||||
# .content can safely be accessed multiple times.
|
||||
r = HttpResponse(iter(['hello', 'world']))
|
||||
self.assertEqual(r.content, r.content)
|
||||
self.assertEqual(r.content, b'helloworld')
|
||||
# accessing the iterator works (once) after accessing .content
|
||||
self.assertEqual(b''.join(r), b'helloworld')
|
||||
self.assertEqual(b''.join(r), b'')
|
||||
# accessing .content still works
|
||||
self.assertEqual(r.content, b'helloworld')
|
||||
|
||||
# XXX accessing .content doesn't work if the response was iterated first
|
||||
# XXX change this when the deprecation completes in HttpResponse
|
||||
r = HttpResponse(iter(['hello', 'world']))
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", PendingDeprecationWarning)
|
||||
self.assertEqual(b''.join(r), b'helloworld')
|
||||
self.assertEqual(r.content, b'') # not the expected result!
|
||||
|
||||
# additional content can be written to the response.
|
||||
r = HttpResponse(iter(['hello', 'world']))
|
||||
self.assertEqual(r.content, b'helloworld')
|
||||
r.write('!')
|
||||
self.assertEqual(r.content, b'helloworld!')
|
||||
|
||||
def test_iterator_isnt_rewound(self):
|
||||
# Regression test for #13222
|
||||
r = HttpResponse('abc')
|
||||
i = iter(r)
|
||||
self.assertEqual(list(i), [b'abc'])
|
||||
self.assertEqual(list(i), [])
|
||||
|
||||
def test_file_interface(self):
|
||||
r = HttpResponse()
|
||||
|
|
Loading…
Reference in New Issue