We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
mypy "error: <nothing> not callable" when passing config to validate_arguments
# Bug

Output of `python -c "import pydantic.utils; print(pydantic.utils.version_info())"`:
```
             pydantic version: 1.7
            pydantic compiled: True
                 install path: /home/brian/repos/medigator/venv/lib/python3.6/site-packages/pydantic
               python version: 3.6.9 (default, Oct  8 2020, 12:12:24)  [GCC 8.4.0]
                     platform: Linux-4.15.0-121-generic-x86_64-with-Ubuntu-18.04-bionic
     optional deps. installed: ['typing-extensions', 'email-validator']
```

The example code from the docs demonstrating the use of passing a config to `validate_arguments` causes an error when running mypy (version 0.790):

```py
from pydantic import ValidationError, validate_arguments


class Foobar:
    def __init__(self, v: str):
        self.v = v

    def __add__(self, other: 'Foobar') -> str:
        return f'{self} + {other}'

    def __str__(self) -> str:
        return f'Foobar({self.v})'


@validate_arguments(config=dict(arbitrary_types_allowed=True))
def add_foobars(a: Foobar, b: Foobar):
    return a + b
```

```
test.py:15: error: <nothing> not callable
```

If I remove the `config` parameter but still call `validate_arguments` it still occurs.
If I remove the call and just decorate with `@validate_arguments` then mypy is happy.

I assume it has something to do with the type annotation of `validate_arguments`.
mypy "error: <nothing> not callable" when passing config to validate_arguments
# Bug

Output of `python -c "import pydantic.utils; print(pydantic.utils.version_info())"`:
```
             pydantic version: 1.7
            pydantic compiled: True
                 install path: /home/brian/repos/medigator/venv/lib/python3.6/site-packages/pydantic
               python version: 3.6.9 (default, Oct  8 2020, 12:12:24)  [GCC 8.4.0]
                     platform: Linux-4.15.0-121-generic-x86_64-with-Ubuntu-18.04-bionic
     optional deps. installed: ['typing-extensions', 'email-validator']
```

The example code from the docs demonstrating the use of passing a config to `validate_arguments` causes an error when running mypy (version 0.790):

```py
from pydantic import ValidationError, validate_arguments


class Foobar:
    def __init__(self, v: str):
        self.v = v

    def __add__(self, other: 'Foobar') -> str:
        return f'{self} + {other}'

    def __str__(self) -> str:
        return f'Foobar({self.v})'


@validate_arguments(config=dict(arbitrary_types_allowed=True))
def add_foobars(a: Foobar, b: Foobar):
    return a + b
```

```
test.py:15: error: <nothing> not callable
```

If I remove the `config` parameter but still call `validate_arguments` it still occurs.
If I remove the call and just decorate with `@validate_arguments` then mypy is happy.

