@@ -3261,7 +3261,10 @@ b.bad = 'a' # E: Incompatible types in assignment (expression has type "str", v
32613261from typing import Any
32623262
32633263class Test:
3264- def __setattr__() -> None: ... # E: Method must have at least one argument. Did you forget the "self" argument? # E: Invalid signature "Callable[[], None]" for "__setattr__"
3264+ def __setattr__() -> None: ... \
3265+ # E: Invalid signature "Callable[[], None]" for "__setattr__" \
3266+ # E: Method must have at least one argument. Did you forget the "self" argument?
3267+
32653268t = Test()
32663269t.crash = 'test' # E: Attribute function "__setattr__" with type "Callable[[], None]" does not accept self argument \
32673270 # E: "Test" has no attribute "crash"
@@ -7742,6 +7745,231 @@ class Foo:
77427745 def bad(): # E: Method must have at least one argument. Did you forget the "self" argument?
77437746 self.x = 0 # E: Name "self" is not defined
77447747
7748+ [case testMethodSelfArgumentChecks]
7749+ from typing import Callable, ParamSpec, TypeVar
7750+
7751+ T = TypeVar("T")
7752+ P = ParamSpec("P")
7753+
7754+ def to_number_1(fn: Callable[[], int]) -> int:
7755+ return 0
7756+
7757+ def to_number_2(fn: Callable[[int], int]) -> int:
7758+ return 0
7759+
7760+ def to_same_callable(fn: Callable[P, T]) -> Callable[P, T]:
7761+ return fn
7762+
7763+ class A:
7764+ def undecorated() -> None: ... # E: Method must have at least one argument. Did you forget the "self" argument?
7765+
7766+ def undecorated_not_self(x: int) -> None: ... # E: Self argument missing for a non-static method (or an invalid type for self)
7767+
7768+ def undecorated_not_self_2(self: int) -> None: ... # E: The erased type of self "builtins.int" is not a supertype of its class "__main__.A"
7769+
7770+ @to_number_1
7771+ def fn1() -> int:
7772+ return 0
7773+
7774+ @to_number_1 # E: Argument 1 to "to_number_1" has incompatible type "Callable[[int], int]"; expected "Callable[[], int]"
7775+ def fn2(_x: int) -> int:
7776+ return 0
7777+
7778+ @to_number_2 # E: Argument 1 to "to_number_2" has incompatible type "Callable[[], int]"; expected "Callable[[int], int]"
7779+ def fn3() -> int:
7780+ return 0
7781+
7782+ @to_number_2
7783+ def fn4(_x: int) -> int:
7784+ return 0
7785+
7786+ @to_number_2 # E: Argument 1 to "to_number_2" has incompatible type "Callable[[str], int]"; expected "Callable[[int], int]"
7787+ def fn5(_x: str) -> int:
7788+ return 0
7789+
7790+ @to_same_callable
7791+ def g1() -> None: ... # E: Method must have at least one argument. Did you forget the "self" argument?
7792+
7793+ @to_same_callable
7794+ def g2(x: int) -> None: ... # E: Self argument missing for a non-static method (or an invalid type for self)
7795+
7796+ @to_same_callable
7797+ def g3(self: int) -> None: ... # E: The erased type of self "builtins.int" is not a supertype of its class "__main__.A"
7798+
7799+ reveal_type(A().fn1) # N: Revealed type is "builtins.int"
7800+ reveal_type(A().fn2) # N: Revealed type is "builtins.int"
7801+ reveal_type(A().fn3) # N: Revealed type is "builtins.int"
7802+ reveal_type(A().fn4) # N: Revealed type is "builtins.int"
7803+ reveal_type(A().fn5) # N: Revealed type is "builtins.int"
7804+
7805+ reveal_type(A().g1) # E: Attribute function "g1" with type "Callable[[], None]" does not accept self argument \
7806+ # N: Revealed type is "def ()"
7807+ reveal_type(A().g2) # E: Invalid self argument "A" to attribute function "g2" with type "Callable[[int], None]" \
7808+ # N: Revealed type is "def ()"
7809+ reveal_type(A().g3) # E: Invalid self argument "A" to attribute function "g3" with type "Callable[[int], None]" \
7810+ # N: Revealed type is "def ()"
7811+ [builtins fixtures/tuple.pyi]
7812+
7813+ [case testMethodSelfArgumentChecksConcatenate]
7814+ from typing import Callable, ParamSpec, TypeVar
7815+ from typing_extensions import Concatenate
7816+
7817+ T = TypeVar("T")
7818+ P = ParamSpec("P")
7819+ R = TypeVar("R")
7820+
7821+ def to_same_callable(fn: Callable[Concatenate[T, P], R]) -> Callable[Concatenate[T, P], R]:
7822+ return fn
7823+
7824+ def remove_first(fn: Callable[Concatenate[T, P], R]) -> Callable[P, R]:
7825+ ...
7826+
7827+ def add_correct_first(fn: Callable[P, R]) -> Callable[Concatenate["C", P], R]:
7828+ ...
7829+
7830+ def add_wrong_first(fn: Callable[P, R]) -> Callable[Concatenate[int, P], R]:
7831+ ...
7832+
7833+ class A:
7834+ @to_same_callable # E: Argument 1 to "to_same_callable" has incompatible type "Callable[[], int]"; expected "Callable[[T], int]"
7835+ def fn1() -> int:
7836+ return 0
7837+
7838+ @to_same_callable
7839+ def fn2(_x: int) -> int: # E: Self argument missing for a non-static method (or an invalid type for self)
7840+ return 0
7841+
7842+ @to_same_callable
7843+ def fn3(self, _x: int) -> int:
7844+ return 0
7845+
7846+ reveal_type(A().fn1) # N: Revealed type is "def () -> builtins.int"
7847+ reveal_type(A().fn2) # E: Invalid self argument "A" to attribute function "fn2" with type "Callable[[int], int]" \
7848+ # N: Revealed type is "def () -> builtins.int"
7849+ reveal_type(A().fn3) # N: Revealed type is "def (_x: builtins.int) -> builtins.int"
7850+
7851+ class B:
7852+ @remove_first # E: Argument 1 to "remove_first" has incompatible type "Callable[[], int]"; expected "Callable[[T], int]"
7853+ def fn1() -> int: # E: Method must have at least one argument. Did you forget the "self" argument?
7854+ return 0
7855+
7856+ @remove_first
7857+ def fn2(_x: int) -> int: # E: Method must have at least one argument. Did you forget the "self" argument?
7858+ return 0
7859+
7860+ @remove_first
7861+ def fn3(self, _x: int) -> int: # E: Self argument missing for a non-static method (or an invalid type for self)
7862+ return 0
7863+
7864+ @remove_first
7865+ def fn4(self, new_self: 'B') -> int:
7866+ return 0
7867+
7868+ reveal_type(B().fn1) # E: Attribute function "fn1" with type "Callable[[], int]" does not accept self argument \
7869+ # N: Revealed type is "def () -> builtins.int"
7870+ reveal_type(B().fn2) # E: Attribute function "fn2" with type "Callable[[], int]" does not accept self argument \
7871+ # N: Revealed type is "def () -> builtins.int"
7872+ reveal_type(B().fn3) # E: Invalid self argument "B" to attribute function "fn3" with type "Callable[[int], int]" \
7873+ # N: Revealed type is "def () -> builtins.int"
7874+ reveal_type(B().fn4) # N: Revealed type is "def () -> builtins.int"
7875+
7876+ class C:
7877+ @add_correct_first
7878+ def fn1() -> int:
7879+ return 0
7880+
7881+ @add_correct_first
7882+ def fn2(_x: int) -> int:
7883+ return 0
7884+
7885+ @add_correct_first
7886+ def fn3(self, _x: int) -> int:
7887+ return 0
7888+
7889+ reveal_type(C().fn1) # N: Revealed type is "def () -> builtins.int"
7890+ reveal_type(C().fn2) # N: Revealed type is "def (_x: builtins.int) -> builtins.int"
7891+ reveal_type(C().fn3) # N: Revealed type is "def (self: __main__.C, _x: builtins.int) -> builtins.int"
7892+
7893+ class D:
7894+ @add_wrong_first
7895+ def fn1() -> int: # E: Self argument missing for a non-static method (or an invalid type for self)
7896+ return 0
7897+
7898+ @add_wrong_first
7899+ def fn2(_x: int) -> int: # E: Self argument missing for a non-static method (or an invalid type for self)
7900+ return 0
7901+
7902+ @add_wrong_first
7903+ def fn3(self, _x: int) -> int: # E: Self argument missing for a non-static method (or an invalid type for self)
7904+ return 0
7905+
7906+ reveal_type(D().fn1) # E: Invalid self argument "D" to attribute function "fn1" with type "Callable[[int], int]" \
7907+ # N: Revealed type is "def () -> builtins.int"
7908+ reveal_type(D().fn2) # E: Invalid self argument "D" to attribute function "fn2" with type "Callable[[int, int], int]" \
7909+ # N: Revealed type is "def (_x: builtins.int) -> builtins.int"
7910+ reveal_type(D().fn3) # E: Invalid self argument "D" to attribute function "fn3" with type "Callable[[int, D, int], int]" \
7911+ # N: Revealed type is "def (self: __main__.D, _x: builtins.int) -> builtins.int"
7912+ [builtins fixtures/tuple.pyi]
7913+
7914+ [case testMethodSelfArgumentChecksInUntyped]
7915+ from typing import Callable, ParamSpec, TypeVar
7916+
7917+ T = TypeVar("T")
7918+ P = ParamSpec("P")
7919+
7920+ def to_same_callable(fn: Callable[P, T]) -> Callable[P, T]:
7921+ return fn
7922+
7923+ def unchecked():
7924+ class Bad:
7925+ def fn() -> None: ... # E: Method must have at least one argument. Did you forget the "self" argument?
7926+ def fn2(x: int) -> None: ... # E: Self argument missing for a non-static method (or an invalid type for self)
7927+
7928+ # TODO: would be nice to make this error, but now we see the func
7929+ # being decorated as Any, not as a callable
7930+ @to_same_callable
7931+ def gaaa() -> None: ...
7932+ @to_same_callable
7933+ def gaaa2(x: int) -> None: ...
7934+
7935+ class Ok:
7936+ def fn(): ...
7937+ def fn2(x): ...
7938+
7939+ @to_same_callable
7940+ def g(): ...
7941+ @to_same_callable
7942+ def g2(x): ...
7943+
7944+ def checked() -> None:
7945+ class Bad:
7946+ def fn() -> None: ... # E: Method must have at least one argument. Did you forget the "self" argument?
7947+ def fn2(x: int) -> None: ... # E: Self argument missing for a non-static method (or an invalid type for self)
7948+
7949+ @to_same_callable
7950+ def g() -> None: ... # E: Method must have at least one argument. Did you forget the "self" argument?
7951+ @to_same_callable
7952+ def g2(x: int) -> None: ... # E: Self argument missing for a non-static method (or an invalid type for self)
7953+
7954+ class AlsoBad:
7955+ def fn(): ... # E: Method must have at least one argument. Did you forget the "self" argument?
7956+ def fn2(x): ...
7957+
7958+ @to_same_callable
7959+ def g(): ... # E: Method must have at least one argument. Did you forget the "self" argument?
7960+ @to_same_callable
7961+ def g2(x): ...
7962+
7963+ class Ok:
7964+ def fn(): ... # E: Method must have at least one argument. Did you forget the "self" argument?
7965+ def fn2(x): ...
7966+
7967+ @to_same_callable
7968+ def g(): ... # E: Method must have at least one argument. Did you forget the "self" argument?
7969+ @to_same_callable
7970+ def g2(x): ...
7971+ [builtins fixtures/tuple.pyi]
7972+
77457973[case testTypeAfterAttributeAccessWithDisallowAnyExpr]
77467974# flags: --disallow-any-expr
77477975
0 commit comments