Skip to content

Commit eac3a34

Browse files
dogukanteberchayimdvora-h
authored
Add support for EXPIREAT command's options (#2024)
* Add support for EXPIREAT command's options * Fix linter errors * Make changes on method arguments * Fix linter errors * add variables to the function header Co-authored-by: Chayim <chayim@users.noreply.github.com> Co-authored-by: dvora-h <dvora.heller@redis.com>
1 parent 2c40585 commit eac3a34

File tree

2 files changed

+67
-4
lines changed

2 files changed

+67
-4
lines changed

redis/commands/core.py

+30-4
Original file line numberDiff line numberDiff line change
@@ -1538,16 +1538,42 @@ def expire(
15381538

15391539
return self.execute_command("EXPIRE", name, time, *exp_option)
15401540

1541-
def expireat(self, name: KeyT, when: AbsExpiryT) -> ResponseT:
1541+
def expireat(
1542+
self,
1543+
name: KeyT,
1544+
when: AbsExpiryT,
1545+
nx: bool = False,
1546+
xx: bool = False,
1547+
gt: bool = False,
1548+
lt: bool = False,
1549+
) -> ResponseT:
15421550
"""
1543-
Set an expire flag on key ``name``. ``when`` can be represented
1544-
as an integer indicating unix time or a Python datetime object.
1551+
Set an expire flag on key ``name`` with given ``option``. ``when``
1552+
can be represented as an integer indicating unix time or a Python
1553+
datetime object.
1554+
1555+
Valid options are:
1556+
-> NX -- Set expiry only when the key has no expiry
1557+
-> XX -- Set expiry only when the key has an existing expiry
1558+
-> GT -- Set expiry only when the new expiry is greater than current one
1559+
-> LT -- Set expiry only when the new expiry is less than current one
15451560
15461561
For more information check https://redis.io/commands/expireat
15471562
"""
15481563
if isinstance(when, datetime.datetime):
15491564
when = int(time.mktime(when.timetuple()))
1550-
return self.execute_command("EXPIREAT", name, when)
1565+
1566+
exp_option = list()
1567+
if nx:
1568+
exp_option.append("NX")
1569+
if xx:
1570+
exp_option.append("XX")
1571+
if gt:
1572+
exp_option.append("GT")
1573+
if lt:
1574+
exp_option.append("LT")
1575+
1576+
return self.execute_command("EXPIREAT", name, when, *exp_option)
15511577

15521578
def expiretime(self, key: str) -> int:
15531579
"""

tests/test_commands.py

+37
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,43 @@ def test_expiretime(self, r):
11061106
r.expireat("a", 33177117420)
11071107
assert r.expiretime("a") == 33177117420
11081108

1109+
@skip_if_server_version_lt("7.0.0")
1110+
def test_expireat_option_nx(self, r):
1111+
assert r.set("key", "val") is True
1112+
expire_at = redis_server_time(r) + datetime.timedelta(minutes=1)
1113+
assert r.expireat("key", expire_at, nx=True) is True
1114+
expire_at = redis_server_time(r) + datetime.timedelta(minutes=2)
1115+
assert r.expireat("key", expire_at, nx=True) is False
1116+
1117+
@skip_if_server_version_lt("7.0.0")
1118+
def test_expireat_option_xx(self, r):
1119+
assert r.set("key", "val") is True
1120+
expire_at = redis_server_time(r) + datetime.timedelta(minutes=1)
1121+
assert r.expireat("key", expire_at, xx=True) is False
1122+
assert r.expireat("key", expire_at) is True
1123+
expire_at = redis_server_time(r) + datetime.timedelta(minutes=2)
1124+
assert r.expireat("key", expire_at, xx=True) is True
1125+
1126+
@skip_if_server_version_lt("7.0.0")
1127+
def test_expireat_option_gt(self, r):
1128+
expire_at = redis_server_time(r) + datetime.timedelta(minutes=2)
1129+
assert r.set("key", "val") is True
1130+
assert r.expireat("key", expire_at) is True
1131+
expire_at = redis_server_time(r) + datetime.timedelta(minutes=1)
1132+
assert r.expireat("key", expire_at, gt=True) is False
1133+
expire_at = redis_server_time(r) + datetime.timedelta(minutes=3)
1134+
assert r.expireat("key", expire_at, gt=True) is True
1135+
1136+
@skip_if_server_version_lt("7.0.0")
1137+
def test_expireat_option_lt(self, r):
1138+
expire_at = redis_server_time(r) + datetime.timedelta(minutes=2)
1139+
assert r.set("key", "val") is True
1140+
assert r.expireat("key", expire_at) is True
1141+
expire_at = redis_server_time(r) + datetime.timedelta(minutes=3)
1142+
assert r.expireat("key", expire_at, lt=True) is False
1143+
expire_at = redis_server_time(r) + datetime.timedelta(minutes=1)
1144+
assert r.expireat("key", expire_at, lt=True) is True
1145+
11091146
def test_get_and_set(self, r):
11101147
# get and set can't be tested independently of each other
11111148
assert r.get("a") is None

0 commit comments

Comments
 (0)