From 446bbc87ca37ed0b620317d33eee4121a2a334b8 Mon Sep 17 00:00:00 2001 From: Jordan Cook Date: Thu, 20 Oct 2022 13:07:20 -0500 Subject: [PATCH] Explicitly disable pickling CachedSession objects Fixes #707 (for 0.9) --- HISTORY.md | 6 ++++++ requests_cache/session.py | 6 ++++++ tests/unit/test_session.py | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index be41a265..6fc6d880 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,20 +1,26 @@ # History ## 0.9.7 (Unreleased) +Backport fixes from 1.0: * Fix potential `AttributeError` due to undetected imports when requests-cache is bundled in a PyInstaller package +* Fix `AttributeError` when attempting to unpickle a `CachedSession` object, and instead disable + pickling by raising a `NotImplementedError` * Update to cattrs 22.2 ## 0.9.6 (2022-08-24) +Backport fixes from 1.0: * Remove potentially problematic row count from `BaseCache.__str__()` * Remove upper version constraints for all non-dev dependencies * Make dependency specification consistent between PyPI and Conda-Forge packages ## 0.9.5 (2022-06-29) +Backport fixes from 1.0: * Fix usage of memory backend with `install_cache()` * Add `CachedRequest.path_url` property * Add compatibility with cattrs 22.1 ## 0.9.4 (2022-04-22) +Backport fixes from 1.0: * Fix forwarding connection parameters passed to `RedisCache` for redis-py 4.2 and python <=3.8 * Fix forwarding connection parameters passed to `MongoCache` for pymongo 4.1 and python <=3.8 diff --git a/requests_cache/session.py b/requests_cache/session.py index 79f10ccb..a334cd21 100644 --- a/requests_cache/session.py +++ b/requests_cache/session.py @@ -280,6 +280,12 @@ def remove_expired_responses(self, expire_after: ExpirationTime = None): """ self.cache.remove_expired_responses(expire_after) + def __getstate__(self): + # Unlike requests.Session, CachedSession may contain backend connection objects that can't + # be pickled. Support for this could be added if necessary, but for now it's explicitly + # disabled to avoid confusing errors upon unpickling. + raise NotImplementedError('CachedSession cannot be pickled') + def __repr__(self): repr_attrs = [ 'cache', diff --git a/tests/unit/test_session.py b/tests/unit/test_session.py index 5cde35b5..343a2178 100644 --- a/tests/unit/test_session.py +++ b/tests/unit/test_session.py @@ -1,6 +1,7 @@ """CachedSession + BaseCache tests that use mocked responses only""" # TODO: This could be split up into some smaller test modules import json +import pickle import time from collections import UserDict, defaultdict from datetime import datetime, timedelta @@ -78,6 +79,11 @@ def test_init_backend_class(): assert session.cache.cache_name == 'test_cache' +def test_pickle__disabled(): + with pytest.raises(NotImplementedError): + pickle.dumps(CachedSession(backend='memory')) + + @pytest.mark.parametrize('method', ALL_METHODS) @pytest.mark.parametrize('field', ['params', 'data', 'json']) def test_all_methods(field, method, mock_session):