Skip to content

Commit 2789f08

Browse files
author
Jiekun
authored
Added GET argument to SET command (#1412)
1 parent 8c4fc80 commit 2789f08

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

redis/client.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,20 @@ def parse_module_result(response):
555555
return True
556556

557557

558+
def parse_set_result(response, **options):
559+
"""
560+
Handle SET result since GET argument is available since Redis 6.2.
561+
Parsing SET result into:
562+
- BOOL
563+
- String when GET argument is used
564+
"""
565+
if options.get('get'):
566+
# Redis will return a getCommand result.
567+
# See `setGenericCommand` in t_string.c
568+
return response
569+
return response and str_if_bytes(response) == 'OK'
570+
571+
558572
class Redis:
559573
"""
560574
Implementation of the Redis protocol.
@@ -683,7 +697,7 @@ class Redis:
683697
'SENTINEL SENTINELS': parse_sentinel_slaves_and_sentinels,
684698
'SENTINEL SET': bool_ok,
685699
'SENTINEL SLAVES': parse_sentinel_slaves_and_sentinels,
686-
'SET': lambda r: r and str_if_bytes(r) == 'OK',
700+
'SET': parse_set_result,
687701
'SLOWLOG GET': parse_slowlog_get,
688702
'SLOWLOG LEN': int,
689703
'SLOWLOG RESET': bool_ok,
@@ -1804,6 +1818,9 @@ def getset(self, name, value):
18041818
"""
18051819
Sets the value at key ``name`` to ``value``
18061820
and returns the old value at key ``name`` atomically.
1821+
1822+
As per Redis 6.2, GETSET is considered deprecated.
1823+
Please use SET with GET parameter in new code.
18071824
"""
18081825
return self.execute_command('GETSET', name, value)
18091826

@@ -1964,7 +1981,7 @@ def restore(self, name, ttl, value, replace=False, absttl=False):
19641981
return self.execute_command('RESTORE', *params)
19651982

19661983
def set(self, name, value,
1967-
ex=None, px=None, nx=False, xx=False, keepttl=False):
1984+
ex=None, px=None, nx=False, xx=False, keepttl=False, get=False):
19681985
"""
19691986
Set the value at key ``name`` to ``value``
19701987
@@ -1980,8 +1997,13 @@ def set(self, name, value,
19801997
19811998
``keepttl`` if True, retain the time to live associated with the key.
19821999
(Available since Redis 6.0)
2000+
2001+
``get`` if True, set the value at key ``name`` to ``value`` and return
2002+
the old value stored at key, or None when key did not exist.
2003+
(Available since Redis 6.2)
19832004
"""
19842005
pieces = [name, value]
2006+
options = {}
19852007
if ex is not None:
19862008
pieces.append('EX')
19872009
if isinstance(ex, datetime.timedelta):
@@ -2001,7 +2023,11 @@ def set(self, name, value,
20012023
if keepttl:
20022024
pieces.append('KEEPTTL')
20032025

2004-
return self.execute_command('SET', *pieces)
2026+
if get:
2027+
pieces.append('GET')
2028+
options["get"] = True
2029+
2030+
return self.execute_command('SET', *pieces, **options)
20052031

20062032
def __setitem__(self, name, value):
20072033
self.set(name, value)

tests/test_commands.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,14 @@ def test_set_keepttl(self, r):
10061006
assert r.get('a') == b'2'
10071007
assert 0 < r.ttl('a') <= 10
10081008

1009+
@skip_if_server_version_lt('6.2.0')
1010+
def test_set_get(self, r):
1011+
assert r.set('a', 'True', get=True) is None
1012+
assert r.set('a', 'True', get=True) == b'True'
1013+
assert r.set('a', 'foo') is True
1014+
assert r.set('a', 'bar', get=True) == b'foo'
1015+
assert r.get('a') == b'bar'
1016+
10091017
def test_setex(self, r):
10101018
assert r.setex('a', 60, '1')
10111019
assert r['a'] == b'1'

0 commit comments

Comments
 (0)