Source code for app.util.callguard.generic

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


from collections.abc import Callable
from typing import TYPE_CHECKING, Unpack, overload

from .callable_decorator import CallguardCallableDecorator
from .class_decorator import CallguardClassDecorator
from .classmethod_decorator import CallguardClassmethodDecorator
from .property_decorator import CallguardPropertyDecorator


if TYPE_CHECKING:
    from .types import CallguardClassOptions, CallguardOptions


# MARK: Generic Decorator
@overload
def callguard[T: property](obj: T, **callguard_options: Unpack[CallguardOptions]) -> T: ...


@overload
def callguard[T: classmethod](obj: T, **callguard_options: Unpack[CallguardOptions]) -> T: ...


@overload
def callguard[T: type](obj: T, **callguard_options: Unpack[CallguardClassOptions]) -> T: ...


@overload
def callguard[T: Callable](obj: T, **callguard_options: Unpack[CallguardOptions]) -> T: ...


[docs] def callguard[T](obj: T, **callguard_options) -> T: if isinstance(obj, staticmethod): msg = "callguard cannot be applied to staticmethods, as they have no self/cls" raise TypeError(msg) if isinstance(obj, property): return CallguardPropertyDecorator.guard(obj, **callguard_options) elif isinstance(obj, classmethod): return CallguardClassmethodDecorator.guard(obj, **callguard_options) elif isinstance(obj, type): return CallguardClassDecorator.guard(obj, **callguard_options) elif callable(obj): return CallguardCallableDecorator.guard(obj, **callguard_options) else: msg = "callguard can only be applied to classes, methods, or properties" raise TypeError(msg)