Skip to content

Commit 2c40585

Browse files
dogukanteberdvora-hchayim
authored
Add support for EXPIRE command's options (#2002)
* Add support for EXPIRE command's options * Add requested changes * Change method arguments * add variables to the function header Co-authored-by: dvora-h <[email protected]> Co-authored-by: Chayim <[email protected]> Co-authored-by: dvora-h <[email protected]>
1 parent a12b5fd commit 2c40585

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

redis/commands/core.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,16 +1501,42 @@ def exists(self, *names: KeyT) -> ResponseT:
15011501

15021502
__contains__ = exists
15031503

1504-
def expire(self, name: KeyT, time: ExpiryT) -> ResponseT:
1504+
def expire(
1505+
self,
1506+
name: KeyT,
1507+
time: ExpiryT,
1508+
nx: bool = False,
1509+
xx: bool = False,
1510+
gt: bool = False,
1511+
lt: bool = False,
1512+
) -> ResponseT:
15051513
"""
1506-
Set an expire flag on key ``name`` for ``time`` seconds. ``time``
1507-
can be represented by an integer or a Python timedelta object.
1514+
Set an expire flag on key ``name`` for ``time`` seconds with given
1515+
``option``. ``time`` can be represented by an integer or a Python timedelta
1516+
object.
1517+
1518+
Valid options are:
1519+
NX -> Set expiry only when the key has no expiry
1520+
XX -> Set expiry only when the key has an existing expiry
1521+
GT -> Set expiry only when the new expiry is greater than current one
1522+
LT -> Set expiry only when the new expiry is less than current one
15081523
15091524
For more information check https://redis.io/commands/expire
15101525
"""
15111526
if isinstance(time, datetime.timedelta):
15121527
time = int(time.total_seconds())
1513-
return self.execute_command("EXPIRE", name, time)
1528+
1529+
exp_option = list()
1530+
if nx:
1531+
exp_option.append("NX")
1532+
if xx:
1533+
exp_option.append("XX")
1534+
if gt:
1535+
exp_option.append("GT")
1536+
if lt:
1537+
exp_option.append("LT")
1538+
1539+
return self.execute_command("EXPIRE", name, time, *exp_option)
15141540

15151541
def expireat(self, name: KeyT, when: AbsExpiryT) -> ResponseT:
15161542
"""

tests/test_commands.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,31 @@ def test_expire(self, r):
10581058
assert r.persist("a")
10591059
assert r.ttl("a") == -1
10601060

1061+
@skip_if_server_version_lt("7.0.0")
1062+
def test_expire_option_nx(self, r):
1063+
r.set("key", "val")
1064+
assert r.expire("key", 100, nx=True) == 1
1065+
assert r.expire("key", 500, nx=True) == 0
1066+
1067+
@skip_if_server_version_lt("7.0.0")
1068+
def test_expire_option_xx(self, r):
1069+
r.set("key", "val")
1070+
assert r.expire("key", 100, xx=True) == 0
1071+
assert r.expire("key", 100)
1072+
assert r.expire("key", 500, nx=True) == 1
1073+
1074+
@skip_if_server_version_lt("7.0.0")
1075+
def test_expire_option_gt(self, r):
1076+
r.set("key", "val", 100)
1077+
assert r.expire("key", 50, gt=True) == 0
1078+
assert r.expire("key", 500, gt=True) == 1
1079+
1080+
@skip_if_server_version_lt("7.0.0")
1081+
def test_expire_option_lt(self, r):
1082+
r.set("key", "val", 100)
1083+
assert r.expire("key", 50, lt=True) == 1
1084+
assert r.expire("key", 150, lt=True) == 0
1085+
10611086
def test_expireat_datetime(self, r):
10621087
expire_at = redis_server_time(r) + datetime.timedelta(minutes=1)
10631088
r["a"] = "foo"

0 commit comments

Comments
 (0)