/
decorator.py
41 lines (32 loc) · 1.13 KB
/
decorator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import asyncio
from inspect import isfunction
from .assertions import assert_corofunction
def decorate(fn):
"""
Generic decorator for coroutines helper functions allowing
multiple variadic initialization arguments.
This function is intended to be used internally.
Arguments:
fn (function): target function to decorate.
Raises:
TypeError: if function or coroutine function is not provided.
Returns:
function: decorated function.
"""
if not isfunction(fn):
raise TypeError('fn must be a callable object')
def decorator(*args, **kw):
for arg in args:
if asyncio.iscoroutinefunction(arg):
return fn(*args, **kw)
# Explicit argument must be at least a coroutine
if len(args) and args[0] is None:
raise TypeError('first argument cannot be None')
def wrapper(coro, *_args, **_kw):
assert_corofunction(coro=coro)
# Merge call arguments
_args = ((coro,) + (args + _args))
kw.update(_kw)
return fn(*_args, **kw)
return wrapper
return decorator