-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathasfunction.py
More file actions
47 lines (36 loc) · 1.35 KB
/
asfunction.py
File metadata and controls
47 lines (36 loc) · 1.35 KB
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
42
43
44
45
46
47
from collections.abc import Callable
from functools import wraps
from inspect import iscoroutinefunction
from typing import Any
from injection._core.common.asynchronous import Caller
from injection._core.module import Module, mod
def asfunction[**P, T](
wrapped: type[Callable[P, T]] | None = None,
/,
*,
module: Module | None = None,
threadsafe: bool = False,
) -> Any:
module = module or mod()
def decorator(wp: type[Callable[P, T]]) -> Callable[P, T]:
get_method = wp.__call__.__get__
method = get_method(NotImplemented)
factory: Caller[..., Callable[P, T]] = module.make_injected_function(
wp,
threadsafe=threadsafe,
).__inject_metadata__
wrapper: Callable[P, T]
if iscoroutinefunction(method):
@wraps(method)
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> Any:
self = await factory.acall()
return await get_method(self)(*args, **kwargs)
else:
@wraps(method)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
self = factory.call()
return get_method(self)(*args, **kwargs)
wrapper.__name__ = wp.__name__
wrapper.__qualname__ = wp.__qualname__
return wrapper
return decorator(wrapped) if wrapped else decorator