From a123c8f91dde246e3aeda8cab38367961e139440 Mon Sep 17 00:00:00 2001 From: Petya Slavova Date: Wed, 12 Mar 2025 13:06:44 +0200 Subject: [PATCH] Removing support for RedisGears module. --- redis/cluster.py | 1 - redis/commands/cluster.py | 10 --- redis/commands/core.py | 127 ---------------------------------- tests/test_cluster.py | 44 ------------ tests/test_commands.py | 51 -------------- tests/test_connection_pool.py | 4 +- tests/test_multiprocessing.py | 4 +- 7 files changed, 4 insertions(+), 237 deletions(-) diff --git a/redis/cluster.py b/redis/cluster.py index 13253ec896..25e5b39278 100644 --- a/redis/cluster.py +++ b/redis/cluster.py @@ -307,7 +307,6 @@ class AbstractRedisCluster: "FUNCTION LIST", "FUNCTION LOAD", "FUNCTION RESTORE", - "REDISGEARS_2.REFRESHCLUSTER", "SCAN", "SCRIPT EXISTS", "SCRIPT FLUSH", diff --git a/redis/commands/cluster.py b/redis/commands/cluster.py index f0b65612e0..13f2035265 100644 --- a/redis/commands/cluster.py +++ b/redis/commands/cluster.py @@ -31,13 +31,11 @@ AsyncACLCommands, AsyncDataAccessCommands, AsyncFunctionCommands, - AsyncGearsCommands, AsyncManagementCommands, AsyncModuleCommands, AsyncScriptCommands, DataAccessCommands, FunctionCommands, - GearsCommands, ManagementCommands, ModuleCommands, PubSubCommands, @@ -693,12 +691,6 @@ def readwrite(self, target_nodes: Optional["TargetNodesT"] = None) -> ResponseT: self.read_from_replicas = False return self.execute_command("READWRITE", target_nodes=target_nodes) - def gears_refresh_cluster(self, **kwargs) -> ResponseT: - """ - On an OSS cluster, before executing any gears function, you must call this command. # noqa - """ - return self.execute_command("REDISGEARS_2.REFRESHCLUSTER", **kwargs) - class AsyncClusterManagementCommands( ClusterManagementCommands, AsyncManagementCommands @@ -874,7 +866,6 @@ class RedisClusterCommands( ClusterDataAccessCommands, ScriptCommands, FunctionCommands, - GearsCommands, ModuleCommands, RedisModuleCommands, ): @@ -905,7 +896,6 @@ class AsyncRedisClusterCommands( AsyncClusterDataAccessCommands, AsyncScriptCommands, AsyncFunctionCommands, - AsyncGearsCommands, AsyncModuleCommands, AsyncRedisModuleCommands, ): diff --git a/redis/commands/core.py b/redis/commands/core.py index b0e5dc6794..df76eafed0 100644 --- a/redis/commands/core.py +++ b/redis/commands/core.py @@ -6470,131 +6470,6 @@ def function_stats(self) -> Union[Awaitable[List], List]: AsyncFunctionCommands = FunctionCommands -class GearsCommands: - def tfunction_load( - self, lib_code: str, replace: bool = False, config: Union[str, None] = None - ) -> ResponseT: - """ - Load a new library to RedisGears. - - ``lib_code`` - the library code. - ``config`` - a string representation of a JSON object - that will be provided to the library on load time, - for more information refer to - https://github.com/RedisGears/RedisGears/blob/master/docs/function_advance_topics.md#library-configuration - ``replace`` - an optional argument, instructs RedisGears to replace the - function if its already exists - - For more information see https://redis.io/commands/tfunction-load/ - """ - pieces = [] - if replace: - pieces.append("REPLACE") - if config is not None: - pieces.extend(["CONFIG", config]) - pieces.append(lib_code) - return self.execute_command("TFUNCTION LOAD", *pieces) - - def tfunction_delete(self, lib_name: str) -> ResponseT: - """ - Delete a library from RedisGears. - - ``lib_name`` the library name to delete. - - For more information see https://redis.io/commands/tfunction-delete/ - """ - return self.execute_command("TFUNCTION DELETE", lib_name) - - def tfunction_list( - self, - with_code: bool = False, - verbose: int = 0, - lib_name: Union[str, None] = None, - ) -> ResponseT: - """ - List the functions with additional information about each function. - - ``with_code`` Show libraries code. - ``verbose`` output verbosity level, higher number will increase verbosity level - ``lib_name`` specifying a library name (can be used multiple times to show multiple libraries in a single command) # noqa - - For more information see https://redis.io/commands/tfunction-list/ - """ - pieces = [] - if with_code: - pieces.append("WITHCODE") - if verbose >= 1 and verbose <= 3: - pieces.append("v" * verbose) - else: - raise DataError("verbose can be 1, 2 or 3") - if lib_name is not None: - pieces.append("LIBRARY") - pieces.append(lib_name) - - return self.execute_command("TFUNCTION LIST", *pieces) - - def _tfcall( - self, - lib_name: str, - func_name: str, - keys: KeysT = None, - _async: bool = False, - *args: List, - ) -> ResponseT: - pieces = [f"{lib_name}.{func_name}"] - if keys is not None: - pieces.append(len(keys)) - pieces.extend(keys) - else: - pieces.append(0) - if args is not None: - pieces.extend(args) - if _async: - return self.execute_command("TFCALLASYNC", *pieces) - return self.execute_command("TFCALL", *pieces) - - def tfcall( - self, - lib_name: str, - func_name: str, - keys: KeysT = None, - *args: List, - ) -> ResponseT: - """ - Invoke a function. - - ``lib_name`` - the library name contains the function. - ``func_name`` - the function name to run. - ``keys`` - the keys that will be touched by the function. - ``args`` - Additional argument to pass to the function. - - For more information see https://redis.io/commands/tfcall/ - """ - return self._tfcall(lib_name, func_name, keys, False, *args) - - def tfcall_async( - self, - lib_name: str, - func_name: str, - keys: KeysT = None, - *args: List, - ) -> ResponseT: - """ - Invoke an async function (coroutine). - - ``lib_name`` - the library name contains the function. - ``func_name`` - the function name to run. - ``keys`` - the keys that will be touched by the function. - ``args`` - Additional argument to pass to the function. - - For more information see https://redis.io/commands/tfcall/ - """ - return self._tfcall(lib_name, func_name, keys, True, *args) - - -AsyncGearsCommands = GearsCommands - - class DataAccessCommands( BasicKeyCommands, HyperlogCommands, @@ -6638,7 +6513,6 @@ class CoreCommands( PubSubCommands, ScriptCommands, FunctionCommands, - GearsCommands, ): """ A class containing all of the implemented redis commands. This class is @@ -6655,7 +6529,6 @@ class AsyncCoreCommands( AsyncPubSubCommands, AsyncScriptCommands, AsyncFunctionCommands, - AsyncGearsCommands, ): """ A class containing all of the implemented redis commands. This class is diff --git a/tests/test_cluster.py b/tests/test_cluster.py index bec9a8ecb0..e64db3690b 100644 --- a/tests/test_cluster.py +++ b/tests/test_cluster.py @@ -2448,50 +2448,6 @@ def try_delete_libs(self, r, *lib_names): except Exception: pass - @pytest.mark.redismod - @skip_if_server_version_lt("7.1.140") - def test_tfunction_load_delete(self, r): - r.gears_refresh_cluster() - self.try_delete_libs(r, "lib1") - lib_code = self.generate_lib_code("lib1") - assert r.tfunction_load(lib_code) - assert r.tfunction_delete("lib1") - - @pytest.mark.redismod - @skip_if_server_version_lt("7.1.140") - def test_tfunction_list(self, r): - r.gears_refresh_cluster() - self.try_delete_libs(r, "lib1", "lib2", "lib3") - assert r.tfunction_load(self.generate_lib_code("lib1")) - assert r.tfunction_load(self.generate_lib_code("lib2")) - assert r.tfunction_load(self.generate_lib_code("lib3")) - - # test error thrown when verbose > 4 - with pytest.raises(DataError): - assert r.tfunction_list(verbose=8) - - functions = r.tfunction_list(verbose=1) - assert len(functions) == 3 - - expected_names = [b"lib1", b"lib2", b"lib3"] - actual_names = [functions[0][13], functions[1][13], functions[2][13]] - - assert sorted(expected_names) == sorted(actual_names) - assert r.tfunction_delete("lib1") - assert r.tfunction_delete("lib2") - assert r.tfunction_delete("lib3") - - @pytest.mark.redismod - @skip_if_server_version_lt("7.1.140") - def test_tfcall(self, r): - r.gears_refresh_cluster() - self.try_delete_libs(r, "lib1") - assert r.tfunction_load(self.generate_lib_code("lib1")) - assert r.tfcall("lib1", "foo") == b"bar" - assert r.tfcall_async("lib1", "foo") == b"bar" - - assert r.tfunction_delete("lib1") - @pytest.mark.onlycluster class TestNodesManager: diff --git a/tests/test_commands.py b/tests/test_commands.py index c6e39f565d..5c72a019ba 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -2050,57 +2050,6 @@ def try_delete_libs(self, r, *lib_names): except Exception: pass - @pytest.mark.onlynoncluster - @skip_if_server_version_lt("7.1.140") - @skip_if_server_version_gte("7.9.0") - def test_tfunction_load_delete(self, stack_r): - self.try_delete_libs(stack_r, "lib1") - lib_code = self.generate_lib_code("lib1") - assert stack_r.tfunction_load(lib_code) - assert stack_r.tfunction_delete("lib1") - - @pytest.mark.onlynoncluster - @skip_if_server_version_lt("7.1.140") - @skip_if_server_version_gte("7.9.0") - def test_tfunction_list(self, stack_r): - self.try_delete_libs(stack_r, "lib1", "lib2", "lib3") - assert stack_r.tfunction_load(self.generate_lib_code("lib1")) - assert stack_r.tfunction_load(self.generate_lib_code("lib2")) - assert stack_r.tfunction_load(self.generate_lib_code("lib3")) - - # test error thrown when verbose > 4 - with pytest.raises(redis.exceptions.DataError): - assert stack_r.tfunction_list(verbose=8) - - functions = stack_r.tfunction_list(verbose=1) - assert len(functions) == 3 - - expected_names = [b"lib1", b"lib2", b"lib3"] - if is_resp2_connection(stack_r): - actual_names = [functions[0][13], functions[1][13], functions[2][13]] - else: - actual_names = [ - functions[0][b"name"], - functions[1][b"name"], - functions[2][b"name"], - ] - - assert sorted(expected_names) == sorted(actual_names) - assert stack_r.tfunction_delete("lib1") - assert stack_r.tfunction_delete("lib2") - assert stack_r.tfunction_delete("lib3") - - @pytest.mark.onlynoncluster - @skip_if_server_version_lt("7.1.140") - @skip_if_server_version_gte("7.9.0") - def test_tfcall(self, stack_r): - self.try_delete_libs(stack_r, "lib1") - assert stack_r.tfunction_load(self.generate_lib_code("lib1")) - assert stack_r.tfcall("lib1", "foo") == b"bar" - assert stack_r.tfcall_async("lib1", "foo") == b"bar" - - assert stack_r.tfunction_delete("lib1") - def test_ttl(self, r): r["a"] = "1" assert r.expire("a", 10) diff --git a/tests/test_connection_pool.py b/tests/test_connection_pool.py index c92d84c226..0ec77a4fff 100644 --- a/tests/test_connection_pool.py +++ b/tests/test_connection_pool.py @@ -94,11 +94,11 @@ def test_reuse_previously_released_connection(self, master_host): def test_release_not_owned_connection(self, master_host): connection_kwargs = {"host": master_host[0], "port": master_host[1]} pool1 = self.get_pool(connection_kwargs=connection_kwargs) - c1 = pool1.get_connection("_") + c1 = pool1.get_connection() pool2 = self.get_pool( connection_kwargs={"host": master_host[0], "port": master_host[1]} ) - c2 = pool2.get_connection("_") + c2 = pool2.get_connection() pool2.release(c2) assert len(pool2._available_connections) == 1 diff --git a/tests/test_multiprocessing.py b/tests/test_multiprocessing.py index 8b9e9fb90b..f42f8c7919 100644 --- a/tests/test_multiprocessing.py +++ b/tests/test_multiprocessing.py @@ -99,11 +99,11 @@ def test_release_parent_connection_from_pool_in_child_process( max_connections=max_connections, ) - parent_conn = pool.get_connection("ping") + parent_conn = pool.get_connection() def target(pool, parent_conn): with exit_callback(pool.disconnect): - child_conn = pool.get_connection("ping") + child_conn = pool.get_connection() assert child_conn.pid != parent_conn.pid pool.release(child_conn) assert pool._created_connections == 1