diff --git a/mypy/checkmember.py b/mypy/checkmember.py index 3efc39753627..01c6afeb9cec 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -532,17 +532,6 @@ def instance_alias_type(alias: TypeAlias, return expand_type_by_instance(tp, target) -def is_instance_var(var: Var, info: TypeInfo) -> bool: - """Return if var is an instance variable according to PEP 526.""" - return ( - # check the type_info node is the var (not a decorated function, etc.) - var.name in info.names and info.names[var.name].node is var - and not var.is_classvar - # variables without annotations are treated as classvar - and not var.is_inferred - ) - - def analyze_var(name: str, var: Var, itype: Instance, @@ -571,12 +560,7 @@ def analyze_var(name: str, t = get_proper_type(expand_type_by_instance(typ, itype)) result: Type = t typ = get_proper_type(typ) - if ( - var.is_initialized_in_class - and not is_instance_var(var, info) - and isinstance(typ, FunctionLike) - and not typ.is_type_obj() - ): + if var.is_initialized_in_class and isinstance(typ, FunctionLike) and not typ.is_type_obj(): if mx.is_lvalue: if var.is_property: if not var.is_settable_property: diff --git a/test-data/unit/check-dataclasses.test b/test-data/unit/check-dataclasses.test index 3d5f0a1da6e5..73476a646c99 100644 --- a/test-data/unit/check-dataclasses.test +++ b/test-data/unit/check-dataclasses.test @@ -1263,45 +1263,81 @@ reveal_type(A.__dataclass_fields__) # N: Revealed type is "builtins.dict[builti [builtins fixtures/dict.pyi] -[case testDataclassCallableFieldAccess] +[case testDataclassCallableProperty] # flags: --python-version 3.7 from dataclasses import dataclass from typing import Callable @dataclass class A: - x: Callable[[int], int] - y: Callable[[int], int] = lambda i: i + foo: Callable[[int], int] -a = A(lambda i:i) -x: int = a.x(0) -y: str = a.y(0) # E: Incompatible types in assignment (expression has type "int", variable has type "str") -reveal_type(a.x) # N: Revealed type is "def (builtins.int) -> builtins.int" -reveal_type(a.y) # N: Revealed type is "def (builtins.int) -> builtins.int" -reveal_type(A.y) # N: Revealed type is "def (builtins.int) -> builtins.int" +def my_foo(x: int) -> int: + return x +a = A(foo=my_foo) +a.foo(1) +reveal_type(a.foo) # N: Revealed type is "def (builtins.int) -> builtins.int" +reveal_type(A.foo) # N: Revealed type is "def (builtins.int) -> builtins.int" +[typing fixtures/typing-medium.pyi] [builtins fixtures/dataclasses.pyi] -[case testDataclassCallableFieldAssignment] +[case testDataclassCallableAssignment] # flags: --python-version 3.7 from dataclasses import dataclass from typing import Callable @dataclass class A: - x: Callable[[int], int] + foo: Callable[[int], int] + +def my_foo(x: int) -> int: + return x -def x(i: int) -> int: - return i -def x2(s: str) -> str: - return s +a = A(foo=my_foo) -a = A(lambda i:i) -a.x = x -a.x = x2 # E: Incompatible types in assignment (expression has type "Callable[[str], str]", variable has type "Callable[[int], int]") +def another_foo(x: int) -> int: + return x + +a.foo = another_foo +[builtins fixtures/dataclasses.pyi] +[case testDataclassCallablePropertyWrongType] +# flags: --python-version 3.7 +from dataclasses import dataclass +from typing import Callable + +@dataclass +class A: + foo: Callable[[int], int] + +def my_foo(x: int) -> str: + return "foo" + +a = A(foo=my_foo) # E: Argument "foo" to "A" has incompatible type "Callable[[int], str]"; expected "Callable[[int], int]" +[typing fixtures/typing-medium.pyi] [builtins fixtures/dataclasses.pyi] +[case testDataclassCallablePropertyWrongTypeAssignment] +# flags: --python-version 3.7 +from dataclasses import dataclass +from typing import Callable + +@dataclass +class A: + foo: Callable[[int], int] + +def my_foo(x: int) -> int: + return x + +a = A(foo=my_foo) + +def another_foo(x: int) -> str: + return "foo" + +a.foo = another_foo # E: Incompatible types in assignment (expression has type "Callable[[int], str]", variable has type "Callable[[int], int]") +[typing fixtures/typing-medium.pyi] +[builtins fixtures/dataclasses.pyi] [case testDataclassFieldDoesNotFailOnKwargsUnpacking] # flags: --python-version 3.7 @@ -1351,7 +1387,6 @@ class Foo: reveal_type(Foo(bar=1.5)) # N: Revealed type is "__main__.Foo" [builtins fixtures/dataclasses.pyi] - [case testDataclassWithSlotsArg] # flags: --python-version 3.10 from dataclasses import dataclass diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 6279e34a2904..62107686880f 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -599,12 +599,12 @@ A().f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "i [case testMethodAsDataAttribute] -from typing import Any, Callable, ClassVar +from typing import Any, Callable class B: pass x = None # type: Any class A: - f = x # type: ClassVar[Callable[[A], None]] - g = x # type: ClassVar[Callable[[A, B], None]] + f = x # type: Callable[[A], None] + g = x # type: Callable[[A, B], None] a = None # type: A a.f() a.g(B()) @@ -612,38 +612,26 @@ a.f(a) # E: Too many arguments a.g() # E: Too few arguments [case testMethodWithInvalidMethodAsDataAttribute] -from typing import Any, Callable, ClassVar +from typing import Any, Callable class B: pass x = None # type: Any class A: - f = x # type: ClassVar[Callable[[], None]] - g = x # type: ClassVar[Callable[[B], None]] + f = x # type: Callable[[], None] + g = x # type: Callable[[B], None] a = None # type: A a.f() # E: Attribute function "f" with type "Callable[[], None]" does not accept self argument a.g() # E: Invalid self argument "A" to attribute function "g" with type "Callable[[B], None]" [case testMethodWithDynamicallyTypedMethodAsDataAttribute] -from typing import Any, Callable, ClassVar +from typing import Any, Callable class B: pass x = None # type: Any class A: - f = x # type: ClassVar[Callable[[Any], Any]] + f = x # type: Callable[[Any], Any] a = None # type: A a.f() a.f(a) # E: Too many arguments -[case testMethodWithInferredMethodAsDataAttribute] -from typing import Any -def m(self: "A") -> int: ... - -class A: - n = m - -a = A() -reveal_type(a.n()) # N: Revealed type is "builtins.int" -reveal_type(A.n(a)) # N: Revealed type is "builtins.int" -A.n() # E: Too few arguments - [case testOverloadedMethodAsDataAttribute] from foo import * [file foo.pyi] @@ -685,35 +673,35 @@ a.g(B()) a.g(a) # E: Argument 1 has incompatible type "A[B]"; expected "B" [case testInvalidMethodAsDataAttributeInGenericClass] -from typing import Any, TypeVar, Generic, Callable, ClassVar +from typing import Any, TypeVar, Generic, Callable t = TypeVar('t') class B: pass class C: pass x = None # type: Any class A(Generic[t]): - f = x # type: ClassVar[Callable[[A[B]], None]] + f = x # type: Callable[[A[B]], None] ab = None # type: A[B] ac = None # type: A[C] ab.f() ac.f() # E: Invalid self argument "A[C]" to attribute function "f" with type "Callable[[A[B]], None]" [case testPartiallyTypedSelfInMethodDataAttribute] -from typing import Any, TypeVar, Generic, Callable, ClassVar +from typing import Any, TypeVar, Generic, Callable t = TypeVar('t') class B: pass class C: pass x = None # type: Any class A(Generic[t]): - f = x # type: ClassVar[Callable[[A], None]] + f = x # type: Callable[[A], None] ab = None # type: A[B] ac = None # type: A[C] ab.f() ac.f() [case testCallableDataAttribute] -from typing import Callable, ClassVar +from typing import Callable class A: - g = None # type: ClassVar[Callable[[A], None]] + g = None # type: Callable[[A], None] def __init__(self, f: Callable[[], None]) -> None: self.f = f a = A(None) diff --git a/test-data/unit/check-functools.test b/test-data/unit/check-functools.test index 5332454202cc..33653c8d3fbc 100644 --- a/test-data/unit/check-functools.test +++ b/test-data/unit/check-functools.test @@ -25,12 +25,12 @@ Ord() >= 1 # E: Unsupported operand types for >= ("Ord" and "int") [case testTotalOrderingLambda] from functools import total_ordering -from typing import Any, Callable, ClassVar +from typing import Any, Callable @total_ordering class Ord: - __eq__: ClassVar[Callable[[Any, object], bool]] = lambda self, other: False - __lt__: ClassVar[Callable[[Any, "Ord"], bool]] = lambda self, other: False + __eq__: Callable[[Any, object], bool] = lambda self, other: False + __lt__: Callable[[Any, "Ord"], bool] = lambda self, other: False reveal_type(Ord() < Ord()) # N: Revealed type is "builtins.bool" reveal_type(Ord() <= Ord()) # N: Revealed type is "builtins.bool" diff --git a/test-data/unit/check-selftype.test b/test-data/unit/check-selftype.test index 7e37276a3f75..a1fa234e6d0d 100644 --- a/test-data/unit/check-selftype.test +++ b/test-data/unit/check-selftype.test @@ -366,7 +366,7 @@ reveal_type(x.f) # N: Revealed type is "builtins.int" [builtins fixtures/property.pyi] [case testSelfTypeProperSupertypeAttribute] -from typing import Callable, TypeVar, ClassVar +from typing import Callable, TypeVar class K: pass T = TypeVar('T', bound=K) class A(K): @@ -374,8 +374,8 @@ class A(K): def g(self: K) -> int: return 0 @property def gt(self: T) -> T: return self - f: ClassVar[Callable[[object], int]] - ft: ClassVar[Callable[[T], T]] + f: Callable[[object], int] + ft: Callable[[T], T] class B(A): pass @@ -392,15 +392,15 @@ reveal_type(B().ft()) # N: Revealed type is "__main__.B*" [builtins fixtures/property.pyi] [case testSelfTypeProperSupertypeAttributeTuple] -from typing import Callable, TypeVar, Tuple, ClassVar +from typing import Callable, TypeVar, Tuple T = TypeVar('T') class A(Tuple[int, int]): @property def g(self: object) -> int: return 0 @property def gt(self: T) -> T: return self - f: ClassVar[Callable[[object], int]] - ft: ClassVar[Callable[[T], T]] + f: Callable[[object], int] + ft: Callable[[T], T] class B(A): pass @@ -450,7 +450,7 @@ reveal_type(X1.ft()) # N: Revealed type is "Type[__main__.X]" [builtins fixtures/property.pyi] [case testSelfTypeProperSupertypeAttributeGeneric] -from typing import Callable, TypeVar, Generic, ClassVar +from typing import Callable, TypeVar, Generic Q = TypeVar('Q', covariant=True) class K(Generic[Q]): q: Q @@ -460,8 +460,8 @@ class A(K[Q]): def g(self: K[object]) -> int: return 0 @property def gt(self: K[T]) -> T: return self.q - f: ClassVar[Callable[[object], int]] - ft: ClassVar[Callable[[T], T]] + f: Callable[[object], int] + ft: Callable[[T], T] class B(A[Q]): pass diff --git a/test-data/unit/check-slots.test b/test-data/unit/check-slots.test index 96e4eba3c966..254aa983f82f 100644 --- a/test-data/unit/check-slots.test +++ b/test-data/unit/check-slots.test @@ -361,7 +361,8 @@ a.a = 1 a.b = custom_obj a.c = custom_obj a.d = custom_obj -a.e = custom_obj +# TODO: Should this be allowed? +a.e = custom_obj # E: Cannot assign to a method [out] [builtins fixtures/tuple.pyi] [builtins fixtures/dict.pyi]