From c1eefbdb76614435f7433207bf385ba8cb930b60 Mon Sep 17 00:00:00 2001 From: Gabriel Erzse Date: Fri, 19 Jul 2024 14:57:21 +0300 Subject: [PATCH] Return Redis sets as Python lists (#189) In some (rare) cases, the sets from a Redis response contain nested types that are not hashable in Python, for example maps. To handle these cases uniformly, always return Python lists for Redis sets. The elements will still be unique, relying on the correctness of data arriving from the server. This is a breaking change, although in reality it might not have a big impact. Therefore the major version gets bumped to 3. --- hiredis/version.py | 2 +- src/reader.c | 7 ------- tests/test_reader.py | 6 +++++- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/hiredis/version.py b/hiredis/version.py index 3d67cd6..528787c 100644 --- a/hiredis/version.py +++ b/hiredis/version.py @@ -1 +1 @@ -__version__ = "2.4.0" +__version__ = "3.0.0" diff --git a/src/reader.c b/src/reader.c index 77a7efe..5960995 100644 --- a/src/reader.c +++ b/src/reader.c @@ -82,10 +82,6 @@ static void *tryParentize(const redisReadTask *task, PyObject *obj) { PyDict_SetItem(parent, last_key, obj); } break; - case REDIS_REPLY_SET: - assert(PyAnySet_CheckExact(parent)); - PySet_Add(parent, obj); - break; default: assert(PyList_CheckExact(parent)); PyList_SET_ITEM(parent, task->idx, obj); @@ -162,9 +158,6 @@ static void *createArrayObject(const redisReadTask *task, size_t elements) { case REDIS_REPLY_MAP: obj = PyDict_New(); break; - case REDIS_REPLY_SET: - obj = PySet_New(NULL); - break; default: obj = PyList_New(elements); } diff --git a/tests/test_reader.py b/tests/test_reader.py index d78fb63..5b36a73 100644 --- a/tests/test_reader.py +++ b/tests/test_reader.py @@ -136,7 +136,11 @@ def test_none(reader): def test_set(reader): reader.feed(b"~3\r\n+tangerine\r\n_\r\n,10.5\r\n") - assert {b"tangerine", None, 10.5} == reader.gets() + assert [b"tangerine", None, 10.5] == reader.gets() + +def test_set_with_nested_dict(reader): + reader.feed(b"~2\r\n+tangerine\r\n%1\r\n+a\r\n:1\r\n") + assert [b"tangerine", {b"a": 1}] == reader.gets() def test_dict(reader): reader.feed(b"%2\r\n+radius\r\n,4.5\r\n+diameter\r\n:9\r\n")