Skip to content

Commit 37ed3d5

Browse files
committed
Fix bug with Redis Set commands returns List instead of Set in RESP2
1 parent 2e46613 commit 37ed3d5

File tree

6 files changed

+128
-15
lines changed

6 files changed

+128
-15
lines changed

redis/_parsers/helpers.py

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

786786

787787
_RedisCallbacksRESP2 = {
788+
**string_keys_to_dict(
789+
"SDIFF SINTER SMEMBERS SUNION", lambda r: r and set(r) or set()
790+
),
788791
**string_keys_to_dict(
789792
"ZDIFF ZINTER ZPOPMAX ZPOPMIN ZRANGE ZRANGEBYSCORE ZRANK ZREVRANGE "
790793
"ZREVRANGEBYSCORE ZREVRANK ZUNION",

tests/test_asyncio/test_cluster.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,26 +1754,26 @@ async def test_cluster_sdiff(self, r: RedisCluster) -> None:
17541754
await r.sadd("{foo}a", "1", "2", "3")
17551755
assert set(await r.sdiff("{foo}a", "{foo}b")) == {b"1", b"2", b"3"}
17561756
await r.sadd("{foo}b", "2", "3")
1757-
assert await r.sdiff("{foo}a", "{foo}b") == [b"1"]
1757+
assert await r.sdiff("{foo}a", "{foo}b") == {b"1"}
17581758

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

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

17731773
async def test_cluster_sinterstore(self, r: RedisCluster) -> None:
17741774
await r.sadd("{foo}a", "1", "2", "3")
17751775
assert await r.sinterstore("{foo}c", "{foo}a", "{foo}b") == 0
1776-
assert await r.smembers("{foo}c") == []
1776+
assert await r.smembers("{foo}c") == set()
17771777
await r.sadd("{foo}b", "2", "3")
17781778
assert await r.sinterstore("{foo}c", "{foo}a", "{foo}b") == 2
17791779
assert set(await r.smembers("{foo}c")) == {b"2", b"3"}
@@ -1782,7 +1782,7 @@ async def test_cluster_smove(self, r: RedisCluster) -> None:
17821782
await r.sadd("{foo}a", "a1", "a2")
17831783
await r.sadd("{foo}b", "b1", "b2")
17841784
assert await r.smove("{foo}a", "{foo}b", "a1")
1785-
assert await r.smembers("{foo}a") == [b"a2"]
1785+
assert await r.smembers("{foo}a") == {b"a2"}
17861786
assert set(await r.smembers("{foo}b")) == {b"b1", b"b2", b"a1"}
17871787

17881788
async def test_cluster_sunion(self, r: RedisCluster) -> None:

tests/test_asyncio/test_commands.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,7 +1417,7 @@ async def test_sdiff(self, r: redis.Redis):
14171417
await r.sadd("a", "1", "2", "3")
14181418
assert set(await r.sdiff("a", "b")) == {b"1", b"2", b"3"}
14191419
await r.sadd("b", "2", "3")
1420-
assert await r.sdiff("a", "b") == [b"1"]
1420+
assert await r.sdiff("a", "b") == {b"1"}
14211421

14221422
@pytest.mark.onlynoncluster
14231423
async def test_sdiffstore(self, r: redis.Redis):
@@ -1426,20 +1426,20 @@ async def test_sdiffstore(self, r: redis.Redis):
14261426
assert set(await r.smembers("c")) == {b"1", b"2", b"3"}
14271427
await r.sadd("b", "2", "3")
14281428
assert await r.sdiffstore("c", "a", "b") == 1
1429-
assert await r.smembers("c") == [b"1"]
1429+
assert await r.smembers("c") == {b"1"}
14301430

14311431
@pytest.mark.onlynoncluster
14321432
async def test_sinter(self, r: redis.Redis):
14331433
await r.sadd("a", "1", "2", "3")
1434-
assert await r.sinter("a", "b") == []
1434+
assert await r.sinter("a", "b") == set()
14351435
await r.sadd("b", "2", "3")
14361436
assert set(await r.sinter("a", "b")) == {b"2", b"3"}
14371437

14381438
@pytest.mark.onlynoncluster
14391439
async def test_sinterstore(self, r: redis.Redis):
14401440
await r.sadd("a", "1", "2", "3")
14411441
assert await r.sinterstore("c", "a", "b") == 0
1442-
assert await r.smembers("c") == []
1442+
assert await r.smembers("c") == set()
14431443
await r.sadd("b", "2", "3")
14441444
assert await r.sinterstore("c", "a", "b") == 2
14451445
assert set(await r.smembers("c")) == {b"2", b"3"}
@@ -1460,7 +1460,7 @@ async def test_smove(self, r: redis.Redis):
14601460
await r.sadd("a", "a1", "a2")
14611461
await r.sadd("b", "b1", "b2")
14621462
assert await r.smove("a", "b", "a1")
1463-
assert await r.smembers("a") == [b"a2"]
1463+
assert await r.smembers("a") == {b"a2"}
14641464
assert set(await r.smembers("b")) == {b"b1", b"b2", b"a1"}
14651465

14661466
async def test_spop(self, r: redis.Redis):

tests/test_cache.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def r(request):
4141

4242
@pytest.mark.skipif(HIREDIS_AVAILABLE, reason="PythonParser only")
4343
@pytest.mark.onlynoncluster
44-
# @skip_if_resp_version(2)
44+
@skip_if_resp_version(2)
4545
@skip_if_server_version_lt("7.4.0")
4646
class TestCache:
4747
@pytest.mark.parametrize(

tests/test_cluster.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
skip_if_redis_enterprise,
4949
skip_if_server_version_lt,
5050
skip_unless_arch_bits,
51-
wait_for_command,
51+
wait_for_command, skip_if_resp_version,
5252
)
5353

5454
default_host = "127.0.0.1"
@@ -284,6 +284,19 @@ def ok_response(connection, *args, **options):
284284
assert prev_primary.server_type == REPLICA
285285

286286

287+
@pytest.fixture()
288+
def r(request):
289+
protocol = 2
290+
291+
if hasattr(request, "param"):
292+
protocol = request.param.get("protocol", 2)
293+
with _get_client(
294+
redis.Redis,
295+
request,
296+
protocol=protocol,
297+
) as client:
298+
yield client
299+
287300
@pytest.mark.onlycluster
288301
class TestRedisClusterObj:
289302
"""
@@ -1864,12 +1877,30 @@ def test_cluster_rpoplpush(self, r):
18641877
assert r.lrange("{foo}b", 0, -1) == [b"a3", b"b1", b"b2", b"b3"]
18651878

18661879
def test_cluster_sdiff(self, r):
1880+
r.sadd("{foo}a", "1", "2", "3")
1881+
assert set(r.sdiff("{foo}a", "{foo}b")) == {b"1", b"2", b"3"}
1882+
r.sadd("{foo}b", "2", "3")
1883+
assert r.sdiff("{foo}a", "{foo}b") == {b"1"}
1884+
1885+
@pytest.mark.parametrize("r", [{"protocol": 3}], indirect=True)
1886+
@skip_if_resp_version(2)
1887+
def test_cluster_sdiff_resp3(self, r):
18671888
r.sadd("{foo}a", "1", "2", "3")
18681889
assert set(r.sdiff("{foo}a", "{foo}b")) == {b"1", b"2", b"3"}
18691890
r.sadd("{foo}b", "2", "3")
18701891
assert r.sdiff("{foo}a", "{foo}b") == [b"1"]
18711892

18721893
def test_cluster_sdiffstore(self, r):
1894+
r.sadd("{foo}a", "1", "2", "3")
1895+
assert r.sdiffstore("{foo}c", "{foo}a", "{foo}b") == 3
1896+
assert set(r.smembers("{foo}c")) == {b"1", b"2", b"3"}
1897+
r.sadd("{foo}b", "2", "3")
1898+
assert r.sdiffstore("{foo}c", "{foo}a", "{foo}b") == 1
1899+
assert r.smembers("{foo}c") == {b"1"}
1900+
1901+
@pytest.mark.parametrize("r", [{"protocol": 3}], indirect=True)
1902+
@skip_if_resp_version(2)
1903+
def test_cluster_sdiffstore_resp3(self, r):
18731904
r.sadd("{foo}a", "1", "2", "3")
18741905
assert r.sdiffstore("{foo}c", "{foo}a", "{foo}b") == 3
18751906
assert set(r.smembers("{foo}c")) == {b"1", b"2", b"3"}
@@ -1878,12 +1909,30 @@ def test_cluster_sdiffstore(self, r):
18781909
assert r.smembers("{foo}c") == [b"1"]
18791910

18801911
def test_cluster_sinter(self, r):
1912+
r.sadd("{foo}a", "1", "2", "3")
1913+
assert r.sinter("{foo}a", "{foo}b") == set()
1914+
r.sadd("{foo}b", "2", "3")
1915+
assert set(r.sinter("{foo}a", "{foo}b")) == {b"2", b"3"}
1916+
1917+
@pytest.mark.parametrize("r", [{"protocol": 3}], indirect=True)
1918+
@skip_if_resp_version(2)
1919+
def test_cluster_sinter_resp3(self, r):
18811920
r.sadd("{foo}a", "1", "2", "3")
18821921
assert r.sinter("{foo}a", "{foo}b") == []
18831922
r.sadd("{foo}b", "2", "3")
18841923
assert set(r.sinter("{foo}a", "{foo}b")) == {b"2", b"3"}
18851924

18861925
def test_cluster_sinterstore(self, r):
1926+
r.sadd("{foo}a", "1", "2", "3")
1927+
assert r.sinterstore("{foo}c", "{foo}a", "{foo}b") == 0
1928+
assert r.smembers("{foo}c") == set()
1929+
r.sadd("{foo}b", "2", "3")
1930+
assert r.sinterstore("{foo}c", "{foo}a", "{foo}b") == 2
1931+
assert set(r.smembers("{foo}c")) == {b"2", b"3"}
1932+
1933+
@pytest.mark.parametrize("r", [{"protocol": 3}], indirect=True)
1934+
@skip_if_resp_version(2)
1935+
def test_cluster_sinterstore_resp3(self, r):
18871936
r.sadd("{foo}a", "1", "2", "3")
18881937
assert r.sinterstore("{foo}c", "{foo}a", "{foo}b") == 0
18891938
assert r.smembers("{foo}c") == []
@@ -1892,6 +1941,15 @@ def test_cluster_sinterstore(self, r):
18921941
assert set(r.smembers("{foo}c")) == {b"2", b"3"}
18931942

18941943
def test_cluster_smove(self, r):
1944+
r.sadd("{foo}a", "a1", "a2")
1945+
r.sadd("{foo}b", "b1", "b2")
1946+
assert r.smove("{foo}a", "{foo}b", "a1")
1947+
assert r.smembers("{foo}a") == {b"a2"}
1948+
assert set(r.smembers("{foo}b")) == {b"b1", b"b2", b"a1"}
1949+
1950+
@pytest.mark.parametrize("r", [{"protocol": 3}], indirect=True)
1951+
@skip_if_resp_version(2)
1952+
def test_cluster_smove_resp3(self, r):
18951953
r.sadd("{foo}a", "a1", "a2")
18961954
r.sadd("{foo}b", "b1", "b2")
18971955
assert r.smove("{foo}a", "{foo}b", "a1")

tests/test_commands.py

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,21 @@
2727
skip_if_redis_enterprise,
2828
skip_if_server_version_gte,
2929
skip_if_server_version_lt,
30-
skip_unless_arch_bits,
30+
skip_unless_arch_bits, skip_if_resp_version,
3131
)
3232

33+
@pytest.fixture()
34+
def r(request):
35+
protocol = 2
36+
37+
if hasattr(request, "param"):
38+
protocol = request.param.get("protocol", 2)
39+
with _get_client(
40+
redis.Redis,
41+
request,
42+
protocol=protocol,
43+
) as client:
44+
yield client
3345

3446
@pytest.fixture()
3547
def slowlog(request, r):
@@ -2246,6 +2258,15 @@ def test_scard(self, r):
22462258

22472259
@pytest.mark.onlynoncluster
22482260
def test_sdiff(self, r):
2261+
r.sadd("a", "1", "2", "3")
2262+
assert set(r.sdiff("a", "b")) == {b"1", b"2", b"3"}
2263+
r.sadd("b", "2", "3")
2264+
assert r.sdiff("a", "b") == {b"1"}
2265+
2266+
@pytest.mark.parametrize("r", [{"protocol": 3}], indirect=True)
2267+
@pytest.mark.onlynoncluster
2268+
@skip_if_resp_version(2)
2269+
def test_sdiff_resp3(self, r):
22492270
r.sadd("a", "1", "2", "3")
22502271
assert set(r.sdiff("a", "b")) == {b"1", b"2", b"3"}
22512272
r.sadd("b", "2", "3")
@@ -2258,10 +2279,30 @@ def test_sdiffstore(self, r):
22582279
assert set(r.smembers("c")) == {b"1", b"2", b"3"}
22592280
r.sadd("b", "2", "3")
22602281
assert r.sdiffstore("c", "a", "b") == 1
2261-
assert r.smembers("c") == [b"1"]
2282+
assert r.smembers("c") == {b"1"}
2283+
2284+
@pytest.mark.parametrize("r", [{"protocol": 3}], indirect=True)
2285+
@pytest.mark.onlynoncluster
2286+
@skip_if_resp_version(2)
2287+
def test_sdiffstore_resp3(self, r):
2288+
r.sadd("a", "1", "2", "3")
2289+
assert r.sdiffstore("c", "a", "b") == 3
2290+
assert set(r.smembers("c")) == {b"1", b"2", b"3"}
2291+
r.sadd("b", "2", "3")
2292+
assert r.sdiffstore("c", "a", "b") == 1
2293+
assert r.smembers("c") == {b"1"}
22622294

22632295
@pytest.mark.onlynoncluster
22642296
def test_sinter(self, r):
2297+
r.sadd("a", "1", "2", "3")
2298+
assert r.sinter("a", "b") == set()
2299+
r.sadd("b", "2", "3")
2300+
assert set(r.sinter("a", "b")) == {b"2", b"3"}
2301+
2302+
@pytest.mark.parametrize("r", [{"protocol": 3}], indirect=True)
2303+
@pytest.mark.onlynoncluster
2304+
@skip_if_resp_version(2)
2305+
def test_sinter_resp3(self, r):
22652306
r.sadd("a", "1", "2", "3")
22662307
assert r.sinter("a", "b") == []
22672308
r.sadd("b", "2", "3")
@@ -2278,6 +2319,17 @@ def test_sintercard(self, r):
22782319

22792320
@pytest.mark.onlynoncluster
22802321
def test_sinterstore(self, r):
2322+
r.sadd("a", "1", "2", "3")
2323+
assert r.sinterstore("c", "a", "b") == 0
2324+
assert r.smembers("c") == set()
2325+
r.sadd("b", "2", "3")
2326+
assert r.sinterstore("c", "a", "b") == 2
2327+
assert set(r.smembers("c")) == {b"2", b"3"}
2328+
2329+
@pytest.mark.parametrize("r", [{"protocol": 3}], indirect=True)
2330+
@pytest.mark.onlynoncluster
2331+
@skip_if_resp_version(2)
2332+
def test_sinterstore_resp3(self, r):
22812333
r.sadd("a", "1", "2", "3")
22822334
assert r.sinterstore("c", "a", "b") == 0
22832335
assert r.smembers("c") == []
@@ -2308,7 +2360,7 @@ def test_smove(self, r):
23082360
r.sadd("a", "a1", "a2")
23092361
r.sadd("b", "b1", "b2")
23102362
assert r.smove("a", "b", "a1")
2311-
assert r.smembers("a") == [b"a2"]
2363+
assert r.smembers("a") == {b"a2"}
23122364
assert set(r.smembers("b")) == {b"b1", b"b2", b"a1"}
23132365

23142366
def test_spop(self, r):

0 commit comments

Comments
 (0)