Skip to content

Commit b1c3238

Browse files
committed
Give self a type when using check_untyped_defs
1 parent 832ccc4 commit b1c3238

File tree

5 files changed

+34
-8
lines changed

5 files changed

+34
-8
lines changed

mypy/checker.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,11 @@ def check_overlapping_overloads(self, defn: OverloadedFuncDef) -> None:
535535
else:
536536
impl = impl_type
537537

538+
# Prevent extra noise from inconsistent use of @classmethod by copying
539+
# the first arg from the method being checked against.
540+
if sig1.arg_types and defn.info:
541+
impl = impl.copy_modified(arg_types=[sig1.arg_types[0]] + impl.arg_types[1:])
542+
538543
# Is the overload alternative's arguments subtypes of the implementation's?
539544
if not is_callable_compatible(impl, sig1,
540545
is_compat=is_subtype_no_promote,

mypy/semanal.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,11 +616,11 @@ def prepare_method_signature(self, func: FuncDef, info: TypeInfo) -> None:
616616
# Only non-static methods are special.
617617
functype = func.type
618618
if not func.is_static:
619+
if func.name() == '__init_subclass__':
620+
func.is_class = True
619621
if not func.arguments:
620622
self.fail('Method must have at least one argument', func)
621623
elif isinstance(functype, CallableType):
622-
if func.name() == '__init_subclass__':
623-
func.is_class = True
624624
self_type = get_proper_type(functype.arg_types[0])
625625
if isinstance(self_type, AnyType):
626626
leading_type = fill_typevars(info) # type: Type

mypy/typeops.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from mypy.types import (
1111
TupleType, Instance, FunctionLike, Type, CallableType, TypeVarDef, Overloaded,
1212
TypeVarType, TypeType, UninhabitedType, FormalArgument, UnionType, NoneType,
13-
AnyType, TypeOfAny, ProperType, get_proper_type, get_proper_types, copy_type
13+
AnyType, TypeOfAny, TypeType, ProperType, get_proper_type, get_proper_types, copy_type
1414
)
1515
from mypy.nodes import (
1616
FuncBase, FuncItem, OverloadedFuncDef, TypeInfo, TypeVar, ARG_STAR, ARG_STAR2,
@@ -397,8 +397,17 @@ def function_type(func: FuncBase, fallback: Instance) -> FunctionLike:
397397

398398
def callable_type(fdef: FuncItem, fallback: Instance,
399399
ret_type: Optional[Type] = None) -> CallableType:
400+
# FIXME? somewhat unfortunate duplication with prepare_method_signature in semanal
401+
if fdef.info and not fdef.is_static:
402+
self_type = fill_typevars(fdef.info) # type: Type
403+
if fdef.is_class or fdef.name() == '__new__':
404+
self_type = TypeType.make_normalized(self_type)
405+
args = [self_type] + [AnyType(TypeOfAny.unannotated)] * (len(fdef.arg_names)-1)
406+
else:
407+
args = [AnyType(TypeOfAny.unannotated)] * len(fdef.arg_names)
408+
400409
return CallableType(
401-
[AnyType(TypeOfAny.unannotated)] * len(fdef.arg_names),
410+
args,
402411
fdef.arg_kinds,
403412
[None if argument_elide_name(n) else n for n in fdef.arg_names],
404413
ret_type or AnyType(TypeOfAny.unannotated),

test-data/unit/check-classes.test

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2610,7 +2610,7 @@ t = Test()
26102610
t.crash = 'test' # E: "Test" has no attribute "crash"
26112611

26122612
class A:
2613-
def __setattr__(self): ... # E: Invalid signature "def (self: Any) -> Any" for "__setattr__"
2613+
def __setattr__(self): ... # E: Invalid signature "def (self: __main__.A) -> Any" for "__setattr__"
26142614
a = A()
26152615
a.test = 4 # E: "A" has no attribute "test"
26162616

@@ -6178,3 +6178,15 @@ class B(A):
61786178
def meth(cls: Type[T]) -> List[T]: ...
61796179

61806180
[builtins fixtures/isinstancelist.pyi]
6181+
6182+
[case testCheckUntypedDefsSelf]
6183+
# flags: --check-untyped-defs
6184+
class Foo:
6185+
def foo(self):
6186+
self.bar()
6187+
self.baz() # E: "Foo" has no attribute "baz"
6188+
6189+
@classmethod
6190+
def bar(cls):
6191+
cls.baz() # E: "Type[Foo]" has no attribute "baz"
6192+
[builtins fixtures/classmethod.pyi]

test-data/unit/typexport-basic.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ class A:
893893
def f(self): pass
894894
A.f
895895
[out]
896-
MemberExpr(5) : def (self: Any) -> Any
896+
MemberExpr(5) : def (self: A) -> Any
897897

898898
[case testOverloadedUnboundMethod]
899899
## MemberExpr
@@ -921,7 +921,7 @@ class A:
921921
def f(self, *args): pass
922922
A.f
923923
[out]
924-
MemberExpr(10) : Overload(def (self: Any) -> Any, def (self: Any, Any) -> Any)
924+
MemberExpr(10) : Overload(def (self: A) -> Any, def (self: A, Any) -> Any)
925925

926926
[case testUnboundMethodWithInheritance]
927927
## MemberExpr
@@ -986,7 +986,7 @@ class A(Generic[t]):
986986
def f(self, x): pass
987987
A.f(None, None)
988988
[out]
989-
MemberExpr(7) : def (self: Any, x: Any) -> Any
989+
MemberExpr(7) : def (self: A[t`1], x: Any) -> Any
990990

991991
[case testGenericMethodOfGenericClass]
992992
## MemberExpr

0 commit comments

Comments
 (0)