18
18
from mypy .types import (
19
19
Type , AnyType , CallableType , Overloaded , NoneTyp , TypeVarDef ,
20
20
TupleType , TypedDictType , Instance , TypeVarType , ErasedType , UnionType ,
21
- PartialType , DeletedType , UninhabitedType , TypeType , TypeOfAny , true_only ,
22
- false_only , is_named_instance , function_type , callable_type , FunctionLike , StarType ,
21
+ PartialType , DeletedType , UninhabitedType , TypeType , TypeOfAny ,
22
+ true_only , false_only , is_named_instance , function_type , callable_type , FunctionLike ,
23
+ StarType , is_optional , remove_optional , is_invariant_instance
23
24
)
24
25
from mypy .nodes import (
25
26
NameExpr , RefExpr , Var , FuncDef , OverloadedFuncDef , TypeInfo , CallExpr ,
30
31
ConditionalExpr , ComparisonExpr , TempNode , SetComprehension ,
31
32
DictionaryComprehension , ComplexExpr , EllipsisExpr , StarExpr , AwaitExpr , YieldExpr ,
32
33
YieldFromExpr , TypedDictExpr , PromoteExpr , NewTypeExpr , NamedTupleExpr , TypeVarExpr ,
33
- TypeAliasExpr , BackquoteExpr , EnumCallExpr , TypeAlias , ClassDef , Block , SymbolNode ,
34
+ TypeAliasExpr , BackquoteExpr , EnumCallExpr , TypeAlias , SymbolNode ,
34
35
ARG_POS , ARG_OPT , ARG_NAMED , ARG_STAR , ARG_STAR2 , MODULE_REF , LITERAL_TYPE , REVEAL_TYPE
35
36
)
36
37
from mypy .literals import literal
@@ -819,20 +820,36 @@ def infer_function_type_arguments_using_context(
819
820
# valid results.
820
821
erased_ctx = replace_meta_vars (ctx , ErasedType ())
821
822
ret_type = callable .ret_type
822
- if isinstance (ret_type , TypeVarType ):
823
- if ret_type .values or (not isinstance (ctx , Instance ) or
824
- not ctx .args ):
825
- # The return type is a type variable. If it has values, we can't easily restrict
826
- # type inference to conform to the valid values. If it's unrestricted, we could
827
- # infer a too general type for the type variable if we use context, and this could
828
- # result in confusing and spurious type errors elsewhere.
829
- #
830
- # Give up and just use function arguments for type inference. As an exception,
831
- # if the context is a generic instance type, actually use it as context, as
832
- # this *seems* to usually be the reasonable thing to do.
833
- #
834
- # See also github issues #462 and #360.
835
- ret_type = NoneTyp ()
823
+ if is_optional (ret_type ) and is_optional (ctx ):
824
+ # If both the context and the return type are optional, unwrap the optional,
825
+ # since in 99% cases this is what a user expects. In other words, we replace
826
+ # Optional[T] <: Optional[int]
827
+ # with
828
+ # T <: int
829
+ # while the former would infer T <: Optional[int].
830
+ ret_type = remove_optional (ret_type )
831
+ erased_ctx = remove_optional (erased_ctx )
832
+ #
833
+ # TODO: Instead of this hack and the one below, we need to use outer and
834
+ # inner contexts at the same time. This is however not easy because of two
835
+ # reasons:
836
+ # * We need to support constraints like [1 <: 2, 2 <: X], i.e. with variables
837
+ # on both sides. (This is not too hard.)
838
+ # * We need to update all the inference "infrastructure", so that all
839
+ # variables in an expression are inferred at the same time.
840
+ # (And this is hard, also we need to be careful with lambdas that require
841
+ # two passes.)
842
+ if isinstance (ret_type , TypeVarType ) and not is_invariant_instance (ctx ):
843
+ # Another special case: the return type is a type variable. If it's unrestricted,
844
+ # we could infer a too general type for the type variable if we use context,
845
+ # and this could result in confusing and spurious type errors elsewhere.
846
+ #
847
+ # Give up and just use function arguments for type inference. As an exception,
848
+ # if the context is an invariant instance type, actually use it as context, as
849
+ # this *seems* to usually be the reasonable thing to do.
850
+ #
851
+ # See also github issues #462 and #360.
852
+ return callable .copy_modified ()
836
853
args = infer_type_arguments (callable .type_var_ids (), ret_type , erased_ctx )
837
854
# Only substitute non-Uninhabited and non-erased types.
838
855
new_args = [] # type: List[Optional[Type]]
@@ -841,7 +858,10 @@ def infer_function_type_arguments_using_context(
841
858
new_args .append (None )
842
859
else :
843
860
new_args .append (arg )
844
- return self .apply_generic_arguments (callable , new_args , error_context )
861
+ # Don't show errors after we have only used the outer context for inference.
862
+ # We will use argument context to infer more variables.
863
+ return self .apply_generic_arguments (callable , new_args , error_context ,
864
+ skip_unsatisfied = True )
845
865
846
866
def infer_function_type_arguments (self , callee_type : CallableType ,
847
867
args : List [Expression ],
@@ -1609,9 +1629,10 @@ def check_arg(caller_type: Type, original_caller_type: Type, caller_kind: int,
1609
1629
return False
1610
1630
1611
1631
def apply_generic_arguments (self , callable : CallableType , types : Sequence [Optional [Type ]],
1612
- context : Context ) -> CallableType :
1632
+ context : Context , skip_unsatisfied : bool = False ) -> CallableType :
1613
1633
"""Simple wrapper around mypy.applytype.apply_generic_arguments."""
1614
- return applytype .apply_generic_arguments (callable , types , self .msg , context )
1634
+ return applytype .apply_generic_arguments (callable , types , self .msg , context ,
1635
+ skip_unsatisfied = skip_unsatisfied )
1615
1636
1616
1637
def visit_member_expr (self , e : MemberExpr , is_lvalue : bool = False ) -> Type :
1617
1638
"""Visit member expression (of form e.id)."""
0 commit comments