Skip to content

Commit

Permalink
Merge pull request psf#2825 from Lukasa/universal_newlines
Browse files Browse the repository at this point in the history
Add warnings about text/binary mode files.
sigmavirus24 committed Oct 24, 2015
2 parents 1dff6c9 + f1fd11e commit d290a9b
Showing 5 changed files with 66 additions and 4 deletions.
20 changes: 19 additions & 1 deletion docs/user/advanced.rst
Original file line number Diff line number Diff line change
@@ -315,6 +315,15 @@ file-like object for your body::
with open('massive-body', 'rb') as f:
requests.post('http://some.url/streamed', data=f)

.. warning:: It is strongly recommended that you open files in `binary mode`_.
This is because Requests may attempt to provide the
``Content-Length`` header for you, and if it does this value will
be set to the number of *bytes* in the file. Errors may occur if
you open the file in *text mode*.

.. _binary mode: https://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files


.. _chunk-encoding:

Chunk-Encoded Requests
@@ -362,6 +371,15 @@ To do that, just set files to a list of tuples of (form_field_name, file_info):
...
}

.. warning:: It is strongly recommended that you open files in `binary mode`_.
This is because Requests may attempt to provide the
``Content-Length`` header for you, and if it does this value will
be set to the number of *bytes* in the file. Errors may occur if
you open the file in *text mode*.

.. _binary mode: https://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files


.. _event-hooks:

Event Hooks
@@ -519,7 +537,7 @@ any request to the given scheme and exact hostname.
}

Note that proxy URLs must include the scheme.

.. _compliance:

Compliance
8 changes: 8 additions & 0 deletions docs/user/quickstart.rst
Original file line number Diff line number Diff line change
@@ -302,6 +302,14 @@ support this, but there is a separate package which does -
For sending multiple files in one request refer to the :ref:`advanced <advanced>`
section.

.. warning:: It is strongly recommended that you open files in `binary mode`_.
This is because Requests may attempt to provide the
``Content-Length`` header for you, and if it does this value will
be set to the number of *bytes* in the file. Errors may occur if
you open the file in *text mode*.

.. _binary mode: https://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files


Response Status Codes
---------------------
8 changes: 7 additions & 1 deletion requests/__init__.py
Original file line number Diff line number Diff line change
@@ -62,7 +62,8 @@
from .status_codes import codes
from .exceptions import (
RequestException, Timeout, URLRequired,
TooManyRedirects, HTTPError, ConnectionError
TooManyRedirects, HTTPError, ConnectionError,
FileModeWarning,
)

# Set default logging handler to avoid "No handler found" warnings.
@@ -75,3 +76,8 @@ def emit(self, record):
pass

logging.getLogger(__name__).addHandler(NullHandler())

import warnings

# FileModeWarnings go off per the default.
warnings.simplefilter('default', FileModeWarning, append=True)
15 changes: 15 additions & 0 deletions requests/exceptions.py
Original file line number Diff line number Diff line change
@@ -97,3 +97,18 @@ class StreamConsumedError(RequestException, TypeError):

class RetryError(RequestException):
"""Custom retries logic failed"""


# Warnings


class RequestsWarning(Warning):
"""Base warning for Requests."""
pass


class FileModeWarning(RequestsWarning, DeprecationWarning):
"""
A file was opened in text mode, but Requests determined its binary length.
"""
pass
19 changes: 17 additions & 2 deletions requests/utils.py
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@
basestring)
from .cookies import RequestsCookieJar, cookiejar_from_dict
from .structures import CaseInsensitiveDict
from .exceptions import InvalidURL
from .exceptions import InvalidURL, FileModeWarning

_hush_pyflakes = (RequestsCookieJar,)

@@ -60,7 +60,22 @@ def super_len(o):
except io.UnsupportedOperation:
pass
else:
return os.fstat(fileno).st_size
filesize = os.fstat(fileno).st_size

# Having used fstat to determine the file length, we need to
# confirm that this file was opened up in binary mode.
if 'b' not in o.mode:
warnings.warn((
"Requests has determined the content-length for this "
"request using the binary size of the file: however, the "
"file has been opened in text mode (i.e. without the 'b' "
"flag in the mode). This may lead to an incorrect "
"content-length. In Requests 3.0, support will be removed "
"for files in text mode."),
FileModeWarning
)

return filesize

if hasattr(o, 'getvalue'):
# e.g. BytesIO, cStringIO.StringIO

0 comments on commit d290a9b

Please sign in to comment.