diff --git a/CHANGES b/CHANGES index d89079ba6f..9d82341a76 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,4 @@ + * Support `.unlink()` in ClusterPipeline * Simplify synchronous SocketBuffer state management * Fix string cleanse in Redis Graph * Make PythonParser resumable in case of error (#2510) diff --git a/redis/cluster.py b/redis/cluster.py index 5f730a8596..d6dc02d493 100644 --- a/redis/cluster.py +++ b/redis/cluster.py @@ -2136,6 +2136,17 @@ def delete(self, *names): return self.execute_command("DEL", names[0]) + def unlink(self, *names): + """ + "Unlink a key specified by ``names``" + """ + if len(names) != 1: + raise RedisClusterException( + "unlinking multiple keys is not implemented in pipeline command" + ) + + return self.execute_command("UNLINK", names[0]) + def block_pipeline_command(name: str) -> Callable[..., Any]: """ diff --git a/tests/test_cluster.py b/tests/test_cluster.py index da6a8e4bf7..1bf57a357c 100644 --- a/tests/test_cluster.py +++ b/tests/test_cluster.py @@ -2703,6 +2703,25 @@ def test_multi_delete_unsupported(self, r): with pytest.raises(RedisClusterException): pipe.delete("a", "b") + def test_unlink_single(self, r): + """ + Test a single unlink operation + """ + r["a"] = 1 + with r.pipeline(transaction=False) as pipe: + pipe.unlink("a") + assert pipe.execute() == [1] + + def test_multi_unlink_unsupported(self, r): + """ + Test that multi unlink operation is unsupported + """ + with r.pipeline(transaction=False) as pipe: + r["a"] = 1 + r["b"] = 2 + with pytest.raises(RedisClusterException): + pipe.unlink("a", "b") + def test_brpoplpush_disabled(self, r): """ Test that brpoplpush is disabled for ClusterPipeline