From ae1ac2d4e075fddf67b81e9aa19fbaf6e2c40941 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Thu, 21 Apr 2016 08:12:05 -0700 Subject: [PATCH] Flip conditional in session.send() Previously we checked that the `request` being sent was an instance of a PreparedRequest. If a user somehow created a PreparedRequest using a different Requests library instance, this check makes the request un-sendable. (This happened recently - unbeknownst to me, my server was running an outdated version of pip, vulnerable to this issue - pypa/pip#1489, which creates multiple subdirectories (src/requests, src/requests/requests) when you rerun pip install --target. So the PreparedRequest was being created in one version of the library and compared against the other version of the library, and throwing this exception, even though they were both PreparedRequest instances!) It would probably be preferable to check the object's behavior (instead of its type), but a PreparedRequest has a lot of behavior, and it wouldn't be really feasible or allow us to provide a helpful error message to check all of it here. Instead flip the conditional to guard against the user sending an unprepared Request, which should still give us most of the benefits of the better error message. Fixes #3102 --- requests/sessions.py | 2 +- tests/test_requests.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/requests/sessions.py b/requests/sessions.py index 0fad2543..45be9733 100644 --- a/requests/sessions.py +++ b/requests/sessions.py @@ -557,7 +557,7 @@ class Session(SessionRedirectMixin): # It's possible that users might accidentally send a Request object. # Guard against that specific failure case. - if not isinstance(request, PreparedRequest): + if isinstance(request, Request): raise ValueError('You can only send PreparedRequests.') # Set up variables needed for resolve_redirects and dispatching of hooks diff --git a/tests/test_requests.py b/tests/test_requests.py index ebef0ba3..26146674 100755 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -638,6 +638,14 @@ class TestRequests: resp = s.send(prep) assert resp.status_code == 200 + def test_non_prepared_request_error(self): + s = requests.Session() + req = requests.Request(u('POST'), '/') + + with pytest.raises(ValueError) as e: + s.send(req) + assert str(e.value) == 'You can only send PreparedRequests.' + def test_custom_content_type(self, httpbin): r = requests.post( httpbin('post'),