validate_call.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. """Decorator for validating function calls."""
  2. from __future__ import annotations as _annotations
  3. from typing import TYPE_CHECKING, Any, Callable, TypeVar, overload
  4. from ._internal import _validate_call
  5. __all__ = ('validate_call',)
  6. if TYPE_CHECKING:
  7. from .config import ConfigDict
  8. AnyCallableT = TypeVar('AnyCallableT', bound=Callable[..., Any])
  9. @overload
  10. def validate_call(
  11. *, config: ConfigDict | None = None, validate_return: bool = False
  12. ) -> Callable[[AnyCallableT], AnyCallableT]:
  13. ...
  14. @overload
  15. def validate_call(__func: AnyCallableT) -> AnyCallableT:
  16. ...
  17. def validate_call(
  18. __func: AnyCallableT | None = None,
  19. *,
  20. config: ConfigDict | None = None,
  21. validate_return: bool = False,
  22. ) -> AnyCallableT | Callable[[AnyCallableT], AnyCallableT]:
  23. """Usage docs: https://docs.pydantic.dev/2.4/concepts/validation_decorator/
  24. Returns a decorated wrapper around the function that validates the arguments and, optionally, the return value.
  25. Usage may be either as a plain decorator `@validate_call` or with arguments `@validate_call(...)`.
  26. Args:
  27. __func: The function to be decorated.
  28. config: The configuration dictionary.
  29. validate_return: Whether to validate the return value.
  30. Returns:
  31. The decorated function.
  32. """
  33. def validate(function: AnyCallableT) -> AnyCallableT:
  34. if isinstance(function, (classmethod, staticmethod)):
  35. name = type(function).__name__
  36. raise TypeError(f'The `@{name}` decorator should be applied after `@validate_call` (put `@{name}` on top)')
  37. return _validate_call.ValidateCallWrapper(function, config, validate_return) # type: ignore
  38. if __func:
  39. return validate(__func)
  40. else:
  41. return validate