Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/730.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add option flags nx, xx, gt, lt for expire and pexpire
12 changes: 10 additions & 2 deletions django_redis/client/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,10 @@ def expire(
timeout: ExpiryT,
version: Optional[int] = None,
client: Optional[Redis] = None,
nx: bool = False,
xx: bool = False,
gt: bool = False,
lt: bool = False,
) -> bool:
if timeout is DEFAULT_TIMEOUT:
timeout = self._backend.default_timeout # type: ignore
Expand All @@ -309,14 +313,18 @@ def expire(

# for some strange reason mypy complains,
# saying that timeout type is float | timedelta
return client.expire(key, timeout) # type: ignore
return client.expire(key, timeout, nx, xx, gt, lt) # type: ignore

def pexpire(
self,
key: KeyT,
timeout: ExpiryT,
version: Optional[int] = None,
client: Optional[Redis] = None,
nx: bool = False,
xx: bool = False,
gt: bool = False,
lt: bool = False,
) -> bool:
if timeout is DEFAULT_TIMEOUT:
timeout = self._backend.default_timeout # type: ignore
Expand All @@ -330,7 +338,7 @@ def pexpire(
# is fixed.
# for some strange reason mypy complains,
# saying that timeout type is float | timedelta
return bool(client.pexpire(key, timeout)) # type: ignore
return bool(client.pexpire(key, timeout, nx, xx, gt, lt)) # type: ignore

def pexpire_at(
self,
Expand Down
46 changes: 42 additions & 4 deletions django_redis/client/sharded.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,19 +169,57 @@ def persist(self, key, version=None, client=None):

return super().persist(key=key, version=version, client=client)

def expire(self, key, timeout, version=None, client=None):
def expire(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about type hints?

self,
key,
timeout,
version=None,
client=None,
nx=False,
xx=False,
gt=False,
lt=False,
):
if client is None:
key = self.make_key(key, version=version)
client = self.get_server(key)

return super().expire(key=key, timeout=timeout, version=version, client=client)
return super().expire(
key=key,
timeout=timeout,
version=version,
client=client,
nx=nx,
xx=xx,
gt=gt,
lt=lt,
)

def pexpire(self, key, timeout, version=None, client=None):
def pexpire(
self,
key,
timeout,
version=None,
client=None,
nx=False,
xx=False,
gt=False,
lt=False,
):
if client is None:
key = self.make_key(key, version=version)
client = self.get_server(key)

return super().pexpire(key=key, timeout=timeout, version=version, client=client)
return super().pexpire(
key=key,
timeout=timeout,
version=version,
client=client,
nx=nx,
xx=xx,
gt=gt,
lt=lt,
)

def pexpire_at(self, key, when: Union[datetime, int], version=None, client=None):
"""
Expand Down
12 changes: 12 additions & 0 deletions tests/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,12 @@ def test_expire(self, cache: RedisCache):
ttl = cache.ttl("foo")
assert pytest.approx(ttl) == 20
assert cache.expire("not-existent-key", 20) is False
cache.set("key1", "value1", timeout=None)
assert cache.expire("key1", 20, nx=True) is True
cache.set("key2", "value2", timeout=20)
assert cache.expire("key2", 21, xx=True) is True
assert cache.expire("key2", 30, gt=True) is True
assert cache.expire("key2", 20, lt=True) is True
Comment on lines +609 to +614
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to check also ttl after, please add separate tests or use parametrize


def test_expire_with_default_timeout(self, cache: RedisCache):
cache.set("foo", "bar", timeout=None)
Expand All @@ -619,6 +625,12 @@ def test_pexpire(self, cache: RedisCache):
# delta is set to 10 as precision error causes tests to fail
assert pytest.approx(ttl, 10) == 20500
assert cache.pexpire("not-existent-key", 20500) is False
cache.set("key1", "value1", timeout=None)
assert cache.pexpire("key1", 20000, nx=True) is True
cache.set("key2", "value2", timeout=20000)
assert cache.expire("key2", 20500, xx=True) is True
assert cache.expire("key2", 30000, gt=True) is True
assert cache.expire("key2", 20000, lt=True) is True
Comment on lines +628 to +633
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as the above


def test_pexpire_with_default_timeout(self, cache: RedisCache):
cache.set("foo", "bar", timeout=None)
Expand Down