diff --git a/redis/commands.py b/redis/commands.py index 003b0f1bcc..bd31b5b265 100644 --- a/redis/commands.py +++ b/redis/commands.py @@ -1014,7 +1014,8 @@ def restore(self, name, ttl, value, replace=False, absttl=False): return self.execute_command('RESTORE', *params) def set(self, name, value, - ex=None, px=None, nx=False, xx=False, keepttl=False, get=False): + ex=None, px=None, nx=False, xx=False, keepttl=False, get=False, + exat=None, pxat=None): """ Set the value at key ``name`` to ``value`` @@ -1034,6 +1035,12 @@ def set(self, name, value, ``get`` if True, set the value at key ``name`` to ``value`` and return the old value stored at key, or None when key did not exist. (Available since Redis 6.2) + + ``exat`` sets an expire flag on key ``name`` for ``ex`` seconds, + specified in unix time. + + ``pxat`` sets an expire flag on key ``name`` for ``ex`` milliseconds, + specified in unix time. """ pieces = [name, value] options = {} @@ -1047,15 +1054,26 @@ def set(self, name, value, if isinstance(px, datetime.timedelta): px = int(px.total_seconds() * 1000) pieces.append(px) + if exat is not None: + pieces.append('EXAT') + if isinstance(exat, datetime.datetime): + s = int(exat.microsecond / 1000000) + exat = int(time.mktime(exat.timetuple())) + s + pieces.append(exat) + if pxat is not None: + pieces.append('PXAT') + if isinstance(pxat, datetime.datetime): + ms = int(pxat.microsecond / 1000) + pxat = int(time.mktime(pxat.timetuple())) * 1000 + ms + pieces.append(pxat) + if keepttl: + pieces.append('KEEPTTL') if nx: pieces.append('NX') if xx: pieces.append('XX') - if keepttl: - pieces.append('KEEPTTL') - if get: pieces.append('GET') options["get"] = True diff --git a/tests/test_commands.py b/tests/test_commands.py index 3c87dd9dd6..b5d2ecbeff 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -1011,6 +1011,18 @@ def test_set_ex_timedelta(self, r): assert r.set('a', '1', ex=expire_at) assert 0 < r.ttl('a') <= 60 + @skip_if_server_version_lt('6.2.0') + def test_set_exat_timedelta(self, r): + expire_at = redis_server_time(r) + datetime.timedelta(seconds=10) + assert r.set('a', '1', exat=expire_at) + assert 0 < r.ttl('a') <= 10 + + @skip_if_server_version_lt('6.2.0') + def test_set_pxat_timedelta(self, r): + expire_at = redis_server_time(r) + datetime.timedelta(seconds=10) + assert r.set('a', '1', pxat=expire_at) + assert 0 < r.ttl('a') <= 10 + @skip_if_server_version_lt('2.6.0') def test_set_multipleoptions(self, r): r['a'] = 'val'