Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Removed compatibility code for streaming responses.

This code provided a deprecation path for old-style streaming responses.

Refs #6527, #7581.
  • Loading branch information...
commit 8b9b8d3bda09eb1b447631182d06c6c5e51425f6 1 parent 59b0c48
Aymeric Augustin aaugustin authored
8 django/http/__init__.py
View
@@ -2,9 +2,9 @@
from django.http.request import (HttpRequest, QueryDict, UnreadablePostError,
build_request_repr)
from django.http.response import (HttpResponse, StreamingHttpResponse,
- CompatibleStreamingHttpResponse, HttpResponsePermanentRedirect,
- HttpResponseRedirect, HttpResponseNotModified, HttpResponseBadRequest,
- HttpResponseForbidden, HttpResponseNotFound, HttpResponseNotAllowed,
- HttpResponseGone, HttpResponseServerError, Http404, BadHeaderError)
+ HttpResponseRedirect, HttpResponsePermanentRedirect,
+ HttpResponseNotModified, HttpResponseBadRequest, HttpResponseForbidden,
+ HttpResponseNotFound, HttpResponseNotAllowed, HttpResponseGone,
+ HttpResponseServerError, Http404, BadHeaderError)
from django.http.utils import (fix_location_header, conditional_content_removal,
fix_IE_for_attach, fix_IE_for_vary)
61 django/http/response.py
View
@@ -2,7 +2,6 @@
import datetime
import time
-import warnings
from email.header import Header
try:
from urllib.parse import urlparse
@@ -332,53 +331,27 @@ def serialize(self):
else:
__str__ = serialize
- def _consume_content(self):
- # If the response was instantiated with an iterator, when its content
- # is accessed, the iterator is going be exhausted and the content
- # loaded in memory. At this point, it's better to abandon the original
- # iterator and save the content for later reuse. This is a temporary
- # solution. See the comment in __iter__ below for the long term plan.
- if self._base_content_is_iter:
- self.content = b''.join(self.make_bytes(e) for e in self._container)
-
@property
def content(self):
- self._consume_content()
return b''.join(self.make_bytes(e) for e in self._container)
@content.setter
def content(self, value):
if hasattr(value, '__iter__') and not isinstance(value, (bytes, six.string_types)):
- self._container = value
- self._base_content_is_iter = True
if hasattr(value, 'close'):
self._closable_objects.append(value)
- else:
- self._container = [value]
- self._base_content_is_iter = False
+ value = b''.join(self.make_bytes(e) for e in value)
+ self._container = [value]
def __iter__(self):
- # Raise a deprecation warning only if the content wasn't consumed yet,
- # because the response may be intended to be streamed.
- # Once the deprecation completes, iterators should be consumed upon
- # assignment rather than upon access. The _consume_content method
- # should be removed. See #6527.
- if self._base_content_is_iter:
- warnings.warn(
- 'Creating streaming responses with `HttpResponse` is '
- 'deprecated. Use `StreamingHttpResponse` instead '
- 'if you need the streaming behavior.',
- DeprecationWarning, stacklevel=2)
if not hasattr(self, '_iterator'):
self._iterator = iter(self._container)
return self
def write(self, content):
- self._consume_content()
self._container.append(content)
def tell(self):
- self._consume_content()
return len(self.content)
@@ -416,35 +389,6 @@ def streaming_content(self, value):
self._closable_objects.append(value)
-class CompatibleStreamingHttpResponse(StreamingHttpResponse):
- """
- This class maintains compatibility with middleware that doesn't know how
- to handle the content of a streaming response by exposing a `content`
- attribute that will consume and cache the content iterator when accessed.
-
- These responses will stream only if no middleware attempts to access the
- `content` attribute. Otherwise, they will behave like a regular response,
- and raise a `DeprecationWarning`.
- """
- @property
- def content(self):
- warnings.warn(
- 'Accessing the `content` attribute on a streaming response is '
- 'deprecated. Use the `streaming_content` attribute instead.',
- DeprecationWarning, stacklevel=2)
- content = b''.join(self)
- self.streaming_content = [content]
- return content
-
- @content.setter
- def content(self, content):
- warnings.warn(
- 'Accessing the `content` attribute on a streaming response is '
- 'deprecated. Use the `streaming_content` attribute instead.',
- DeprecationWarning, stacklevel=2)
- self.streaming_content = [content]
-
-
class HttpResponseRedirectBase(HttpResponse):
allowed_schemes = ['http', 'https', 'ftp']
@@ -478,7 +422,6 @@ def content(self, value):
if value:
raise AttributeError("You cannot set content to a 304 (Not Modified) response")
self._container = []
- self._base_content_is_iter = False
class HttpResponseBadRequest(HttpResponse):
8 django/views/static.py
View
@@ -14,8 +14,8 @@
except ImportError: # Python 2
from urllib import unquote
-from django.http import (CompatibleStreamingHttpResponse, Http404,
- HttpResponse, HttpResponseRedirect, HttpResponseNotModified)
+from django.http import (Http404, HttpResponse, HttpResponseRedirect,
+ HttpResponseNotModified, StreamingHttpResponse)
from django.template import loader, Template, Context, TemplateDoesNotExist
from django.utils.http import http_date, parse_http_date
from django.utils.translation import ugettext as _, ugettext_noop
@@ -63,8 +63,8 @@ def serve(request, path, document_root=None, show_indexes=False):
return HttpResponseNotModified()
content_type, encoding = mimetypes.guess_type(fullpath)
content_type = content_type or 'application/octet-stream'
- response = CompatibleStreamingHttpResponse(open(fullpath, 'rb'),
- content_type=content_type)
+ response = StreamingHttpResponse(open(fullpath, 'rb'),
+ content_type=content_type)
response["Last-Modified"] = http_date(statobj.st_mtime)
if stat.S_ISREG(statobj.st_mode):
response["Content-Length"] = statobj.st_size
25 tests/httpwrappers/tests.py
View
@@ -324,19 +324,10 @@ def test_iter_content(self):
r.content = [1, 2, 3]
self.assertEqual(r.content, b'123')
- #test retrieval explicitly using iter (deprecated) and odd inputs
+ #test odd inputs
r = HttpResponse()
r.content = ['1', '2', 3, '\u079e']
- with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always", DeprecationWarning)
- my_iter = iter(r)
- self.assertEqual(w[0].category, DeprecationWarning)
- with warnings.catch_warnings(record=True) as w:
- warnings.simplefilter("always", DeprecationWarning)
- result = list(my_iter)
- self.assertEqual(w[0].category, DeprecationWarning)
#'\xde\x9e' == unichr(1950).encode('utf-8')
- self.assertEqual(result, [b'1', b'2', b'3', b'\xde\x9e'])
self.assertEqual(r.content, b'123\xde\x9e')
#with Content-Encoding header
@@ -344,9 +335,8 @@ def test_iter_content(self):
r['Content-Encoding'] = 'winning'
r.content = [b'abc', b'def']
self.assertEqual(r.content, b'abcdef')
- r.content = ['\u079e']
self.assertRaises(TypeError if six.PY3 else UnicodeEncodeError,
- getattr, r, 'content')
+ setattr, r, 'content', ['\u079e'])
# .content can safely be accessed multiple times.
r = HttpResponse(iter(['hello', 'world']))
@@ -358,15 +348,12 @@ def test_iter_content(self):
# 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
+ # Accessing .content also works if the response was iterated first.
r = HttpResponse(iter(['hello', 'world']))
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- self.assertEqual(b''.join(r), b'helloworld')
- self.assertEqual(r.content, b'') # not the expected result!
+ self.assertEqual(b''.join(r), b'helloworld')
+ self.assertEqual(r.content, b'helloworld')
- # additional content can be written to the response.
+ # Additional content can be written to the response.
r = HttpResponse(iter(['hello', 'world']))
self.assertEqual(r.content, b'helloworld')
r.write('!')
Please sign in to comment.
Something went wrong with that request. Please try again.