@@ -1671,6 +1671,10 @@ def check_call(
1671
1671
object_type ,
1672
1672
original_type = callee ,
1673
1673
)
1674
+ elif isinstance (callee , UninhabitedType ):
1675
+ ret = UninhabitedType ()
1676
+ ret .ambiguous = callee .ambiguous
1677
+ return callee , ret
1674
1678
else :
1675
1679
return self .msg .not_callable (callee , context ), AnyType (TypeOfAny .from_error )
1676
1680
@@ -1751,14 +1755,6 @@ def check_callable_call(
1751
1755
return AnyType (TypeOfAny .from_error ), callee
1752
1756
seen_unpack = True
1753
1757
1754
- formal_to_actual = map_actuals_to_formals (
1755
- arg_kinds ,
1756
- arg_names ,
1757
- callee .arg_kinds ,
1758
- callee .arg_names ,
1759
- lambda i : self .accept (args [i ]),
1760
- )
1761
-
1762
1758
# This is tricky: return type may contain its own type variables, like in
1763
1759
# def [S] (S) -> def [T] (T) -> tuple[S, T], so we need to update their ids
1764
1760
# to avoid possible id clashes if this call itself appears in a generic
@@ -1769,27 +1765,29 @@ def check_callable_call(
1769
1765
freeze_all_type_vars (fresh_ret_type )
1770
1766
callee = callee .copy_modified (ret_type = fresh_ret_type )
1771
1767
1768
+ if callee .is_generic ():
1769
+ callee = freshen_function_type_vars (callee )
1770
+ callee = self .infer_function_type_arguments_using_context (callee , context )
1771
+
1772
+ formal_to_actual = map_actuals_to_formals (
1773
+ arg_kinds ,
1774
+ arg_names ,
1775
+ callee .arg_kinds ,
1776
+ callee .arg_names ,
1777
+ lambda i : self .accept (args [i ]),
1778
+ )
1779
+
1772
1780
if callee .is_generic ():
1773
1781
need_refresh = any (
1774
1782
isinstance (v , (ParamSpecType , TypeVarTupleType )) for v in callee .variables
1775
1783
)
1776
- callee = freshen_function_type_vars (callee )
1777
- callee = self .infer_function_type_arguments_using_context (callee , context )
1778
- if need_refresh :
1779
- # Argument kinds etc. may have changed due to
1780
- # ParamSpec or TypeVarTuple variables being replaced with an arbitrary
1781
- # number of arguments; recalculate actual-to-formal map
1782
- formal_to_actual = map_actuals_to_formals (
1783
- arg_kinds ,
1784
- arg_names ,
1785
- callee .arg_kinds ,
1786
- callee .arg_names ,
1787
- lambda i : self .accept (args [i ]),
1788
- )
1789
1784
callee = self .infer_function_type_arguments (
1790
1785
callee , args , arg_kinds , arg_names , formal_to_actual , need_refresh , context
1791
1786
)
1792
1787
if need_refresh :
1788
+ # Argument kinds etc. may have changed due to
1789
+ # ParamSpec or TypeVarTuple variables being replaced with an arbitrary
1790
+ # number of arguments; recalculate actual-to-formal map
1793
1791
formal_to_actual = map_actuals_to_formals (
1794
1792
arg_kinds ,
1795
1793
arg_names ,
@@ -2254,6 +2252,11 @@ def infer_function_type_arguments_pass2(
2254
2252
if isinstance (arg , (NoneType , UninhabitedType )) or has_erased_component (arg ):
2255
2253
inferred_args [i ] = None
2256
2254
callee_type = self .apply_generic_arguments (callee_type , inferred_args , context )
2255
+
2256
+ if not callee_type .is_generic ():
2257
+ # Fast path, second pass can't give new information.
2258
+ return callee_type , []
2259
+
2257
2260
if need_refresh :
2258
2261
formal_to_actual = map_actuals_to_formals (
2259
2262
arg_kinds ,
@@ -3465,7 +3468,7 @@ def visit_op_expr(self, e: OpExpr) -> Type:
3465
3468
# It's actually a type expression X | Y.
3466
3469
return self .accept (e .analyzed )
3467
3470
if e .op == "and" or e .op == "or" :
3468
- return self .check_boolean_op (e , e )
3471
+ return self .check_boolean_op (e )
3469
3472
if e .op == "*" and isinstance (e .left , ListExpr ):
3470
3473
# Expressions of form [...] * e get special type inference.
3471
3474
return self .check_list_multiply (e )
@@ -4252,20 +4255,18 @@ def check_op(
4252
4255
context = context ,
4253
4256
)
4254
4257
4255
- def check_boolean_op (self , e : OpExpr , context : Context ) -> Type :
4258
+ def check_boolean_op (self , e : OpExpr ) -> Type :
4256
4259
"""Type check a boolean operation ('and' or 'or')."""
4257
4260
4258
4261
# A boolean operation can evaluate to either of the operands.
4259
4262
4260
- # We use the current type context to guide the type inference of of
4263
+ # We use the current type context to guide the type inference of
4261
4264
# the left operand. We also use the left operand type to guide the type
4262
4265
# inference of the right operand so that expressions such as
4263
4266
# '[1] or []' are inferred correctly.
4264
4267
ctx = self .type_context [- 1 ]
4265
4268
left_type = self .accept (e .left , ctx )
4266
- expanded_left_type = try_expanding_sum_type_to_union (
4267
- self .accept (e .left , ctx ), "builtins.bool"
4268
- )
4269
+ expanded_left_type = try_expanding_sum_type_to_union (left_type , "builtins.bool" )
4269
4270
4270
4271
assert e .op in ("and" , "or" ) # Checked by visit_op_expr
4271
4272
0 commit comments