@@ -4781,7 +4781,11 @@ class C(Generic[T, Unpack[Ts]]): ...
4781
4781
We simply group the arguments that need to go into Ts variable into a TupleType,
4782
4782
similar to how it is done in other places using split_with_prefix_and_suffix().
4783
4783
"""
4784
- vars = t .variables
4784
+ if t .is_type_obj ():
4785
+ # Type arguments must map to class type variables, ignoring constructor vars.
4786
+ vars = t .type_object ().defn .type_vars
4787
+ else :
4788
+ vars = list (t .variables )
4785
4789
args = flatten_nested_tuples (args )
4786
4790
4787
4791
# TODO: this logic is duplicated with semanal_typeargs.
@@ -4799,6 +4803,7 @@ class C(Generic[T, Unpack[Ts]]): ...
4799
4803
4800
4804
if not vars or not any (isinstance (v , TypeVarTupleType ) for v in vars ):
4801
4805
return list (args )
4806
+ # TODO: in future we may want to support type application to variadic functions.
4802
4807
assert t .is_type_obj ()
4803
4808
info = t .type_object ()
4804
4809
# We reuse the logic from semanal phase to reduce code duplication.
@@ -4832,10 +4837,23 @@ def apply_type_arguments_to_callable(
4832
4837
tp = get_proper_type (tp )
4833
4838
4834
4839
if isinstance (tp , CallableType ):
4835
- min_arg_count = sum (not v .has_default () for v in tp .variables )
4836
- has_type_var_tuple = any (isinstance (v , TypeVarTupleType ) for v in tp .variables )
4840
+ if tp .is_type_obj ():
4841
+ # If we have a class object in runtime context, then the available type
4842
+ # variables are those of the class, we don't include additional variables
4843
+ # of the constructor. So that with
4844
+ # class C(Generic[T]):
4845
+ # def __init__(self, f: Callable[[S], T], x: S) -> None
4846
+ # C[int] is valid
4847
+ # C[int, str] is invalid (although C as a callable has 2 type variables)
4848
+ # Note: various logic below and in applytype.py relies on the fact that
4849
+ # class type variables appear *before* constructor variables.
4850
+ type_vars = tp .type_object ().defn .type_vars
4851
+ else :
4852
+ type_vars = list (tp .variables )
4853
+ min_arg_count = sum (not v .has_default () for v in type_vars )
4854
+ has_type_var_tuple = any (isinstance (v , TypeVarTupleType ) for v in type_vars )
4837
4855
if (
4838
- len (args ) < min_arg_count or len (args ) > len (tp . variables )
4856
+ len (args ) < min_arg_count or len (args ) > len (type_vars )
4839
4857
) and not has_type_var_tuple :
4840
4858
if tp .is_type_obj () and tp .type_object ().fullname == "builtins.tuple" :
4841
4859
# e.g. expression tuple[X, Y]
@@ -4854,19 +4872,24 @@ def apply_type_arguments_to_callable(
4854
4872
bound_args = tp .bound_args ,
4855
4873
)
4856
4874
self .msg .incompatible_type_application (
4857
- min_arg_count , len (tp . variables ), len (args ), ctx
4875
+ min_arg_count , len (type_vars ), len (args ), ctx
4858
4876
)
4859
4877
return AnyType (TypeOfAny .from_error )
4860
4878
return self .apply_generic_arguments (tp , self .split_for_callable (tp , args , ctx ), ctx )
4861
4879
if isinstance (tp , Overloaded ):
4862
4880
for it in tp .items :
4863
- min_arg_count = sum (not v .has_default () for v in it .variables )
4864
- has_type_var_tuple = any (isinstance (v , TypeVarTupleType ) for v in it .variables )
4881
+ if tp .is_type_obj ():
4882
+ # Same as above.
4883
+ type_vars = tp .type_object ().defn .type_vars
4884
+ else :
4885
+ type_vars = list (it .variables )
4886
+ min_arg_count = sum (not v .has_default () for v in type_vars )
4887
+ has_type_var_tuple = any (isinstance (v , TypeVarTupleType ) for v in type_vars )
4865
4888
if (
4866
- len (args ) < min_arg_count or len (args ) > len (it . variables )
4889
+ len (args ) < min_arg_count or len (args ) > len (type_vars )
4867
4890
) and not has_type_var_tuple :
4868
4891
self .msg .incompatible_type_application (
4869
- min_arg_count , len (it . variables ), len (args ), ctx
4892
+ min_arg_count , len (type_vars ), len (args ), ctx
4870
4893
)
4871
4894
return AnyType (TypeOfAny .from_error )
4872
4895
return Overloaded (
0 commit comments