Source code for app.util.callguard.callable_decorator

# SPDX-License-Identifier: GPLv3-or-later
# Copyright © 2025 pygaindalf Rui Pinheiro

import functools

from typing import TYPE_CHECKING, Protocol, Unpack, runtime_checkable

from . import lib
from .callguard import Callguard


if TYPE_CHECKING:
    from .types import CallguardHandlerInfo, CallguardOptions, CallguardWrapped


# MARK: Callable decorator
[docs] class CallguardCallableDecorator[T: object, **P, R]:
[docs] @runtime_checkable class CallguardHandlerProtocol(Protocol): def __callguard_handler__(self: T, method: CallguardWrapped[T, P, R], info: CallguardHandlerInfo, /, *args: P.args, **kwargs: P.kwargs) -> R: ...
[docs] def __init__(self, **options: Unpack[CallguardOptions[T, P, R]]) -> None: self.options = options
def __call__(self, method: CallguardWrapped[T, P, R]) -> CallguardWrapped[T, P, R]: return self.guard(method, **self.options)
[docs] @staticmethod def guard(method: CallguardWrapped[T, P, R], **callguard_options: Unpack[CallguardOptions[T, P, R]]) -> CallguardWrapped[T, P, R]: if not lib.callguard_enabled(method): return method callguard = Callguard(**callguard_options) method = callguard.decorate(method) if callguard_options.get("guard", True): method = functools.wraps(method)(functools.partial(callguard.guard, method)) setattr(method, "__callguarded__", True) return method
[docs] def callguard_callable[T: object, **P, R](**callguard_options: Unpack[CallguardOptions[T, P, R]]) -> CallguardCallableDecorator[T, P, R]: return CallguardCallableDecorator(**callguard_options)