Repository: redis/redis-py
Pull request #3517 (2025-02-19 13:18:40)

Deprecating unused arguments in connection pools's get_connection functions
### Pull Request check-list

_Please make sure to review and check all of these items:_

- [ ] Do tests and lints pass with this change?
- [ ] Do the CI tests pass with this change (enable it first in your forked repo and wait for the github action build to finish)?
- [ ] Is the new or changed code fully tested?
- [ ] Is a documentation update included (if this change modifies existing APIs, or introduces new ones)?
- [ ] Is there an example added to the examples folder (if applicable)?
- [ ] Was the change added to CHANGES file?

_NOTE: these things are not required to open a PR and can be done
afterwards / while the PR is open._

### Description of change

- Adding deprecation annotations for unused arguments in connection pools's get_connection functions.
- Adding a new decorator function that can be used to deprecate just input optional arguments for a function.
- Updating all internal  usages of get_connection functions not to provide any arguments.



Patch:
diff --git a/redis/asyncio/client.py b/redis/asyncio/client.py
index 7c179387..42544410 100644
--- a/redis/asyncio/client.py
+++ b/redis/asyncio/client.py
@@ -375,7 +375,7 @@ class Redis(
         if self.single_connection_client:
             async with self._single_conn_lock:
                 if self.connection is None:
-                    self.connection = await self.connection_pool.get_connection("_")
+                    self.connection = await self.connection_pool.get_connection()
 
             self._event_dispatcher.dispatch(
                 AfterSingleConnectionInstantiationEvent(
@@ -638,7 +638,7 @@ class Redis(
         await self.initialize()
         pool = self.connection_pool
         command_name = args[0]
-        conn = self.connection or await pool.get_connection(command_name, **options)
+        conn = self.connection or await pool.get_connection()
 
         if self.single_connection_client:
             await self._single_conn_lock.acquire()
@@ -712,7 +712,7 @@ class Monitor:
 
     async def connect(self):
         if self.connection is None:
-            self.connection = await self.connection_pool.get_connection("MONITOR")
+            self.connection = await self.connection_pool.get_connection()
 
     async def __aenter__(self):
         await self.connect()
@@ -900,9 +900,7 @@ class PubSub:
         Ensure that the PubSub is connected
         """
         if self.connection is None:
-            self.connection = await self.connection_pool.get_connection(
-                "pubsub", self.shard_hint
-            )
+            self.connection = await self.connection_pool.get_connection()
             # register a callback that re-subscribes to any channels we
             # were listening to when we were disconnected
             self.connection.register_connect_callback(self.on_connect)
@@ -1370,9 +1368,7 @@ class Pipeline(Redis):  # lgtm [py/init-calls-subclass]
         conn = self.connection
         # if this is the first call, we need a connection
         if not conn:
-            conn = await self.connection_pool.get_connection(
-                command_name, self.shard_hint
-            )
+            conn = await self.connection_pool.get_connection()
             self.connection = conn
 
         return await conn.retry.call_with_retry(
@@ -1568,7 +1564,7 @@ class Pipeline(Redis):  # lgtm [py/init-calls-subclass]
 
         conn = self.connection
         if not conn:
-            conn = await self.connection_pool.get_connection("MULTI", self.shard_hint)
+            conn = await self.connection_pool.get_connection()
             # assign to self.connection so reset() releases the connection
             # back to the pool after we're done
             self.connection = conn
diff --git a/redis/asyncio/connection.py b/redis/asyncio/connection.py
index 4a743ff3..e67dc5b2 100644
--- a/redis/asyncio/connection.py
+++ b/redis/asyncio/connection.py
@@ -29,7 +29,7 @@ from urllib.parse import ParseResult, parse_qs, unquote, urlparse
 
 from ..auth.token import TokenInterface
 from ..event import AsyncAfterConnectionReleasedEvent, EventDispatcher
-from ..utils import format_error_message
+from ..utils import deprecated_args, format_error_message
 
 # the functionality is available in 3.11.x but has a major issue before
 # 3.11.3. See https://github.com/redis/redis-py/issues/2633
@@ -1087,7 +1087,12 @@ class ConnectionPool:
             or len(self._in_use_connections) < self.max_connections
         )
 
-    async def get_connection(self, command_name, *keys, **options):
+    @deprecated_args(
+        args_to_warn=["*"],
+        reason="Use get_connection() without args instead",
+        version="5.0.3",
+    )
+    async def get_connection(self, command_name=None, *keys, **options):
         async with self._lock:
             """Get a connected connection from the pool"""
             connection = self.get_available_connection()
@@ -1255,7 +1260,12 @@ class BlockingConnectionPool(ConnectionPool):
         self._condition = asyncio.Condition()
         self.timeout = timeout
 
-    async def get_connection(self, command_name, *keys, **options):
+    @deprecated_args(
+        args_to_warn=["*"],
+        reason="Use get_connection() without args instead",
+        version="5.0.3",
+    )
+    async def get_connection(self, command_name=None, *keys, **options):
         """Gets a connection from the pool, blocking until one is available"""
         try:
             async with self._condition:
diff --git a/redis/client.py b/redis/client.py
index 5a9f4faf..fc535c8c 100755
--- a/redis/client.py
+++ b/redis/client.py
@@ -366,7 +366,7 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
         self.connection = None
         self._single_connection_client = single_connection_client
         if self._single_connection_client:
-            self.connection = self.connection_pool.get_connection("_")
+            self.connection = self.connection_pool.get_connection()
             self._event_dispatcher.dispatch(
                 AfterSingleConnectionInstantiationEvent(
                     self.connection, ClientType.SYNC, self.single_connection_lock
@@ -608,7 +608,7 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
         """Execute a command and return a parsed response"""
         pool = self.connection_pool
         command_name = args[0]
-        conn = self.connection or pool.get_connection(command_name, **options)
+        conn = self.connection or pool.get_connection()
 
         if self._single_connection_client:
             self.single_connection_lock.acquire()
@@ -667,7 +667,7 @@ class Monitor:
 
     def __init__(self, connection_pool):
         self.connection_pool = connection_pool
-        self.connection = self.connection_pool.get_connection("MONITOR")
+        self.connection = self.connection_pool.get_connection()
 
     def __enter__(self):
         self.connection.send_command("MONITOR")
@@ -840,9 +840,7 @@ class PubSub:
         # subscribed to one or more channels
 
         if self.connection is None:
-            self.connection = self.connection_pool.get_connection(
-                "pubsub", self.shard_hint
-            )
+            self.connection = self.connection_pool.get_connection()
             # register a callback that re-subscribes to any channels we
             # were listening to when we were disconnected
             self.connection.register_connect_callback(self.on_connect)
@@ -1397,7 +1395,7 @@ class Pipeline(Redis):
         conn = self.connection
         # if this is the first call, we need a connection
         if not conn:
-            conn = self.connection_pool.get_connection(command_name, self.shard_hint)
+            conn = self.connection_pool.get_connection()
             self.connection = conn
 
         return conn.retry.call_with_retry(
@@ -1583,7 +1581,7 @@ class Pipeline(Redis):
 
         conn = self.connection
         if not conn:
-            conn = self.connection_pool.get_connection("MULTI", self.shard_hint)
+            conn = self.connection_pool.get_connection()
             # assign to self.connection so reset() releases the connection
             # back to the pool after we're done
             self.connection = conn
diff --git a/redis/cluster.py b/redis/cluster.py
index db866ce2..c184838a 100644
--- a/redis/cluster.py
+++ b/redis/cluster.py
@@ -40,6 +40,7 @@ from redis.lock import Lock
 from redis.retry import Retry
 from redis.utils import (
     HIREDIS_AVAILABLE,
+    deprecated_args,
     dict_merge,
     list_keys_to_dict,
     merge_result,
@@ -52,10 +53,13 @@ def get_node_name(host: str, port: Union[str, int]) -> str:
     return f"{host}:{port}"
 
 
+@deprecated_args(
+    allowed_args=["redis_node"],
+    reason="Use get_connection(redis_node) instead",
+    version="5.0.3",
+)
 def get_connection(redis_node, *args, **options):
-    return redis_node.connection or redis_node.connection_pool.get_connection(
-        args[0], **options
-    )
+    return redis_node.connection or redis_node.connection_pool.get_connection()
 
 
 def parse_scan_result(command, res, **options):
@@ -1151,7 +1155,7 @@ class RedisCluster(AbstractRedisCluster, RedisClusterCommands):
                     moved = False
 
                 redis_node = self.get_redis_connection(target_node)
-                connection = get_connection(redis_node, *args, **kwargs)
+                connection = get_connection(redis_node)
                 if asking:
                     connection.send_command("ASKING")
                     redis_node.parse_response(connection, "ASKING", **kwargs)
@@ -1822,9 +1826,7 @@ class ClusterPubSub(PubSub):
                 self.node = node
                 redis_connection = self.cluster.get_redis_connection(node)
                 self.connection_pool = redis_connection.connection_pool
-            self.connection = self.connection_pool.get_connection(
-                "pubsub", self.shard_hint
-            )
+            self.connection = self.connection_pool.get_connection()
             # register a callback that re-subscribes to any channels we
             # were listening to when we were disconnected
             self.connection.register_connect_callback(self.on_connect)
@@ -2184,7 +2186,7 @@ class ClusterPipeline(RedisCluster):
                 if node_name not in nodes:
                     redis_node = self.get_redis_connection(node)
                     try:
-                        connection = get_connection(redis_node, c.args)
+                        connection = get_connection(redis_node)
                     except (ConnectionError, TimeoutError):
                         for n in nodes.values():
                             n.connection_pool.release(n.connection)
diff --git a/redis/connection.py b/redis/connection.py
index c4ff9b7b..d59a9b06 100644
--- a/redis/connection.py
+++ b/redis/connection.py
@@ -42,6 +42,7 @@ from .utils import (
     HIREDIS_AVAILABLE,
     SSL_AVAILABLE,
     compare_versions,
+    deprecated_args,
     ensure_string,
     format_error_message,
     get_lib_version,
@@ -1461,8 +1462,14 @@ class ConnectionPool:
             finally:
                 self._fork_lock.release()
 
-    def get_connection(self, command_name: str, *keys, **options) -> "Connection":
+    @deprecated_args(
+        args_to_warn=["*"],
+        reason="Use get_connection() without args instead",
+        version="5.0.3",
+    )
+    def get_connection(self, command_name=None, *keys, **options) -> "Connection":
         "Get a connection from the pool"
+
         self._checkpid()
         with self._lock:
             try:
@@ -1683,7 +1690,12 @@ class BlockingConnectionPool(ConnectionPool):
         self._connections.append(connection)
         return connection
 
-    def get_connection(self, command_name, *keys, **options):
+    @deprecated_args(
+        args_to_warn=["*"],
+        reason="Use get_connection() without args instead",
+        version="5.0.3",
+    )
+    def get_connection(self, command_name=None, *keys, **options):
         """
         Get a connection, blocking for ``self.timeout`` until a connection
         is available from the pool.
diff --git a/redis/utils.py b/redis/utils.py
index 8693fb3c..66465636 100644
--- a/redis/utils.py
+++ b/redis/utils.py
@@ -122,6 +122,71 @@ def deprecated_function(reason="", version="", name=None):
     return decorator
 
 
+def warn_deprecated_arg_usage(
+    arg_name: Union[list, str],
+    function_name: str,
+    reason: str = "",
+    version: str = "",
+    stacklevel: int = 2,
+):
+    import warnings
+
+    msg = (
+        f"Call to '{function_name}' function with deprecated"
+        f" usage of input argument/s '{arg_name}'."
+    )
+    if reason:
+        msg += f" ({reason})"
+    if version:
+        msg += f" -- Deprecated since version {version}."
+    warnings.warn(msg, category=DeprecationWarning, stacklevel=stacklevel)
+
+
+def deprecated_args(
+    args_to_warn: list = ["*"],
+    allowed_args: list = [],
+    reason: str = "",
+    version: str = "",
+):
+    """
+    Decorator to mark specified args of a function as deprecated.
+    If '*' is in args_to_warn, all arguments will be marked as deprecated.
+    """
+
+    def decorator(func):
+        @wraps(func)
+        def wrapper(*args, **kwargs):
+            # Get function argument names
+            arg_names = func.__code__.co_varnames[: func.__code__.co_argcount]
+
+            provided_args = dict(zip(arg_names, args))
+            provided_args.update(kwargs)
+
+            provided_args.pop("self", None)
+            for allowed_arg in allowed_args:
+                provided_args.pop(allowed_arg, None)
+
+            for arg in args_to_warn:
+                if arg == "*" and len(provided_args) > 0:
+                    warn_deprecated_arg_usage(
+                        list(provided_args.keys()),
+                        func.__name__,
+                        reason,
+                        version,
+                        stacklevel=3,
+                    )
+                elif arg in provided_args:
+                    warn_deprecated_arg_usage(
+                        arg, func.__name__, reason, version, stacklevel=3
+                    )
+
+            return func(*args, **kwargs)
+
+        return wrapper
+
+    return decorator
+
+
 def _set_info_logger():
     """
     Set up a logger that log info logs to stdout.


Test patch:
diff --git a/tests/test_asyncio/test_connection.py b/tests/test_asyncio/test_connection.py
index d4956f16..38764d30 100644
--- a/tests/test_asyncio/test_connection.py
+++ b/tests/test_asyncio/test_connection.py
@@ -78,7 +78,7 @@ async def test_single_connection():
     mock_conn = mock.AsyncMock(spec=Connection)
     mock_conn.retry = Retry_()
 
-    async def get_conn(_):
+    async def get_conn():
         # Validate only one client is created in single-client mode when
         # concurrent requests are made
         nonlocal init_call_count
diff --git a/tests/test_asyncio/test_connection_pool.py b/tests/test_asyncio/test_connection_pool.py
index 83545b4e..3d120e4c 100644
--- a/tests/test_asyncio/test_connection_pool.py
+++ b/tests/test_asyncio/test_connection_pool.py
@@ -29,8 +29,8 @@ class TestRedisAutoReleaseConnectionPool:
     @staticmethod
     async def create_two_conn(r: redis.Redis):
         if not r.single_connection_client:  # Single already initialized connection
-            r.connection = await r.connection_pool.get_connection("_")
-        return await r.connection_pool.get_connection("_")
+            r.connection = await r.connection_pool.get_connection()
+        return await r.connection_pool.get_connection()
 
     @staticmethod
     def has_no_connected_connections(pool: redis.ConnectionPool):
@@ -138,7 +138,7 @@ class TestConnectionPool:
         async with self.get_pool(
             connection_kwargs=connection_kwargs, connection_class=DummyConnection
         ) as pool:
-            connection = await pool.get_connection("_")
+            connection = await pool.get_connection()
             assert isinstance(connection, DummyConnection)
             assert connection.kwargs == connection_kwargs
 
@@ -155,8 +155,8 @@ class TestConnectionPool:
     async def test_multiple_connections(self, master_host):
         connection_kwargs = {"host": master_host[0]}
         async with self.get_pool(connection_kwargs=connection_kwargs) as pool:
-            c1 = await pool.get_connection("_")
-            c2 = await pool.get_connection("_")
+            c1 = await pool.get_connection()
+            c2 = await pool.get_connection()
             assert c1 != c2
 
     async def test_max_connections(self, master_host):
@@ -164,17 +164,17 @@ class TestConnectionPool:
         async with self.get_pool(
             max_connections=2, connection_kwargs=connection_kwargs
         ) as pool:
-            await pool.get_connection("_")
-            await pool.get_connection("_")
+            await pool.get_connection()
+            await pool.get_connection()
             with pytest.raises(redis.ConnectionError):
-                await pool.get_connection("_")
+                await pool.get_connection()
 
     async def test_reuse_previously_released_connection(self, master_host):
         connection_kwargs = {"host": master_host[0]}
         async with self.get_pool(connection_kwargs=connection_kwargs) as pool:
-            c1 = await pool.get_connection("_")
+            c1 = await pool.get_connection()
             await pool.release(c1)
-            c2 = await pool.get_connection("_")
+            c2 = await pool.get_connection()
             assert c1 == c2
 
     async def test_repr_contains_db_info_tcp(self):
@@ -223,7 +223,7 @@ class TestBlockingConnectionPool:
             "port": master_host[1],
         }
         async with self.get_pool(connection_kwargs=connection_kwargs) as pool:
-            connection = await pool.get_connection("_")
+            connection = await pool.get_connection()
             assert isinstance(connection, DummyConnection)
             assert connection.kwargs == connection_kwargs
 
@@ -236,14 +236,14 @@ class TestBlockingConnectionPool:
             "port": master_host[1],
         }
         async with self.get_pool(connection_kwargs=connection_kwargs) as pool:
-            await pool.get_connection("_")
+            await pool.get_connection()
             await pool.disconnect()
 
     async def test_multiple_connections(self, master_host):
         connection_kwargs = {"host": master_host[0], "port": master_host[1]}
         async with self.get_pool(connection_kwargs=connection_kwargs) as pool:
-            c1 = await pool.get_connection("_")
-            c2 = await pool.get_connection("_")
+            c1 = await pool.get_connection()
+            c2 = await pool.get_connection()
             assert c1 != c2
 
     async def test_connection_pool_blocks_until_timeout(self, master_host):
@@ -252,11 +252,11 @@ class TestBlockingConnectionPool:
         async with self.get_pool(
             max_connections=1, timeout=0.1, connection_kwargs=connection_kwargs
         ) as pool:
-            c1 = await pool.get_connection("_")
+            c1 = await pool.get_connection()
 
             start = asyncio.get_running_loop().time()
             with pytest.raises(redis.ConnectionError):
-                await pool.get_connection("_")
+                await pool.get_connection()
 
             # we should have waited at least some period of time
             assert asyncio.get_running_loop().time() - start >= 0.05
@@ -271,23 +271,23 @@ class TestBlockingConnectionPool:
         async with self.get_pool(
             max_connections=1, timeout=2, connection_kwargs=connection_kwargs
         ) as pool:
-            c1 = await pool.get_connection("_")
+            c1 = await pool.get_connection()
 
             async def target():
                 await asyncio.sleep(0.1)
                 await pool.release(c1)
 
             start = asyncio.get_running_loop().time()
-            await asyncio.gather(target(), pool.get_connection("_"))
+            await asyncio.gather(target(), pool.get_connection())
             stop = asyncio.get_running_loop().time()
             assert (stop - start) <= 0.2
 
     async def test_reuse_previously_released_connection(self, master_host):
         connection_kwargs = {"host": master_host[0]}
         async with self.get_pool(connection_kwargs=connection_kwargs) as pool:
-            c1 = await pool.get_connection("_")
+            c1 = await pool.get_connection()
             await pool.release(c1)
-            c2 = await pool.get_connection("_")
+            c2 = await pool.get_connection()
             assert c1 == c2
 
     def test_repr_contains_db_info_tcp(self):
@@ -552,23 +552,23 @@ class TestSSLConnectionURLParsing:
         import ssl
 
         class DummyConnectionPool(redis.ConnectionPool):
-            def get_connection(self, *args, **kwargs):
+            def get_connection(self):
                 return self.make_connection()
 
         pool = DummyConnectionPool.from_url("rediss://?ssl_cert_reqs=none")
-        assert pool.get_connection("_").cert_reqs == ssl.CERT_NONE
+        assert pool.get_connection().cert_reqs == ssl.CERT_NONE
 
         pool = DummyConnectionPool.from_url("rediss://?ssl_cert_reqs=optional")
-        assert pool.get_connection("_").cert_reqs == ssl.CERT_OPTIONAL
+        assert pool.get_connection().cert_reqs == ssl.CERT_OPTIONAL
 
         pool = DummyConnectionPool.from_url("rediss://?ssl_cert_reqs=required")
-        assert pool.get_connection("_").cert_reqs == ssl.CERT_REQUIRED
+        assert pool.get_connection().cert_reqs == ssl.CERT_REQUIRED
 
         pool = DummyConnectionPool.from_url("rediss://?ssl_check_hostname=False")
-        assert pool.get_connection("_").check_hostname is False
+        assert pool.get_connection().check_hostname is False
 
         pool = DummyConnectionPool.from_url("rediss://?ssl_check_hostname=True")
-        assert pool.get_connection("_").check_hostname is True
+        assert pool.get_connection().check_hostname is True
 
 
 class TestConnection:
@@ -756,7 +756,7 @@ class TestHealthCheck:
 
     async def test_health_check_in_pipeline(self, r):
         async with r.pipeline(transaction=False) as pipe:
-            pipe.connection = await pipe.connection_pool.get_connection("_")
+            pipe.connection = await pipe.connection_pool.get_connection()
             pipe.connection.next_health_check = 0
             with mock.patch.object(
                 pipe.connection, "send_command", wraps=pipe.connection.send_command
@@ -767,7 +767,7 @@ class TestHealthCheck:
 
     async def test_health_check_in_transaction(self, r):
         async with r.pipeline(transaction=True) as pipe:
-            pipe.connection = await pipe.connection_pool.get_connection("_")
+            pipe.connection = await pipe.connection_pool.get_connection()
             pipe.connection.next_health_check = 0
             with mock.patch.object(
                 pipe.connection, "send_command", wraps=pipe.connection.send_command
@@ -779,7 +779,7 @@ class TestHealthCheck:
     async def test_health_check_in_watched_pipeline(self, r):
         await r.set("foo", "bar")
         async with r.pipeline(transaction=False) as pipe:
-            pipe.connection = await pipe.connection_pool.get_connection("_")
+            pipe.connection = await pipe.connection_pool.get_connection()
             pipe.connection.next_health_check = 0
             with mock.patch.object(
                 pipe.connection, "send_command", wraps=pipe.connection.send_command
@@ -803,7 +803,7 @@ class TestHealthCheck:
     async def test_health_check_in_pubsub_before_subscribe(self, r):
         """A health check happens before the first [p]subscribe"""
         p = r.pubsub()
-        p.connection = await p.connection_pool.get_connection("_")
+        p.connection = await p.connection_pool.get_connection()
         p.connection.next_health_check = 0
         with mock.patch.object(
             p.connection, "send_command", wraps=p.connection.send_command
@@ -825,7 +825,7 @@ class TestHealthCheck:
         connection health
         """
         p = r.pubsub()
-        p.connection = await p.connection_pool.get_connection("_")
+        p.connection = await p.connection_pool.get_connection()
         p.connection.next_health_check = 0
         with mock.patch.object(
             p.connection, "send_command", wraps=p.connection.send_command
@@ -865,7 +865,7 @@ class TestHealthCheck:
         check the connection's health.
         """
         p = r.pubsub()
-        p.connection = await p.connection_pool.get_connection("_")
+        p.connection = await p.connection_pool.get_connection()
         with mock.patch.object(
             p.connection, "send_command", wraps=p.connection.send_command
         ) as m:
diff --git a/tests/test_asyncio/test_credentials.py b/tests/test_asyncio/test_credentials.py
index ca42d190..1eb988ce 100644
--- a/tests/test_asyncio/test_credentials.py
+++ b/tests/test_asyncio/test_credentials.py
@@ -274,7 +274,7 @@ class TestCredentialsProvider:
         await init_acl_user(r, username, password)
         r2 = await create_redis(flushdb=False, username=username, password=password)
         assert await r2.ping() is True
-        conn = await r2.connection_pool.get_connection("_")
+        conn = await r2.connection_pool.get_connection()
         await conn.send_command("PING")
         assert str_if_bytes(await conn.read_response()) == "PONG"
         assert conn.username == username
diff --git a/tests/test_asyncio/test_encoding.py b/tests/test_asyncio/test_encoding.py
index 162ccb36..74a9f28b 100644
--- a/tests/test_asyncio/test_encoding.py
+++ b/tests/test_asyncio/test_encoding.py
@@ -74,7 +74,7 @@ class TestMemoryviewsAreNotPacked:
     async def test_memoryviews_are_not_packed(self, r):
         arg = memoryview(b"some_arg")
         arg_list = ["SOME_COMMAND", arg]
-        c = r.connection or await r.connection_pool.get_connection("_")
+        c = r.connection or await r.connection_pool.get_connection()
         cmd = c.pack_command(*arg_list)
         assert cmd[1] is arg
         cmds = c.pack_commands([arg_list, arg_list])
diff --git a/tests/test_asyncio/test_retry.py b/tests/test_asyncio/test_retry.py
index 8bc71c14..cd251a98 100644
--- a/tests/test_asyncio/test_retry.py
+++ b/tests/test_asyncio/test_retry.py
@@ -126,13 +126,13 @@ class TestRedisClientRetry:
         assert r.get_retry()._retries == retry._retries
         assert isinstance(r.get_retry()._backoff, NoBackoff)
         new_retry_policy = Retry(ExponentialBackoff(), 3)
-        exiting_conn = await r.connection_pool.get_connection("_")
+        exiting_conn = await r.connection_pool.get_connection()
         r.set_retry(new_retry_policy)
         assert r.get_retry()._retries == new_retry_policy._retries
         assert isinstance(r.get_retry()._backoff, ExponentialBackoff)
         assert exiting_conn.retry._retries == new_retry_policy._retries
         await r.connection_pool.release(exiting_conn)
-        new_conn = await r.connection_pool.get_connection("_")
+        new_conn = await r.connection_pool.get_connection()
         assert new_conn.retry._retries == new_retry_policy._retries
         await r.connection_pool.release(new_conn)
         await r.aclose()
diff --git a/tests/test_asyncio/test_sentinel.py b/tests/test_asyncio/test_sentinel.py
index e553fdb0..a27ba92b 100644
--- a/tests/test_asyncio/test_sentinel.py
+++ b/tests/test_asyncio/test_sentinel.py
@@ -269,7 +269,7 @@ async def test_auto_close_pool(cluster, sentinel, method_name):
 @pytest.mark.onlynoncluster
 async def test_repr_correctly_represents_connection_object(sentinel):
     pool = SentinelConnectionPool("mymaster", sentinel)
-    connection = await pool.get_connection("PING")
+    connection = await pool.get_connection()
 
     assert (
         str(connection)
diff --git a/tests/test_cache.py b/tests/test_cache.py
index 67733dc9..7010baff 100644
--- a/tests/test_cache.py
+++ b/tests/test_cache.py
@@ -159,7 +159,7 @@ class TestCache:
             == b"bar"
         )
         # Force disconnection
-        r.connection_pool.get_connection("_").disconnect()
+        r.connection_pool.get_connection().disconnect()
         # Make sure cache is empty
         assert cache.size == 0
 
@@ -429,7 +429,7 @@ class TestClusterCache:
         # Force disconnection
         r.nodes_manager.get_node_from_slot(
             12000
-        ).redis_connection.connection_pool.get_connection("_").disconnect()
+        ).redis_connection.connection_pool.get_connection().disconnect()
         # Make sure cache is empty
         assert cache.size == 0
 
@@ -667,7 +667,7 @@ class TestSentinelCache:
             == b"bar"
         )
         # Force disconnection
-        master.connection_pool.get_connection("_").disconnect()
+        master.connection_pool.get_connection().disconnect()
         # Make sure cache_data is empty
         assert cache.size == 0
 
diff --git a/tests/test_cluster.py b/tests/test_cluster.py
index 1b9b9969..908ac262 100644
--- a/tests/test_cluster.py
+++ b/tests/test_cluster.py
@@ -845,7 +845,7 @@ class TestRedisClusterObj:
             assert node.redis_connection.get_retry()._retries == retry._retries
             assert isinstance(node.redis_connection.get_retry()._backoff, NoBackoff)
         rand_node = r.get_random_node()
-        existing_conn = rand_node.redis_connection.connection_pool.get_connection("_")
+        existing_conn = rand_node.redis_connection.connection_pool.get_connection()
         # Change retry policy
         new_retry = Retry(ExponentialBackoff(), 3)
         r.set_retry(new_retry)
@@ -857,7 +857,7 @@ class TestRedisClusterObj:
                 node.redis_connection.get_retry()._backoff, ExponentialBackoff
             )
         assert existing_conn.retry._retries == new_retry._retries
-        new_conn = rand_node.redis_connection.connection_pool.get_connection("_")
+        new_conn = rand_node.redis_connection.connection_pool.get_connection()
         assert new_conn.retry._retries == new_retry._retries
 
     def test_cluster_retry_object(self, r) -> None:
diff --git a/tests/test_connection_pool.py b/tests/test_connection_pool.py
index 118294ee..387a0f45 100644
--- a/tests/test_connection_pool.py
+++ b/tests/test_connection_pool.py
@@ -54,7 +54,7 @@ class TestConnectionPool:
         pool = self.get_pool(
             connection_kwargs=connection_kwargs, connection_class=DummyConnection
         )
-        connection = pool.get_connection("_")
+        connection = pool.get_connection()
         assert isinstance(connection, DummyConnection)
         assert connection.kwargs == connection_kwargs
 
@@ -71,24 +71,24 @@ class TestConnectionPool:
     def test_multiple_connections(self, master_host):
         connection_kwargs = {"host": master_host[0], "port": master_host[1]}
         pool = self.get_pool(connection_kwargs=connection_kwargs)
-        c1 = pool.get_connection("_")
-        c2 = pool.get_connection("_")
+        c1 = pool.get_connection()
+        c2 = pool.get_connection()
         assert c1 != c2
 
     def test_max_connections(self, master_host):
         connection_kwargs = {"host": master_host[0], "port": master_host[1]}
         pool = self.get_pool(max_connections=2, connection_kwargs=connection_kwargs)
-        pool.get_connection("_")
-        pool.get_connection("_")
+        pool.get_connection()
+        pool.get_connection()
         with pytest.raises(redis.ConnectionError):
-            pool.get_connection("_")
+            pool.get_connection()
 
     def test_reuse_previously_released_connection(self, master_host):
         connection_kwargs = {"host": master_host[0], "port": master_host[1]}
         pool = self.get_pool(connection_kwargs=connection_kwargs)
-        c1 = pool.get_connection("_")
+        c1 = pool.get_connection()
         pool.release(c1)
-        c2 = pool.get_connection("_")
+        c2 = pool.get_connection()
         assert c1 == c2
 
     def test_repr_contains_db_info_tcp(self):
@@ -133,15 +133,15 @@ class TestBlockingConnectionPool:
             "port": master_host[1],
         }
         pool = self.get_pool(connection_kwargs=connection_kwargs)
-        connection = pool.get_connection("_")
+        connection = pool.get_connection()
         assert isinstance(connection, DummyConnection)
         assert connection.kwargs == connection_kwargs
 
     def test_multiple_connections(self, master_host):
         connection_kwargs = {"host": master_host[0], "port": master_host[1]}
         pool = self.get_pool(connection_kwargs=connection_kwargs)
-        c1 = pool.get_connection("_")
-        c2 = pool.get_connection("_")
+        c1 = pool.get_connection()
+        c2 = pool.get_connection()
         assert c1 != c2
 
     def test_connection_pool_blocks_until_timeout(self, master_host):
@@ -150,11 +150,11 @@ class TestBlockingConnectionPool:
         pool = self.get_pool(
             max_connections=1, timeout=0.1, connection_kwargs=connection_kwargs
         )
-        pool.get_connection("_")
+        pool.get_connection()
 
         start = time.time()
         with pytest.raises(redis.ConnectionError):
-            pool.get_connection("_")
+            pool.get_connection()
         # we should have waited at least 0.1 seconds
         assert time.time() - start >= 0.1
 
@@ -167,7 +167,7 @@ class TestBlockingConnectionPool:
         pool = self.get_pool(
             max_connections=1, timeout=2, connection_kwargs=connection_kwargs
         )
-        c1 = pool.get_connection("_")
+        c1 = pool.get_connection()
 
         def target():
             time.sleep(0.1)
@@ -175,15 +175,15 @@ class TestBlockingConnectionPool:
 
         start = time.time()
         Thread(target=target).start()
-        pool.get_connection("_")
+        pool.get_connection()
         assert time.time() - start >= 0.1
 
     def test_reuse_previously_released_connection(self, master_host):
         connection_kwargs = {"host": master_host[0], "port": master_host[1]}
         pool = self.get_pool(connection_kwargs=connection_kwargs)
-        c1 = pool.get_connection("_")
+        c1 = pool.get_connection()
         pool.release(c1)
-        c2 = pool.get_connection("_")
+        c2 = pool.get_connection()
         assert c1 == c2
 
     def test_repr_contains_db_info_tcp(self):
@@ -214,7 +214,7 @@ class TestBlockingConnectionPool:
             protocol=3,
             cache_config=CacheConfig(),
         )
-        assert isinstance(pool.get_connection("_"), CacheProxyConnection)
+        assert isinstance(pool.get_connection(), CacheProxyConnection)
 
 
 class TestConnectionPoolURLParsing:
@@ -489,23 +489,23 @@ class TestSSLConnectionURLParsing:
         import ssl
 
         class DummyConnectionPool(redis.ConnectionPool):
-            def get_connection(self, *args, **kwargs):
+            def get_connection(self):
                 return self.make_connection()
 
         pool = DummyConnectionPool.from_url("rediss://?ssl_cert_reqs=none")
-        assert pool.get_connection("_").cert_reqs == ssl.CERT_NONE
+        assert pool.get_connection().cert_reqs == ssl.CERT_NONE
 
         pool = DummyConnectionPool.from_url("rediss://?ssl_cert_reqs=optional")
-        assert pool.get_connection("_").cert_reqs == ssl.CERT_OPTIONAL
+        assert pool.get_connection().cert_reqs == ssl.CERT_OPTIONAL
 
         pool = DummyConnectionPool.from_url("rediss://?ssl_cert_reqs=required")
-        assert pool.get_connection("_").cert_reqs == ssl.CERT_REQUIRED
+        assert pool.get_connection().cert_reqs == ssl.CERT_REQUIRED
 
         pool = DummyConnectionPool.from_url("rediss://?ssl_check_hostname=False")
-        assert pool.get_connection("_").check_hostname is False
+        assert pool.get_connection().check_hostname is False
 
         pool = DummyConnectionPool.from_url("rediss://?ssl_check_hostname=True")
-        assert pool.get_connection("_").check_hostname is True
+        assert pool.get_connection().check_hostname is True
 
 
 class TestConnection:
@@ -701,7 +701,7 @@ class TestHealthCheck:
 
     def test_health_check_in_pipeline(self, r):
         with r.pipeline(transaction=False) as pipe:
-            pipe.connection = pipe.connection_pool.get_connection("_")
+            pipe.connection = pipe.connection_pool.get_connection()
             pipe.connection.next_health_check = 0
             with mock.patch.object(
                 pipe.connection, "send_command", wraps=pipe.connection.send_command
@@ -712,7 +712,7 @@ class TestHealthCheck:
 
     def test_health_check_in_transaction(self, r):
         with r.pipeline(transaction=True) as pipe:
-            pipe.connection = pipe.connection_pool.get_connection("_")
+            pipe.connection = pipe.connection_pool.get_connection()
             pipe.connection.next_health_check = 0
             with mock.patch.object(
                 pipe.connection, "send_command", wraps=pipe.connection.send_command
@@ -724,7 +724,7 @@ class TestHealthCheck:
     def test_health_check_in_watched_pipeline(self, r):
         r.set("foo", "bar")
         with r.pipeline(transaction=False) as pipe:
-            pipe.connection = pipe.connection_pool.get_connection("_")
+            pipe.connection = pipe.connection_pool.get_connection()
             pipe.connection.next_health_check = 0
             with mock.patch.object(
                 pipe.connection, "send_command", wraps=pipe.connection.send_command
@@ -748,7 +748,7 @@ class TestHealthCheck:
     def test_health_check_in_pubsub_before_subscribe(self, r):
         "A health check happens before the first [p]subscribe"
         p = r.pubsub()
-        p.connection = p.connection_pool.get_connection("_")
+        p.connection = p.connection_pool.get_connection()
         p.connection.next_health_check = 0
         with mock.patch.object(
             p.connection, "send_command", wraps=p.connection.send_command
@@ -770,7 +770,7 @@ class TestHealthCheck:
         connection health
         """
         p = r.pubsub()
-        p.connection = p.connection_pool.get_connection("_")
+        p.connection = p.connection_pool.get_connection()
         p.connection.next_health_check = 0
         with mock.patch.object(
             p.connection, "send_command", wraps=p.connection.send_command
@@ -810,7 +810,7 @@ class TestHealthCheck:
         check the connection's health.
         """
         p = r.pubsub()
-        p.connection = p.connection_pool.get_connection("_")
+        p.connection = p.connection_pool.get_connection()
         with mock.patch.object(
             p.connection, "send_command", wraps=p.connection.send_command
         ) as m:
diff --git a/tests/test_credentials.py b/tests/test_credentials.py
index b0b79d30..95ec5577 100644
--- a/tests/test_credentials.py
+++ b/tests/test_credentials.py
@@ -252,7 +252,7 @@ class TestCredentialsProvider:
             redis.Redis, request, flushdb=False, username=username, password=password
         )
         assert r2.ping() is True
-        conn = r2.connection_pool.get_connection("_")
+        conn = r2.connection_pool.get_connection()
         conn.send_command("PING")
         assert str_if_bytes(conn.read_response()) == "PONG"
         assert conn.username == username
diff --git a/tests/test_multiprocessing.py b/tests/test_multiprocessing.py
index 116d20da..0e8e8958 100644
--- a/tests/test_multiprocessing.py
+++ b/tests/test_multiprocessing.py
@@ -95,7 +95,7 @@ class TestMultiprocessing:
             max_connections=max_connections,
         )
 
-        conn = pool.get_connection("ping")
+        conn = pool.get_connection()
         main_conn_pid = conn.pid
         with exit_callback(pool.release, conn):
             conn.send_command("ping")
@@ -103,7 +103,7 @@ class TestMultiprocessing:
 
         def target(pool):
             with exit_callback(pool.disconnect):
-                conn = pool.get_connection("ping")
+                conn = pool.get_connection()
                 assert conn.pid != main_conn_pid
                 with exit_callback(pool.release, conn):
                     assert conn.send_command("ping") is None
@@ -116,7 +116,7 @@ class TestMultiprocessing:
 
         # Check that connection is still alive after fork process has exited
         # and disconnected the connections in its pool
-        conn = pool.get_connection("ping")
+        conn = pool.get_connection()
         with exit_callback(pool.release, conn):
             assert conn.send_command("ping") is None
             assert conn.read_response() == b"PONG"
@@ -132,12 +132,12 @@ class TestMultiprocessing:
             max_connections=max_connections,
         )
 
-        conn = pool.get_connection("ping")
+        conn = pool.get_connection()
         assert conn.send_command("ping") is None
         assert conn.read_response() == b"PONG"
 
         def target(pool, disconnect_event):
-            conn = pool.get_connection("ping")
+            conn = pool.get_connection()
             with exit_callback(pool.release, conn):
                 assert conn.send_command("ping") is None
                 assert conn.read_response() == b"PONG"
diff --git a/tests/test_retry.py b/tests/test_retry.py
index 18380738..e1e4c414 100644
--- a/tests/test_retry.py
+++ b/tests/test_retry.py
@@ -206,7 +206,7 @@ class TestRedisClientRetry:
     def test_get_set_retry_object(self, request):
         retry = Retry(NoBackoff(), 2)
         r = _get_client(Redis, request, retry_on_timeout=True, retry=retry)
-        exist_conn = r.connection_pool.get_connection("_")
+        exist_conn = r.connection_pool.get_connection()
         assert r.get_retry()._retries == retry._retries
         assert isinstance(r.get_retry()._backoff, NoBackoff)
         new_retry_policy = Retry(ExponentialBackoff(), 3)
@@ -214,5 +214,5 @@ class TestRedisClientRetry:
         assert r.get_retry()._retries == new_retry_policy._retries
         assert isinstance(r.get_retry()._backoff, ExponentialBackoff)
         assert exist_conn.retry._retries == new_retry_policy._retries
-        new_conn = r.connection_pool.get_connection("_")
+        new_conn = r.connection_pool.get_connection()
         assert new_conn.retry._retries == new_retry_policy._retries
diff --git a/tests/test_sentinel.py b/tests/test_sentinel.py
index 54b96470..93455f32 100644
--- a/tests/test_sentinel.py
+++ b/tests/test_sentinel.py
@@ -101,7 +101,7 @@ def test_discover_master_error(sentinel):
 @pytest.mark.onlynoncluster
 def test_dead_pool(sentinel):
     master = sentinel.master_for("mymaster", db=9)
-    conn = master.connection_pool.get_connection("_")
+    conn = master.connection_pool.get_connection()
     conn.disconnect()
     del master
     conn.connect()