-
Notifications
You must be signed in to change notification settings - Fork 116
Description
In Python without decorator package, if I want to create a custom decorator that supports both sync and async function, I can write the following:
import inspect
def custom_decorator(func):
if inspect.iscoroutinefunction(func):
# Support for async functions
async def awrapper(*args, **kwargs):
print("custom_decorator")
return await func(*args, **kwargs)
return awrapper
else:
# Support for sync functions
def wrapper(*args, **kwargs):
print("custom_decorator")
return func(*args, **kwargs)
return wrapperHowever, with the decorator package, how can I write a custom decorator that supports both sync and async function?
I've tried this way: (minimal example)
from decorator import decorator
import asyncio
@decorator
def custom_decorator(func, *args, **kwargs):
print("custom_decorator_start")
return func(*args, **kwargs)
@custom_decorator
def sum(x, y):
return x+y
@custom_decorator
async def asum(x, y):
await asyncio.sleep(1)
return x+yIn this way, I can call the async asum function with await asum(1, 2), but if I check whether asum is a coroutine function with inspect.iscoroutinefunction, it returns False.
I've also tried another way:
import inspect
from decorator import decorator
import asyncio
@decorator
async def custom_decorator(func, *args, **kwargs):
print("custom_decorator_start")
if inspect.iscoroutinefunction(func):
return await func(*args, **kwargs)
else:
return func(*args, **kwargs)
@custom_decorator
def sum(x, y):
return x+y
@custom_decorator
async def asum(x, y):
await asyncio.sleep(1)
return x+yBut this time, calling inspect.iscoroutinefunction(sum) and inspect.iscoroutinefunction(asum) will both return True.
Is there any way I can write a custom decorator that supports both sync and async function with decorator package? If not, would you consider supporting this use case?