2424 DictionaryComprehension , ComplexExpr , EllipsisExpr , TypeAliasExpr ,
2525 RefExpr , YieldExpr , BackquoteExpr , ImportFrom , ImportAll , ImportBase ,
2626 AwaitExpr ,
27- CONTRAVARIANT , COVARIANT
28- )
29- from mypy .nodes import function_type , method_type , method_type_with_fallback
27+ CONTRAVARIANT , COVARIANT )
3028from mypy import nodes
3129from mypy .types import (
3230 Type , AnyType , CallableType , Void , FunctionLike , Overloaded , TupleType ,
3331 Instance , NoneTyp , ErrorType , strip_type ,
3432 UnionType , TypeVarId , TypeVarType , PartialType , DeletedType , UninhabitedType ,
35- true_only , false_only
33+ true_only , false_only , function_type
3634)
3735from mypy .sametypes import is_same_type
3836from mypy .messages import MessageBuilder
3937import mypy .checkexpr
40- from mypy .checkmember import map_type_from_supertype
38+ from mypy .checkmember import map_type_from_supertype , bind_self
4139from mypy import messages
4240from mypy .subtypes import (
43- is_subtype , is_equivalent , is_proper_subtype ,
44- is_more_precise , restrict_subtype_away
41+ is_subtype , is_equivalent , is_proper_subtype , is_more_precise , restrict_subtype_away
4542)
4643from mypy .maptype import map_instance_to_supertype
47- from mypy .semanal import self_type , set_callable_name , refers_to_fullname
44+ from mypy .semanal import fill_typevars , set_callable_name , refers_to_fullname
4845from mypy .erasetype import erase_typevars
4946from mypy .expandtype import expand_type
5047from mypy .visitor import NodeVisitor
@@ -93,6 +90,11 @@ class TypeChecker(NodeVisitor[Type]):
9390 # Helper for type checking expressions
9491 expr_checker = None # type: mypy.checkexpr.ExpressionChecker
9592
93+ # Class context for checking overriding of a method of the form
94+ # def foo(self: T) -> T
95+ # We need to pass the current class definition for instantiation of T
96+ class_context = None # type: List[Type]
97+
9698 # Stack of function return types
9799 return_types = None # type: List[Type]
98100 # Type context for type inference
@@ -136,6 +138,7 @@ def __init__(self, errors: Errors, modules: Dict[str, MypyFile], options: Option
136138 self .path = path
137139 self .msg = MessageBuilder (errors , modules )
138140 self .expr_checker = mypy .checkexpr .ExpressionChecker (self , self .msg )
141+ self .class_context = []
139142 self .binder = ConditionalTypeBinder ()
140143 self .globals = tree .names
141144 self .return_types = []
@@ -602,11 +605,13 @@ def is_implicit_any(t: Type) -> bool:
602605 arg_type = typ .arg_types [i ]
603606
604607 # Refuse covariant parameter type variables
608+ # TODO: check recuresively for inner type variables
605609 if isinstance (arg_type , TypeVarType ):
606- if arg_type .variance == COVARIANT :
607- self .fail (messages .FUNCTION_PARAMETER_CANNOT_BE_COVARIANT ,
608- arg_type )
609-
610+ if i > 0 :
611+ if arg_type .variance == COVARIANT :
612+ self .fail (messages .FUNCTION_PARAMETER_CANNOT_BE_COVARIANT ,
613+ arg_type )
614+ # FIX: if i == 0 and this is not a method then same as above
610615 if typ .arg_kinds [i ] == nodes .ARG_STAR :
611616 # builtins.tuple[T] is typing.Tuple[T, ...]
612617 arg_type = self .named_generic_type ('builtins.tuple' ,
@@ -788,11 +793,11 @@ def check_inplace_operator_method(self, defn: FuncBase) -> None:
788793 method = defn .name ()
789794 if method not in nodes .inplace_operator_methods :
790795 return
791- typ = self .method_type (defn )
796+ typ = bind_self ( self .function_type (defn ) )
792797 cls = defn .info
793798 other_method = '__' + method [3 :]
794799 if cls .has_readable_member (other_method ):
795- instance = self_type (cls )
800+ instance = fill_typevars (cls )
796801 typ2 = self .expr_checker .analyze_external_member_access (
797802 other_method , instance , defn )
798803 fail = False
@@ -868,7 +873,7 @@ def check_method_override_for_base_with_name(
868873 # The name of the method is defined in the base class.
869874
870875 # Construct the type of the overriding method.
871- typ = self .method_type (defn )
876+ typ = bind_self ( self .function_type (defn ), self . class_context [ - 1 ] )
872877 # Map the overridden method type to subtype context so that
873878 # it can be checked for compatibility.
874879 original_type = base_attr .type
@@ -881,7 +886,7 @@ def check_method_override_for_base_with_name(
881886 assert False , str (base_attr .node )
882887 if isinstance (original_type , FunctionLike ):
883888 original = map_type_from_supertype (
884- method_type (original_type ),
889+ bind_self (original_type , self . class_context [ - 1 ] ),
885890 defn .info , base )
886891 # Check that the types are compatible.
887892 # TODO overloaded signatures
@@ -965,7 +970,9 @@ def visit_class_def(self, defn: ClassDef) -> Type:
965970 old_binder = self .binder
966971 self .binder = ConditionalTypeBinder ()
967972 with self .binder .top_frame_context ():
973+ self .class_context .append (fill_typevars (defn .info ))
968974 self .accept (defn .defs )
975+ self .class_context .pop ()
969976 self .binder = old_binder
970977 if not defn .has_incompatible_baseclass :
971978 # Otherwise we've already found errors; more errors are not useful
@@ -1012,8 +1019,8 @@ def check_compatibility(self, name: str, base1: TypeInfo,
10121019 if (isinstance (first_type , FunctionLike ) and
10131020 isinstance (second_type , FunctionLike )):
10141021 # Method override
1015- first_sig = method_type (first_type )
1016- second_sig = method_type (second_type )
1022+ first_sig = bind_self (first_type )
1023+ second_sig = bind_self (second_type )
10171024 ok = is_subtype (first_sig , second_sig )
10181025 elif first_type and second_type :
10191026 ok = is_equivalent (first_type , second_type )
@@ -2335,9 +2342,6 @@ def iterable_item_type(self, instance: Instance) -> Type:
23352342 def function_type (self , func : FuncBase ) -> FunctionLike :
23362343 return function_type (func , self .named_type ('builtins.function' ))
23372344
2338- def method_type (self , func : FuncBase ) -> FunctionLike :
2339- return method_type_with_fallback (func , self .named_type ('builtins.function' ))
2340-
23412345 # TODO: These next two functions should refer to TypeMap below
23422346 def find_isinstance_check (self , n : Expression ) -> Tuple [Optional [Dict [Expression , Type ]],
23432347 Optional [Dict [Expression , Type ]]]:
@@ -2350,7 +2354,6 @@ def push_type_map(self, type_map: Optional[Dict[Expression, Type]]) -> None:
23502354 for expr , type in type_map .items ():
23512355 self .binder .push (expr , type )
23522356
2353-
23542357# Data structure returned by find_isinstance_check representing
23552358# information learned from the truth or falsehood of a condition. The
23562359# dict maps nodes representing expressions like 'a[0].x' to their
0 commit comments