Release/v0.5.0 #8

Merged
rus07tam merged 20 commits from release/v0.5.0 into main 2025-11-24 16:28:03 +03:00
2 changed files with 80 additions and 4 deletions
Showing only changes of commit 694dbf99be - Show all commits

View file

@ -2,17 +2,21 @@ from .inject_after import after_hook, inject_after
from .inject_before import before_hook, inject_before from .inject_before import before_hook, inject_before
from .inject_const import inject_const from .inject_const import inject_const
from .inject_replace import inject_replace, replace_hook from .inject_replace import inject_replace, replace_hook
from .meta_decorators import hook_decorator, inject_decorator, replace_decorator
from .pass_exceptions import pass_exceptions from .pass_exceptions import pass_exceptions
from .singleton import singleton from .singleton import singleton
__all__ = [ __all__ = [
"inject_replace",
"replace_hook",
"inject_after",
"after_hook", "after_hook",
"inject_before",
"before_hook", "before_hook",
"inject_after",
"inject_before",
"inject_const", "inject_const",
"inject_decorator",
"inject_replace",
"hook_decorator",
"pass_exceptions", "pass_exceptions",
"replace_decorator",
"replace_hook",
"singleton", "singleton",
] ]

View file

@ -0,0 +1,72 @@
import functools
from typing import Callable, Concatenate, ParamSpec, TypeVar
T = TypeVar("T")
R = TypeVar("R")
D = ParamSpec("D")
P = ParamSpec("P")
def inject_decorator(
decorator: Callable[Concatenate[Callable[P, T], D], None],
) -> Callable[D, Callable[[Callable[P, T]], Callable[P, T]]]:
@functools.wraps(decorator)
def wrapper(
*d_args: D.args, **d_kwargs: D.kwargs
) -> Callable[[Callable[P, T]], Callable[P, T]]:
def inner(obj: Callable[P, T]) -> Callable[P, T]:
@functools.wraps(obj)
def func(*args: P.args, **kwargs: P.kwargs) -> T:
decorator(obj, *d_args, **d_kwargs)
return obj(*args, **kwargs)
return func
return inner
return wrapper
def hook_decorator(
decorator: Callable[Concatenate[Callable[P, T], T, D], T],
) -> Callable[D, Callable[[Callable[P, T]], Callable[P, T]]]:
@functools.wraps(decorator)
def wrapper(
*d_args: D.args, **d_kwargs: D.kwargs
) -> Callable[[Callable[P, T]], Callable[P, T]]:
def inner(obj: Callable[P, T]) -> Callable[P, T]:
@functools.wraps(obj)
def func(*args: P.args, **kwargs: P.kwargs) -> T:
val = obj(*args, **kwargs)
return decorator(obj, val, *d_args, **d_kwargs)
return func
return inner
return wrapper
def replace_decorator(
decorator: Callable[Concatenate[T, D], T],
) -> Callable[D, Callable[[T], T]]:
@functools.wraps(decorator)
def wrapper(*d_args: D.args, **d_kwargs: D.kwargs) -> Callable[[T], T]:
def inner(obj: T) -> T:
result = decorator(obj, *d_args, **d_kwargs)
if not callable(obj):
return result
for attr in functools.WRAPPER_ASSIGNMENTS:
try:
value = getattr(obj, attr)
except AttributeError:
pass
else:
setattr(result, attr, value)
return result
return inner
return wrapper