From 62200cb07e76b0b6189bc64d1ca35d43514d0566 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 7 Mar 2015 09:40:25 +0200 Subject: [PATCH 1/2] Add testcase to demonstrate r.iter_lines() reentrancy issue --- test_requests.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test_requests.py b/test_requests.py index 07430a8e..15406a22 100755 --- a/test_requests.py +++ b/test_requests.py @@ -1052,6 +1052,23 @@ class RequestsTestCase(unittest.TestCase): assert 'application/json' in r.request.headers['Content-Type'] assert {'life': 42} == r.json()['json'] + def test_response_iter_lines(self): + r = requests.get(httpbin('stream/4'), stream=True) + assert r.status_code == 200 + + it = r.iter_lines() + next(it) + assert len(list(it)) == 3 + + @pytest.mark.xfail + def test_response_iter_lines_reentrant(self): + """Response.iter_lines() is not reentrant safe""" + r = requests.get(httpbin('stream/4'), stream=True) + assert r.status_code == 200 + + next(r.iter_lines()) + assert len(list(r.iter_lines())) == 3 + class TestContentEncodingDetection(unittest.TestCase): From 4497a26c376c60360d05644b574be0db3c887fe3 Mon Sep 17 00:00:00 2001 From: Priit Laes Date: Sat, 7 Mar 2015 11:04:43 +0200 Subject: [PATCH 2/2] Document Response.iter_lines() reentrancy issues --- docs/user/advanced.rst | 13 +++++++++++++ requests/models.py | 2 ++ 2 files changed, 15 insertions(+) diff --git a/docs/user/advanced.rst b/docs/user/advanced.rst index ed990666..a2fe653b 100644 --- a/docs/user/advanced.rst +++ b/docs/user/advanced.rst @@ -399,6 +399,19 @@ set ``stream`` to ``True`` and iterate over the response with if line: print(json.loads(line)) +.. warning:: + + :class:`~requests.Response.iter_lines()` is not reentrant safe. + Calling this method multiple times causes some of the received data + being lost. In case you need to call it from multiple places, use + the resulting iterator object instead:: + + lines = r.iter_lines() + # Save the first line for later or just skip it + first_line = next(lines) + for line in lines: + print(line) + .. _proxies: Proxies diff --git a/requests/models.py b/requests/models.py index 4b2648f6..ce1eb40e 100644 --- a/requests/models.py +++ b/requests/models.py @@ -688,6 +688,8 @@ class Response(object): """Iterates over the response data, one line at a time. When stream=True is set on the request, this avoids reading the content at once into memory for large responses. + + .. note:: This method is not reentrant safe. """ pending = None