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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy