@@ -204,6 +204,8 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool)
204
204
if tvar_def is None :
205
205
self .fail ('ParamSpec "{}" is unbound' .format (t .name ), t )
206
206
return AnyType (TypeOfAny .from_error )
207
+ self .fail ('Invalid location for ParamSpec "{}"' .format (t .name ), t )
208
+ return AnyType (TypeOfAny .from_error )
207
209
if isinstance (sym .node , TypeVarExpr ) and tvar_def is not None and self .defining_alias :
208
210
self .fail ('Can\' t use bound type variable "{}"'
209
211
' to define generic alias' .format (t .name ), t )
@@ -624,10 +626,11 @@ def analyze_callable_type(self, t: UnboundType) -> Type:
624
626
fallback = fallback ,
625
627
is_ellipsis_args = True )
626
628
elif len (t .args ) == 2 :
629
+ callable_args = t .args [0 ]
627
630
ret_type = t .args [1 ]
628
- if isinstance (t . args [ 0 ] , TypeList ):
631
+ if isinstance (callable_args , TypeList ):
629
632
# Callable[[ARG, ...], RET] (ordinary callable type)
630
- analyzed_args = self .analyze_callable_args (t . args [ 0 ] )
633
+ analyzed_args = self .analyze_callable_args (callable_args )
631
634
if analyzed_args is None :
632
635
return AnyType (TypeOfAny .from_error )
633
636
args , kinds , names = analyzed_args
@@ -636,7 +639,7 @@ def analyze_callable_type(self, t: UnboundType) -> Type:
636
639
names ,
637
640
ret_type = ret_type ,
638
641
fallback = fallback )
639
- elif isinstance (t . args [ 0 ] , EllipsisType ):
642
+ elif isinstance (callable_args , EllipsisType ):
640
643
# Callable[..., RET] (with literal ellipsis; accept arbitrary arguments)
641
644
ret = CallableType ([AnyType (TypeOfAny .explicit ),
642
645
AnyType (TypeOfAny .explicit )],
@@ -646,8 +649,23 @@ def analyze_callable_type(self, t: UnboundType) -> Type:
646
649
fallback = fallback ,
647
650
is_ellipsis_args = True )
648
651
else :
649
- self .fail ('The first argument to Callable must be a list of types or "..."' , t )
650
- return AnyType (TypeOfAny .from_error )
652
+ try :
653
+ if not isinstance (callable_args , UnboundType ):
654
+ raise ValueError
655
+ sym = self .lookup_qualified (callable_args .name , callable_args )
656
+ if sym is None :
657
+ raise ValueError
658
+ tvar_def = self .tvar_scope .get_binding (sym )
659
+ if not isinstance (tvar_def , ParamSpecDef ):
660
+ raise ValueError
661
+
662
+ # TODO(shantanu): construct correct type for paramspec
663
+ return AnyType (TypeOfAny .from_error )
664
+ except ValueError :
665
+ # TODO(shantanu): change error to mention paramspec, once we actually have some
666
+ # support for it
667
+ self .fail ('The first argument to Callable must be a list of types or "..."' , t )
668
+ return AnyType (TypeOfAny .from_error )
651
669
else :
652
670
self .fail ('Please use "Callable[[<parameters>], <return type>]" or "Callable"' , t )
653
671
return AnyType (TypeOfAny .from_error )
@@ -828,7 +846,7 @@ def bind_function_type_variables(
828
846
var_node = self .lookup_qualified (var .name , defn )
829
847
assert var_node , "Binding for function type variable not found within function"
830
848
var_expr = var_node .node
831
- assert isinstance (var_expr , TypeVarExpr )
849
+ assert isinstance (var_expr , TypeVarLikeExpr )
832
850
self .tvar_scope .bind_new (var .name , var_expr )
833
851
return fun_type .variables
834
852
typevars = self .infer_type_variables (fun_type )
0 commit comments