Coverage for pydantic/validate_call_decorator.py: 100.00%

19 statements  

« prev     ^ index     » next       coverage.py v7.5.3, created at 2024-06-21 17:00 +0000

1"""Decorator for validating function calls.""" 

2 

3from __future__ import annotations as _annotations 1ghijklmnabopqrstuvwxcdHIJKLMNOGyzABCDEFef

4 

5import functools 1ghijklmnabopqrstuvwxcdHIJKLMNOGyzABCDEFef

6from typing import TYPE_CHECKING, Any, Callable, TypeVar, overload 1ghijklmnabopqrstuvwxcdHIJKLMNOGyzABCDEFef

7 

8from ._internal import _validate_call 1ghijklmnabopqrstuvwxcdHIJKLMNOGyzABCDEFef

9 

10__all__ = ('validate_call',) 1ghijklmnabopqrstuvwxcdHIJKLMNOGyzABCDEFef

11 

12if TYPE_CHECKING: 1ghijklmnabopqrstuvwxcdHIJKLMNOGyzABCDEFef

13 from .config import ConfigDict 

14 

15 AnyCallableT = TypeVar('AnyCallableT', bound=Callable[..., Any]) 

16 

17 

18@overload 1ghijklmnabopqrstuvwxcdHIJKLMNOGyzABCDEFef

19def validate_call( 1ghijklmnabopqrstuvwxcdHIJKLMNOGyzABCDEFef

20 *, config: ConfigDict | None = None, validate_return: bool = False 1ghijklmnabopqrstuvwxcdHIJKLMNOGyzABCDEFef

21) -> Callable[[AnyCallableT], AnyCallableT]: ... 1abopcdGef

22 

23 

24@overload 1ghijklmnabopqrstuvwxcdHIJKLMNOGyzABCDEFef

25def validate_call(func: AnyCallableT, /) -> AnyCallableT: ... 1ghijklmnabopqrstuvwxcdHIJKLMNOGyzABCDEFef

26 

27 

28def validate_call( 1ghijklmnabqrstuvwxcdHIJKLMNOGyzABCDEFef

29 func: AnyCallableT | None = None, 

30 /, 

31 *, 

32 config: ConfigDict | None = None, 

33 validate_return: bool = False, 

34) -> AnyCallableT | Callable[[AnyCallableT], AnyCallableT]: 

35 """Usage docs: https://docs.pydantic.dev/2.8/concepts/validation_decorator/ 

36 

37 Returns a decorated wrapper around the function that validates the arguments and, optionally, the return value. 

38 

39 Usage may be either as a plain decorator `@validate_call` or with arguments `@validate_call(...)`. 

40 

41 Args: 

42 func: The function to be decorated. 

43 config: The configuration dictionary. 

44 validate_return: Whether to validate the return value. 

45 

46 Returns: 

47 The decorated function. 

48 """ 

49 

50 def validate(function: AnyCallableT) -> AnyCallableT: 1ghijklmnabopqrstuvwxcdyzABCDEFef

51 if isinstance(function, (classmethod, staticmethod)): 1ghijklmnabopqrstuvwxcdyzABCDEFef

52 name = type(function).__name__ 1ghijklmnabopqrstuvwxcdyzABCDEFef

53 raise TypeError(f'The `@{name}` decorator should be applied after `@validate_call` (put `@{name}` on top)') 1ghijklmnabopqrstuvwxcdyzABCDEFef

54 validate_call_wrapper = _validate_call.ValidateCallWrapper(function, config, validate_return) 1ghijklmnabopqrstuvwxcdyzABCDEFef

55 

56 @functools.wraps(function) 1ghijklmnabopqrstuvwxcdyzABCDEFef

57 def wrapper_function(*args, **kwargs): 1ghijklmnabopqrstuvwxcdyzABCDEFef

58 return validate_call_wrapper(*args, **kwargs) 1ghijklmnabopqrstuvwxcdyzABCDEFef

59 

60 wrapper_function.raw_function = function # type: ignore 1ghijklmnabopqrstuvwxcdyzABCDEFef

61 

62 return wrapper_function # type: ignore 1ghijklmnabopqrstuvwxcdyzABCDEFef

63 

64 if func: 1ghijklmnabopqrstuvwxcdyzABCDEFef

65 return validate(func) 1ghijklmnabopqrstuvwxcdyzABCDEFef

66 else: 

67 return validate 1ghijklmnabopqrstuvwxcdyzABCDEFef