Source code for argclz.dispatch.annotations

from typing import Callable, TypeVar, overload

from ..validator import Validator

__all__ = [
    'dispatch',
    'validator_for'
]

T = TypeVar('T')
F = TypeVar('F', bound=Callable)


[docs] def dispatch(command: str, *alias: str, group: str | None = None, order: float = 5, usage: str | None = None, hidden=False) -> Callable[[F], F]: """ A decorator that mark a function as a dispatch target function. All functions decorated in same dispatch group should have save function signature (at least for non-default parameters). For example: **Example** >>> class D(Dispatch): ... @dispatch('A') ... def function_a(self, a, b, c=None): ... pass ... @dispatch('B') ... def function_b(self, a, b, d=None): ... pass ... def run_function(self): ... self.invoke_command(self, 'A', a, b) :param command: primary command name :param alias: secondary command names :param group: command group :param order: order of this command shown in the :meth:`~argclz.dispatch.core.Dispatch.build_command_usages()` :param usage: usage line of this command shown in the :meth:`~argclz.dispatch.core.Dispatch.build_command_usages()` :param hidden: hide this command from :meth:`~argclz.dispatch.core.Dispatch.list_commands()` """ if len(command) == 0: raise ValueError('empty command string') def _dispatch(f: F) -> F: from .builder import DispatchCommandBuilder DispatchCommandBuilder.of(f).build(command, alias, order, group, usage, hidden) return f return _dispatch
@overload def validator_for(arg: str) -> Callable[[F], F]: pass @overload def validator_for(arg: str, caster: Callable[[str], T] | Validator) -> Callable[[F], F]: pass @overload def validator_for(arg: str, caster: Callable[[str], T], validator: Validator) -> Callable[[F], F]: pass
[docs] def validator_for(arg: str, caster: Callable[[str], T] | Validator | None = None, validator: Validator | None = None) -> Callable[[F], F]: """ A decorator that do the caster and valudation on dispatch arguments. **Example** >>> class D(Dispatch): ... @dispatch('cmd') ... @validator_for('a') ... def run_cmd(self, a: int): ... assert isinstance(a, int) **Type (caster)** The parameter ``caster`` usually can be infered via the annotation of target parameter, like the `a: int` in above example. :param arg: name of the parameter. :param caster: type caster with the signature ``(str) -> T``. :param validator: validator with the signatire ``(T) -> bool``. """ if isinstance(caster, Validator) and validator is None: caster, validator = None, caster def _validator_for(f: F) -> F: from .builder import DispatchCommandBuilder DispatchCommandBuilder.of(f).validator_for(arg, caster, validator) # pyright: ignore[reportArgumentType] return f return _validator_for