Skip to content

Commit 9e141b4

Browse files
dvora-hvladvildanov
authored andcommitted
Return a copy of the respnse from cache (#3106)
1 parent 02a5090 commit 9e141b4

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

redis/_cache.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import copy
12
import random
23
import time
34
from collections import OrderedDict, defaultdict
@@ -226,7 +227,7 @@ def get(self, command: str) -> ResponseT:
226227
self.delete(command)
227228
return
228229
self._update_access(command)
229-
return self.cache[command]["response"]
230+
return copy.deepcopy(self.cache[command]["response"])
230231

231232
def delete(self, command: str):
232233
"""

tests/test_asyncio/test_cache.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,17 @@ async def test_cache_blacklist(self, r):
131131
assert cache.get(("LLEN", "mylist")) is None
132132
assert cache.get(("LINDEX", "mylist", 1)) == b"bar"
133133

134+
@pytest.mark.parametrize("r", [{"cache": _LocalCache()}], indirect=True)
135+
async def test_cache_return_copy(self, r):
136+
r, cache = r
137+
await r.lpush("mylist", "foo", "bar", "baz")
138+
assert await r.lrange("mylist", 0, -1) == [b"baz", b"bar", b"foo"]
139+
res = cache.get(("LRANGE", "mylist", 0, -1))
140+
assert res == [b"baz", b"bar", b"foo"]
141+
res.append(b"new")
142+
check = cache.get(("LRANGE", "mylist", 0, -1))
143+
assert check == [b"baz", b"bar", b"foo"]
144+
134145

135146
@pytest.mark.skipif(HIREDIS_AVAILABLE, reason="PythonParser only")
136147
@pytest.mark.onlycluster

tests/test_cache.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def r(request):
1515
redis.Redis, request, protocol=3, client_cache=cache, **kwargs
1616
) as client:
1717
yield client, cache
18+
# client.flushdb()
1819

1920

2021
@pytest.mark.skipif(HIREDIS_AVAILABLE, reason="PythonParser only")
@@ -134,6 +135,17 @@ def test_cache_blacklist(self, r):
134135
assert cache.get(("LLEN", "mylist")) is None
135136
assert cache.get(("LINDEX", "mylist", 1)) == b"bar"
136137

138+
@pytest.mark.parametrize("r", [{"cache": _LocalCache()}], indirect=True)
139+
def test_cache_return_copy(self, r):
140+
r, cache = r
141+
r.lpush("mylist", "foo", "bar", "baz")
142+
assert r.lrange("mylist", 0, -1) == [b"baz", b"bar", b"foo"]
143+
res = cache.get(("LRANGE", "mylist", 0, -1))
144+
assert res == [b"baz", b"bar", b"foo"]
145+
res.append(b"new")
146+
check = cache.get(("LRANGE", "mylist", 0, -1))
147+
assert check == [b"baz", b"bar", b"foo"]
148+
137149

138150
@pytest.mark.skipif(HIREDIS_AVAILABLE, reason="PythonParser only")
139151
@pytest.mark.onlycluster

0 commit comments

Comments
 (0)