Structure of redis.asyncio does not allow asyncio coroutine inspection
Version: redis-py 5.0.1 Platform: Python 3.11 macOS
Description
There are many libraries / frameworks that try to be polyglottal by nature and support both sync python and asyncio-based Python. One of the key ways libraries do this is by using python stdlib functions like inspect.isawaitable or asyncio.iscoroutinefunction or similar in order to test if a function is a coroutine or not, and then treat it appropriately (e.g. by running it in the event loop or in a threadpool)
The problem is that redis-py's asyncio system does not use async functions, it uses "normal" functions that return coroutines. This effectively breaks everyone else's ability to treat asyncio redis methods appropriately.
Simple repro
import asyncio
import inspect
from redis import asyncio as AsyncRedis
redis_instance = AsyncRedis.from_url(REDIS_URL, health_check_interval=30, encoding="utf-8")
# returns False, should be True
print(asyncio.iscoroutinefunction(redis_instance.delete))
# also returns False but realistically should be True
print(inspect.isawaitable(redis_instance.delete))
# example of why this matters
async def utility_function(func, *args, **kwargs):
if asyncio.iscoroutinefunction(func):
await func(*args, **kwargs)
else:
await asyncio.to_thread(func, *args, **kwargs)
# does the wrong thing, coroutine is never awaited
await utility_function(redis_instance.delete, "card-cache:9f3faff0-9001-4a06-98cd-eaf1439861c5")
This is a fairly common pattern in other libs. Is there anything that can be done about this so that async functions are properly marked as such?
This issue is marked stale. It will be closed in 30 days if it is not updated.
This is still an issue in redis-py 5.2.1