@@ -59,11 +59,15 @@ def from_annotation(cls, annot, module=None):
59
59
(inner ,) = map (cls .from_annotation , get_args (annot ))
60
60
return sequence_of (inner , type = origin_type )
61
61
elif issubclass (origin_type , Mapping ):
62
- key_type , value_type = map (cls .from_annotation , get_args (annot ))
63
- return mapping_of (key_type , value_type , type = origin_type )
62
+ key_inner , value_inner = map (cls .from_annotation , get_args (annot ))
63
+ return mapping_of (key_inner , value_inner , type = origin_type )
64
64
elif issubclass (origin_type , Callable ):
65
- # TODO(kszucs): add a more comprehensive callable_with rule here
66
- return instance_of (Callable )
65
+ if args := get_args (annot ):
66
+ arg_inners = map (cls .from_annotation , args [0 ])
67
+ return_inner = cls .from_annotation (args [1 ])
68
+ return callable_with (tuple (arg_inners ), return_inner )
69
+ else :
70
+ return instance_of (Callable )
67
71
else :
68
72
raise NotImplementedError (
69
73
f"Cannot create validator from annotation { annot } { origin_type } "
@@ -264,13 +268,13 @@ def mapping_of(key_inner, value_inner, arg, *, type, **kwargs):
264
268
265
269
266
270
@validator
267
- def callable_with (args_inner , return_inner , value , ** kwargs ):
271
+ def callable_with (arg_inners , return_inner , value , ** kwargs ):
268
272
from ibis .common .annotations import annotated
269
273
270
274
if not callable (value ):
271
275
raise IbisTypeError ("Argument must be a callable" )
272
276
273
- fn = annotated (args_inner , return_inner , value )
277
+ fn = annotated (arg_inners , return_inner , value )
274
278
275
279
has_varargs = False
276
280
positional , keyword_only = [], []
@@ -286,9 +290,9 @@ def callable_with(args_inner, return_inner, value, **kwargs):
286
290
raise IbisTypeError (
287
291
"Callable has mandatory keyword-only arguments which cannot be specified"
288
292
)
289
- elif len (positional ) > len (args_inner ):
293
+ elif len (positional ) > len (arg_inners ):
290
294
raise IbisTypeError ("Callable has more positional arguments than expected" )
291
- elif len (positional ) < len (args_inner ) and not has_varargs :
295
+ elif len (positional ) < len (arg_inners ) and not has_varargs :
292
296
raise IbisTypeError ("Callable has less positional arguments than expected" )
293
297
else :
294
298
return fn
0 commit comments