I assume it has something to do with the type annotation of `validate_arguments`.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pydantic/decorator.py`
Content:
```
1 from functools import wraps
2 from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Tuple, Type, TypeVar, Union, cast, get_type_hints
3 
4 from . import validator
5 from .errors import ConfigError
6 from .main import BaseModel, Extra, create_model
7 from .utils import to_camel
8 
9 __all__ = ('validate_arguments',)
10 
11 if TYPE_CHECKING:
12     from .typing import AnyCallable
13 
14     Callable = TypeVar('Callable', bound=AnyCallable)
15     ConfigType = Union[None, Type[Any], Dict[str, Any]]
16 
17 
18 def validate_arguments(func: 'Callable' = None, *, config: 'ConfigType' = None) -> 'Callable':
19     """
20     Decorator to validate the arguments passed to a function.
21     """
22 
23     def validate(_func: 'Callable') -> 'Callable':
24         vd = ValidatedFunction(_func, config)
25 
26         @wraps(_func)
27         def wrapper_function(*args: Any, **kwargs: Any) -> Any:
28             return vd.call(*args, **kwargs)
29 
30         wrapper_function.vd = vd  # type: ignore
31         wrapper_function.raw_function = vd.raw_function  # type: ignore
32         wrapper_function.model = vd.model  # type: ignore
33         return cast('Callable', wrapper_function)
34 
35     if func:
36         return validate(func)
37     else:
38         return cast('Callable', validate)
39 
40 
41 ALT_V_ARGS = 'v__args'
42 ALT_V_KWARGS = 'v__kwargs'
43 V_POSITIONAL_ONLY_NAME = 'v__positional_only'
44 
45 
46 class ValidatedFunction:
47     def __init__(self, function: 'Callable', config: 'ConfigType'):  # noqa C901
48         from inspect import Parameter, signature
49 
50         parameters: Mapping[str, Parameter] = signature(function).parameters
51 
52         if parameters.keys() & {ALT_V_ARGS, ALT_V_KWARGS, V_POSITIONAL_ONLY_NAME}:
53             raise ConfigError(
54                 f'"{ALT_V_ARGS}", "{ALT_V_KWARGS}" and "{V_POSITIONAL_ONLY_NAME}" are not permitted as argument '
55                 f'names when using the "{validate_arguments.__name__}" decorator'
56             )
57 
58         self.raw_function = function
59         self.arg_mapping: Dict[int, str] = {}
60         self.positional_only_args = set()
61         self.v_args_name = 'args'
62         self.v_kwargs_name = 'kwargs'
63 
64         type_hints = get_type_hints(function)
65         takes_args = False
66         takes_kwargs = False
67         fields: Dict[str, Tuple[Any, Any]] = {}
68         for i, (name, p) in enumerate(parameters.items()):
69             if p.annotation == p.empty:
70                 annotation = Any
71             else:
72                 annotation = type_hints[name]
73 
74             default = ... if p.default == p.empty else p.default
75             if p.kind == Parameter.POSITIONAL_ONLY:
76                 self.arg_mapping[i] = name
77                 fields[name] = annotation, default
78                 fields[V_POSITIONAL_ONLY_NAME] = List[str], None
79                 self.positional_only_args.add(name)
80             elif p.kind == Parameter.POSITIONAL_OR_KEYWORD:
81                 self.arg_mapping[i] = name
82                 fields[name] = annotation, default
83             elif p.kind == Parameter.KEYWORD_ONLY:
84                 fields[name] = annotation, default
85             elif p.kind == Parameter.VAR_POSITIONAL:
86                 self.v_args_name = name
87                 fields[name] = Tuple[annotation, ...], None
88                 takes_args = True
89             else:
90                 assert p.kind == Parameter.VAR_KEYWORD, p.kind
91                 self.v_kwargs_name = name
92                 fields[name] = Dict[str, annotation], None  # type: ignore
93                 takes_kwargs = True
94 
95         # these checks avoid a clash between "args" and a field with that name
96         if not takes_args and self.v_args_name in fields:
97             self.v_args_name = ALT_V_ARGS
98 
99         # same with "kwargs"
100         if not takes_kwargs and self.v_kwargs_name in fields:
101             self.v_kwargs_name = ALT_V_KWARGS
102 
103         if not takes_args:
104             # we add the field so validation below can raise the correct exception
105             fields[self.v_args_name] = List[Any], None
106 
107         if not takes_kwargs:
108             # same with kwargs
109             fields[self.v_kwargs_name] = Dict[Any, Any], None
110 
111         self.create_model(fields, takes_args, takes_kwargs, config)
112 
113     def call(self, *args: Any, **kwargs: Any) -> Any:
114         values = self.build_values(args, kwargs)
115         m = self.model(**values)
116         return self.execute(m)
117 
118     def build_values(self, args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> Dict[str, Any]:
119         values: Dict[str, Any] = {}
120         if args:
121             arg_iter = enumerate(args)
122             while True:
123                 try:
124                     i, a = next(arg_iter)
125                 except StopIteration:
126                     break
127                 arg_name = self.arg_mapping.get(i)
128                 if arg_name is not None:
129                     values[arg_name] = a
130                 else:
131                     values[self.v_args_name] = [a] + [a for _, a in arg_iter]
132                     break
133 
134         var_kwargs = {}
135         wrong_positional_args = []
136         for k, v in kwargs.items():
137             if k in self.model.__fields__:
138                 if k in self.positional_only_args:
139                     wrong_positional_args.append(k)
140                 values[k] = v
141             else:
142                 var_kwargs[k] = v
143 
144         if var_kwargs:
145             values[self.v_kwargs_name] = var_kwargs
146         if wrong_positional_args:
147             values[V_POSITIONAL_ONLY_NAME] = wrong_positional_args
148         return values
149 
150     def execute(self, m: BaseModel) -> Any:
151         d = {k: v for k, v in m._iter() if k in m.__fields_set__}
152         kwargs = d.pop(self.v_kwargs_name, None)
153         if kwargs:
154             d.update(kwargs)
155 
156         if self.v_args_name in d:
157             args_: List[Any] = []
158             in_kwargs = False
159             kwargs = {}
160             for name, value in d.items():
161                 if in_kwargs:
162                     kwargs[name] = value
163                 elif name == self.v_args_name:
164                     args_ += value
165                     in_kwargs = True
166                 else:
167                     args_.append(value)
168             return self.raw_function(*args_, **kwargs)
169         elif self.positional_only_args:
170             args_ = []
171             kwargs = {}
172             for name, value in d.items():
173                 if name in self.positional_only_args:
174                     args_.append(value)
175                 else:
176                     kwargs[name] = value
177             return self.raw_function(*args_, **kwargs)
178         else:
179             return self.raw_function(**d)
180 
181     def create_model(self, fields: Dict[str, Any], takes_args: bool, takes_kwargs: bool, config: 'ConfigType') -> None:
182         pos_args = len(self.arg_mapping)
183 
184         class CustomConfig:
185             pass
186 
187         if not TYPE_CHECKING:  # pragma: no branch
188             if isinstance(config, dict):
189                 CustomConfig = type('Config', (), config)  # noqa: F811
190             elif config is not None:
191                 CustomConfig = config  # noqa: F811
192 
193         if hasattr(CustomConfig, 'fields') or hasattr(CustomConfig, 'alias_generator'):
194             raise ConfigError(
195                 'Setting the "fields" and "alias_generator" property on custom Config for '
196                 '@validate_arguments is not yet supported, please remove.'
197             )
198 
199         class DecoratorBaseModel(BaseModel):
200             @validator(self.v_args_name, check_fields=False, allow_reuse=True)
201             def check_args(cls, v: List[Any]) -> List[Any]:
202                 if takes_args:
203                     return v
204 
205                 raise TypeError(f'{pos_args} positional arguments expected but {pos_args + len(v)} given')
206 
207             @validator(self.v_kwargs_name, check_fields=False, allow_reuse=True)
208             def check_kwargs(cls, v: Dict[str, Any]) -> Dict[str, Any]:
209                 if takes_kwargs:
210                     return v
211 
212                 plural = '' if len(v) == 1 else 's'
213                 keys = ', '.join(map(repr, v.keys()))
214                 raise TypeError(f'unexpected keyword argument{plural}: {keys}')
215 
216             @validator(V_POSITIONAL_ONLY_NAME, check_fields=False, allow_reuse=True)
217             def check_positional_only(cls, v: List[str]) -> None:
218                 plural = '' if len(v) == 1 else 's'
219                 keys = ', '.join(map(repr, v))
220                 raise TypeError(f'positional-only argument{plural} passed as keyword argument{plural}: {keys}')
221 
222             class Config(CustomConfig):
223                 extra = Extra.forbid
224 
225         self.model = create_model(to_camel(self.raw_function.__name__), __base__=DecoratorBaseModel, **fields)
226
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pydantic/decorator.py b/pydantic/decorator.py
--- a/pydantic/decorator.py
+++ b/pydantic/decorator.py
@@ -1,5 +1,19 @@
 from functools import wraps
-from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Tuple, Type, TypeVar, Union, cast, get_type_hints
+from typing import (
+    TYPE_CHECKING,
+    Any,
+    Callable,
+    Dict,
+    List,
+    Mapping,
+    Optional,
+    Tuple,
+    Type,
+    TypeVar,
+    Union,
+    get_type_hints,
+    overload,
+)
 
 from . import validator
 from .errors import ConfigError
@@ -11,16 +25,26 @@
 if TYPE_CHECKING:
     from .typing import AnyCallable
 
-    Callable = TypeVar('Callable', bound=AnyCallable)
+    AnyCallableT = TypeVar('AnyCallableT', bound=AnyCallable)
     ConfigType = Union[None, Type[Any], Dict[str, Any]]
 
 
-def validate_arguments(func: 'Callable' = None, *, config: 'ConfigType' = None) -> 'Callable':
+@overload
+def validate_arguments(func: None = None, *, config: 'ConfigType' = None) -> Callable[['AnyCallableT'], 'AnyCallableT']:
+    ...
+
+
+@overload
+def validate_arguments(func: 'AnyCallableT') -> 'AnyCallableT':
+    ...
+
+
+def validate_arguments(func: Optional['AnyCallableT'] = None, *, config: 'ConfigType' = None) -> Any:
     """
     Decorator to validate the arguments passed to a function.
     """
 
-    def validate(_func: 'Callable') -> 'Callable':
+    def validate(_func: 'AnyCallable') -> 'AnyCallable':
         vd = ValidatedFunction(_func, config)
 
         @wraps(_func)
@@ -30,12 +54,12 @@
         wrapper_function.vd = vd  # type: ignore
         wrapper_function.raw_function = vd.raw_function  # type: ignore
         wrapper_function.model = vd.model  # type: ignore
-        return cast('Callable', wrapper_function)
+        return wrapper_function
 
     if func:
         return validate(func)
     else:
-        return cast('Callable', validate)
+        return validate
 
 
 ALT_V_ARGS = 'v__args'
@@ -44,7 +68,7 @@
 
 
 class ValidatedFunction:
-    def __init__(self, function: 'Callable', config: 'ConfigType'):  # noqa C901
+    def __init__(self, function: 'AnyCallableT', config: 'ConfigType'):  # noqa C901
         from inspect import Parameter, signature
 
         parameters: Mapping[str, Parameter] = signature(function).parameters

{"golden_diff": "diff --git a/pydantic/decorator.py b/pydantic/decorator.py\n--- a/pydantic/decorator.py\n+++ b/pydantic/decorator.py\n@@ -1,5 +1,19 @@\n from functools import wraps\n-from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Tuple, Type, TypeVar, Union, cast, get_type_hints\n+from typing import (\n+    TYPE_CHECKING,\n+    Any,\n+    Callable,\n+    Dict,\n+    List,\n+    Mapping,\n+    Optional,\n+    Tuple,\n+    Type,\n+    TypeVar,\n+    Union,\n+    get_type_hints,\n+    overload,\n+)\n \n from . import validator\n from .errors import ConfigError\n@@ -11,16 +25,26 @@\n if TYPE_CHECKING:\n     from .typing import AnyCallable\n \n-    Callable = TypeVar('Callable', bound=AnyCallable)\n+    AnyCallableT = TypeVar('AnyCallableT', bound=AnyCallable)\n     ConfigType = Union[None, Type[Any], Dict[str, Any]]\n \n \n-def validate_arguments(func: 'Callable' = None, *, config: 'ConfigType' = None) -> 'Callable':\n+@overload\n+def validate_arguments(func: None = None, *, config: 'ConfigType' = None) -> Callable[['AnyCallableT'], 'AnyCallableT']:\n+    ...\n+\n+\n+@overload\n+def validate_arguments(func: 'AnyCallableT') -> 'AnyCallableT':\n+    ...\n+\n+\n+def validate_arguments(func: Optional['AnyCallableT'] = None, *, config: 'ConfigType' = None) -> Any:\n     \"\"\"\n     Decorator to validate the arguments passed to a function.\n     \"\"\"\n \n-    def validate(_func: 'Callable') -> 'Callable':\n+    def validate(_func: 'AnyCallable') -> 'AnyCallable':\n         vd = ValidatedFunction(_func, config)\n \n         @wraps(_func)\n@@ -30,12 +54,12 @@\n         wrapper_function.vd = vd  # type: ignore\n         wrapper_function.raw_function = vd.raw_function  # type: ignore\n         wrapper_function.model = vd.model  # type: ignore\n-        return cast('Callable', wrapper_function)\n+        return wrapper_function\n \n     if func:\n         return validate(func)\n     else:\n-        return cast('Callable', validate)\n+        return validate\n \n \n ALT_V_ARGS = 'v__args'\n@@ -44,7 +68,7 @@\n \n \n class ValidatedFunction:\n-    def __init__(self, function: 'Callable', config: 'ConfigType'):  # noqa C901\n+    def __init__(self, function: 'AnyCallableT', config: 'ConfigType'):  # noqa C901\n         from inspect import Parameter, signature\n \n         parameters: Mapping[str, Parameter] = signature(function).parameters\n", "issue": "mypy \"error: <nothing> not callable\" when passing config to validate_arguments\n# Bug\r\n\r\nOutput of `python -c \"import pydantic.utils; print(pydantic.utils.version_info())\"`:\r\n```\r\n             pydantic version: 1.7\r\n            pydantic compiled: True\r\n                 install path: /home/brian/repos/medigator/venv/lib/python3.6/site-packages/pydantic\r\n               python version: 3.6.9 (default, Oct  8 2020, 12:12:24)  [GCC 8.4.0]\r\n                     platform: Linux-4.15.0-121-generic-x86_64-with-Ubuntu-18.04-bionic\r\n     optional deps. installed: ['typing-extensions', 'email-validator']\r\n```\r\n\r\nThe example code from the docs demonstrating the use of passing a config to `validate_arguments` causes an error when running mypy (version 0.790):\r\n\r\n```py\r\nfrom pydantic import ValidationError, validate_arguments\r\n\r\n\r\nclass Foobar:\r\n    def __init__(self, v: str):\r\n        self.v = v\r\n\r\n    def __add__(self, other: 'Foobar') -> str:\r\n        return f'{self} + {other}'\r\n\r\n    def __str__(self) -> str:\r\n        return f'Foobar({self.v})'\r\n\r\n\r\n@validate_arguments(config=dict(arbitrary_types_allowed=True))\r\ndef add_foobars(a: Foobar, b: Foobar):\r\n    return a + b\r\n```\r\n\r\n```\r\ntest.py:15: error: <nothing> not callable\r\n```\r\n\r\nIf I remove the `config` parameter but still call `validate_arguments` it still occurs.\r\nIf I remove the call and just decorate with `@validate_arguments` then mypy is happy.\r\n\r\nI assume it has something to do with the type annotation of `validate_arguments`.\nmypy \"error: <nothing> not callable\" when passing config to validate_arguments\n# Bug\r\n\r\nOutput of `python -c \"import pydantic.utils; print(pydantic.utils.version_info())\"`:\r\n```\r\n             pydantic version: 1.7\r\n            pydantic compiled: True\r\n                 install path: /home/brian/repos/medigator/venv/lib/python3.6/site-packages/pydantic\r\n               python version: 3.6.9 (default, Oct  8 2020, 12:12:24)  [GCC 8.4.0]\r\n                     platform: Linux-4.15.0-121-generic-x86_64-with-Ubuntu-18.04-bionic\r\n     optional deps. installed: ['typing-extensions', 'email-validator']\r\n```\r\n\r\nThe example code from the docs demonstrating the use of passing a config to `validate_arguments` causes an error when running mypy (version 0.790):\r\n\r\n```py\r\nfrom pydantic import ValidationError, validate_arguments\r\n\r\n\r\nclass Foobar:\r\n    def __init__(self, v: str):\r\n        self.v = v\r\n\r\n    def __add__(self, other: 'Foobar') -> str:\r\n        return f'{self} + {other}'\r\n\r\n    def __str__(self) -> str:\r\n        return f'Foobar({self.v})'\r\n\r\n\r\n@validate_arguments(config=dict(arbitrary_types_allowed=True))\r\ndef add_foobars(a: Foobar, b: Foobar):\r\n    return a + b\r\n```\r\n\r\n```\r\ntest.py:15: error: <nothing> not callable\r\n```\r\n\r\nIf I remove the `config` parameter but still call `validate_arguments` it still occurs.\r\nIf I remove the call and just decorate with `@validate_arguments` then mypy is happy.\r\n\r\nI assume it has something to do with the type annotation of `validate_arguments`.\n", "before_files": [{"content": "from functools import wraps\nfrom typing import TYPE_CHECKING, Any, Dict, List, Mapping, Tuple, Type, TypeVar, Union, cast, get_type_hints\n\nfrom . import validator\nfrom .errors import ConfigError\nfrom .main import BaseModel, Extra, create_model\nfrom .utils import to_camel\n\n__all__ = ('validate_arguments',)\n\nif TYPE_CHECKING:\n    from .typing import AnyCallable\n\n    Callable = TypeVar('Callable', bound=AnyCallable)\n    ConfigType = Union[None, Type[Any], Dict[str, Any]]\n\n\ndef validate_arguments(func: 'Callable' = None, *, config: 'ConfigType' = None) -> 'Callable':\n    \"\"\"\n    Decorator to validate the arguments passed to a function.\n    \"\"\"\n\n    def validate(_func: 'Callable') -> 'Callable':\n        vd = ValidatedFunction(_func, config)\n\n        @wraps(_func)\n        def wrapper_function(*args: Any, **kwargs: Any) -> Any:\n            return vd.call(*args, **kwargs)\n\n        wrapper_function.vd = vd  # type: ignore\n        wrapper_function.raw_function = vd.raw_function  # type: ignore\n        wrapper_function.model = vd.model  # type: ignore\n        return cast('Callable', wrapper_function)\n\n    if func:\n        return validate(func)\n    else:\n        return cast('Callable', validate)\n\n\nALT_V_ARGS = 'v__args'\nALT_V_KWARGS = 'v__kwargs'\nV_POSITIONAL_ONLY_NAME = 'v__positional_only'\n\n\nclass ValidatedFunction:\n    def __init__(self, function: 'Callable', config: 'ConfigType'):  # noqa C901\n        from inspect import Parameter, signature\n\n        parameters: Mapping[str, Parameter] = signature(function).parameters\n\n        if parameters.keys() & {ALT_V_ARGS, ALT_V_KWARGS, V_POSITIONAL_ONLY_NAME}:\n            raise ConfigError(\n                f'\"{ALT_V_ARGS}\", \"{ALT_V_KWARGS}\" and \"{V_POSITIONAL_ONLY_NAME}\" are not permitted as argument '\n                f'names when using the \"{validate_arguments.__name__}\" decorator'\n            )\n\n        self.raw_function = function\n        self.arg_mapping: Dict[int, str] = {}\n        self.positional_only_args = set()\n        self.v_args_name = 'args'\n        self.v_kwargs_name = 'kwargs'\n\n        type_hints = get_type_hints(function)\n        takes_args = False\n        takes_kwargs = False\n        fields: Dict[str, Tuple[Any, Any]] = {}\n        for i, (name, p) in enumerate(parameters.items()):\n            if p.annotation == p.empty:\n                annotation = Any\n            else:\n                annotation = type_hints[name]\n\n            default = ... if p.default == p.empty else p.default\n            if p.kind == Parameter.POSITIONAL_ONLY:\n                self.arg_mapping[i] = name\n                fields[name] = annotation, default\n                fields[V_POSITIONAL_ONLY_NAME] = List[str], None\n                self.positional_only_args.add(name)\n            elif p.kind == Parameter.POSITIONAL_OR_KEYWORD:\n                self.arg_mapping[i] = name\n                fields[name] = annotation, default\n            elif p.kind == Parameter.KEYWORD_ONLY:\n                fields[name] = annotation, default\n            elif p.kind == Parameter.VAR_POSITIONAL:\n                self.v_args_name = name\n                fields[name] = Tuple[annotation, ...], None\n                takes_args = True\n            else:\n                assert p.kind == Parameter.VAR_KEYWORD, p.kind\n                self.v_kwargs_name = name\n                fields[name] = Dict[str, annotation], None  # type: ignore\n                takes_kwargs = True\n\n        # these checks avoid a clash between \"args\" and a field with that name\n        if not takes_args and self.v_args_name in fields:\n            self.v_args_name = ALT_V_ARGS\n\n        # same with \"kwargs\"\n        if not takes_kwargs and self.v_kwargs_name in fields:\n            self.v_kwargs_name = ALT_V_KWARGS\n\n        if not takes_args:\n            # we add the field so validation below can raise the correct exception\n            fields[self.v_args_name] = List[Any], None\n\n        if not takes_kwargs:\n            # same with kwargs\n            fields[self.v_kwargs_name] = Dict[Any, Any], None\n\n        self.create_model(fields, takes_args, takes_kwargs, config)\n\n    def call(self, *args: Any, **kwargs: Any) -> Any:\n        values = self.build_values(args, kwargs)\n        m = self.model(**values)\n        return self.execute(m)\n\n    def build_values(self, args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> Dict[str, Any]:\n        values: Dict[str, Any] = {}\n        if args:\n            arg_iter = enumerate(args)\n            while True:\n                try:\n                    i, a = next(arg_iter)\n                except StopIteration:\n                    break\n                arg_name = self.arg_mapping.get(i)\n                if arg_name is not None:\n                    values[arg_name] = a\n                else:\n                    values[self.v_args_name] = [a] + [a for _, a in arg_iter]\n                    break\n\n        var_kwargs = {}\n        wrong_positional_args = []\n        for k, v in kwargs.items():\n            if k in self.model.__fields__:\n                if k in self.positional_only_args:\n                    wrong_positional_args.append(k)\n                values[k] = v\n            else:\n                var_kwargs[k] = v\n\n        if var_kwargs:\n            values[self.v_kwargs_name] = var_kwargs\n        if wrong_positional_args:\n            values[V_POSITIONAL_ONLY_NAME] = wrong_positional_args\n        return values\n\n    def execute(self, m: BaseModel) -> Any:\n        d = {k: v for k, v in m._iter() if k in m.__fields_set__}\n        kwargs = d.pop(self.v_kwargs_name, None)\n        if kwargs:\n            d.update(kwargs)\n\n        if self.v_args_name in d:\n            args_: List[Any] = []\n            in_kwargs = False\n            kwargs = {}\n            for name, value in d.items():\n                if in_kwargs:\n                    kwargs[name] = value\n                elif name == self.v_args_name:\n                    args_ += value\n                    in_kwargs = True\n                else:\n                    args_.append(value)\n            return self.raw_function(*args_, **kwargs)\n        elif self.positional_only_args:\n            args_ = []\n            kwargs = {}\n            for name, value in d.items():\n                if name in self.positional_only_args:\n                    args_.append(value)\n                else:\n                    kwargs[name] = value\n            return self.raw_function(*args_, **kwargs)\n        else:\n            return self.raw_function(**d)\n\n    def create_model(self, fields: Dict[str, Any], takes_args: bool, takes_kwargs: bool, config: 'ConfigType') -> None:\n        pos_args = len(self.arg_mapping)\n\n        class CustomConfig:\n            pass\n\n        if not TYPE_CHECKING:  # pragma: no branch\n            if isinstance(config, dict):\n                CustomConfig = type('Config', (), config)  # noqa: F811\n            elif config is not None:\n                CustomConfig = config  # noqa: F811\n\n        if hasattr(CustomConfig, 'fields') or hasattr(CustomConfig, 'alias_generator'):\n            raise ConfigError(\n                'Setting the \"fields\" and \"alias_generator\" property on custom Config for '\n                '@validate_arguments is not yet supported, please remove.'\n            )\n\n        class DecoratorBaseModel(BaseModel):\n            @validator(self.v_args_name, check_fields=False, allow_reuse=True)\n            def check_args(cls, v: List[Any]) -> List[Any]:\n                if takes_args:\n                    return v\n\n                raise TypeError(f'{pos_args} positional arguments expected but {pos_args + len(v)} given')\n\n            @validator(self.v_kwargs_name, check_fields=False, allow_reuse=True)\n            def check_kwargs(cls, v: Dict[str, Any]) -> Dict[str, Any]:\n                if takes_kwargs:\n                    return v\n\n                plural = '' if len(v) == 1 else 's'\n                keys = ', '.join(map(repr, v.keys()))\n                raise TypeError(f'unexpected keyword argument{plural}: {keys}')\n\n            @validator(V_POSITIONAL_ONLY_NAME, check_fields=False, allow_reuse=True)\n            def check_positional_only(cls, v: List[str]) -> None:\n                plural = '' if len(v) == 1 else 's'\n                keys = ', '.join(map(repr, v))\n                raise TypeError(f'positional-only argument{plural} passed as keyword argument{plural}: {keys}')\n\n            class Config(CustomConfig):\n                extra = Extra.forbid\n\n        self.model = create_model(to_camel(self.raw_function.__name__), __base__=DecoratorBaseModel, **fields)\n", "path": "pydantic/decorator.py"}], "after_files": [{"content": "from functools import wraps\nfrom typing import (\n    TYPE_CHECKING,\n    Any,\n    Callable,\n    Dict,\n    List,\n    Mapping,\n    Optional,\n    Tuple,\n    Type,\n    TypeVar,\n    Union,\n    get_type_hints,\n    overload,\n)\n\nfrom . import validator\nfrom .errors import ConfigError\nfrom .main import BaseModel, Extra, create_model\nfrom .utils import to_camel\n\n__all__ = ('validate_arguments',)\n\nif TYPE_CHECKING:\n    from .typing import AnyCallable\n\n    AnyCallableT = TypeVar('AnyCallableT', bound=AnyCallable)\n    ConfigType = Union[None, Type[Any], Dict[str, Any]]\n\n\n@overload\ndef validate_arguments(func: None = None, *, config: 'ConfigType' = None) -> Callable[['AnyCallableT'], 'AnyCallableT']:\n    ...\n\n\n@overload\ndef validate_arguments(func: 'AnyCallableT') -> 'AnyCallableT':\n    ...\n\n\ndef validate_arguments(func: Optional['AnyCallableT'] = None, *, config: 'ConfigType' = None) -> Any:\n    \"\"\"\n    Decorator to validate the arguments passed to a function.\n    \"\"\"\n\n    def validate(_func: 'AnyCallable') -> 'AnyCallable':\n        vd = ValidatedFunction(_func, config)\n\n        @wraps(_func)\n        def wrapper_function(*args: Any, **kwargs: Any) -> Any:\n            return vd.call(*args, **kwargs)\n\n        wrapper_function.vd = vd  # type: ignore\n        wrapper_function.raw_function = vd.raw_function  # type: ignore\n        wrapper_function.model = vd.model  # type: ignore\n        return wrapper_function\n\n    if func:\n        return validate(func)\n    else:\n        return validate\n\n\nALT_V_ARGS = 'v__args'\nALT_V_KWARGS = 'v__kwargs'\nV_POSITIONAL_ONLY_NAME = 'v__positional_only'\n\n\nclass ValidatedFunction:\n    def __init__(self, function: 'AnyCallableT', config: 'ConfigType'):  # noqa C901\n        from inspect import Parameter, signature\n\n        parameters: Mapping[str, Parameter] = signature(function).parameters\n\n        if parameters.keys() & {ALT_V_ARGS, ALT_V_KWARGS, V_POSITIONAL_ONLY_NAME}:\n            raise ConfigError(\n                f'\"{ALT_V_ARGS}\", \"{ALT_V_KWARGS}\" and \"{V_POSITIONAL_ONLY_NAME}\" are not permitted as argument '\n                f'names when using the \"{validate_arguments.__name__}\" decorator'\n            )\n\n        self.raw_function = function\n        self.arg_mapping: Dict[int, str] = {}\n        self.positional_only_args = set()\n        self.v_args_name = 'args'\n        self.v_kwargs_name = 'kwargs'\n\n        type_hints = get_type_hints(function)\n        takes_args = False\n        takes_kwargs = False\n        fields: Dict[str, Tuple[Any, Any]] = {}\n        for i, (name, p) in enumerate(parameters.items()):\n            if p.annotation == p.empty:\n                annotation = Any\n            else:\n                annotation = type_hints[name]\n\n            default = ... if p.default == p.empty else p.default\n            if p.kind == Parameter.POSITIONAL_ONLY:\n                self.arg_mapping[i] = name\n                fields[name] = annotation, default\n                fields[V_POSITIONAL_ONLY_NAME] = List[str], None\n                self.positional_only_args.add(name)\n            elif p.kind == Parameter.POSITIONAL_OR_KEYWORD:\n                self.arg_mapping[i] = name\n                fields[name] = annotation, default\n            elif p.kind == Parameter.KEYWORD_ONLY:\n                fields[name] = annotation, default\n            elif p.kind == Parameter.VAR_POSITIONAL:\n                self.v_args_name = name\n                fields[name] = Tuple[annotation, ...], None\n                takes_args = True\n            else:\n                assert p.kind == Parameter.VAR_KEYWORD, p.kind\n                self.v_kwargs_name = name\n                fields[name] = Dict[str, annotation], None  # type: ignore\n                takes_kwargs = True\n\n        # these checks avoid a clash between \"args\" and a field with that name\n        if not takes_args and self.v_args_name in fields:\n            self.v_args_name = ALT_V_ARGS\n\n        # same with \"kwargs\"\n        if not takes_kwargs and self.v_kwargs_name in fields:\n            self.v_kwargs_name = ALT_V_KWARGS\n\n        if not takes_args:\n            # we add the field so validation below can raise the correct exception\n            fields[self.v_args_name] = List[Any], None\n\n        if not takes_kwargs:\n            # same with kwargs\n            fields[self.v_kwargs_name] = Dict[Any, Any], None\n\n        self.create_model(fields, takes_args, takes_kwargs, config)\n\n    def call(self, *args: Any, **kwargs: Any) -> Any:\n        values = self.build_values(args, kwargs)\n        m = self.model(**values)\n        return self.execute(m)\n\n    def build_values(self, args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> Dict[str, Any]:\n        values: Dict[str, Any] = {}\n        if args:\n            arg_iter = enumerate(args)\n            while True:\n                try:\n                    i, a = next(arg_iter)\n                except StopIteration:\n                    break\n                arg_name = self.arg_mapping.get(i)\n                if arg_name is not None:\n                    values[arg_name] = a\n                else:\n                    values[self.v_args_name] = [a] + [a for _, a in arg_iter]\n                    break\n\n        var_kwargs = {}\n        wrong_positional_args = []\n        for k, v in kwargs.items():\n            if k in self.model.__fields__:\n                if k in self.positional_only_args:\n                    wrong_positional_args.append(k)\n                values[k] = v\n            else:\n                var_kwargs[k] = v\n\n        if var_kwargs:\n            values[self.v_kwargs_name] = var_kwargs\n        if wrong_positional_args:\n            values[V_POSITIONAL_ONLY_NAME] = wrong_positional_args\n        return values\n\n    def execute(self, m: BaseModel) -> Any:\n        d = {k: v for k, v in m._iter() if k in m.__fields_set__}\n        kwargs = d.pop(self.v_kwargs_name, None)\n        if kwargs:\n            d.update(kwargs)\n\n        if self.v_args_name in d:\n            args_: List[Any] = []\n            in_kwargs = False\n            kwargs = {}\n            for name, value in d.items():\n                if in_kwargs:\n                    kwargs[name] = value\n                elif name == self.v_args_name:\n                    args_ += value\n                    in_kwargs = True\n                else:\n                    args_.append(value)\n            return self.raw_function(*args_, **kwargs)\n        elif self.positional_only_args:\n            args_ = []\n            kwargs = {}\n            for name, value in d.items():\n                if name in self.positional_only_args:\n                    args_.append(value)\n                else:\n                    kwargs[name] = value\n            return self.raw_function(*args_, **kwargs)\n        else:\n            return self.raw_function(**d)\n\n    def create_model(self, fields: Dict[str, Any], takes_args: bool, takes_kwargs: bool, config: 'ConfigType') -> None:\n        pos_args = len(self.arg_mapping)\n\n        class CustomConfig:\n            pass\n\n        if not TYPE_CHECKING:  # pragma: no branch\n            if isinstance(config, dict):\n                CustomConfig = type('Config', (), config)  # noqa: F811\n            elif config is not None:\n                CustomConfig = config  # noqa: F811\n\n        if hasattr(CustomConfig, 'fields') or hasattr(CustomConfig, 'alias_generator'):\n            raise ConfigError(\n                'Setting the \"fields\" and \"alias_generator\" property on custom Config for '\n                '@validate_arguments is not yet supported, please remove.'\n            )\n\n        class DecoratorBaseModel(BaseModel):\n            @validator(self.v_args_name, check_fields=False, allow_reuse=True)\n            def check_args(cls, v: List[Any]) -> List[Any]:\n                if takes_args:\n                    return v\n\n                raise TypeError(f'{pos_args} positional arguments expected but {pos_args + len(v)} given')\n\n            @validator(self.v_kwargs_name, check_fields=False, allow_reuse=True)\n            def check_kwargs(cls, v: Dict[str, Any]) -> Dict[str, Any]:\n                if takes_kwargs:\n                    return v\n\n                plural = '' if len(v) == 1 else 's'\n                keys = ', '.join(map(repr, v.keys()))\n                raise TypeError(f'unexpected keyword argument{plural}: {keys}')\n\n            @validator(V_POSITIONAL_ONLY_NAME, check_fields=False, allow_reuse=True)\n            def check_positional_only(cls, v: List[str]) -> None:\n                plural = '' if len(v) == 1 else 's'\n                keys = ', '.join(map(repr, v))\n                raise TypeError(f'positional-only argument{plural} passed as keyword argument{plural}: {keys}')\n\n            class Config(CustomConfig):\n                extra = Extra.forbid\n\n        self.model = create_model(to_camel(self.raw_function.__name__), __base__=DecoratorBaseModel, **fields)\n", "path": "pydantic/decorator.py"}]}