diff options
author | Jordan Cook <jordan.cook@pioneer.com> | 2022-02-15 12:47:04 -0600 |
---|---|---|
committer | Jordan Cook <jordan.cook@pioneer.com> | 2022-02-15 13:00:34 -0600 |
commit | 261bda40a5c2cf804fc40fff7838cc33a8b1b64e (patch) | |
tree | 4b5eca3acd7f9ece39ef247263a01d7aecbc280d | |
parent | 04ff30b8d95beef829031116a28faebd7ac51021 (diff) | |
download | requests-cache-261bda40a5c2cf804fc40fff7838cc33a8b1b64e.tar.gz |
Fix disabling expiration for a single request with `CachedSession.request(..., expire_after=-1)`
-rw-r--r-- | requests_cache/cache_control.py | 16 | ||||
-rw-r--r-- | tests/unit/test_session.py | 13 |
2 files changed, 21 insertions, 8 deletions
diff --git a/requests_cache/cache_control.py b/requests_cache/cache_control.py index d7d6f2c..81fbcac 100644 --- a/requests_cache/cache_control.py +++ b/requests_cache/cache_control.py @@ -27,8 +27,9 @@ if TYPE_CHECKING: __all__ = ['DO_NOT_CACHE', 'CacheActions'] -# May be set by either headers or expire_after param to disable caching +# May be set by either headers or expire_after param to disable caching or disable expiration DO_NOT_CACHE = 0 +NEVER_EXPIRE = -1 # Supported Cache-Control directives CACHE_DIRECTIVES = ['immutable', 'max-age', 'no-cache', 'no-store'] @@ -139,7 +140,7 @@ class CacheActions: # Check headers for expiration, validators, and other cache directives if directives.get('immutable'): - self.expire_after = -1 + self.expire_after = NEVER_EXPIRE else: self.expire_after = coalesce( directives.get('max-age'), directives.get('expires'), self.expire_after @@ -156,7 +157,7 @@ class CacheActions: def get_expiration_datetime(expire_after: ExpirationTime) -> Optional[datetime]: """Convert an expiration value in any supported format to an absolute datetime""" # Never expire - if expire_after is None or expire_after == -1: + if expire_after is None or expire_after == NEVER_EXPIRE: return None # Expire immediately elif try_int(expire_after) == DO_NOT_CACHE: @@ -173,10 +174,10 @@ def get_expiration_datetime(expire_after: ExpirationTime) -> Optional[datetime]: return datetime.utcnow() + expire_after -def get_expiration_seconds(expire_after: ExpirationTime) -> Optional[int]: +def get_expiration_seconds(expire_after: ExpirationTime) -> int: """Convert an expiration value in any supported format to an expiration time in seconds""" expires = get_expiration_datetime(expire_after) - return ceil((expires - datetime.utcnow()).total_seconds()) if expires else None + return ceil((expires - datetime.utcnow()).total_seconds()) if expires else NEVER_EXPIRE def get_cache_directives(headers: Mapping) -> Dict: @@ -242,7 +243,10 @@ def to_utc(dt: datetime): def try_int(value: Any) -> Optional[int]: """Convert a value to an int, if possible, otherwise ``None``""" - return int(str(value)) if str(value).isnumeric() else None + try: + return int(value) + except (TypeError, ValueError): + return None def url_match(url: str, pattern: str) -> bool: diff --git a/tests/unit/test_session.py b/tests/unit/test_session.py index 9fc5df0..09b491f 100644 --- a/tests/unit/test_session.py +++ b/tests/unit/test_session.py @@ -718,8 +718,8 @@ def test_remove_expired_responses__per_request(mock_session): assert len(mock_session.cache.responses) == 1 -def test_per_request__expiration(mock_session): - """No per-session expiration is set, but then overridden with per-request expiration""" +def test_per_request__enable_expiration(mock_session): + """No per-session expiration is set, but then overridden for a single request""" mock_session.expire_after = None response = mock_session.get(MOCKED_URL, expire_after=1) assert response.from_cache is False @@ -730,6 +730,15 @@ def test_per_request__expiration(mock_session): assert response.from_cache is False +def test_per_request__disable_expiration(mock_session): + """A per-session expiration is set, but then disabled for a single request""" + mock_session.expire_after = 60 + response = mock_session.get(MOCKED_URL, expire_after=-1) + response = mock_session.get(MOCKED_URL, expire_after=-1) + assert response.from_cache is True + assert response.expires is None + + def test_per_request__prepared_request(mock_session): """The same should work for PreparedRequests with CachedSession.send()""" mock_session.expire_after = None |