diff options
author | Ian Cordasco <graffatcolmingov@gmail.com> | 2014-11-17 22:13:35 -0600 |
---|---|---|
committer | Ian Cordasco <graffatcolmingov@gmail.com> | 2014-11-17 22:16:32 -0600 |
commit | c8baf881257ff3194879ad79bef81c27007b4dcf (patch) | |
tree | cfa8aef7d7385cf4df55452cc324e1435de1b991 | |
parent | 431282e77888e6601991d8c1e2481b3692f4194a (diff) | |
download | python-requests-c8baf881257ff3194879ad79bef81c27007b4dcf.tar.gz |
Properly serialize RecentlyUsedContainers for cache
RecentlyUsedContainers are threadsafe so they require a lock and as such
cannot be serialized with pickle directly. To handle it, we need to
convert it to a dictionary first and then back when deserializing.
Fixes #2345
-rw-r--r-- | requests/sessions.py | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/requests/sessions.py b/requests/sessions.py index c2f42b14..ba8eaa3d 100644 --- a/requests/sessions.py +++ b/requests/sessions.py @@ -36,6 +36,8 @@ from .status_codes import codes # formerly defined here, reexposed here for backward compatibility from .models import REDIRECT_STATI +REDIRECT_CACHE_SIZE = 1000 + def merge_setting(request_setting, session_setting, dict_class=OrderedDict): """ @@ -274,7 +276,7 @@ class Session(SessionRedirectMixin): __attrs__ = [ 'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify', 'cert', 'prefetch', 'adapters', 'stream', 'trust_env', - 'max_redirects', 'redirect_cache' + 'max_redirects', ] def __init__(self): @@ -329,7 +331,7 @@ class Session(SessionRedirectMixin): self.mount('http://', HTTPAdapter()) # Only store 1000 redirects to prevent using infinite memory - self.redirect_cache = RecentlyUsedContainer(1000) + self.redirect_cache = RecentlyUsedContainer(REDIRECT_CACHE_SIZE) def __enter__(self): return self @@ -660,12 +662,19 @@ class Session(SessionRedirectMixin): self.adapters[key] = self.adapters.pop(key) def __getstate__(self): - return dict((attr, getattr(self, attr, None)) for attr in self.__attrs__) + state = dict((attr, getattr(self, attr, None)) for attr in self.__attrs__) + state['redirect_cache'] = dict(self.redirect_cache) + return state def __setstate__(self, state): + redirect_cache = state.pop('redirect_cache', {}) for attr, value in state.items(): setattr(self, attr, value) + self.redirect_cache = RecentlyUsedContainer(REDIRECT_CACHE_SIZE) + for redirect, to in redirect_cache.items(): + self.redirect_cache[redirect] = to + def session(): """Returns a :class:`Session` for context-management.""" |