@@ -78,23 +78,23 @@ def __init__(self, validator=None, default=EMPTY, kind=POSITIONAL_OR_KEYWORD):
78
78
self ._validator = validator
79
79
80
80
@classmethod
81
- def required (cls , validator = None ):
81
+ def required (cls , validator = None , kind = POSITIONAL_OR_KEYWORD ):
82
82
"""Annotation to mark a mandatory argument."""
83
- return cls (validator )
83
+ return cls (validator = validator , kind = kind )
84
84
85
85
@classmethod
86
- def default (cls , default , validator = None ):
86
+ def default (cls , default , validator = None , kind = POSITIONAL_OR_KEYWORD ):
87
87
"""Annotation to allow missing arguments with a default value."""
88
- return cls (validator , default = default )
88
+ return cls (validator = validator , default = default , kind = kind )
89
89
90
90
@classmethod
91
- def optional (cls , validator = None , default = None ):
91
+ def optional (cls , validator = None , default = None , kind = POSITIONAL_OR_KEYWORD ):
92
92
"""Annotation to allow and treat `None` values as missing arguments."""
93
93
if validator is None :
94
94
validator = option (any_ , default = default )
95
95
else :
96
96
validator = option (validator , default = default )
97
- return cls (validator , default = None )
97
+ return cls (validator = validator , default = None , kind = kind )
98
98
99
99
@classmethod
100
100
def varargs (cls , validator = None ):
@@ -174,8 +174,12 @@ def merge(cls, *signatures, **annotations):
174
174
175
175
for name , param in params .items ():
176
176
if param .kind == VAR_POSITIONAL :
177
+ if var_args :
178
+ raise TypeError ('only one variadic *args parameter is allowed' )
177
179
var_args .append (param )
178
180
elif param .kind == VAR_KEYWORD :
181
+ if var_kwargs :
182
+ raise TypeError ('only one variadic **kwargs parameter is allowed' )
179
183
var_kwargs .append (param )
180
184
elif name in inherited :
181
185
if param .default is EMPTY :
@@ -188,11 +192,6 @@ def merge(cls, *signatures, **annotations):
188
192
else :
189
193
new_kwargs .append (param )
190
194
191
- if len (var_args ) > 1 :
192
- raise TypeError ('only one variadic positional *args parameter is allowed' )
193
- if len (var_kwargs ) > 1 :
194
- raise TypeError ('only one variadic keywords **kwargs parameter is allowed' )
195
-
196
195
return cls (
197
196
old_args + new_args + var_args + new_kwargs + old_kwargs + var_kwargs
198
197
)
@@ -229,9 +228,6 @@ def from_callable(cls, fn, validators=None, return_validator=None):
229
228
230
229
parameters = []
231
230
for param in sig .parameters .values ():
232
- if param .kind in {POSITIONAL_ONLY , KEYWORD_ONLY }:
233
- raise TypeError (f"unsupported parameter kind { param .kind } in { fn } " )
234
-
235
231
if param .name in validators :
236
232
validator = validators [param .name ]
237
233
elif param .annotation is not EMPTY :
@@ -246,9 +242,9 @@ def from_callable(cls, fn, validators=None, return_validator=None):
246
242
elif param .kind is VAR_KEYWORD :
247
243
annot = Argument .varkwds (validator )
248
244
elif param .default is EMPTY :
249
- annot = Argument .required (validator )
245
+ annot = Argument .required (validator , kind = param . kind )
250
246
else :
251
- annot = Argument .default (param .default , validator )
247
+ annot = Argument .default (param .default , validator , kind = param . kind )
252
248
253
249
parameters .append (Parameter (param .name , annot ))
254
250
@@ -288,6 +284,10 @@ def unbind(self, this: Any):
288
284
args .extend (value )
289
285
elif param .kind is VAR_KEYWORD :
290
286
kwargs .update (value )
287
+ elif param .kind is KEYWORD_ONLY :
288
+ kwargs [name ] = value
289
+ elif param .kind is POSITIONAL_ONLY :
290
+ args .append (value )
291
291
else :
292
292
raise TypeError (f"unsupported parameter kind { param .kind } " )
293
293
return tuple (args ), kwargs
@@ -435,9 +435,13 @@ def annotated(_1=None, _2=None, _3=None, **kwargs):
435
435
436
436
@functools .wraps (func )
437
437
def wrapped (* args , ** kwargs ):
438
+ # 1. Validate the passed arguments
438
439
values = sig .validate (* args , ** kwargs )
440
+ # 2. Reconstruction of the original arguments
439
441
args , kwargs = sig .unbind (values )
442
+ # 3. Call the function with the validated arguments
440
443
result = func (* args , ** kwargs )
444
+ # 4. Validate the return value
441
445
return sig .validate_return (result )
442
446
443
447
wrapped .__signature__ = sig
0 commit comments