Skip to content

Commit

Permalink
Return a copy of the respnse from cache (#3106)
Browse files Browse the repository at this point in the history
  • Loading branch information
dvora-h committed Jan 11, 2024
1 parent 273f032 commit df29566
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 1 deletion.
3 changes: 2 additions & 1 deletion redis/_cache.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import copy
import random
import time
from collections import OrderedDict, defaultdict
Expand Down Expand Up @@ -226,7 +227,7 @@ def get(self, command: str) -> ResponseT:
self.delete(command)
return
self._update_access(command)
return self.cache[command]["response"]
return copy.deepcopy(self.cache[command]["response"])

def delete(self, command: str):
"""
Expand Down
11 changes: 11 additions & 0 deletions tests/test_asyncio/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,17 @@ async def test_cache_blacklist(self, r):
assert cache.get(("LLEN", "mylist")) is None
assert cache.get(("LINDEX", "mylist", 1)) == b"bar"

@pytest.mark.parametrize("r", [{"cache": _LocalCache()}], indirect=True)
async def test_cache_return_copy(self, r):
r, cache = r
await r.lpush("mylist", "foo", "bar", "baz")
assert await r.lrange("mylist", 0, -1) == [b"baz", b"bar", b"foo"]
res = cache.get(("LRANGE", "mylist", 0, -1))
assert res == [b"baz", b"bar", b"foo"]
res.append(b"new")
check = cache.get(("LRANGE", "mylist", 0, -1))
assert check == [b"baz", b"bar", b"foo"]


@pytest.mark.skipif(HIREDIS_AVAILABLE, reason="PythonParser only")
@pytest.mark.onlycluster
Expand Down
12 changes: 12 additions & 0 deletions tests/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def r(request):
redis.Redis, request, protocol=3, client_cache=cache, **kwargs
) as client:
yield client, cache
# client.flushdb()


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

@pytest.mark.parametrize("r", [{"cache": _LocalCache()}], indirect=True)
def test_cache_return_copy(self, r):
r, cache = r
r.lpush("mylist", "foo", "bar", "baz")
assert r.lrange("mylist", 0, -1) == [b"baz", b"bar", b"foo"]
res = cache.get(("LRANGE", "mylist", 0, -1))
assert res == [b"baz", b"bar", b"foo"]
res.append(b"new")
check = cache.get(("LRANGE", "mylist", 0, -1))
assert check == [b"baz", b"bar", b"foo"]


@pytest.mark.skipif(HIREDIS_AVAILABLE, reason="PythonParser only")
@pytest.mark.onlycluster
Expand Down

0 comments on commit df29566

Please sign in to comment.