From: Eric Larson Date: Thu, 7 Nov 2013 02:01:27 +0000 (-0600) Subject: Response and Request objects are pickleable. X-Git-Tag: v2.1.0~18^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=512beb8795f49ed474e3d679dda9524853853378;p=services%2Fpython-requests.git Response and Request objects are pickleable. Includes a basic test. More could be add to confirm known attributes that could cause problems. --- diff --git a/requests/models.py b/requests/models.py index f82f56a..81eb109 100644 --- a/requests/models.py +++ b/requests/models.py @@ -489,6 +489,19 @@ class Response(object): server's response to an HTTP request. """ + __attrs__ = [ + '_content', + 'status_code', + 'headers', + 'url', + 'history', + 'encoding', + 'reason', + 'cookies', + 'elapsed', + 'request', + ] + def __init__(self): super(Response, self).__init__() @@ -528,6 +541,24 @@ class Response(object): #: and the arrival of the response (as a timedelta) self.elapsed = datetime.timedelta(0) + def __getstate__(self): + # Consume everything; accessing the content attribute makes + # sure the content has been fully read. + if not self._content_consumed: + self.content + + return dict( + (attr, getattr(self, attr, None)) + for attr in self.__attrs__ + ) + + def __setstate__(self, state): + for name, value in state.items(): + setattr(self, name, value) + + # pickled objects do not have .raw + setattr(self, '_content_consumed', True) + def __repr__(self): return '' % (self.status_code) diff --git a/test_requests.py b/test_requests.py index 754581e..777137b 100755 --- a/test_requests.py +++ b/test_requests.py @@ -433,7 +433,7 @@ class RequestsTestCase(unittest.TestCase): prep = r.prepare() assert b'name="stuff"' in prep.body assert b'name="b\'stuff\'"' not in prep.body - + def test_unicode_method_name(self): files = {'file': open('test_requests.py', 'rb')} r = requests.request(method=u'POST', url=httpbin('post'), files=files) @@ -547,6 +547,18 @@ class RequestsTestCase(unittest.TestCase): assert next(iter(r)) io.close() + def test_request_and_response_are_pickleable(self): + r = requests.get(httpbin('get')) + + # verify we can pickle the original request + assert pickle.loads(pickle.dumps(r.request)) + + # verify we can pickle the response and that we have access to + # the original request. + pr = pickle.loads(pickle.dumps(r)) + assert r.request.url == pr.request.url + assert r.request.headers == pr.request.headers + def test_get_auth_from_url(self): url = 'http://user:pass@complex.url.com/path?query=yes' assert ('user', 'pass') == requests.utils.get_auth_from_url(url)