mirror of
https://github.com/kennethreitz/requests.git
synced 2026-06-05 22:50:18 +00:00
Allow Requests.Response to be used as a context manager
This saves having to wrap the call to requests with
`contextlib.closing()`, allowing it to be used directly in a
`with` statement, like so:
```
with requests.get('http://httpbin.org/get', stream=True) as r:
# Do things with the response here.
```
Fixes #4136.
This commit is contained in:
@@ -183,3 +183,4 @@ Patches and Suggestions
|
||||
- Shmuel Amar (`@shmuelamar <https://github.com/shmuelamar>`_)
|
||||
- Gary Wu (`@garywu <https://github.com/garywu>`_)
|
||||
- Ryan Pineo (`@ryanpineo <https://github.com/ryanpineo>`_)
|
||||
- Ed Morley (`@edmorley <https://github.com/edmorley>`_)
|
||||
|
||||
@@ -6,6 +6,11 @@ Release History
|
||||
dev
|
||||
+++
|
||||
|
||||
**Improvements**
|
||||
|
||||
- ``Response`` is now a context manager, so can be used directly in a `with` statement
|
||||
without first having to be wrapped by ``contextlib.closing()``.
|
||||
|
||||
**Bugfixes**
|
||||
|
||||
- Resolve installation failure if multiprocessing is not available
|
||||
|
||||
@@ -301,15 +301,11 @@ release the connection back to the pool unless you consume all the data or call
|
||||
:meth:`Response.close <requests.Response.close>`. This can lead to
|
||||
inefficiency with connections. If you find yourself partially reading request
|
||||
bodies (or not reading them at all) while using ``stream=True``, you should
|
||||
consider using ``contextlib.closing`` (`documented here`_), like this::
|
||||
make the request within a ``with`` statement to ensure it's always closed::
|
||||
|
||||
from contextlib import closing
|
||||
|
||||
with closing(requests.get('http://httpbin.org/get', stream=True)) as r:
|
||||
with requests.get('http://httpbin.org/get', stream=True) as r:
|
||||
# Do things with the response here.
|
||||
|
||||
.. _`documented here`: http://docs.python.org/2/library/contextlib.html#contextlib.closing
|
||||
|
||||
.. _keep-alive:
|
||||
|
||||
Keep-Alive
|
||||
|
||||
@@ -634,6 +634,12 @@ class Response(object):
|
||||
#: is a response.
|
||||
self.request = None
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.close()
|
||||
|
||||
def __getstate__(self):
|
||||
# Consume everything; accessing the content attribute makes
|
||||
# sure the content has been fully read.
|
||||
|
||||
@@ -1668,6 +1668,12 @@ class TestRequests:
|
||||
next(it)
|
||||
assert len(list(it)) == 3
|
||||
|
||||
def test_response_context_manager(self, httpbin):
|
||||
with requests.get(httpbin('stream/4'), stream=True) as response:
|
||||
assert isinstance(response, requests.Response)
|
||||
|
||||
assert response.raw.closed
|
||||
|
||||
def test_unconsumed_session_response_closes_connection(self, httpbin):
|
||||
s = requests.session()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user