Skip to content

Commit b9e239e

Browse files
committed
Merge branch 'client-side-caching-improvements' of github.com:redis/redis-py into client-side-caching-improvements
2 parents 79364a6 + ca66c38 commit b9e239e

20 files changed

+159
-145
lines changed

.github/workflows/integration.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ env:
2828
# this speeds up coverage with Python 3.12: https://github.com/nedbat/coveragepy/issues/1665
2929
COVERAGE_CORE: sysmon
3030
REDIS_IMAGE: redis:7.4-rc2
31-
REDIS_STACK_IMAGE: redis/redis-stack-server:7.4.0-rc2
31+
REDIS_STACK_IMAGE: redis/redis-stack-server:latest
3232

3333
jobs:
3434
dependency-audit:

doctests/dt_set.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@
5858
r.sadd("bikes:racing:usa", "bike:1", "bike:4")
5959
# HIDE_END
6060
res7 = r.sinter("bikes:racing:france", "bikes:racing:usa")
61-
print(res7) # >>> {'bike:1'}
61+
print(res7) # >>> ['bike:1']
6262
# STEP_END
6363

6464
# REMOVE_START
65-
assert res7 == {"bike:1"}
65+
assert res7 == ["bike:1"]
6666
# REMOVE_END
6767

6868
# STEP_START scard
@@ -83,12 +83,12 @@
8383
print(res9) # >>> 3
8484

8585
res10 = r.smembers("bikes:racing:france")
86-
print(res10) # >>> {'bike:1', 'bike:2', 'bike:3'}
86+
print(res10) # >>> ['bike:1', 'bike:2', 'bike:3']
8787
# STEP_END
8888

8989
# REMOVE_START
9090
assert res9 == 3
91-
assert res10 == {"bike:1", "bike:2", "bike:3"}
91+
assert res10 == ['bike:1', 'bike:2', 'bike:3']
9292
# REMOVE_END
9393

9494
# STEP_START smismember
@@ -109,11 +109,11 @@
109109
r.sadd("bikes:racing:usa", "bike:1", "bike:4")
110110

111111
res13 = r.sdiff("bikes:racing:france", "bikes:racing:usa")
112-
print(res13) # >>> {'bike:2', 'bike:3'}
112+
print(res13) # >>> ['bike:2', 'bike:3']
113113
# STEP_END
114114

115115
# REMOVE_START
116-
assert res13 == {"bike:2", "bike:3"}
116+
assert res13 == ['bike:2', 'bike:3']
117117
r.delete("bikes:racing:france")
118118
r.delete("bikes:racing:usa")
119119
# REMOVE_END
@@ -124,27 +124,27 @@
124124
r.sadd("bikes:racing:italy", "bike:1", "bike:2", "bike:3", "bike:4")
125125

126126
res13 = r.sinter("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy")
127-
print(res13) # >>> {'bike:1'}
127+
print(res13) # >>> ['bike:1']
128128

129129
res14 = r.sunion("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy")
130-
print(res14) # >>> {'bike:1', 'bike:2', 'bike:3', 'bike:4'}
130+
print(res14) # >>> ['bike:1', 'bike:2', 'bike:3', 'bike:4']
131131

132132
res15 = r.sdiff("bikes:racing:france", "bikes:racing:usa", "bikes:racing:italy")
133-
print(res15) # >>> set()
133+
print(res15) # >>> []
134134

135135
res16 = r.sdiff("bikes:racing:usa", "bikes:racing:france")
136-
print(res16) # >>> {'bike:4'}
136+
print(res16) # >>> ['bike:4']
137137

138138
res17 = r.sdiff("bikes:racing:france", "bikes:racing:usa")
139-
print(res17) # >>> {'bike:2', 'bike:3'}
139+
print(res17) # >>> ['bike:2', 'bike:3']
140140
# STEP_END
141141

142142
# REMOVE_START
143-
assert res13 == {"bike:1"}
144-
assert res14 == {"bike:1", "bike:2", "bike:3", "bike:4"}
145-
assert res15 == set()
146-
assert res16 == {"bike:4"}
147-
assert res17 == {"bike:2", "bike:3"}
143+
assert res13 == ['bike:1']
144+
assert res14 == ['bike:1', 'bike:2', 'bike:3', 'bike:4']
145+
assert res15 == []
146+
assert res16 == ['bike:4']
147+
assert res17 == ['bike:2', 'bike:3']
148148
r.delete("bikes:racing:france")
149149
r.delete("bikes:racing:usa")
150150
r.delete("bikes:racing:italy")
@@ -160,7 +160,7 @@
160160
print(res19) # >>> bike:3
161161

162162
res20 = r.smembers("bikes:racing:france")
163-
print(res20) # >>> {'bike:2', 'bike:4', 'bike:5'}
163+
print(res20) # >>> ['bike:2', 'bike:4', 'bike:5']
164164

165165
res21 = r.srandmember("bikes:racing:france")
166166
print(res21) # >>> bike:4

