mirror of
https://github.com/kennethreitz/requests.git
synced 2026-06-05 22:50:18 +00:00
consolidate super_len code and cleanup docstrings
This commit is contained in:
@@ -104,12 +104,15 @@ class StreamConsumedError(RequestException, TypeError):
|
||||
class RetryError(RequestException):
|
||||
"""Custom retries logic failed"""
|
||||
|
||||
|
||||
class UnrewindableBodyError(RequestException):
|
||||
"""Requests encountered an error when trying to rewind a body"""
|
||||
|
||||
|
||||
class ConflictingHeaderError(RequestException):
|
||||
"""Mutually exclusive request headers set"""
|
||||
|
||||
|
||||
class InvalidBodyError(RequestException, ValueError):
|
||||
"""An invalid request body was specified"""
|
||||
|
||||
|
||||
+11
-17
@@ -39,7 +39,7 @@ from .utils import (
|
||||
guess_filename, get_auth_from_url, requote_uri,
|
||||
stream_decode_response_unicode, to_key_val_list, parse_header_links,
|
||||
iter_slices, guess_json_utf, super_len, check_header_validity,
|
||||
determine_if_stream)
|
||||
is_stream)
|
||||
from .compat import (
|
||||
cookielib, urlunparse, urlsplit, urlencode, str, bytes, StringIO,
|
||||
is_py2, chardet, builtin_str, basestring)
|
||||
@@ -468,9 +468,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
|
||||
if not isinstance(body, bytes):
|
||||
body = body.encode('utf-8')
|
||||
|
||||
is_stream = determine_if_stream(data)
|
||||
|
||||
if is_stream:
|
||||
if is_stream(data):
|
||||
body = data
|
||||
|
||||
if getattr(body, 'tell', None) is not None:
|
||||
@@ -509,30 +507,26 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
|
||||
def prepare_content_length(self, body):
|
||||
"""Prepares Content-Length header.
|
||||
|
||||
If the length of the body of the request can be computed, Content-Length is set using
|
||||
super_len. If user has manually set either a Transfer-Encoding or Content-Length header
|
||||
when it should not be set (they should be mutually exclusive) an ConflictingHeaderError
|
||||
If the length of the body of the request can be computed, Content-Length
|
||||
is set using ``super_len``. If user has manually set either a
|
||||
Transfer-Encoding or Content-Length header when it should not be set
|
||||
(they should be mutually exclusive) a ConflictingHeaderError
|
||||
error will be raised.
|
||||
"""
|
||||
if body is not None:
|
||||
is_stream = determine_if_stream(body)
|
||||
|
||||
try:
|
||||
length = super_len(body)
|
||||
except (TypeError, AttributeError, UnsupportedOperation):
|
||||
length = None
|
||||
length = super_len(body)
|
||||
|
||||
if length:
|
||||
self.headers['Content-Length'] = builtin_str(length)
|
||||
elif is_stream and not length:
|
||||
elif is_stream(body):
|
||||
self.headers['Transfer-Encoding'] = 'chunked'
|
||||
else:
|
||||
raise InvalidBodyError("Non-null body must have length or be streamable")
|
||||
elif (self.method not in ('GET', 'HEAD')) and (self.headers.get('Content-Length') is None):
|
||||
raise InvalidBodyError('Non-null body must have length or be streamable.')
|
||||
elif self.method not in ('GET', 'HEAD') and self.headers.get('Content-Length') is None:
|
||||
self.headers['Content-Length'] = '0'
|
||||
|
||||
if 'Transfer-Encoding' in self.headers and 'Content-Length' in self.headers:
|
||||
raise ConflictingHeaderError('Transfer-Encoding and Content-Length headers both set')
|
||||
raise ConflictingHeaderError('Transfer-Encoding and Content-Length headers both set.')
|
||||
|
||||
def prepare_auth(self, auth, url=''):
|
||||
"""Prepares the given HTTP auth data."""
|
||||
|
||||
+3
-4
@@ -881,9 +881,8 @@ def rewind_body(prepared_request):
|
||||
raise UnrewindableBodyError("Unable to rewind request body for redirect.")
|
||||
|
||||
|
||||
def determine_if_stream(data):
|
||||
"""Given data, determines if it should be sent as a stream.
|
||||
"""
|
||||
def is_stream(data):
|
||||
"""Given data, determines if it should be sent as a stream."""
|
||||
is_iterable = getattr(data, '__iter__', False)
|
||||
is_io_type = not isinstance(data, (basestring, list, tuple, dict))
|
||||
is_io_type = not isinstance(data, (basestring, list, tuple, collections.Mapping))
|
||||
return is_iterable and is_io_type
|
||||
|
||||
@@ -1925,16 +1925,18 @@ class TestRequests:
|
||||
assert 'Content-Length' not in prepared_request.headers
|
||||
|
||||
def test_chunked_upload_with_manually_set_content_length_header_raises_error(self, httpbin):
|
||||
"""Ensure that if a user manually sets a content length header when the data
|
||||
is chunked that an ConflictingHeaderError is raised"""
|
||||
data = (i for i in [b'a', b'b', b'c'])
|
||||
"""Ensure that if a user manually sets a content length header, when
|
||||
the data is chunked, that a ConflictingHeaderError is raised.
|
||||
"""
|
||||
data = (i for i in [b'a', b'b', b'c'])
|
||||
url = httpbin('post')
|
||||
with pytest.raises(ConflictingHeaderError):
|
||||
r = requests.post(url, data=data, headers={'Content-Length': 'foo'})
|
||||
|
||||
def test_content_length_with_manually_set_transfer_encoding_raises_error(self, httpbin):
|
||||
"""Ensure that if a user manually sets a Transfer-Encoding header when data is not chunked
|
||||
that an ConflictingHeaderError is raised"""
|
||||
"""Ensure that if a user manually sets a Transfer-Encoding header when
|
||||
data is not chunked that an ConflictingHeaderError is raised.
|
||||
"""
|
||||
data = 'test data'
|
||||
url = httpbin('post')
|
||||
with pytest.raises(ConflictingHeaderError):
|
||||
@@ -1945,7 +1947,7 @@ class TestRequests:
|
||||
try:
|
||||
requests.post(url, data=None)
|
||||
except ConflictingHeaderError:
|
||||
pytest.fail('ConflictingHeaderError raised')
|
||||
pytest.fail('ConflictingHeaderError raised.')
|
||||
|
||||
def test_custom_redirect_mixin(self, httpbin):
|
||||
"""Tests a custom mixin to overwrite ``get_redirect_target``.
|
||||
|
||||
Reference in New Issue
Block a user