summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Cook <jordan.cook@pioneer.com>2022-02-15 12:47:04 -0600
committerJordan Cook <jordan.cook@pioneer.com>2022-02-15 13:00:34 -0600
commit261bda40a5c2cf804fc40fff7838cc33a8b1b64e (patch)
tree4b5eca3acd7f9ece39ef247263a01d7aecbc280d
parent04ff30b8d95beef829031116a28faebd7ac51021 (diff)
downloadrequests-cache-261bda40a5c2cf804fc40fff7838cc33a8b1b64e.tar.gz
Fix disabling expiration for a single request with `CachedSession.request(..., expire_after=-1)`
-rw-r--r--requests_cache/cache_control.py16
-rw-r--r--tests/unit/test_session.py13
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