redis/_parsers/helpers.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -783,9 +783,6 @@ def string_keys_to_dict(key_string, callback):
783783

784784

785785
_RedisCallbacksRESP2 = {
786-
**string_keys_to_dict(
787-
"SDIFF SINTER SMEMBERS SUNION", lambda r: r and set(r) or set()
788-
),
789786
**string_keys_to_dict(
790787
"ZDIFF ZINTER ZPOPMAX ZPOPMIN ZRANGE ZRANGEBYSCORE ZRANK ZREVRANGE "
791788
"ZREVRANGEBYSCORE ZREVRANK ZUNION",

redis/_parsers/resp3.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,11 @@ def _read_response(self, disable_decoding=False, push_request=False):
8888
# set response
8989
elif byte == b"~":
9090
# redis can return unhashable types (like dict) in a set,
91-
# so we need to first convert to a list, and then try to convert it to a set
91+
# so we return sets as list, all the time, for predictability
9292
response = [
9393
self._read_response(disable_decoding=disable_decoding)
9494
for _ in range(int(response))
9595
]
96-
try:
97-
response = set(response)
98-
except TypeError:
99-
pass
10096
# map response
10197
elif byte == b"%":
10298
# We cannot use a dict-comprehension to parse stream.
@@ -230,15 +226,11 @@ async def _read_response(
230226
# set response
231227
elif byte == b"~":
232228
# redis can return unhashable types (like dict) in a set,
233-
# so we need to first convert to a list, and then try to convert it to a set
229+
# so we always convert to a list, to have predictable return types
234230
response = [
235231
(await self._read_response(disable_decoding=disable_decoding))
236232
for _ in range(int(response))
237233
]
238-
try:
239-
response = set(response)
240-
except TypeError:
241-
pass
242234
# map response
243235
elif byte == b"%":
244236
# We cannot use a dict-comprehension to parse stream.

redis/commands/bf/commands.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from redis.client import NEVER_DECODE
2-
from redis.exceptions import ModuleError
3-
from redis.utils import HIREDIS_AVAILABLE, deprecated_function
2+
from redis.utils import deprecated_function
43

54
BF_RESERVE = "BF.RESERVE"
65
BF_ADD = "BF.ADD"
@@ -139,9 +138,6 @@ def scandump(self, key, iter):
139138
This command will return successive (iter, data) pairs until (0, NULL) to indicate completion.
140139
For more information see `BF.SCANDUMP <https://redis.io/commands/bf.scandump>`_.
141140
""" # noqa
142-
if HIREDIS_AVAILABLE:
143-
raise ModuleError("This command cannot be used when hiredis is available.")
144-
145141
params = [key, iter]
146142
options = {}
147143
options[NEVER_DECODE] = []

redis/commands/search/aggregation.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ def __init__(self, query: str = "*") -> None:
111111
self._verbatim = False
112112
self._cursor = []
113113
self._dialect = None
114+
self._add_scores = False
114115

115116
def load(self, *fields: List[str]) -> "AggregateRequest":
116117
"""
@@ -292,6 +293,13 @@ def with_schema(self) -> "AggregateRequest":
292293
self._with_schema = True
293294
return self
294295

296+
def add_scores(self) -> "AggregateRequest":
297+
"""
298+
If set, includes the score as an ordinary field of the row.
299+
"""
300+
self._add_scores = True
301+
return self
302+
295303
def verbatim(self) -> "AggregateRequest":
296304
self._verbatim = True
297305
return self
@@ -315,6 +323,9 @@ def build_args(self) -> List[str]:
315323
if self._verbatim:
316324
ret.append("VERBATIM")
317325

326+
if self._add_scores:
327+
ret.append("ADDSCORES")
328+
318329
if self._cursor:
319330
ret += self._cursor
320331

redis/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
try:
77
import hiredis # noqa
88

9-
# Only support Hiredis >= 1.0:
10-
HIREDIS_AVAILABLE = not hiredis.__version__.startswith("0.")
9+
# Only support Hiredis >= 3.0:
10+
HIREDIS_AVAILABLE = int(hiredis.__version__.split(".")[0]) >= 3
1111
HIREDIS_PACK_AVAILABLE = hasattr(hiredis, "pack_command")
1212
except ImportError:
1313
HIREDIS_AVAILABLE = False

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
"Programming Language :: Python :: Implementation :: PyPy",
5757
],
5858
extras_require={
59-
"hiredis": ["hiredis>=1.0.0"],
59+
"hiredis": ["hiredis>=3.0.0"],
6060
"ocsp": ["cryptography>=36.0.1", "pyopenssl==23.2.1", "requests>=2.31.0"],
6161
},
6262
)

tests/test_asyncio/test_bloom.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
import pytest
44
import pytest_asyncio
55
import redis.asyncio as redis
6-
from redis.exceptions import ModuleError, RedisError
7-
from redis.utils import HIREDIS_AVAILABLE
6+
from redis.exceptions import RedisError
87
from tests.conftest import (
98
assert_resp_response,
109
is_resp2_connection,
@@ -105,10 +104,6 @@ async def do_verify():
105104

106105
await do_verify()
107106
cmds = []
108-
if HIREDIS_AVAILABLE:
109-
with pytest.raises(ModuleError):
110-
cur = await decoded_r.bf().scandump("myBloom", 0)
111-
return
112107

113108
cur = await decoded_r.bf().scandump("myBloom", 0)
114109
first = cur[0]

tests/test_asyncio/test_cluster.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,49 +1751,49 @@ async def test_cluster_rpoplpush(self, r: RedisCluster) -> None:
17511751

17521752
async def test_cluster_sdiff(self, r: RedisCluster) -> None:
17531753
await r.sadd("{foo}a", "1", "2", "3")
1754-
assert await r.sdiff("{foo}a", "{foo}b") == {b"1", b"2", b"3"}
1754+
assert set(await r.sdiff("{foo}a", "{foo}b")) == {b"1", b"2", b"3"}
17551755
await r.sadd("{foo}b", "2", "3")
1756-
assert await r.sdiff("{foo}a", "{foo}b") == {b"1"}
1756+
assert await r.sdiff("{foo}a", "{foo}b") == [b"1"]
17571757

17581758
async def test_cluster_sdiffstore(self, r: RedisCluster) -> None:
17591759
await r.sadd("{foo}a", "1", "2", "3")
17601760
assert await r.sdiffstore("{foo}c", "{foo}a", "{foo}b") == 3
1761-
assert await r.smembers("{foo}c") == {b"1", b"2", b"3"}
1761+
assert set(await r.smembers("{foo}c")) == {b"1", b"2", b"3"}
17621762
await r.sadd("{foo}b", "2", "3")
17631763
assert await r.sdiffstore("{foo}c", "{foo}a", "{foo}b") == 1
1764-
assert await r.smembers("{foo}c") == {b"1"}
1764+
assert await r.smembers("{foo}c") == [b"1"]
17651765

17661766
async def test_cluster_sinter(self, r: RedisCluster) -> None:
17671767
await r.sadd("{foo}a", "1", "2", "3")
1768-
assert await r.sinter("{foo}a", "{foo}b") == set()
1768+
assert await r.sinter("{foo}a", "{foo}b") == []
17691769
await r.sadd("{foo}b", "2", "3")
1770-
assert await r.sinter("{foo}a", "{foo}b") == {b"2", b"3"}
1770+
assert set(await r.sinter("{foo}a", "{foo}b")) == {b"2", b"3"}
17711771

17721772
async def test_cluster_sinterstore(self, r: RedisCluster) -> None:
17731773
await r.sadd("{foo}a", "1", "2", "3")
17741774
assert await r.sinterstore("{foo}c", "{foo}a", "{foo}b") == 0
1775-
assert await r.smembers("{foo}c") == set()
1775+
assert await r.smembers("{foo}c") == []
17761776
await r.sadd("{foo}b", "2", "3")
17771777
assert await r.sinterstore("{foo}c", "{foo}a", "{foo}b") == 2
1778-
assert await r.smembers("{foo}c") == {b"2", b"3"}
1778+
assert set(await r.smembers("{foo}c")) == {b"2", b"3"}
17791779

17801780
async def test_cluster_smove(self, r: RedisCluster) -> None:
17811781
await r.sadd("{foo}a", "a1", "a2")
17821782
await r.sadd("{foo}b", "b1", "b2")
17831783
assert await r.smove("{foo}a", "{foo}b", "a1")
1784-
assert await r.smembers("{foo}a") == {b"a2"}
1785-
assert await r.smembers("{foo}b") == {b"b1", b"b2", b"a1"}
1784+
assert await r.smembers("{foo}a") == [b"a2"]
1785+
assert set(await r.smembers("{foo}b")) == {b"b1", b"b2", b"a1"}
17861786

17871787
async def test_cluster_sunion(self, r: RedisCluster) -> None:
17881788
await r.sadd("{foo}a", "1", "2")
17891789
await r.sadd("{foo}b", "2", "3")
1790-
assert await r.sunion("{foo}a", "{foo}b") == {b"1", b"2", b"3"}
1790+
assert set(await r.sunion("{foo}a", "{foo}b")) == {b"1", b"2", b"3"}
17911791

17921792
async def test_cluster_sunionstore(self, r: RedisCluster) -> None:
17931793
await r.sadd("{foo}a", "1", "2")
17941794
await r.sadd("{foo}b", "2", "3")
17951795
assert await r.sunionstore("{foo}c", "{foo}a", "{foo}b") == 3
1796-
assert await r.smembers("{foo}c") == {b"1", b"2", b"3"}
1796+
assert set(await r.smembers("{foo}c")) == {b"1", b"2", b"3"}
17971797

17981798
@skip_if_server_version_lt("6.2.0")
17991799
async def test_cluster_zdiff(self, r: RedisCluster) -> None:

0 commit comments

Comments
 (0)