1818from mypy .types import (
1919 Type , AnyType , CallableType , Overloaded , NoneTyp , TypeVarDef ,
2020 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
2324)
2425from mypy .nodes import (
2526 NameExpr , RefExpr , Var , FuncDef , OverloadedFuncDef , TypeInfo , CallExpr ,
3031 ConditionalExpr , ComparisonExpr , TempNode , SetComprehension ,
3132 DictionaryComprehension , ComplexExpr , EllipsisExpr , StarExpr , AwaitExpr , YieldExpr ,
3233 YieldFromExpr , TypedDictExpr , PromoteExpr , NewTypeExpr , NamedTupleExpr , TypeVarExpr ,
33- TypeAliasExpr , BackquoteExpr , EnumCallExpr , TypeAlias , ClassDef , Block , SymbolNode ,
34+ TypeAliasExpr , BackquoteExpr , EnumCallExpr , TypeAlias , SymbolNode ,
3435 ARG_POS , ARG_OPT , ARG_NAMED , ARG_STAR , ARG_STAR2 , MODULE_REF , LITERAL_TYPE , REVEAL_TYPE
3536)
3637from mypy .literals import literal
@@ -819,20 +820,36 @@ def infer_function_type_arguments_using_context(
819820 # valid results.
820821 erased_ctx = replace_meta_vars (ctx , ErasedType ())
821822 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 ()
836853 args = infer_type_arguments (callable .type_var_ids (), ret_type , erased_ctx )
837854 # Only substitute non-Uninhabited and non-erased types.
838855 new_args = [] # type: List[Optional[Type]]
@@ -841,7 +858,10 @@ def infer_function_type_arguments_using_context(
841858 new_args .append (None )
842859 else :
843860 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 )
845865
846866 def infer_function_type_arguments (self , callee_type : CallableType ,
847867 args : List [Expression ],
@@ -1609,9 +1629,10 @@ def check_arg(caller_type: Type, original_caller_type: Type, caller_kind: int,
16091629 return False
16101630
16111631 def apply_generic_arguments (self , callable : CallableType , types : Sequence [Optional [Type ]],
1612- context : Context ) -> CallableType :
1632+ context : Context , skip_unsatisfied : bool = False ) -> CallableType :
16131633 """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 )
16151636
16161637 def visit_member_expr (self , e : MemberExpr , is_lvalue : bool = False ) -> Type :
16171638 """Visit member expression (of form e.id)."""
0 commit comments