| -- Methods | |
| -- ------- | |
| [case testMethodCall] | |
| class A: | |
| def foo(self, x: 'A') -> None: pass | |
| class B: | |
| def bar(self, x: 'B', y: A) -> None: pass | |
| a: A | |
| b: B | |
| a.foo(B()) # E: Argument 1 to "foo" of "A" has incompatible type "B"; expected "A" | |
| a.bar(B(), A()) # E: "A" has no attribute "bar" | |
| a.foo(A()) | |
| b.bar(B(), A()) | |
| [case testMethodCallWithSubtype] | |
| class A: | |
| def foo(self, x: 'A') -> None: pass | |
| def bar(self, x: 'B') -> None: pass | |
| class B(A): pass | |
| a: A | |
| a.foo(A()) | |
| a.foo(B()) | |
| a.bar(A()) # E: Argument 1 to "bar" of "A" has incompatible type "A"; expected "B" | |
| a.bar(B()) | |
| [case testInheritingMethod] | |
| class A: | |
| def foo(self, x: 'B') -> None: pass | |
| class B(A): pass | |
| a: B | |
| a.foo(A()) # Fail | |
| a.foo(B()) | |
| [targets __main__, __main__.A.foo] | |
| [out] | |
| main:6: error: Argument 1 to "foo" of "A" has incompatible type "A"; expected "B" | |
| [case testMethodCallWithInvalidNumberOfArguments] | |
| class A: | |
| def foo(self, x: 'A') -> None: pass | |
| a: A | |
| a.foo() # Fail | |
| a.foo(object(), A()) # Fail | |
| [out] | |
| main:5: error: Missing positional argument "x" in call to "foo" of "A" | |
| main:6: error: Too many arguments for "foo" of "A" | |
| main:6: error: Argument 1 to "foo" of "A" has incompatible type "object"; expected "A" | |
| [case testMethodBody] | |
| import typing | |
| class A: | |
| def f(self) -> None: | |
| a = object() # type: A # Fail | |
| [out] | |
| main:4: error: Incompatible types in assignment (expression has type "object", variable has type "A") | |
| [case testMethodArguments] | |
| import typing | |
| class A: | |
| def f(self, a: 'A', b: 'B') -> None: | |
| if int(): | |
| a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") | |
| b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| a = A() | |
| b = B() | |
| a = a | |
| a = b # E: Incompatible types in assignment (expression has type "B", variable has type "A") | |
| class B: pass | |
| [out] | |
| [case testReturnFromMethod] | |
| import typing | |
| class A: | |
| def f(self) -> 'A': | |
| return B() # Fail | |
| return A() | |
| class B: pass | |
| [out] | |
| main:4: error: Incompatible return value type (got "B", expected "A") | |
| [case testSelfArgument] | |
| import typing | |
| class A: | |
| def f(self) -> None: | |
| o = self # type: B # Fail | |
| self.g() # Fail | |
| a = self # type: A | |
| self.f() | |
| class B: pass | |
| [out] | |
| main:4: error: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| main:5: error: "A" has no attribute "g" | |
| [case testAssignToMethodViaInstance] | |
| import typing | |
| class A: | |
| def f(self): pass | |
| A().f = None # E: Cannot assign to a method \ | |
| # E: Incompatible types in assignment (expression has type "None", variable has type "Callable[[], Any]") | |
| [case testOverrideAttributeWithMethod] | |
| # This was crashing: | |
| # https://github.com/python/mypy/issues/10134 | |
| from typing import Protocol | |
| class Base: | |
| __hash__: None = None | |
| class Derived(Base): | |
| def __hash__(self) -> int: # E: Signature of "__hash__" incompatible with supertype "Base" \ | |
| # N: Superclass: \ | |
| # N: None \ | |
| # N: Subclass: \ | |
| # N: def __hash__(self) -> int | |
| pass | |
| # Correct: | |
| class CallableProtocol(Protocol): | |
| def __call__(self, arg: int) -> int: | |
| pass | |
| class CorrectBase: | |
| attr: CallableProtocol | |
| class CorrectDerived(CorrectBase): | |
| def attr(self, arg: int) -> int: | |
| pass | |
| [case testOverrideMethodWithAttribute] | |
| # The reverse should not crash as well: | |
| from typing import Callable | |
| class Base: | |
| def __hash__(self) -> int: | |
| pass | |
| class Derived(Base): | |
| __hash__ = 1 # E: Incompatible types in assignment (expression has type "int", base class "Base" defined the type as "Callable[[], int]") | |
| [case testOverridePartialAttributeWithMethod] | |
| # This was crashing: https://github.com/python/mypy/issues/11686. | |
| class Base: | |
| def __init__(self, arg: int): | |
| self.partial_type = [] # E: Need type annotation for "partial_type" (hint: "partial_type: list[<type>] = ...") | |
| self.force_deferral = [] | |
| # Force inference of the `force_deferral` attribute in `__init__` to be | |
| # deferred to a later pass by providing a definition in another context, | |
| # which means `partial_type` remains only partially inferred. | |
| force_deferral = [] # E: Need type annotation for "force_deferral" (hint: "force_deferral: list[<type>] = ...") | |
| class Derived(Base): | |
| def partial_type(self) -> int: # E: Signature of "partial_type" incompatible with supertype "Base" \ | |
| # N: Superclass: \ | |
| # N: list[Any] \ | |
| # N: Subclass: \ | |
| # N: def partial_type(self) -> int | |
| ... | |
| -- Attributes | |
| -- ---------- | |
| [case testReferToInvalidAttribute] | |
| class A: | |
| def __init__(self) -> None: | |
| self.x = object() | |
| a: A | |
| a.y # E: "A" has no attribute "y" | |
| a.y = object() # E: "A" has no attribute "y" | |
| a.x | |
| a.x = object() | |
| [case testReferToInvalidAttributeUnannotatedInit] | |
| class A: | |
| def __init__(self): | |
| self.x = object() | |
| a: A | |
| a.y # E: "A" has no attribute "y" | |
| a.y = object() # E: "A" has no attribute "y" | |
| a.x | |
| a.x = object() | |
| [case testArgumentTypeInference] | |
| class A: | |
| def __init__(self, aa: 'A', bb: 'B') -> None: | |
| self.a = aa | |
| self.b = bb | |
| class B: pass | |
| a: A | |
| b: B | |
| a.a = b # Fail | |
| a.b = a # Fail | |
| b.a # Fail | |
| a.a = a | |
| a.b = b | |
| [out] | |
| main:9: error: Incompatible types in assignment (expression has type "B", variable has type "A") | |
| main:10: error: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| main:11: error: "B" has no attribute "a" | |
| [case testExplicitAttributeInBody] | |
| class A: | |
| x: A | |
| a: A | |
| a.x = object() # E: Incompatible types in assignment (expression has type "object", variable has type "A") | |
| a.x = A() | |
| [case testAttributeDefinedInNonInitMethod] | |
| import typing | |
| class A: | |
| def f(self) -> None: | |
| self.x = 1 | |
| self.y = '' | |
| self.x = 1 | |
| a = A() | |
| a.x = 1 | |
| a.y = '' | |
| a.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| a.z = 0 # E: "A" has no attribute "z" | |
| [case testInheritanceAndAttributeAssignment] | |
| import typing | |
| class A: | |
| def f(self) -> None: | |
| self.x = 0 | |
| class B(A): | |
| def f(self) -> None: | |
| self.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| [targets __main__, __main__.A.f, __main__.B.f] | |
| [case testAssignmentToAttributeInMultipleMethods] | |
| import typing | |
| class A: | |
| def f(self) -> None: | |
| self.x = 0 | |
| def g(self) -> None: | |
| self.x = '' # Fail | |
| def __init__(self) -> None: | |
| self.x = '' # Fail | |
| [out] | |
| main:6: error: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| main:8: error: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| [case testClassNamesDefinedOnSelUsedInClassBody] | |
| class A(object): | |
| def f(self): | |
| self.attr = 1 | |
| attr = 0 | |
| class B(object): | |
| attr = 0 | |
| def f(self): | |
| self.attr = 1 | |
| class C(object): | |
| attr = 0 | |
| def f(self): | |
| self.attr = 1 | |
| attr = 0 | |
| class D(object): | |
| def g(self): | |
| self.attr = 1 | |
| attr = 0 | |
| def f(self): | |
| self.attr = 1 | |
| [out] | |
| [case testClassNamesDefinedOnSelUsedInClassBodyReveal] | |
| class A(object): | |
| def f(self) -> None: | |
| self.attr = 1 | |
| attr # E: Name "attr" is not defined | |
| class B(object): | |
| attr = 0 | |
| def f(self) -> None: | |
| reveal_type(self.attr) # N: Revealed type is "builtins.int" | |
| [out] | |
| -- Method overriding | |
| -- ----------------- | |
| [case testMethodOverridingWithIdenticalSignature] | |
| import typing | |
| class A: | |
| def f(self, x: 'A') -> None: pass | |
| def g(self, x: 'B' , y: object) -> 'A': pass | |
| def h(self) -> None: pass | |
| class B(A): | |
| def f(self, x: A) -> None: pass | |
| def g(self, x: 'B' , y: object) -> A: pass | |
| def h(self) -> None: pass | |
| [out] | |
| [case testMethodOverridingWithCovariantType] | |
| import typing | |
| class A: | |
| def f(self, x: 'A', y: 'B') -> 'A': pass | |
| def g(self, x: 'A', y: 'B') -> 'A': pass | |
| class B(A): | |
| def f(self, x: A, y: 'B') -> 'B': pass | |
| def g(self, x: A, y: A) -> 'A': pass | |
| [out] | |
| [case testMethodOverridingWithIncompatibleTypes] | |
| import typing | |
| class A: | |
| def f(self, x: 'A', y: 'B') -> 'A': pass | |
| def g(self, x: 'A', y: 'B') -> 'A': pass | |
| def h(self, x: 'A', y: 'B') -> 'A': pass | |
| class B(A): | |
| def f(self, x: 'B', y: 'B') -> A: pass # Fail | |
| def g(self, x: A, y: A) -> A: pass | |
| def h(self, x: A, y: 'B') -> object: pass # Fail | |
| [out] | |
| main:7: error: Argument 1 of "f" is incompatible with supertype "A"; supertype defines the argument type as "A" | |
| main:7: note: This violates the Liskov substitution principle | |
| main:7: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| main:9: error: Return type "object" of "h" incompatible with return type "A" in supertype "A" | |
| [case testMethodOverridingWithIncompatibleTypesOnMultipleLines] | |
| class A: | |
| def f(self, x: int, y: str) -> None: pass | |
| class B(A): | |
| def f( | |
| self, | |
| x: int, | |
| y: bool, | |
| ) -> None: | |
| pass | |
| [out] | |
| main:7: error: Argument 2 of "f" is incompatible with supertype "A"; supertype defines the argument type as "str" | |
| main:7: note: This violates the Liskov substitution principle | |
| main:7: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| [case testMultiLineMethodOverridingWithIncompatibleTypesIgnorableAtArgument] | |
| class A: | |
| def f(self, x: int, y: str) -> None: pass | |
| class B(A): | |
| def f( | |
| self, | |
| x: int, | |
| y: bool, # type: ignore[override] | |
| ) -> None: | |
| pass | |
| [case testMultiLineMethodOverridingWithIncompatibleTypesIgnorableAtDefinition] | |
| class A: | |
| def f(self, x: int, y: str) -> None: pass | |
| class B(A): | |
| def f( # type: ignore[override] | |
| self, | |
| x: int, | |
| y: bool, | |
| ) -> None: | |
| pass | |
| [case testMultiLineMethodOverridingWithIncompatibleTypesWrongIgnore] | |
| class A: | |
| def f(self, x: int, y: str) -> None: pass | |
| class B(A): | |
| def f( # type: ignore[return-type] | |
| self, | |
| x: int, | |
| y: bool, | |
| ) -> None: | |
| pass | |
| [out] | |
| main:7: error: Argument 2 of "f" is incompatible with supertype "A"; supertype defines the argument type as "str" | |
| main:7: note: This violates the Liskov substitution principle | |
| main:7: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| [case testEqMethodsOverridingWithNonObjects] | |
| class A: | |
| def __eq__(self, other: A) -> bool: pass # Fail | |
| [builtins fixtures/plugin_attrs.pyi] | |
| [out] | |
| main:2: error: Argument 1 of "__eq__" is incompatible with supertype "builtins.object"; supertype defines the argument type as "object" | |
| main:2: note: This violates the Liskov substitution principle | |
| main:2: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| main:2: note: It is recommended for "__eq__" to work with arbitrary objects, for example: | |
| main:2: note: def __eq__(self, other: object) -> bool: | |
| main:2: note: if not isinstance(other, A): | |
| main:2: note: return NotImplemented | |
| main:2: note: return <logic to compare two A instances> | |
| [case testMethodOverridingWithIncompatibleArgumentCount] | |
| import typing | |
| class A: | |
| def f(self, x: 'A') -> None: pass | |
| def g(self, x: 'A', y: 'B') -> 'A': pass | |
| class B(A): | |
| def f(self, x: A, y: A) -> None: pass # Fail | |
| def g(self, x: A) -> A: pass # Fail | |
| [out] | |
| main:6: error: Signature of "f" incompatible with supertype "A" | |
| main:6: note: Superclass: | |
| main:6: note: def f(self, x: A) -> None | |
| main:6: note: Subclass: | |
| main:6: note: def f(self, x: A, y: A) -> None | |
| main:7: error: Signature of "g" incompatible with supertype "A" | |
| main:7: note: Superclass: | |
| main:7: note: def g(self, x: A, y: B) -> A | |
| main:7: note: Subclass: | |
| main:7: note: def g(self, x: A) -> A | |
| [case testMethodOverridingAcrossDeepInheritanceHierarchy1] | |
| import typing | |
| class A: | |
| def f(self, x: 'B') -> None: pass | |
| class B(A): pass | |
| class C(B): # with gap in implementations | |
| def f(self, x: 'C') -> None: # Fail | |
| pass | |
| [out] | |
| main:6: error: Argument 1 of "f" is incompatible with supertype "A"; supertype defines the argument type as "B" | |
| main:6: note: This violates the Liskov substitution principle | |
| main:6: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| [case testMethodOverridingAcrossDeepInheritanceHierarchy2] | |
| import typing | |
| class A: | |
| def f(self) -> 'B': pass | |
| class B(A): | |
| def f(self) -> 'C': pass | |
| class C(B): # with multiple implementations | |
| def f(self) -> B: # Fail | |
| pass | |
| [out] | |
| main:7: error: Return type "B" of "f" incompatible with return type "C" in supertype "B" | |
| [case testMethodOverridingWithVoidReturnValue] | |
| import typing | |
| class A: | |
| def f(self) -> None: pass | |
| def g(self) -> 'A': pass | |
| class B(A): | |
| def f(self) -> A: pass # Fail | |
| def g(self) -> None: pass # Fail | |
| [out] | |
| main:6: error: Return type "A" of "f" incompatible with return type "None" in supertype "A" | |
| main:7: error: Return type "None" of "g" incompatible with return type "A" in supertype "A" | |
| [case testOverride__new__WithDifferentSignature] | |
| class A: | |
| def __new__(cls, x: int) -> A: | |
| pass | |
| class B(A): | |
| def __new__(cls) -> B: | |
| pass | |
| [case testOverride__new__WithLiteralReturnPassing] | |
| from typing import Literal | |
| class Falsy: | |
| def __bool__(self) -> Literal[False]: pass | |
| reveal_type(bool(Falsy())) # N: Revealed type is "Literal[False]" | |
| reveal_type(int()) # N: Revealed type is "Literal[0]" | |
| [builtins fixtures/literal__new__.pyi] | |
| [typing fixtures/typing-medium.pyi] | |
| [case testOverride__new__WithLiteralReturnFailing] | |
| from typing import Literal | |
| class Foo: | |
| def __new__(cls) -> Literal[1]: pass # E: Incompatible return type for "__new__" (returns "Literal[1]", but must return a subtype of "Foo") | |
| [builtins fixtures/__new__.pyi] | |
| [typing fixtures/typing-medium.pyi] | |
| [case testOverride__new__AndCallObject] | |
| from typing import TypeVar, Generic | |
| class A: | |
| def __new__(cls, x: int) -> 'A': | |
| return object.__new__(cls) | |
| T = TypeVar('T') | |
| class B(Generic[T]): | |
| def __new__(cls, foo: T) -> 'B[T]': | |
| x = object.__new__(cls) | |
| # object.__new__ doesn't have a great type :( | |
| reveal_type(x) # N: Revealed type is "Any" | |
| return x | |
| [builtins fixtures/__new__.pyi] | |
| [case testInnerFunctionNotOverriding] | |
| class A: | |
| def f(self) -> int: pass | |
| class B(A): | |
| def g(self) -> None: | |
| def f(self) -> str: pass | |
| [case testOverride__init_subclass__WithDifferentSignature] | |
| class A: | |
| def __init_subclass__(cls, x: int) -> None: pass | |
| class B(A): # E: Missing positional argument "x" in call to "__init_subclass__" of "A" | |
| def __init_subclass__(cls) -> None: pass | |
| [case testOverrideWithDecorator] | |
| from typing import Callable | |
| def int_to_none(f: Callable[..., int]) -> Callable[..., None]: ... | |
| def str_to_int(f: Callable[..., str]) -> Callable[..., int]: ... | |
| class A: | |
| def f(self) -> None: pass | |
| def g(self) -> str: pass | |
| def h(self) -> None: pass | |
| class B(A): | |
| @int_to_none | |
| def f(self) -> int: pass | |
| @str_to_int | |
| def g(self) -> str: pass # Fail | |
| @int_to_none | |
| @str_to_int | |
| def h(self) -> str: pass | |
| [out] | |
| main:15: error: Signature of "g" incompatible with supertype "A" | |
| main:15: note: Superclass: | |
| main:15: note: def g(self) -> str | |
| main:15: note: Subclass: | |
| main:15: note: def g(*Any, **Any) -> int | |
| [case testOverrideDecorated] | |
| from typing import Callable | |
| def str_to_int(f: Callable[..., str]) -> Callable[..., int]: ... | |
| class A: | |
| @str_to_int | |
| def f(self) -> str: pass | |
| @str_to_int | |
| def g(self) -> str: pass | |
| @str_to_int | |
| def h(self) -> str: pass | |
| class B(A): | |
| def f(self) -> int: pass | |
| def g(self) -> str: pass # Fail | |
| @str_to_int | |
| def h(self) -> str: pass | |
| [out] | |
| main:15: error: Signature of "g" incompatible with supertype "A" | |
| main:15: note: Superclass: | |
| main:15: note: def g(*Any, **Any) -> int | |
| main:15: note: Subclass: | |
| main:15: note: def g(self) -> str | |
| [case testOverrideWithDecoratorReturningAny] | |
| def dec(f): pass | |
| class A: | |
| def f(self) -> str: pass | |
| class B(A): | |
| @dec | |
| def f(self) -> int: pass | |
| [case testOverrideWithDecoratorReturningCallable] | |
| from typing import Any, Callable, TypeVar | |
| class Base: | |
| def get(self, a: str) -> None: ... | |
| def dec(fn: Any) -> Callable[[Any, int], None]: ... | |
| class Derived(Base): | |
| @dec | |
| def get(self) -> None: ... # E: Argument 1 of "get" is incompatible with supertype "Base"; supertype defines the argument type as "str" \ | |
| # N: This violates the Liskov substitution principle \ | |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| [builtins fixtures/tuple.pyi] | |
| [case testOverrideWithDecoratorReturningCallable2] | |
| # flags: --pretty | |
| from typing import Any, Callable, TypeVar | |
| _C = TypeVar("_C", bound=Callable[..., Any]) | |
| def infer_signature(f: _C) -> Callable[[Any], _C]: ... | |
| class Base: | |
| def get(self, a: str, b: str, c: str) -> None: ... | |
| def post(self, a: str, b: str) -> None: ... | |
| # Third argument incompatible | |
| def get(self, a: str, b: str, c: int) -> None: ... | |
| # Second argument incompatible - still should not map to **kwargs | |
| def post(self, a: str, b: int) -> None: ... | |
| class Derived(Base): | |
| @infer_signature(get) | |
| def get(self, *args: Any, **kwargs: Any) -> None: ... | |
| @infer_signature(post) | |
| def post(self, *args: Any, **kwargs: Any) -> None: ... | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| main:20: error: Argument 3 of "get" is incompatible with supertype "Base"; supertype defines the argument type as "str" | |
| def get(self, *args: Any, **kwargs: Any) -> None: ... | |
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| main:20: note: This violates the Liskov substitution principle | |
| main:20: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| main:23: error: Argument 2 of "post" is incompatible with supertype "Base"; supertype defines the argument type as "str" | |
| def post(self, *args: Any, **kwargs: Any) -> None: ... | |
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| main:23: note: This violates the Liskov substitution principle | |
| main:23: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| [case testOverrideWithDecoratorReturningInstance] | |
| def dec(f) -> str: pass | |
| class A: | |
| def f(self) -> str: pass | |
| @dec | |
| def g(self) -> int: pass | |
| @dec | |
| def h(self) -> int: pass | |
| class B(A): | |
| @dec | |
| def f(self) -> int: pass # E: Signature of "f" incompatible with supertype "A" \ | |
| # N: Superclass: \ | |
| # N: def f(self) -> str \ | |
| # N: Subclass: \ | |
| # N: str | |
| def g(self) -> int: pass # E: Signature of "g" incompatible with supertype "A" \ | |
| # N: Superclass: \ | |
| # N: str \ | |
| # N: Subclass: \ | |
| # N: def g(self) -> int | |
| @dec | |
| def h(self) -> str: pass | |
| [case testOverrideIncompatibleWithMultipleSupertypes] | |
| class A: | |
| def f(self, *, a: int) -> None: | |
| return | |
| class B(A): | |
| def f(self, *, b: int) -> None: # E: Signature of "f" incompatible with supertype "A" \ | |
| # N: Superclass: \ | |
| # N: def f(self, *, a: int) -> None \ | |
| # N: Subclass: \ | |
| # N: def f(self, *, b: int) -> None | |
| return | |
| class C(B): | |
| def f(self, *, c: int) -> None: # E: Signature of "f" incompatible with supertype "B" \ | |
| # N: Superclass: \ | |
| # N: def f(self, *, b: int) -> None \ | |
| # N: Subclass: \ | |
| # N: def f(self, *, c: int) -> None \ | |
| # E: Signature of "f" incompatible with supertype "A" \ | |
| # N: Superclass: \ | |
| # N: def f(self, *, a: int) -> None \ | |
| # N: Subclass: \ | |
| # N: def f(self, *, c: int) -> None | |
| return | |
| [case testOverrideStaticMethodWithStaticMethod] | |
| class A: | |
| @staticmethod | |
| def f(x: int, y: str) -> None: pass | |
| @staticmethod | |
| def g(x: int, y: str) -> None: pass | |
| class B(A): | |
| @staticmethod | |
| def f(x: int, y: str) -> None: pass | |
| @staticmethod | |
| def g(x: str, y: str) -> None: pass # E: Argument 1 of "g" is incompatible with supertype "A"; supertype defines the argument type as "int" \ | |
| # N: This violates the Liskov substitution principle \ | |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| [builtins fixtures/classmethod.pyi] | |
| [case testOverrideClassMethodWithClassMethod] | |
| class A: | |
| @classmethod | |
| def f(cls, x: int, y: str) -> None: pass | |
| @classmethod | |
| def g(cls, x: int, y: str) -> None: pass | |
| class B(A): | |
| @classmethod | |
| def f(cls, x: int, y: str) -> None: pass | |
| @classmethod | |
| def g(cls, x: str, y: str) -> None: pass # E: Argument 1 of "g" is incompatible with supertype "A"; supertype defines the argument type as "int" \ | |
| # N: This violates the Liskov substitution principle \ | |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| [builtins fixtures/classmethod.pyi] | |
| [case testOverrideClassMethodWithStaticMethod] | |
| class A: | |
| @classmethod | |
| def f(cls, x: int) -> None: pass | |
| @classmethod | |
| def g(cls, x: int) -> int: pass | |
| @classmethod | |
| def h(cls) -> int: pass | |
| class B(A): | |
| @staticmethod | |
| def f(x: int) -> None: pass | |
| @staticmethod | |
| def g(x: str) -> int: pass # E: Argument 1 of "g" is incompatible with supertype "A"; supertype defines the argument type as "int" \ | |
| # N: This violates the Liskov substitution principle \ | |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| @staticmethod | |
| def h() -> int: pass | |
| [builtins fixtures/classmethod.pyi] | |
| [case testOverrideStaticMethodWithClassMethod] | |
| class A: | |
| @staticmethod | |
| def f(x: int) -> None: pass | |
| @staticmethod | |
| def g(x: str) -> int: pass | |
| @staticmethod | |
| def h() -> int: pass | |
| class B(A): | |
| @classmethod | |
| def f(cls, x: int) -> None: pass | |
| @classmethod | |
| def g(cls, x: int) -> int: pass # E: Argument 1 of "g" is incompatible with supertype "A"; supertype defines the argument type as "str" \ | |
| # N: This violates the Liskov substitution principle \ | |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| @classmethod | |
| def h(cls) -> int: pass | |
| [builtins fixtures/classmethod.pyi] | |
| [case testOverrideReplaceMethod] | |
| # flags: --show-error-codes | |
| from typing import Optional | |
| from typing_extensions import Self | |
| class A: | |
| def __replace__(self, x: Optional[str]) -> Self: pass | |
| class B(A): | |
| def __replace__(self, x: str) -> Self: pass # E: \ | |
| # E: Argument 1 of "__replace__" is incompatible with supertype "A"; supertype defines the argument type as "str | None" [override] \ | |
| # N: This violates the Liskov substitution principle \ | |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| [builtins fixtures/tuple.pyi] | |
| [case testAllowCovarianceInReadOnlyAttributes] | |
| from typing import Callable, TypeVar | |
| T = TypeVar('T') | |
| class X: | |
| pass | |
| class Y(X): | |
| pass | |
| def dec(f: Callable[..., T]) -> T: pass | |
| class A: | |
| @dec | |
| def f(self) -> X: pass | |
| class B(A): | |
| @dec | |
| def f(self) -> Y: pass | |
| [case testOverrideCallableAttributeWithMethod] | |
| from typing import Callable | |
| class A: | |
| f1: Callable[[str], None] | |
| f2: Callable[[str], None] | |
| f3: Callable[[str], None] | |
| class B(A): | |
| def f1(self, x: object) -> None: | |
| pass | |
| @classmethod | |
| def f2(cls, x: object) -> None: | |
| pass | |
| @staticmethod | |
| def f3(x: object) -> None: | |
| pass | |
| [builtins fixtures/classmethod.pyi] | |
| [case testOverrideCallableAttributeWithMethodMutableOverride] | |
| # flags: --enable-error-code=mutable-override | |
| from typing import Callable | |
| class A: | |
| f1: Callable[[str], None] | |
| f2: Callable[[str], None] | |
| f3: Callable[[str], None] | |
| class B(A): | |
| def f1(self, x: object) -> None: pass # E: Covariant override of a mutable attribute (base class "A" defined the type as "Callable[[str], None]", override has type "Callable[[object], None]") | |
| @classmethod | |
| def f2(cls, x: object) -> None: pass # E: Covariant override of a mutable attribute (base class "A" defined the type as "Callable[[str], None]", override has type "Callable[[object], None]") | |
| @staticmethod | |
| def f3(x: object) -> None: pass # E: Covariant override of a mutable attribute (base class "A" defined the type as "Callable[[str], None]", override has type "Callable[[object], None]") | |
| [builtins fixtures/classmethod.pyi] | |
| [case testOverrideCallableAttributeWithSettableProperty] | |
| from typing import Callable | |
| class A: | |
| f: Callable[[str], None] | |
| class B(A): | |
| @property | |
| def f(self) -> Callable[[object], None]: pass | |
| @f.setter | |
| def f(self, x: object) -> None: pass | |
| [builtins fixtures/property.pyi] | |
| [case testOverrideCallableAttributeWithSettablePropertyMutableOverride] | |
| # flags: --enable-error-code=mutable-override | |
| from typing import Callable | |
| class A: | |
| f: Callable[[str], None] | |
| class B(A): | |
| @property | |
| def f(self) -> Callable[[object], None]: pass | |
| @f.setter | |
| def f(self, x: object) -> None: pass | |
| [builtins fixtures/property.pyi] | |
| [case testOverrideCallableUnionAttributeWithMethod] | |
| from typing import Callable, Union | |
| class A: | |
| f1: Union[Callable[[str], str], str] | |
| f2: Union[Callable[[str], str], str] | |
| f3: Union[Callable[[str], str], str] | |
| f4: Union[Callable[[str], str], str] | |
| class B(A): | |
| def f1(self, x: str) -> str: | |
| pass | |
| def f2(self, x: object) -> str: | |
| pass | |
| @classmethod | |
| def f3(cls, x: str) -> str: | |
| pass | |
| @staticmethod | |
| def f4(x: str) -> str: | |
| pass | |
| [builtins fixtures/classmethod.pyi] | |
| [case testOverrideCallableUnionAttributeWithMethodMutableOverride] | |
| # flags: --enable-error-code=mutable-override | |
| from typing import Callable, Union | |
| class A: | |
| f1: Union[Callable[[str], str], str] | |
| f2: Union[Callable[[str], str], str] | |
| f3: Union[Callable[[str], str], str] | |
| f4: Union[Callable[[str], str], str] | |
| class B(A): | |
| def f1(self, x: str) -> str: # E: Covariant override of a mutable attribute (base class "A" defined the type as "Callable[[str], str] | str", override has type "Callable[[str], str]") | |
| pass | |
| def f2(self, x: object) -> str: # E: Covariant override of a mutable attribute (base class "A" defined the type as "Callable[[str], str] | str", override has type "Callable[[object], str]") | |
| pass | |
| @classmethod | |
| def f3(cls, x: str) -> str: # E: Covariant override of a mutable attribute (base class "A" defined the type as "Callable[[str], str] | str", override has type "Callable[[str], str]") | |
| pass | |
| @staticmethod | |
| def f4(x: str) -> str: # E: Covariant override of a mutable attribute (base class "A" defined the type as "Callable[[str], str] | str", override has type "Callable[[str], str]") | |
| pass | |
| [builtins fixtures/classmethod.pyi] | |
| -- Constructors | |
| -- ------------ | |
| [case testTrivialConstructor] | |
| class A: | |
| def __init__(self) -> None: pass | |
| a = A() # type: A | |
| b = A() # type: B # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| class B: pass | |
| [case testConstructor] | |
| class A: | |
| def __init__(self, x: 'B') -> None: pass | |
| class B: pass | |
| a = A(B()) # type: A | |
| aa = A(object()) # type: A # E: Argument 1 to "A" has incompatible type "object"; expected "B" | |
| b = A(B()) # type: B # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| [case testConstructorWithTwoArguments] | |
| class A: | |
| def __init__(self, x: 'B', y: 'C') -> None: pass | |
| class B: pass | |
| class C(B): pass | |
| a = A(C(), B()) # type: A # E: Argument 2 to "A" has incompatible type "B"; expected "C" | |
| [case testInheritedConstructor] | |
| class B(A): pass | |
| class C: pass | |
| class D: pass | |
| b = B(C()) # type: B | |
| a = B(D()) # type: A # E: Argument 1 to "B" has incompatible type "D"; expected "C" | |
| class A: | |
| def __init__(self, x: 'C') -> None: pass | |
| [case testOverridingWithIncompatibleConstructor] | |
| class A: | |
| def __init__(self, x: 'C') -> None: pass | |
| class B(A): | |
| def __init__(self) -> None: pass | |
| class C: pass | |
| A() # E: Missing positional argument "x" in call to "A" | |
| B(C()) # E: Too many arguments for "B" | |
| A(C()) | |
| B() | |
| [case testConstructorWithReturnValueType] | |
| import typing | |
| class A: | |
| def __init__(self) -> 'A': pass | |
| [out] | |
| main:3: error: The return type of "__init__" must be None | |
| [case testConstructorWithImplicitReturnValueType] | |
| import typing | |
| class A: | |
| def __init__(self, x: int): pass | |
| [out] | |
| [case testDecoratedConstructorWithImplicitReturnValueType] | |
| import typing | |
| from typing import Callable | |
| def deco(fn: Callable) -> Callable: | |
| return fn | |
| class A: | |
| @deco | |
| def __init__(self, x: int): pass | |
| [out] | |
| [case testOverloadedConstructorWithImplicitReturnValueType] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload | |
| class Foo: | |
| @overload | |
| def __init__(self, a: int): | |
| pass | |
| @overload | |
| def __init__(self, a: str): | |
| pass | |
| [case testConstructorWithAnyReturnValueType] | |
| import typing | |
| from typing import Any | |
| class A: | |
| def __init__(self) -> Any: pass # E: The return type of "__init__" must be None | |
| [case testDecoratedConstructorWithAnyReturnValueType] | |
| import typing | |
| from typing import Callable, Any | |
| def deco(fn: Callable) -> Callable: | |
| return fn | |
| class A: | |
| @deco | |
| def __init__(self) -> Any: pass # E: The return type of "__init__" must be None | |
| [case testOverloadedConstructorWithAnyReturnValueType] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload, Any | |
| class Foo: | |
| @overload | |
| def __init__(self, a: int) -> Any: # E: The return type of "__init__" must be None | |
| pass | |
| @overload | |
| def __init__(self, a: str) -> Any: # E: The return type of "__init__" must be None | |
| pass | |
| [case testInitSubclassWithReturnValueType] | |
| import typing | |
| class A: | |
| def __init_subclass__(cls) -> 'A': pass | |
| [out] | |
| main:3: error: The return type of "__init_subclass__" must be None | |
| [case testInitSubclassWithImplicitReturnValueType] | |
| import typing | |
| class A: | |
| def __init_subclass__(cls, x: int=1): pass | |
| [out] | |
| [case testDecoratedInitSubclassWithImplicitReturnValueType] | |
| import typing | |
| from typing import Callable | |
| def deco(fn: Callable) -> Callable: | |
| return fn | |
| class A: | |
| @deco | |
| def __init_subclass__(cls, x: int=1): pass | |
| [out] | |
| [case testOverloadedInitSubclassWithImplicitReturnValueType] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload | |
| class Foo: | |
| @overload | |
| def __init_subclass__(cls, a: int): | |
| pass | |
| @overload | |
| def __init_subclass__(cls, a: str): | |
| pass | |
| [case testInitSubclassWithAnyReturnValueType] | |
| import typing | |
| from typing import Any | |
| class A: | |
| def __init_subclass__(cls) -> Any: pass # E: The return type of "__init_subclass__" must be None | |
| [case testDecoratedInitSubclassWithAnyReturnValueType] | |
| import typing | |
| from typing import Callable, Any | |
| def deco(fn: Callable) -> Callable: | |
| return fn | |
| class A: | |
| @deco | |
| def __init_subclass__(cls) -> Any: pass # E: The return type of "__init_subclass__" must be None | |
| [out] | |
| [case testOverloadedInitSubclassWithAnyReturnValueType] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload, Any | |
| class Foo: | |
| @overload | |
| def __init_subclass__(cls, a: int) -> Any: # E: The return type of "__init_subclass__" must be None | |
| pass | |
| @overload | |
| def __init_subclass__(cls, a: str) -> Any: # E: The return type of "__init_subclass__" must be None | |
| pass | |
| [case testGlobalFunctionInitWithReturnType] | |
| class A: pass | |
| class B: pass | |
| def __init__() -> 'A': pass | |
| a = __init__() # type: A | |
| b = __init__() # type: B # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| [case testAccessingInit] | |
| from typing import Any, cast | |
| class A: | |
| def __init__(self, a: 'A') -> None: pass | |
| a: A | |
| a.__init__(a) # E: Accessing "__init__" on an instance is unsound, since instance.__init__ could be from an incompatible subclass | |
| (cast(Any, a)).__init__(a) | |
| [case testDeepInheritanceHierarchy] | |
| class A: pass | |
| class B(A): pass | |
| class C(B): pass | |
| class D(C): pass | |
| class D2(C): pass | |
| d = C() # type: D # E: Incompatible types in assignment (expression has type "C", variable has type "D") | |
| if int(): | |
| d = B() # E: Incompatible types in assignment (expression has type "B", variable has type "D") | |
| if int(): | |
| d = A() # E: Incompatible types in assignment (expression has type "A", variable has type "D") | |
| if int(): | |
| d = D2() # E: Incompatible types in assignment (expression has type "D2", variable has type "D") | |
| a = D() # type: A | |
| if int(): | |
| a = D2() | |
| b = D() # type: B | |
| if int(): | |
| b = D2() | |
| [case testConstructorJoinsWithCustomMetaclass] | |
| from typing import TypeVar | |
| import abc | |
| def func() -> None: pass | |
| class NormalClass: pass | |
| class WithMetaclass(metaclass=abc.ABCMeta): pass | |
| T = TypeVar('T') | |
| def join(x: T, y: T) -> T: pass | |
| f1 = join(func, WithMetaclass) | |
| reveal_type(f1()) # N: Revealed type is "__main__.WithMetaclass | None" | |
| f2 = join(WithMetaclass, func) | |
| reveal_type(f2()) # N: Revealed type is "__main__.WithMetaclass | None" | |
| -- Attribute access in class body | |
| -- ------------------------------ | |
| [case testDataAttributeRefInClassBody] | |
| import typing | |
| class B: pass | |
| class A: | |
| x = B() | |
| y = x | |
| b = x # type: B | |
| if int(): | |
| b = x | |
| c = x # type: A # E: Incompatible types in assignment (expression has type "B", variable has type "A") | |
| if int(): | |
| c = b # E: Incompatible types in assignment (expression has type "B", variable has type "A") | |
| [out] | |
| [case testMethodRefInClassBody] | |
| from typing import Callable | |
| class B: pass | |
| class A: | |
| def f(self) -> None: pass | |
| g = f | |
| h = f # type: Callable[[A], None] | |
| if int(): | |
| h = f | |
| g = h | |
| ff = f # type: Callable[[B], None] # E: Incompatible types in assignment (expression has type "Callable[[A], None]", variable has type "Callable[[B], None]") | |
| if int(): | |
| g = ff # E: Incompatible types in assignment (expression has type "Callable[[B], None]", variable has type "Callable[[A], None]") | |
| [out] | |
| -- Arbitrary statements in class body | |
| -- ---------------------------------- | |
| [case testStatementsInClassBody] | |
| import typing | |
| class B: pass | |
| class A: | |
| for x in [A()]: | |
| y = x | |
| if int(): | |
| y = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") | |
| if int(): | |
| x = A() | |
| if int(): | |
| y = A() | |
| if int(): | |
| x = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") | |
| [builtins fixtures/for.pyi] | |
| [out] | |
| -- Class attributes | |
| -- ---------------- | |
| [case testAccessMethodViaClass] | |
| import typing | |
| class A: | |
| def f(self) -> None: pass | |
| A.f(A()) | |
| A.f(object()) # E: Argument 1 to "f" of "A" has incompatible type "object"; expected "A" | |
| A.f() # E: Missing positional argument "self" in call to "f" of "A" | |
| A.f(None, None) # E: Too many arguments for "f" of "A" \ | |
| # E: Argument 1 to "f" of "A" has incompatible type "None"; expected "A" | |
| [case testAccessAttributeViaClass] | |
| import typing | |
| class B: pass | |
| class A: | |
| x: A | |
| a = A.x # type: A | |
| b = A.x # type: B # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| [case testAccessingUndefinedAttributeViaClass] | |
| import typing | |
| class A: pass | |
| A.x # E: "type[A]" has no attribute "x" | |
| [case testAccessingUndefinedAttributeViaClassWithOverloadedInit] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload | |
| class A: | |
| @overload | |
| def __init__(self): pass | |
| @overload | |
| def __init__(self, x): pass | |
| A.x # E: "type[A]" has no attribute "x" | |
| [case testAccessMethodOfClassWithOverloadedInit] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload, Any | |
| class A: | |
| @overload | |
| def __init__(self) -> None: pass | |
| @overload | |
| def __init__(self, x: Any) -> None: pass | |
| def f(self) -> None: pass | |
| A.f(A()) | |
| A.f() # E: Missing positional argument "self" in call to "f" of "A" | |
| [case testAssignmentToClassDataAttribute] | |
| import typing | |
| class B: pass | |
| class A: | |
| x: B | |
| A.x = B() | |
| A.x = object() # E: Incompatible types in assignment (expression has type "object", variable has type "B") | |
| [case testAssignmentToInferredClassDataAttribute] | |
| import typing | |
| class B: pass | |
| class A: | |
| x = B() | |
| A.x = B() | |
| A.x = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| [case testInitMethodUnbound] | |
| class B: pass | |
| class A: | |
| def __init__(self, b: B) -> None: pass | |
| a: A | |
| b: B | |
| A.__init__(a, b) | |
| A.__init__(b, b) # E: Argument 1 to "__init__" of "A" has incompatible type "B"; expected "A" | |
| A.__init__(a, a) # E: Argument 2 to "__init__" of "A" has incompatible type "A"; expected "B" | |
| [case testAssignToMethodViaClass] | |
| import typing | |
| class A: | |
| def f(self): pass | |
| A.f = None # E: Cannot assign to a method \ | |
| # E: Incompatible types in assignment (expression has type "None", variable has type "Callable[[A], Any]") | |
| [case testAssignToNestedClassViaClass] | |
| import typing | |
| class A: | |
| class B: pass | |
| A.B = None # E: Cannot assign to a type \ | |
| # E: Incompatible types in assignment (expression has type "None", variable has type "type[B]") | |
| [targets __main__] | |
| [case testAccessingClassAttributeWithTypeInferenceIssue] | |
| x = C.x # E: Cannot determine type of "x" # E: Name "C" is used before definition | |
| def f() -> int: return 1 | |
| class C: | |
| x = f() | |
| [builtins fixtures/list.pyi] | |
| [case testAccessingClassAttributeWithTypeInferenceIssue2] | |
| class C: | |
| x = [] | |
| x = C.x | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| main:2: error: Need type annotation for "x" (hint: "x: list[<type>] = ...") | |
| [case testAccessingGenericClassAttribute] | |
| from typing import Generic, TypeVar | |
| T = TypeVar('T') | |
| class A(Generic[T]): | |
| x: T | |
| A.x # E: Access to generic instance variables via class is ambiguous | |
| A[int].x # E: Access to generic instance variables via class is ambiguous | |
| [targets __main__] | |
| [case testAccessingNestedGenericClassAttribute] | |
| from typing import Generic, List, TypeVar, Union | |
| T = TypeVar('T') | |
| U = TypeVar('U') | |
| class A(Generic[T, U]): | |
| x: Union[T, List[U]] | |
| A.x # E: Access to generic instance variables via class is ambiguous | |
| A[int, int].x # E: Access to generic instance variables via class is ambiguous | |
| [builtins fixtures/list.pyi] | |
| -- Nested classes | |
| -- -------------- | |
| [case testClassWithinFunction] | |
| def f() -> None: | |
| class A: | |
| def g(self) -> None: pass | |
| a: A | |
| a.g() | |
| a.g(a) # E: Too many arguments for "g" of "A" | |
| [targets __main__, __main__.f] | |
| [case testGenericClassWithinFunction] | |
| from typing import TypeVar | |
| def test() -> None: | |
| T = TypeVar('T', bound='Foo') | |
| class Foo: | |
| def returns_int(self) -> int: | |
| return 0 | |
| def bar(self, foo: T) -> T: | |
| x: T = foo | |
| reveal_type(x) # N: Revealed type is "T`-1" | |
| reveal_type(x.returns_int()) # N: Revealed type is "builtins.int" | |
| return foo | |
| reveal_type(Foo.bar) # N: Revealed type is "def [T <: __main__.Foo@5] (self: __main__.Foo@5, foo: T`1) -> T`1" | |
| [case testGenericClassWithInvalidTypevarUseWithinFunction] | |
| from typing import TypeVar | |
| def test() -> None: | |
| T = TypeVar('T', bound='Foo') | |
| class Foo: | |
| invalid: T # E: Type variable "T" is unbound \ | |
| # N: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class) \ | |
| # N: (Hint: Use "T" in function signature to bind "T" inside a function) | |
| def bar(self, foo: T) -> T: | |
| pass | |
| [case testConstructNestedClass] | |
| import typing | |
| class A: | |
| class B: pass | |
| b = B() | |
| if int(): | |
| b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| if int(): | |
| b = B(b) # E: Too many arguments for "B" | |
| [out] | |
| [case testConstructNestedClassWithCustomInit] | |
| import typing | |
| class A: | |
| def f(self) -> None: | |
| class B: | |
| def __init__(self, a: 'A') -> None: pass | |
| b = B(A()) | |
| if int(): | |
| b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| b = B() # E: Missing positional argument "a" in call to "B" | |
| [out] | |
| [case testDeclareVariableWithNestedClassType] | |
| def f() -> None: | |
| class A: pass | |
| a: A | |
| if int(): | |
| a = A() | |
| a = object() # E: Incompatible types in assignment (expression has type "object", variable has type "A") | |
| [out] | |
| [case testExternalReferenceToClassWithinClass] | |
| class A: | |
| class B: pass | |
| b: A.B | |
| if int(): | |
| b = A.B() | |
| if int(): | |
| b = A() # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| if int(): | |
| b = A.B(b) # E: Too many arguments for "B" | |
| [case testAliasNestedClass] | |
| class Outer: | |
| class Inner: | |
| def make_int(self) -> int: return 1 | |
| reveal_type(Inner().make_int) # N: Revealed type is "def () -> builtins.int" | |
| some_int = Inner().make_int() | |
| reveal_type(Outer.Inner.make_int) # N: Revealed type is "def (self: __main__.Outer.Inner) -> builtins.int" | |
| reveal_type(Outer().some_int) # N: Revealed type is "builtins.int" | |
| Bar = Outer.Inner | |
| reveal_type(Bar.make_int) # N: Revealed type is "def (self: __main__.Outer.Inner) -> builtins.int" | |
| x = Bar() # type: Bar | |
| def produce() -> Bar: | |
| reveal_type(Bar().make_int) # N: Revealed type is "def () -> builtins.int" | |
| return Bar() | |
| [case testInnerClassPropertyAccess] | |
| class Foo: | |
| class Meta: | |
| name = 'Bar' | |
| meta = Meta | |
| reveal_type(Foo.Meta) # N: Revealed type is "def () -> __main__.Foo.Meta" | |
| reveal_type(Foo.meta) # N: Revealed type is "def () -> __main__.Foo.Meta" | |
| reveal_type(Foo.Meta.name) # N: Revealed type is "builtins.str" | |
| reveal_type(Foo.meta.name) # N: Revealed type is "builtins.str" | |
| reveal_type(Foo().Meta) # N: Revealed type is "def () -> __main__.Foo.Meta" | |
| reveal_type(Foo().meta) # N: Revealed type is "def () -> __main__.Foo.Meta" | |
| reveal_type(Foo().meta.name) # N: Revealed type is "builtins.str" | |
| reveal_type(Foo().Meta.name) # N: Revealed type is "builtins.str" | |
| -- Declaring attribute type in method | |
| -- ---------------------------------- | |
| [case testDeclareAttributeTypeInInit] | |
| class A: | |
| def __init__(self): | |
| self.x: int # N: By default the bodies of untyped functions are not checked, consider using --check-untyped-defs | |
| a: A | |
| a.x = 1 | |
| a.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| [case testAccessAttributeDeclaredInInitBeforeDeclaration] | |
| a: A | |
| a.x = 1 | |
| a.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| class A: | |
| def __init__(self): | |
| self.x: int # N: By default the bodies of untyped functions are not checked, consider using --check-untyped-defs | |
| -- Special cases | |
| -- ------------- | |
| [case testMultipleClassDefinition] | |
| class A: pass | |
| class A: pass # E: Name "A" already defined on line 1 | |
| A() | |
| [case testDocstringInClass] | |
| import typing | |
| class A: | |
| """Foo""" | |
| class B: | |
| 'x' | |
| y = B() | |
| [builtins fixtures/primitives.pyi] | |
| [case testErrorMessageInFunctionNestedWithinMethod] | |
| import typing | |
| class A: | |
| def f(self) -> None: | |
| def g() -> None: | |
| "" + 1 # E: Unsupported operand types for + ("str" and "int") | |
| "" + 1 # E: Unsupported operand types for + ("str" and "int") | |
| [builtins fixtures/primitives.pyi] | |
| -- Static methods | |
| -- -------------- | |
| [case testSimpleStaticMethod] | |
| import typing | |
| class A: | |
| @staticmethod | |
| def f(x: int) -> None: pass | |
| A.f(1) | |
| A().f(1) | |
| A.f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" | |
| A().f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" | |
| [builtins fixtures/staticmethod.pyi] | |
| [case testBuiltinStaticMethod] | |
| import typing | |
| int.from_bytes(b'', '') | |
| int.from_bytes('', '') # E: Argument 1 to "from_bytes" of "int" has incompatible type "str"; expected "bytes" | |
| [builtins fixtures/staticmethod.pyi] | |
| [case testAssignStaticMethodOnInstance] | |
| import typing | |
| class A: | |
| @staticmethod | |
| def f(x: int) -> None: pass | |
| A().f = A.f # E: Cannot assign to a method | |
| [builtins fixtures/staticmethod.pyi] | |
| -- Class methods | |
| -- ------------- | |
| [case testSimpleClassMethod] | |
| import typing | |
| class A: | |
| @classmethod | |
| def f(cls, x: int) -> None: pass | |
| A.f(1) | |
| A().f(1) | |
| A.f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" | |
| A().f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" | |
| [builtins fixtures/classmethod.pyi] | |
| [targets __main__, __main__.A.f] | |
| [case testBuiltinClassMethod] | |
| import typing | |
| int.from_bytes(b'', '') | |
| int.from_bytes('', '') # E: Argument 1 to "from_bytes" of "int" has incompatible type "str"; expected "bytes" | |
| [builtins fixtures/classmethod.pyi] | |
| [case testAssignClassMethodOnClass] | |
| import typing | |
| class A: | |
| @classmethod | |
| def f(cls, x: int) -> None: pass | |
| A.f = A.f # E: Cannot assign to a method | |
| [builtins fixtures/classmethod.pyi] | |
| [case testAssignClassMethodOnInstance] | |
| import typing | |
| class A: | |
| @classmethod | |
| def f(cls, x: int) -> None: pass | |
| A().f = A.f # E: Cannot assign to a method | |
| [builtins fixtures/classmethod.pyi] | |
| [case testClassMethodCalledInClassMethod] | |
| import typing | |
| class C: | |
| @classmethod | |
| def foo(cls) -> None: pass | |
| @classmethod | |
| def bar(cls) -> None: | |
| cls() | |
| cls(1) # E: Too many arguments for "C" | |
| cls.bar() | |
| cls.bar(1) # E: Too many arguments for "bar" of "C" | |
| cls.bozo() # E: "type[C]" has no attribute "bozo" | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testClassMethodCalledOnClass] | |
| import typing | |
| class C: | |
| @classmethod | |
| def foo(cls) -> None: pass | |
| C.foo() | |
| C.foo(1) # E: Too many arguments for "foo" of "C" | |
| C.bozo() # E: "type[C]" has no attribute "bozo" | |
| [builtins fixtures/classmethod.pyi] | |
| [case testClassMethodCalledOnInstance] | |
| import typing | |
| class C: | |
| @classmethod | |
| def foo(cls) -> None: pass | |
| C().foo() | |
| C().foo(1) # E: Too many arguments for "foo" of "C" | |
| C.bozo() # E: "type[C]" has no attribute "bozo" | |
| [builtins fixtures/classmethod.pyi] | |
| [case testClassMethodMayCallAbstractMethod] | |
| from abc import abstractmethod | |
| import typing | |
| class C: | |
| @classmethod | |
| def foo(cls) -> None: | |
| cls().bar() | |
| @abstractmethod | |
| def bar(self) -> None: | |
| pass | |
| [builtins fixtures/classmethod.pyi] | |
| [case testClassMethodSubclassing] | |
| class A: | |
| @classmethod | |
| def f(cls) -> None: pass | |
| def g(self) -> None: pass | |
| class B(A): | |
| def f(self) -> None: pass # Fail | |
| @classmethod | |
| def g(cls) -> None: pass | |
| class C(A): | |
| @staticmethod | |
| def f() -> None: pass | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| main:8: error: Signature of "f" incompatible with supertype "A" | |
| main:8: note: Superclass: | |
| main:8: note: @classmethod | |
| main:8: note: def f(cls) -> None | |
| main:8: note: Subclass: | |
| main:8: note: def f(self) -> None | |
| [case testClassMethodAndStaticMethod] | |
| class C: | |
| @classmethod # E: Cannot have both classmethod and staticmethod | |
| @staticmethod | |
| def foo(cls) -> None: pass | |
| [builtins fixtures/classmethod.pyi] | |
| -- Properties | |
| -- ---------- | |
| [case testAccessingReadOnlyProperty] | |
| import typing | |
| class A: | |
| @property | |
| def f(self) -> str: pass | |
| a = A() | |
| reveal_type(a.f) # N: Revealed type is "builtins.str" | |
| [builtins fixtures/property.pyi] | |
| [case testAssigningToReadOnlyProperty] | |
| import typing | |
| class A: | |
| @property | |
| def f(self) -> str: pass | |
| A().f = '' # E: Property "f" defined in "A" is read-only | |
| [builtins fixtures/property.pyi] | |
| [case testAssigningToInheritedReadOnlyProperty] | |
| class A: | |
| @property | |
| def f(self) -> str: pass | |
| class B(A): pass | |
| class C(A): | |
| @property | |
| def f(self) -> str: pass | |
| A().f = '' # E: Property "f" defined in "A" is read-only | |
| B().f = '' # E: Property "f" defined in "A" is read-only | |
| C().f = '' # E: Property "f" defined in "C" is read-only | |
| [builtins fixtures/property.pyi] | |
| [case testPropertyGetterBody] | |
| import typing | |
| class A: | |
| @property | |
| def f(self) -> str: | |
| self.x = 1 | |
| self.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| return '' | |
| [builtins fixtures/property.pyi] | |
| [case testPropertyNameIsChecked] | |
| class A: | |
| @property | |
| def f(self) -> str: ... | |
| @not_f.setter # E: Only supported top decorators are "@f.setter" and "@f.deleter" | |
| def f(self, val: str) -> None: ... | |
| a = A() | |
| reveal_type(a.f) # N: Revealed type is "builtins.str" | |
| a.f = '' # E: Property "f" defined in "A" is read-only | |
| class B: | |
| @property | |
| def f(self) -> str: ... | |
| @not_f.deleter # E: Only supported top decorators are "@f.setter" and "@f.deleter" | |
| def f(self) -> None: ... | |
| class C: | |
| @property | |
| def f(self) -> str: ... | |
| @not_f.setter # E: Only supported top decorators are "@f.setter" and "@f.deleter" | |
| def f(self, val: str) -> None: ... | |
| @not_f.deleter # E: Only supported top decorators are "@f.setter" and "@f.deleter" | |
| def f(self) -> None: ... | |
| [builtins fixtures/property.pyi] | |
| [case testPropertyAttributeIsChecked] | |
| class A: | |
| @property | |
| def f(self) -> str: ... | |
| @f.unknown # E: Only supported top decorators are "@f.setter" and "@f.deleter" | |
| def f(self, val: str) -> None: ... | |
| @f.bad.setter # E: Only supported top decorators are "@f.setter" and "@f.deleter" | |
| def f(self, val: str) -> None: ... | |
| @f # E: Only supported top decorators are "@f.setter" and "@f.deleter" | |
| def f(self, val: str) -> None: ... | |
| @int # E: Only supported top decorators are "@f.setter" and "@f.deleter" | |
| def f(self, val: str) -> None: ... | |
| [builtins fixtures/property.pyi] | |
| [case testPropertyNameAndAttributeIsCheckedPretty] | |
| # flags: --pretty | |
| class A: | |
| @property | |
| def f(self) -> str: ... | |
| @not_f.setter | |
| def f(self, val: str) -> None: ... | |
| @not_f.deleter | |
| def f(self) -> None: ... | |
| class B: | |
| @property | |
| def f(self) -> str: ... | |
| @f.unknown | |
| def f(self, val: str) -> None: ... | |
| [builtins fixtures/property.pyi] | |
| [out] | |
| main:5: error: Only supported top decorators are "@f.setter" and "@f.deleter" | |
| @not_f.setter | |
| ^~~~~~~~~~~~ | |
| main:7: error: Only supported top decorators are "@f.setter" and "@f.deleter" | |
| @not_f.deleter | |
| ^~~~~~~~~~~~~ | |
| main:13: error: Only supported top decorators are "@f.setter" and "@f.deleter" | |
| @f.unknown | |
| ^~~~~~~~~ | |
| [case testPropertyGetterDecoratorIsRejected] | |
| class A: | |
| @property | |
| def f(self) -> str: ... | |
| @f.getter # E: Only supported top decorators are "@f.setter" and "@f.deleter" | |
| def f(self, val: str) -> None: ... | |
| [builtins fixtures/property.pyi] | |
| [case testDynamicallyTypedProperty] | |
| import typing | |
| class A: | |
| @property | |
| def f(self): pass | |
| a = A() | |
| a.f.xx | |
| a.f = '' # E: Property "f" defined in "A" is read-only | |
| [builtins fixtures/property.pyi] | |
| [case testPropertyWithSetter] | |
| import typing | |
| class A: | |
| @property | |
| def f(self) -> int: | |
| return 1 | |
| @f.setter | |
| def f(self, x: int) -> None: | |
| pass | |
| a = A() | |
| a.f = a.f | |
| a.f.x # E: "int" has no attribute "x" | |
| a.f = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| a.f = 1 | |
| reveal_type(a.f) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/property.pyi] | |
| [case testPropertyWithDeleterButNoSetter] | |
| import typing | |
| class A: | |
| @property | |
| def f(self) -> int: | |
| return 1 | |
| @f.deleter | |
| def f(self, x) -> None: | |
| pass | |
| a = A() | |
| a.f = a.f # E: Property "f" defined in "A" is read-only | |
| a.f.x # E: "int" has no attribute "x" | |
| [builtins fixtures/property.pyi] | |
| -- Descriptors | |
| -- ----------- | |
| [case testAccessingNonDataDescriptor] | |
| from typing import Any | |
| class D: | |
| def __get__(self, inst: Any, own: Any) -> str: return 's' | |
| class A: | |
| f = D() | |
| a = A() | |
| reveal_type(a.f) # N: Revealed type is "builtins.str" | |
| [case testSettingNonDataDescriptor] | |
| from typing import Any | |
| class D: | |
| def __get__(self, inst: Any, own: Any) -> str: return 's' | |
| class A: | |
| f = D() | |
| a = A() | |
| a.f = 'foo' | |
| a.f = D() # E: Incompatible types in assignment (expression has type "D", variable has type "str") | |
| [case testSettingDataDescriptor] | |
| from typing import Any | |
| class D: | |
| def __get__(self, inst: Any, own: Any) -> str: return 's' | |
| def __set__(self, inst: Any, value: str) -> None: pass | |
| class A: | |
| f = D() | |
| a = A() | |
| a.f = '' | |
| a.f = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") | |
| [case testSettingDescriptorWithOverloadedDunderSet1] | |
| from typing import Any, overload, Union | |
| class D: | |
| @overload | |
| def __set__(self, inst: Any, value: str) -> None: pass | |
| @overload | |
| def __set__(self, inst: Any, value: int) -> None: pass | |
| def __set__(self, inst: Any, value: Union[str, int]) -> None: pass | |
| class A: | |
| f = D() | |
| a = A() | |
| a.f = '' | |
| a.f = 1 | |
| a.f = 1.5 # E | |
| [out] | |
| main:13: error: No overload variant of "__set__" of "D" matches argument types "A", "float" | |
| main:13: note: Possible overload variants: | |
| main:13: note: def __set__(self, inst: Any, value: str) -> None | |
| main:13: note: def __set__(self, inst: Any, value: int) -> None | |
| [case testSettingDescriptorWithOverloadedDunderSet2] | |
| from typing import overload, Union | |
| class D: | |
| @overload | |
| def __set__(self, inst: A, value: str) -> None: pass | |
| @overload | |
| def __set__(self, inst: B, value: int) -> None: pass | |
| def __set__(self, inst: Union[A, B], value: Union[str, int]) -> None: pass | |
| class A: | |
| f = D() | |
| class B: | |
| f = D() | |
| a = A() | |
| b = B() | |
| a.f = '' | |
| b.f = 1 | |
| a.f = 1 # E | |
| b.f = '' # E | |
| [out] | |
| main:16: error: No overload variant of "__set__" of "D" matches argument types "A", "int" | |
| main:16: note: Possible overload variants: | |
| main:16: note: def __set__(self, inst: A, value: str) -> None | |
| main:16: note: def __set__(self, inst: B, value: int) -> None | |
| main:17: error: No overload variant of "__set__" of "D" matches argument types "B", "str" | |
| main:17: note: Possible overload variants: | |
| main:17: note: def __set__(self, inst: A, value: str) -> None | |
| main:17: note: def __set__(self, inst: B, value: int) -> None | |
| [case testReadingDescriptorWithoutDunderGet] | |
| from typing import Union, Any | |
| class D: | |
| def __set__(self, inst: Any, value: str) -> None: pass | |
| class A: | |
| f = D() | |
| def __init__(self): self.f = 's' | |
| a = A() | |
| reveal_type(a.f) # N: Revealed type is "__main__.D" | |
| [case testAccessingDescriptorFromClass] | |
| from d import D, Base | |
| class A(Base): | |
| f = D() | |
| reveal_type(A.f) # N: Revealed type is "d.D" | |
| reveal_type(A().f) # N: Revealed type is "builtins.str" | |
| [file d.pyi] | |
| from typing import TypeVar, Type, Generic, overload | |
| class Base: pass | |
| class D: | |
| def __init__(self) -> None: pass | |
| @overload | |
| def __get__(self, inst: None, own: Type[Base]) -> D: pass | |
| @overload | |
| def __get__(self, inst: Base, own: Type[Base]) -> str: pass | |
| [builtins fixtures/bool.pyi] | |
| [case testAccessingDescriptorFromClassWrongBase] | |
| from d import D, Base | |
| class A: | |
| f = D() | |
| reveal_type(A.f) | |
| reveal_type(A().f) | |
| [file d.pyi] | |
| from typing import TypeVar, Type, Generic, overload | |
| class Base: pass | |
| class D: | |
| def __init__(self) -> None: pass | |
| @overload | |
| def __get__(self, inst: None, own: Type[Base]) -> D: pass | |
| @overload | |
| def __get__(self, inst: Base, own: Type[Base]) -> str: pass | |
| [builtins fixtures/bool.pyi] | |
| [out] | |
| main:4: error: Argument 2 to "__get__" of "D" has incompatible type "type[A]"; expected "type[Base]" | |
| main:4: note: Revealed type is "d.D" | |
| main:5: error: No overload variant of "__get__" of "D" matches argument types "A", "type[A]" | |
| main:5: note: Possible overload variants: | |
| main:5: note: def __get__(self, inst: None, own: type[Base]) -> D | |
| main:5: note: def __get__(self, inst: Base, own: type[Base]) -> str | |
| main:5: note: Revealed type is "Any" | |
| [case testAccessingGenericNonDataDescriptor] | |
| from typing import TypeVar, Type, Generic, Any | |
| V = TypeVar('V') | |
| class D(Generic[V]): | |
| def __init__(self, v: V) -> None: self.v = v | |
| def __get__(self, inst: Any, own: Type) -> V: return self.v | |
| class A: | |
| f = D(10) | |
| g = D('10') | |
| a = A() | |
| reveal_type(a.f) # N: Revealed type is "builtins.int" | |
| reveal_type(a.g) # N: Revealed type is "builtins.str" | |
| [case testSettingGenericDataDescriptor] | |
| from typing import TypeVar, Type, Generic, Any | |
| V = TypeVar('V') | |
| class D(Generic[V]): | |
| def __init__(self, v: V) -> None: self.v = v | |
| def __get__(self, inst: Any, own: Type) -> V: return self.v | |
| def __set__(self, inst: Any, v: V) -> None: pass | |
| class A: | |
| f = D(10) | |
| g = D('10') | |
| a = A() | |
| a.f = 1 | |
| a.f = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| a.g = '' | |
| a.g = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") | |
| [case testAccessingGenericDescriptorFromClass] | |
| from d import D | |
| class A: | |
| f = D(10) # type: D[A, int] | |
| g = D('10') # type: D[A, str] | |
| reveal_type(A.f) # N: Revealed type is "d.D[__main__.A, builtins.int]" | |
| reveal_type(A.g) # N: Revealed type is "d.D[__main__.A, builtins.str]" | |
| reveal_type(A().f) # N: Revealed type is "builtins.int" | |
| reveal_type(A().g) # N: Revealed type is "builtins.str" | |
| [file d.pyi] | |
| from typing import TypeVar, Type, Generic, overload | |
| T = TypeVar('T') | |
| V = TypeVar('V') | |
| class D(Generic[T, V]): | |
| def __init__(self, v: V) -> None: pass | |
| @overload | |
| def __get__(self, inst: None, own: Type[T]) -> 'D[T, V]': pass | |
| @overload | |
| def __get__(self, inst: T, own: Type[T]) -> V: pass | |
| [builtins fixtures/bool.pyi] | |
| [case testAccessingGenericDescriptorFromInferredClass] | |
| from typing import Type | |
| from d import D | |
| class A: | |
| f = D(10) # type: D[A, int] | |
| g = D('10') # type: D[A, str] | |
| def f(some_class: Type[A]): | |
| reveal_type(some_class.f) | |
| reveal_type(some_class.g) | |
| [file d.pyi] | |
| from typing import TypeVar, Type, Generic, overload | |
| T = TypeVar('T') | |
| V = TypeVar('V') | |
| class D(Generic[T, V]): | |
| def __init__(self, v: V) -> None: pass | |
| @overload | |
| def __get__(self, inst: None, own: Type[T]) -> 'D[T, V]': pass | |
| @overload | |
| def __get__(self, inst: T, own: Type[T]) -> V: pass | |
| [builtins fixtures/bool.pyi] | |
| [out] | |
| main:7: note: Revealed type is "d.D[__main__.A, builtins.int]" | |
| main:8: note: Revealed type is "d.D[__main__.A, builtins.str]" | |
| [case testAccessingGenericDescriptorFromClassBadOverload] | |
| from d import D | |
| class A: | |
| f = D(10) # type: D[A, int] | |
| reveal_type(A.f) | |
| [file d.pyi] | |
| from typing import TypeVar, Type, Generic, overload | |
| T = TypeVar('T') | |
| V = TypeVar('V') | |
| class D(Generic[T, V]): | |
| def __init__(self, v: V) -> None: pass | |
| @overload | |
| def __get__(self, inst: None, own: None) -> 'D[T, V]': pass | |
| @overload | |
| def __get__(self, inst: T, own: Type[T]) -> V: pass | |
| [builtins fixtures/bool.pyi] | |
| [out] | |
| main:4: error: No overload variant of "__get__" of "D" matches argument types "None", "type[A]" | |
| main:4: note: Possible overload variants: | |
| main:4: note: def __get__(self, inst: None, own: None) -> D[A, int] | |
| main:4: note: def __get__(self, inst: A, own: type[A]) -> int | |
| main:4: note: Revealed type is "Any" | |
| [case testAccessingNonDataDescriptorSubclass] | |
| from typing import Any | |
| class C: | |
| def __get__(self, inst: Any, own: Any) -> str: return 's' | |
| class D(C): pass | |
| class A: | |
| f = D() | |
| a = A() | |
| reveal_type(a.f) # N: Revealed type is "builtins.str" | |
| [case testSettingDataDescriptorSubclass] | |
| from typing import Any | |
| class C: | |
| def __get__(self, inst: Any, own: Any) -> str: return 's' | |
| def __set__(self, inst: Any, v: str) -> None: pass | |
| class D(C): pass | |
| class A: | |
| f = D() | |
| a = A() | |
| a.f = '' | |
| a.f = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") | |
| [case testReadingDescriptorSubclassWithoutDunderGet] | |
| from typing import Union, Any | |
| class C: | |
| def __set__(self, inst: Any, v: str) -> None: pass | |
| class D(C): pass | |
| class A: | |
| f = D() | |
| def __init__(self): self.f = 's' | |
| a = A() | |
| reveal_type(a.f) # N: Revealed type is "__main__.D" | |
| [case testAccessingGenericNonDataDescriptorSubclass] | |
| from typing import TypeVar, Type, Generic, Any | |
| V = TypeVar('V') | |
| class C(Generic[V]): | |
| def __init__(self, v: V) -> None: self.v = v | |
| def __get__(self, inst: Any, own: Type) -> V: return self.v | |
| class D(C[V], Generic[V]): pass | |
| class A: | |
| f = D(10) | |
| g = D('10') | |
| a = A() | |
| reveal_type(a.f) # N: Revealed type is "builtins.int" | |
| reveal_type(a.g) # N: Revealed type is "builtins.str" | |
| [case testSettingGenericDataDescriptorSubclass] | |
| from typing import TypeVar, Type, Generic | |
| T = TypeVar('T') | |
| V = TypeVar('V') | |
| class C(Generic[T, V]): | |
| def __init__(self, v: V) -> None: self.v = v | |
| def __get__(self, inst: T, own: Type[T]) -> V: return self.v | |
| def __set__(self, inst: T, v: V) -> None: pass | |
| class D(C[T, V], Generic[T, V]): pass | |
| class A: | |
| f = D(10) # type: D[A, int] | |
| g = D('10') # type: D[A, str] | |
| a = A() | |
| a.f = 1 | |
| a.f = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| a.g = '' | |
| a.g = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") | |
| [case testSetDescriptorOnClass] | |
| from typing import TypeVar, Type, Generic | |
| T = TypeVar('T') | |
| V = TypeVar('V') | |
| class D(Generic[T, V]): | |
| def __init__(self, v: V) -> None: self.v = v | |
| def __get__(self, inst: T, own: Type[T]) -> V: return self.v | |
| def __set__(self, inst: T, v: V) -> None: pass | |
| class A: | |
| f = D(10) # type: D[A, int] | |
| A.f = D(20) | |
| A.f = D('some string') # E: Argument 1 to "D" has incompatible type "str"; expected "int" | |
| [case testSetDescriptorOnInferredClass] | |
| from typing import TypeVar, Type, Generic, Any | |
| V = TypeVar('V') | |
| class D(Generic[V]): | |
| def __init__(self, v: V) -> None: self.v = v | |
| def __get__(self, inst: Any, own: Type) -> V: return self.v | |
| def __set__(self, inst: Any, v: V) -> None: pass | |
| class A: | |
| f = D(10) | |
| def f(some_class: Type[A]): | |
| A.f = D(20) | |
| A.f = D('some string') | |
| [out] | |
| main:11: error: Argument 1 to "D" has incompatible type "str"; expected "int" | |
| [case testDescriptorUncallableDunderSet] | |
| class D: | |
| __set__ = 's' | |
| class A: | |
| f = D() | |
| A().f = 'x' # E: __main__.D.__set__ is not callable | |
| [case testDescriptorDunderSetTooFewArgs] | |
| class D: | |
| def __set__(self, inst): pass | |
| class A: | |
| f = D() | |
| A().f = 'x' # E: Too many arguments for "__set__" | |
| [case testDescriptorDunderSetTooManyArgs] | |
| class D: | |
| def __set__(self, inst, v, other): pass | |
| class A: | |
| f = D() | |
| A().f = 'x' # E: Too few arguments for "__set__" | |
| [case testDescriptorDunderSetWrongArgTypes] | |
| class D: | |
| def __set__(self, inst: str, v:str) -> None: pass | |
| class A: | |
| f = D() | |
| A().f = 'x' # E: Argument 1 to "__set__" of "D" has incompatible type "A"; expected "str" | |
| [case testDescriptorUncallableDunderGet] | |
| class D: | |
| __get__ = 's' | |
| class A: | |
| f = D() | |
| A().f # E: __main__.D.__get__ is not callable | |
| [case testDescriptorDunderGetTooFewArgs] | |
| class D: | |
| def __get__(self, inst): pass | |
| class A: | |
| f = D() | |
| A().f # E: Too many arguments for "__get__" | |
| [case testDescriptorDunderGetTooManyArgs] | |
| class D: | |
| def __get__(self, inst, own, other): pass | |
| class A: | |
| f = D() | |
| A().f = 'x' # E: Too few arguments for "__get__" | |
| [case testDescriptorDunderGetWrongArgTypeForInstance] | |
| from typing import Any | |
| class D: | |
| def __get__(self, inst: str, own: Any) -> Any: pass | |
| class A: | |
| f = D() | |
| A().f # E: Argument 1 to "__get__" of "D" has incompatible type "A"; expected "str" | |
| [case testDescriptorDunderGetWrongArgTypeForOwner] | |
| from typing import Any | |
| class D: | |
| def __get__(self, inst: Any, own: str) -> Any: pass | |
| class A: | |
| f = D() | |
| A().f # E: Argument 2 to "__get__" of "D" has incompatible type "type[A]"; expected "str" | |
| [case testDescriptorGetSetDifferentTypes] | |
| from typing import Any | |
| class D: | |
| def __get__(self, inst: Any, own: Any) -> str: return 's' | |
| def __set__(self, inst: Any, v: int) -> None: pass | |
| class A: | |
| f = D() | |
| a = A() | |
| a.f = 1 | |
| reveal_type(a.f) # N: Revealed type is "builtins.str" | |
| [case testDescriptorGetUnion] | |
| from typing import Any, Union | |
| class String: | |
| def __get__(self, inst: Any, owner: Any) -> str: | |
| return '' | |
| class A: | |
| attr: str | |
| class B: | |
| attr = String() | |
| def foo(x: Union[A, B]) -> None: | |
| reveal_type(x.attr) # N: Revealed type is "builtins.str" | |
| [case testDescriptorGetUnionRestricted] | |
| from typing import Any, Union | |
| class getter: | |
| def __get__(self, instance: X1, owner: Any) -> str: ... | |
| class X1: | |
| prop = getter() | |
| class X2: | |
| prop: str | |
| def foo(x: Union[X1, X2]) -> None: | |
| reveal_type(x.prop) # N: Revealed type is "builtins.str" | |
| [case testDescriptorGetUnionType] | |
| from typing import Any, Union, Type, overload | |
| class getter: | |
| @overload | |
| def __get__(self, instance: None, owner: Any) -> getter: ... | |
| @overload | |
| def __get__(self, instance: object, owner: Any) -> str: ... | |
| def __get__(self, instance, owner): | |
| ... | |
| class X1: | |
| prop = getter() | |
| class X2: | |
| prop = getter() | |
| def foo(x: Type[Union[X1, X2]]) -> None: | |
| reveal_type(x.prop) # N: Revealed type is "__main__.getter" | |
| -- _promote decorators | |
| -- ------------------- | |
| [case testSimpleDucktypeDecorator] | |
| from typing import _promote | |
| class A: pass | |
| @_promote(A) | |
| class B: pass | |
| a: A | |
| b: B | |
| if int(): | |
| b = a # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| a = b | |
| [typing fixtures/typing-medium.pyi] | |
| [case testDucktypeTransitivityDecorator] | |
| from typing import _promote | |
| class A: pass | |
| @_promote(A) | |
| class B: pass | |
| @_promote(B) | |
| class C: pass | |
| a: A | |
| c: C | |
| if int(): | |
| c = a # E: Incompatible types in assignment (expression has type "A", variable has type "C") | |
| a = c | |
| [typing fixtures/typing-medium.pyi] | |
| -- Hard coded type promotions | |
| -- -------------------------- | |
| [case testHardCodedTypePromotions] | |
| import typing | |
| def f(x: float) -> None: pass | |
| def g(x: complex) -> None: pass | |
| f(1) | |
| g(1) | |
| g(1.1) | |
| [builtins fixtures/complex.pyi] | |
| -- Operator methods | |
| -- ---------------- | |
| [case testOperatorMethodOverrideIntroducingOverloading] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload | |
| class A: | |
| def __add__(self, x: int) -> int: pass | |
| class B(A): | |
| @overload # Fail | |
| def __add__(self, x: int) -> int: pass | |
| @overload | |
| def __add__(self, x: str) -> str: pass | |
| [out] | |
| tmp/foo.pyi:5: error: Signature of "__add__" incompatible with supertype "A" | |
| tmp/foo.pyi:5: note: Superclass: | |
| tmp/foo.pyi:5: note: def __add__(self, int, /) -> int | |
| tmp/foo.pyi:5: note: Subclass: | |
| tmp/foo.pyi:5: note: @overload | |
| tmp/foo.pyi:5: note: def __add__(self, int, /) -> int | |
| tmp/foo.pyi:5: note: @overload | |
| tmp/foo.pyi:5: note: def __add__(self, str, /) -> str | |
| tmp/foo.pyi:5: note: Overloaded operator methods can't have wider argument types in overrides | |
| [case testOperatorMethodOverrideWideningArgumentType] | |
| import typing | |
| class A: | |
| def __add__(self, x: int) -> int: pass | |
| class B(A): | |
| def __add__(self, x: object) -> int: pass | |
| [out] | |
| [case testOperatorMethodOverrideNarrowingReturnType] | |
| import typing | |
| class A: | |
| def __add__(self, x: int) -> 'A': pass | |
| class B(A): | |
| def __add__(self, x: int) -> 'B': pass | |
| [case testOperatorMethodOverrideWithDynamicallyTyped] | |
| import typing | |
| class A: | |
| def __add__(self, x: int) -> 'A': pass | |
| class B(A): | |
| def __add__(self, x): pass | |
| [case testOperatorMethodAgainstSameType] | |
| class A: | |
| def __add__(self, x: int) -> 'A': | |
| if isinstance(x, int): | |
| return A() | |
| else: | |
| return NotImplemented | |
| def __radd__(self, x: 'A') -> 'A': | |
| if isinstance(x, A): | |
| return A() | |
| else: | |
| return NotImplemented | |
| class B(A): pass | |
| # Note: This is a runtime error. If we run x.__add__(y) | |
| # where x and y are *not* the same type, Python will not try | |
| # calling __radd__. | |
| A() + A() # E: Unsupported operand types for + ("A" and "A") | |
| # Here, Python *will* call __radd__(...) | |
| reveal_type(B() + A()) # N: Revealed type is "__main__.A" | |
| reveal_type(A() + B()) # N: Revealed type is "__main__.A" | |
| [builtins fixtures/isinstance.pyi] | |
| [case testBinaryOperatorMethodPositionalArgumentsOnly] | |
| class A: | |
| def __add__(self, other: int) -> int: pass | |
| def __iadd__(self, other: int) -> int: pass | |
| def __radd__(self, other: int) -> int: pass | |
| reveal_type(A.__add__) # N: Revealed type is "def (__main__.A, builtins.int) -> builtins.int" | |
| reveal_type(A.__iadd__) # N: Revealed type is "def (__main__.A, builtins.int) -> builtins.int" | |
| reveal_type(A.__radd__) # N: Revealed type is "def (__main__.A, builtins.int) -> builtins.int" | |
| [case testOperatorMethodOverrideWithIdenticalOverloadedType] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload | |
| class A: | |
| @overload | |
| def __add__(self, x: int) -> 'A': pass | |
| @overload | |
| def __add__(self, x: str) -> 'A': pass | |
| class B(A): | |
| @overload | |
| def __add__(self, x: int) -> 'A': pass | |
| @overload | |
| def __add__(self, x: str) -> 'A': pass | |
| [case testOverloadedOperatorMethodOverrideWithDynamicallyTypedMethod] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload, Any | |
| class A: | |
| @overload | |
| def __add__(self, x: int) -> 'A': pass | |
| @overload | |
| def __add__(self, x: str) -> 'A': pass | |
| class B(A): | |
| def __add__(self, x): pass | |
| class C(A): | |
| def __add__(self, x: Any) -> A: pass | |
| [case testOverloadedOperatorMethodOverrideWithNewItem] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload, Any | |
| class A: | |
| @overload | |
| def __add__(self, x: int) -> 'A': pass | |
| @overload | |
| def __add__(self, x: str) -> 'A': pass | |
| class B(A): | |
| @overload # Fail | |
| def __add__(self, x: int) -> A: pass | |
| @overload | |
| def __add__(self, x: str) -> A: pass | |
| @overload | |
| def __add__(self, x: type) -> A: pass | |
| [out] | |
| tmp/foo.pyi:8: error: Signature of "__add__" incompatible with supertype "A" | |
| tmp/foo.pyi:8: note: Superclass: | |
| tmp/foo.pyi:8: note: @overload | |
| tmp/foo.pyi:8: note: def __add__(self, int, /) -> A | |
| tmp/foo.pyi:8: note: @overload | |
| tmp/foo.pyi:8: note: def __add__(self, str, /) -> A | |
| tmp/foo.pyi:8: note: Subclass: | |
| tmp/foo.pyi:8: note: @overload | |
| tmp/foo.pyi:8: note: def __add__(self, int, /) -> A | |
| tmp/foo.pyi:8: note: @overload | |
| tmp/foo.pyi:8: note: def __add__(self, str, /) -> A | |
| tmp/foo.pyi:8: note: @overload | |
| tmp/foo.pyi:8: note: def __add__(self, type, /) -> A | |
| tmp/foo.pyi:8: note: Overloaded operator methods can't have wider argument types in overrides | |
| [case testOverloadedOperatorMethodOverrideWithSwitchedItemOrder] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload, Any | |
| class A: | |
| @overload | |
| def __add__(self, x: 'B') -> 'B': pass | |
| @overload | |
| def __add__(self, x: 'A') -> 'A': pass | |
| class B(A): | |
| @overload | |
| def __add__(self, x: 'A') -> 'A': pass | |
| @overload | |
| def __add__(self, x: 'B') -> 'B': pass | |
| class C(A): | |
| @overload | |
| def __add__(self, x: 'B') -> 'B': pass | |
| @overload | |
| def __add__(self, x: 'A') -> 'A': pass | |
| [out] | |
| tmp/foo.pyi:8: error: Signature of "__add__" incompatible with supertype "A" | |
| tmp/foo.pyi:8: note: Overload variants must be defined in the same order as they are in "A" | |
| tmp/foo.pyi:11: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader | |
| [case testReverseOperatorMethodArgumentType] | |
| from typing import Any | |
| class A: pass | |
| class B: | |
| def __radd__(self, x: A) -> int: pass # Error | |
| class C: | |
| def __radd__(self, x: A) -> Any: pass | |
| class D: | |
| def __radd__(self, x: A) -> object: pass | |
| [out] | |
| [case testReverseOperatorMethodArgumentType2] | |
| from typing import Any, Tuple, Callable | |
| class A: | |
| def __radd__(self, x: Tuple[int, str]) -> int: pass | |
| class B: | |
| def __radd__(self, x: Callable[[], int]) -> int: pass | |
| class C: | |
| def __radd__(self, x: Any) -> int: pass | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testReverseOperatorMethodInvalid] | |
| from foo import * | |
| [file foo.pyi] | |
| class A: ... | |
| class B: | |
| def __rmul__(self) -> A: ... | |
| class C: | |
| def __radd__(self, other, oops) -> int: ... | |
| [out] | |
| tmp/foo.pyi:3: error: Invalid signature "Callable[[B], A]" | |
| tmp/foo.pyi:5: error: Invalid signature "Callable[[C, Any, Any], int]" | |
| [case testReverseOperatorOrderingCase1] | |
| class A: | |
| def __radd__(self, other: 'A') -> int: ... | |
| # Note: Python only tries calling __add__ and never __radd__, even though it's present | |
| A() + A() # E: Unsupported left operand type for + ("A") | |
| [case testReverseOperatorOrderingCase2] | |
| class A: | |
| def __lt__(self, other: object) -> bool: ... | |
| # Not all operators have the above shortcut though. | |
| reveal_type(A() > A()) # N: Revealed type is "builtins.bool" | |
| reveal_type(A() < A()) # N: Revealed type is "builtins.bool" | |
| [builtins fixtures/bool.pyi] | |
| [case testReverseOperatorOrderingCase3] | |
| class A: | |
| def __add__(self, other: B) -> int: ... | |
| class B: | |
| def __radd__(self, other: A) -> str: ... # E: Signatures of "__radd__" of "B" and "__add__" of "A" are unsafely overlapping | |
| # Normally, we try calling __add__ before __radd__ | |
| reveal_type(A() + B()) # N: Revealed type is "builtins.int" | |
| [case testReverseOperatorOrderingCase4] | |
| class A: | |
| def __add__(self, other: B) -> int: ... | |
| class B(A): | |
| def __radd__(self, other: A) -> str: ... # E: Signatures of "__radd__" of "B" and "__add__" of "A" are unsafely overlapping | |
| # However, if B is a subtype of A, we try calling __radd__ first. | |
| reveal_type(A() + B()) # N: Revealed type is "builtins.str" | |
| [case testReverseOperatorOrderingCase5] | |
| # Note: these two methods are not unsafely overlapping because __radd__ is | |
| # never called -- see case 1. | |
| class A: | |
| def __add__(self, other: B) -> int: ... | |
| def __radd__(self, other: A) -> str: ... | |
| class B(A): pass | |
| # ...but only if B specifically defines a new __radd__. | |
| reveal_type(A() + B()) # N: Revealed type is "builtins.int" | |
| [case testReverseOperatorOrderingCase6] | |
| class A: | |
| def __add__(self, other: B) -> int: ... | |
| def __radd__(self, other: A) -> str: ... | |
| class B(A): | |
| # Although A.__radd__ can never be called, B.__radd__ *can* be -- so the | |
| # unsafe overlap check kicks in here. | |
| def __radd__(self, other: A) -> str: ... # E: Signatures of "__radd__" of "B" and "__add__" of "A" are unsafely overlapping | |
| reveal_type(A() + B()) # N: Revealed type is "builtins.str" | |
| [case testReverseOperatorOrderingCase7] | |
| class A: | |
| def __add__(self, other: B) -> int: ... | |
| def __radd__(self, other: A) -> str: ... | |
| class B(A): | |
| def __radd__(self, other: A) -> str: ... # E: Signatures of "__radd__" of "B" and "__add__" of "A" are unsafely overlapping | |
| class C(B): pass | |
| # A refinement made by a parent also counts | |
| reveal_type(A() + C()) # N: Revealed type is "builtins.str" | |
| [case testReverseOperatorWithOverloads1] | |
| from typing import overload | |
| class A: | |
| def __add__(self, other: C) -> int: ... | |
| class B: | |
| def __add__(self, other: C) -> int: ... | |
| class C: | |
| @overload | |
| def __radd__(self, other: A) -> str: ... # E: Signatures of "__radd__" of "C" and "__add__" of "A" are unsafely overlapping | |
| @overload | |
| def __radd__(self, other: B) -> str: ... # E: Signatures of "__radd__" of "C" and "__add__" of "B" are unsafely overlapping | |
| def __radd__(self, other): pass | |
| reveal_type(A() + C()) # N: Revealed type is "builtins.int" | |
| reveal_type(B() + C()) # N: Revealed type is "builtins.int" | |
| [case testReverseOperatorWithOverloads2] | |
| from typing import overload, Union | |
| class Num1: | |
| def __add__(self, other: Num1) -> Num1: ... | |
| def __radd__(self, other: Num1) -> Num1: ... | |
| class Num2(Num1): | |
| @overload | |
| def __add__(self, other: Num2) -> Num2: ... | |
| @overload | |
| def __add__(self, other: Num1) -> Num2: ... | |
| def __add__(self, other): pass | |
| @overload | |
| def __radd__(self, other: Num2) -> Num2: ... | |
| @overload | |
| def __radd__(self, other: Num1) -> Num2: ... | |
| def __radd__(self, other): pass | |
| class Num3(Num1): | |
| def __add__(self, other: Union[Num1, Num3]) -> Num3: ... | |
| def __radd__(self, other: Union[Num1, Num3]) -> Num3: ... | |
| reveal_type(Num1() + Num2()) # N: Revealed type is "__main__.Num2" | |
| reveal_type(Num2() + Num1()) # N: Revealed type is "__main__.Num2" | |
| reveal_type(Num1() + Num3()) # N: Revealed type is "__main__.Num3" | |
| reveal_type(Num3() + Num1()) # N: Revealed type is "__main__.Num3" | |
| reveal_type(Num2() + Num3()) # N: Revealed type is "__main__.Num2" | |
| reveal_type(Num3() + Num2()) # N: Revealed type is "__main__.Num3" | |
| [case testReverseOperatorWithOverloads3] | |
| from typing import Union, overload | |
| class A: | |
| def __mul__(self, value: A, /) -> A: ... | |
| def __rmul__(self, value: A, /) -> A: ... | |
| class B: | |
| @overload | |
| def __mul__(self, other: B, /) -> B: ... | |
| @overload | |
| def __mul__(self, other: A, /) -> str: ... | |
| def __mul__(self, other: Union[B, A], /) -> Union[B, str]: pass | |
| @overload | |
| def __rmul__(self, other: B, /) -> B: ... | |
| @overload | |
| def __rmul__(self, other: A, /) -> str: ... | |
| def __rmul__(self, other: Union[B, A], /) -> Union[B, str]: pass | |
| [case testReverseOperatorWithOverloadsNested] | |
| from typing import Union, overload | |
| class A: | |
| def __mul__(self, value: A, /) -> A: ... | |
| def __rmul__(self, value: A, /) -> A: ... | |
| class B: | |
| @overload | |
| def __mul__(self, other: B, /) -> B: ... | |
| @overload | |
| def __mul__(self, other: A, /) -> str: ... | |
| def __mul__(self, other: Union[B, A], /) -> Union[B, str]: pass | |
| @overload | |
| def __rmul__(self, other: B, /) -> B: ... | |
| @overload | |
| def __rmul__(self, other: A, /) -> str: ... | |
| def __rmul__(self, other: Union[B, A], /) -> Union[B, str]: | |
| class A1: | |
| def __add__(self, other: C1) -> int: ... | |
| class B1: | |
| def __add__(self, other: C1) -> int: ... | |
| class C1: | |
| @overload | |
| def __radd__(self, other: A1) -> str: ... # E: Signatures of "__radd__" of "C1" and "__add__" of "A1" are unsafely overlapping | |
| @overload | |
| def __radd__(self, other: B1) -> str: ... # E: Signatures of "__radd__" of "C1" and "__add__" of "B1" are unsafely overlapping | |
| def __radd__(self, other): pass | |
| return "" | |
| [case testDivReverseOperator] | |
| # No error: __div__ has no special meaning in Python 3 | |
| class A1: | |
| def __div__(self, x: B1) -> int: ... | |
| class B1: | |
| def __rdiv__(self, x: A1) -> str: ... | |
| class A2: | |
| def __truediv__(self, x: B2) -> int: ... | |
| class B2: | |
| def __rtruediv__(self, x: A2) -> str: ... # E: Signatures of "__rtruediv__" of "B2" and "__truediv__" of "A2" are unsafely overlapping | |
| A1() / B1() # E: Unsupported left operand type for / ("A1") | |
| reveal_type(A2() / B2()) # N: Revealed type is "builtins.int" | |
| [case testReverseOperatorMethodForwardIsAny] | |
| from typing import Any | |
| def deco(f: Any) -> Any: return f | |
| class C: | |
| @deco | |
| def __add__(self, other: C) -> C: return C() | |
| def __radd__(self, other: C) -> C: return C() | |
| [out] | |
| [case testReverseOperatorMethodForwardIsAny2] | |
| from typing import Any | |
| def deco(f: Any) -> Any: return f | |
| class C: | |
| __add__ = None # type: Any | |
| def __radd__(self, other: C) -> C: return C() | |
| [out] | |
| [case testReverseOperatorMethodForwardIsAny3] | |
| from typing import Any | |
| def deco(f: Any) -> Any: return f | |
| class C: | |
| __add__ = 42 | |
| def __radd__(self, other: C) -> C: return C() | |
| [out] | |
| main:5: error: Forward operator "__add__" is not callable | |
| [case testOverloadedReverseOperatorMethodArgumentType] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload, Any | |
| class A: | |
| @overload | |
| def __radd__(self, x: 'A') -> str: pass | |
| @overload | |
| def __radd__(self, x: 'A') -> Any: pass # E: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader | |
| [out] | |
| [case testReverseOperatorMethodArgumentTypeAndOverloadedMethod] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload | |
| class A: | |
| @overload | |
| def __add__(self, x: int) -> int: pass | |
| @overload | |
| def __add__(self, x: str) -> int: pass | |
| def __radd__(self, x: 'A') -> str: pass | |
| [case testReverseOperatorStar] | |
| class B: | |
| def __radd__(*self) -> int: pass | |
| def __rsub__(*self: 'B') -> int: pass | |
| [builtins fixtures/tuple.pyi] | |
| [case testReverseOperatorTypeVar1] | |
| from typing import TypeVar | |
| T = TypeVar("T", bound='Real') | |
| class Real: | |
| def __add__(self, other: object) -> str: ... | |
| class Fraction(Real): | |
| def __radd__(self, other: T) -> T: ... # E: Signatures of "__radd__" of "Fraction" and "__add__" of "T" are unsafely overlapping | |
| # Note: When doing A + B and if B is a subtype of A, we will always call B.__radd__(A) first | |
| # and only try A.__add__(B) second if necessary. | |
| reveal_type(Real() + Fraction()) # N: Revealed type is "__main__.Real" | |
| # Note: When doing A + A, we only ever call A.__add__(A), never A.__radd__(A). | |
| reveal_type(Fraction() + Fraction()) # N: Revealed type is "builtins.str" | |
| [case testReverseOperatorTypeVar2a] | |
| from typing import TypeVar | |
| T = TypeVar("T", bound='Real') | |
| class Real: | |
| def __add__(self, other: Fraction) -> str: ... | |
| class Fraction(Real): | |
| def __radd__(self, other: T) -> T: ... # E: Signatures of "__radd__" of "Fraction" and "__add__" of "T" are unsafely overlapping | |
| reveal_type(Real() + Fraction()) # N: Revealed type is "__main__.Real" | |
| reveal_type(Fraction() + Fraction()) # N: Revealed type is "builtins.str" | |
| [case testReverseOperatorTypeVar2b] | |
| from typing import TypeVar | |
| T = TypeVar("T", "Real", "Fraction") | |
| class Real: | |
| def __add__(self, other: Fraction) -> str: ... | |
| class Fraction(Real): | |
| def __radd__(self, other: T) -> T: ... # E: Signatures of "__radd__" of "Fraction" and "__add__" of "Real" are unsafely overlapping | |
| reveal_type(Real() + Fraction()) # N: Revealed type is "__main__.Real" | |
| reveal_type(Fraction() + Fraction()) # N: Revealed type is "builtins.str" | |
| [case testReverseOperatorTypeVar3] | |
| from typing import TypeVar | |
| T = TypeVar("T", bound='Real') | |
| class Real: | |
| def __add__(self, other: FractionChild) -> str: ... | |
| class Fraction(Real): | |
| def __radd__(self, other: T) -> T: ... # E: Signatures of "__radd__" of "Fraction" and "__add__" of "T" are unsafely overlapping | |
| class FractionChild(Fraction): pass | |
| reveal_type(Real() + Fraction()) # N: Revealed type is "__main__.Real" | |
| reveal_type(FractionChild() + Fraction()) # N: Revealed type is "__main__.FractionChild" | |
| reveal_type(FractionChild() + FractionChild()) # N: Revealed type is "builtins.str" | |
| # Runtime error: we try calling __add__, it doesn't match, and we don't try __radd__ since | |
| # the LHS and the RHS are not the same. | |
| Fraction() + Fraction() # E: Unsupported operand types for + ("Fraction" and "Fraction") | |
| [case testReverseOperatorTypeType] | |
| from typing import TypeVar, Type | |
| class Real(type): | |
| def __add__(self, other: FractionChild) -> str: ... | |
| class Fraction(Real): | |
| def __radd__(self, other: Type['A']) -> Real: ... # E: Signatures of "__radd__" of "Fraction" and "__add__" of "type[A]" are unsafely overlapping | |
| class FractionChild(Fraction): pass | |
| class A(metaclass=Real): pass | |
| [case testOperatorDoubleUnionIntFloat] | |
| from typing import Union | |
| a: Union[int, float] | |
| b: int | |
| c: float | |
| reveal_type(a + a) # N: Revealed type is "builtins.int | builtins.float" | |
| reveal_type(a + b) # N: Revealed type is "builtins.int | builtins.float" | |
| reveal_type(b + a) # N: Revealed type is "builtins.int | builtins.float" | |
| reveal_type(a + c) # N: Revealed type is "builtins.float" | |
| reveal_type(c + a) # N: Revealed type is "builtins.float" | |
| [builtins fixtures/ops.pyi] | |
| [case testOperatorDoubleUnionStandardSubtyping] | |
| from typing import Union | |
| class Parent: | |
| def __add__(self, x: Parent) -> Parent: pass | |
| def __radd__(self, x: Parent) -> Parent: pass | |
| class Child(Parent): | |
| def __add__(self, x: Parent) -> Child: pass | |
| def __radd__(self, x: Parent) -> Child: pass | |
| a: Union[Parent, Child] | |
| b: Parent | |
| c: Child | |
| reveal_type(a + a) # N: Revealed type is "__main__.Parent" | |
| reveal_type(a + b) # N: Revealed type is "__main__.Parent" | |
| reveal_type(b + a) # N: Revealed type is "__main__.Parent" | |
| reveal_type(a + c) # N: Revealed type is "__main__.Child" | |
| reveal_type(c + a) # N: Revealed type is "__main__.Child" | |
| [case testOperatorDoubleUnionNoRelationship1] | |
| from typing import Union | |
| class Foo: | |
| def __add__(self, x: Foo) -> Foo: pass | |
| def __radd__(self, x: Foo) -> Foo: pass | |
| class Bar: | |
| def __add__(self, x: Bar) -> Bar: pass | |
| def __radd__(self, x: Bar) -> Bar: pass | |
| a: Union[Foo, Bar] | |
| b: Foo | |
| c: Bar | |
| a + a # E: Unsupported operand types for + ("Foo" and "Bar") \ | |
| # E: Unsupported operand types for + ("Bar" and "Foo") \ | |
| # N: Both left and right operands are unions | |
| a + b # E: Unsupported operand types for + ("Bar" and "Foo") \ | |
| # N: Left operand is of type "Foo | Bar" | |
| b + a # E: Unsupported operand types for + ("Foo" and "Bar") \ | |
| # N: Right operand is of type "Foo | Bar" | |
| a + c # E: Unsupported operand types for + ("Foo" and "Bar") \ | |
| # N: Left operand is of type "Foo | Bar" | |
| c + a # E: Unsupported operand types for + ("Bar" and "Foo") \ | |
| # N: Right operand is of type "Foo | Bar" | |
| [case testOperatorDoubleUnionNoRelationship2] | |
| from typing import Union | |
| class Foo: | |
| def __add__(self, x: Foo) -> Foo: pass | |
| def __radd__(self, x: Foo) -> Foo: pass | |
| class Bar: | |
| def __add__(self, x: Union[Foo, Bar]) -> Bar: pass | |
| def __radd__(self, x: Union[Foo, Bar]) -> Bar: pass | |
| a: Union[Foo, Bar] | |
| b: Foo | |
| c: Bar | |
| reveal_type(a + a) # N: Revealed type is "__main__.Foo | __main__.Bar" | |
| reveal_type(a + b) # N: Revealed type is "__main__.Foo | __main__.Bar" | |
| reveal_type(b + a) # N: Revealed type is "__main__.Foo | __main__.Bar" | |
| reveal_type(a + c) # N: Revealed type is "__main__.Bar" | |
| reveal_type(c + a) # N: Revealed type is "__main__.Bar" | |
| [case testOperatorDoubleUnionNaiveAdd] | |
| from typing import Union | |
| class A: pass | |
| class B: pass | |
| class C: | |
| def __radd__(self, x: A) -> int: pass | |
| class D: | |
| def __radd__(self, x: B) -> str: pass | |
| x: Union[A, B] | |
| y: Union[C, D] | |
| x + y # E: Unsupported operand types for + ("A" and "D") \ | |
| # E: Unsupported operand types for + ("B" and "C") \ | |
| # N: Both left and right operands are unions | |
| [case testOperatorDoubleUnionInterwovenUnionAdd] | |
| from typing import Union | |
| class Out1: pass | |
| class Out2: pass | |
| class Out3: pass | |
| class Out4: pass | |
| class A: | |
| def __add__(self, x: D) -> Out1: pass | |
| class B: | |
| def __add__(self, x: C) -> Out2: pass | |
| class C: | |
| def __radd__(self, x: A) -> Out3: pass | |
| class D: | |
| def __radd__(self, x: B) -> Out4: pass | |
| x: Union[A, B] | |
| y: Union[C, D] | |
| reveal_type(x + y) # N: Revealed type is "__main__.Out3 | __main__.Out1 | __main__.Out2 | __main__.Out4" | |
| reveal_type(A() + y) # N: Revealed type is "__main__.Out3 | __main__.Out1" | |
| reveal_type(B() + y) # N: Revealed type is "__main__.Out2 | __main__.Out4" | |
| reveal_type(x + C()) # N: Revealed type is "__main__.Out3 | __main__.Out2" | |
| reveal_type(x + D()) # N: Revealed type is "__main__.Out1 | __main__.Out4" | |
| [case testOperatorDoubleUnionDivision] | |
| from typing import Union | |
| def f(a): | |
| # type: (Union[int, float]) -> None | |
| a /= 1.1 | |
| b = a / 1.1 | |
| reveal_type(b) # N: Revealed type is "builtins.float" | |
| [builtins fixtures/ops.pyi] | |
| [case testOperatorWithInference] | |
| from typing import TypeVar, Iterable, Union | |
| T = TypeVar('T') | |
| def sum(x: Iterable[T]) -> Union[T, int]: ... | |
| def len(x: Iterable[T]) -> int: ... | |
| x = [1.1, 2.2, 3.3] | |
| reveal_type(sum(x)) # N: Revealed type is "builtins.float | builtins.int" | |
| reveal_type(sum(x) / len(x)) # N: Revealed type is "builtins.float | builtins.int" | |
| [builtins fixtures/floatdict.pyi] | |
| [case testOperatorWithEmptyListAndSum] | |
| from typing import TypeVar, Iterable, Union, overload | |
| T = TypeVar('T') | |
| S = TypeVar('S') | |
| @overload | |
| def sum(x: Iterable[T]) -> Union[T, int]: ... | |
| @overload | |
| def sum(x: Iterable[T], default: S) -> Union[T, S]: ... | |
| def sum(*args): pass | |
| x = ["a", "b", "c"] | |
| reveal_type(x + sum([x, x, x], [])) # N: Revealed type is "builtins.list[builtins.str]" | |
| [builtins fixtures/floatdict.pyi] | |
| [case testAbstractReverseOperatorMethod] | |
| import typing | |
| from abc import abstractmethod | |
| class A: | |
| @abstractmethod | |
| def __lt__(self, x: 'A') -> int: pass | |
| class B: | |
| @abstractmethod | |
| def __lt__(self, x: 'B') -> int: pass | |
| @abstractmethod | |
| def __gt__(self, x: 'B') -> int: pass | |
| [out] | |
| [case testOperatorMethodsAndOverloadingSpecialCase] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload | |
| class A: | |
| @overload | |
| def __add__(self, x: 'A') -> int: pass | |
| @overload | |
| def __add__(self, x: str) -> int: pass | |
| class B: | |
| def __radd__(self, x: 'A') -> str: pass | |
| [out] | |
| [case testUnsafeOverlappingWithOperatorMethodsAndOverloading2] | |
| from foo import A, B | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload | |
| class A: | |
| def __add__(self, x: 'A') -> int: pass | |
| class B: | |
| @overload | |
| def __radd__(self, x: 'X') -> str: pass # Error | |
| @overload | |
| def __radd__(self, x: A) -> str: pass # Error | |
| class X: | |
| def __add__(self, x: B) -> int: pass | |
| [out] | |
| tmp/foo.pyi:6: error: Signatures of "__radd__" of "B" and "__add__" of "X" are unsafely overlapping | |
| [case testUnsafeOverlappingNotWithAny] | |
| from typing import TypeVar | |
| class Real: | |
| def __add__(self, other) -> str: ... | |
| class Fraction(Real): | |
| def __radd__(self, other: Real) -> Real: ... | |
| [case testOverlappingNormalAndInplaceOperatorMethod] | |
| import typing | |
| class A: | |
| # Incompatible (potential trouble with __radd__) | |
| def __add__(self, x: 'A') -> int: pass | |
| def __iadd__(self, x: 'B') -> int: pass | |
| class B: | |
| # Safe | |
| def __add__(self, x: 'C') -> int: pass | |
| def __iadd__(self, x: A) -> int: pass | |
| class C(A): pass | |
| [out] | |
| main:5: error: Signatures of "__iadd__" and "__add__" are incompatible | |
| [case testOverloadedNormalAndInplaceOperatorMethod] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload | |
| class A: | |
| @overload | |
| def __add__(self, x: int) -> int: pass | |
| @overload | |
| def __add__(self, x: str) -> int: pass | |
| @overload # Error | |
| def __iadd__(self, x: int) -> int: pass | |
| @overload | |
| def __iadd__(self, x: object) -> int: pass | |
| class B: | |
| @overload | |
| def __add__(self, x: int) -> int: pass | |
| @overload | |
| def __add__(self, x: str) -> str: pass | |
| @overload | |
| def __iadd__(self, x: int) -> int: pass | |
| @overload | |
| def __iadd__(self, x: str) -> str: pass | |
| [out] | |
| tmp/foo.pyi:7: error: Signatures of "__iadd__" and "__add__" are incompatible | |
| [case testIntroducingInplaceOperatorInSubclass] | |
| import typing | |
| class A: | |
| def __add__(self, x: 'A') -> 'B': pass | |
| class B(A): | |
| # __iadd__ effectively partially overrides __add__ | |
| def __iadd__(self, x: 'A') -> 'A': pass # Error | |
| class C(A): | |
| def __iadd__(self, x: int) -> 'B': pass # Error | |
| class D(A): | |
| def __iadd__(self, x: 'A') -> 'B': pass | |
| [out] | |
| main:6: error: Return type "A" of "__iadd__" incompatible with return type "B" in "__add__" of supertype "A" | |
| main:8: error: Signatures of "__iadd__" and "__add__" are incompatible | |
| main:8: error: Argument 1 of "__iadd__" is incompatible with "__add__" of supertype "A"; supertype defines the argument type as "A" | |
| main:8: note: This violates the Liskov substitution principle | |
| main:8: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| [case testGetattribute] | |
| a: A | |
| b: B | |
| class A: | |
| def __getattribute__(self, x: str) -> A: | |
| return A() | |
| class B: pass | |
| a = a.foo | |
| b = a.bar | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| main:9: error: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| [case testDecoratedGetAttribute] | |
| from typing import Callable, TypeVar | |
| T = TypeVar('T', bound=Callable) | |
| def decorator(f: T) -> T: | |
| return f | |
| def bad(f: Callable) -> Callable[..., int]: | |
| return f | |
| class A: | |
| @decorator | |
| def __getattribute__(self, x: str) -> A: | |
| return A() | |
| class B: | |
| @bad # We test that type will be taken from decorated type, not node itself | |
| def __getattribute__(self, x: str) -> A: | |
| return A() | |
| a: A | |
| b: B | |
| a1: A = a.foo | |
| b1: B = a.bar # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| a2: A = b.baz # E: Incompatible types in assignment (expression has type "int", variable has type "A") | |
| b2: B = b.roo # E: Incompatible types in assignment (expression has type "int", variable has type "B") | |
| [builtins fixtures/tuple.pyi] | |
| [case testGetattributeSignature] | |
| class A: | |
| def __getattribute__(self, x: str) -> A: pass | |
| class B: | |
| def __getattribute__(self, x: A) -> B: pass | |
| class C: | |
| def __getattribute__(self, x: str, y: str) -> C: pass | |
| class D: | |
| def __getattribute__(self, x: str) -> None: pass | |
| [out] | |
| main:4: error: Invalid signature "Callable[[B, A], B]" for "__getattribute__" | |
| main:6: error: Invalid signature "Callable[[C, str, str], C]" for "__getattribute__" | |
| [case testGetattr] | |
| a: A | |
| b: B | |
| class A: | |
| def __getattr__(self, x: str) -> A: | |
| return A() | |
| class B: pass | |
| a = a.foo | |
| b = a.bar | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| main:9: error: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| [case testDecoratedGetattr] | |
| from typing import Callable, TypeVar | |
| T = TypeVar('T', bound=Callable) | |
| def decorator(f: T) -> T: | |
| return f | |
| def bad(f: Callable) -> Callable[..., int]: | |
| return f | |
| class A: | |
| @decorator | |
| def __getattr__(self, x: str) -> A: | |
| return A() | |
| class B: | |
| @bad # We test that type will be taken from decorated type, not node itself | |
| def __getattr__(self, x: str) -> A: | |
| return A() | |
| a: A | |
| b: B | |
| a1: A = a.foo | |
| b1: B = a.bar # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| a2: A = b.baz # E: Incompatible types in assignment (expression has type "int", variable has type "A") | |
| b2: B = b.roo # E: Incompatible types in assignment (expression has type "int", variable has type "B") | |
| [builtins fixtures/tuple.pyi] | |
| [case testGetattrWithGetitem] | |
| class A: | |
| def __getattr__(self, x: str) -> 'A': | |
| return A() | |
| a = A() | |
| a[0] # E: Value of type "A" is not indexable | |
| [case testGetattrWithCall] | |
| class A: | |
| def __getattr__(self, x: str) -> 'A': | |
| return A() | |
| a = A() | |
| a.y() # E: "A" not callable | |
| [case testGetattrWithCallable] | |
| from typing import Callable, Any | |
| class C: | |
| def __getattr__(self, attr: str) -> C: ... | |
| def do(cd: Callable[..., Any]) -> None: ... | |
| do(C()) # E: Argument 1 to "do" has incompatible type "C"; expected "Callable[..., Any]" | |
| [case testGetattrWithCallableTypeVar] | |
| from typing import Callable, Any, TypeVar | |
| class C: | |
| def __getattr__(self, attr: str) -> C: ... | |
| T = TypeVar('T', bound=Callable[..., Any]) | |
| def do(cd: T) -> T: ... | |
| do(C()) # E: Value of type variable "T" of "do" cannot be "C" | |
| [case testNestedGetattr] | |
| def foo() -> object: | |
| def __getattr__() -> None: # no error because not in a class | |
| pass | |
| return __getattr__ | |
| class X: | |
| def foo(self) -> object: | |
| def __getattr__() -> None: # no error because not directly inside a class | |
| pass | |
| return __getattr__ | |
| [case testGetattrSignature] | |
| class A: | |
| def __getattr__(self, x: str) -> A: pass | |
| class B: | |
| def __getattr__(self, x: A) -> B: pass | |
| class C: | |
| def __getattr__(self, x: str, y: str) -> C: pass | |
| class D: | |
| def __getattr__(self, x: str) -> None: pass | |
| [out] | |
| main:4: error: Invalid signature "Callable[[B, A], B]" for "__getattr__" | |
| main:6: error: Invalid signature "Callable[[C, str, str], C]" for "__getattr__" | |
| [case testSetattr] | |
| from typing import Union, Any | |
| class A: | |
| def __setattr__(self, name: str, value: Any) -> None: ... | |
| a = A() | |
| a.test = 'hello' | |
| class B: | |
| def __setattr__(self, name: str, value: Union[int, str]) -> None: ... | |
| b = B() | |
| b.both = 1 | |
| b.work = '2' | |
| class C: | |
| def __setattr__(self, name: str, value: str) -> None: ... | |
| c = C() | |
| c.fail = 4 # E: Incompatible types in assignment (expression has type "int", variable has type "str") | |
| class D: | |
| __setattr__ = 'hello' # E: Invalid signature "str" for "__setattr__" | |
| d = D() | |
| d.crash = 4 # E: "D" has no attribute "crash" | |
| class Ex: | |
| def __setattr__(self, name: str, value: int) -> None:... | |
| test = '42' # type: str | |
| e = Ex() | |
| e.test = 'hello' | |
| e.t = 4 | |
| class Super: | |
| def __setattr__(self, name: str, value: int) -> None: ... | |
| class Sub(Super): | |
| ... | |
| s = Sub() | |
| s.success = 4 | |
| s.fail = 'fail' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| [case testDecoratedSetattr] | |
| from typing import Any, Callable, TypeVar | |
| T = TypeVar('T', bound=Callable) | |
| def decorator(f: T) -> T: | |
| return f | |
| def bad(f: Callable) -> Callable[[Any, str, int], None]: | |
| return f | |
| class A: | |
| @decorator | |
| def __setattr__(self, k: str, v: str) -> None: | |
| pass | |
| class B: | |
| @bad # We test that type will be taken from decorated type, not node itself | |
| def __setattr__(self, k: str, v: str) -> None: | |
| pass | |
| a: A | |
| a.foo = 'a' | |
| a.bar = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") | |
| b: B | |
| b.good = 1 | |
| b.bad = 'a' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| [builtins fixtures/tuple.pyi] | |
| [case testSetattrSignature] | |
| from typing import Any | |
| class Test: | |
| def __setattr__() -> None: ... \ | |
| # E: Invalid signature "Callable[[], None]" for "__setattr__" \ | |
| # E: Method must have at least one argument. Did you forget the "self" argument? | |
| t = Test() | |
| t.crash = 'test' # E: Attribute function "__setattr__" with type "Callable[[], None]" does not accept self argument \ | |
| # E: "Test" has no attribute "crash" | |
| class A: | |
| def __setattr__(self): ... # E: Invalid signature "Callable[[A], Any]" for "__setattr__" | |
| a = A() | |
| a.test = 4 # E: "A" has no attribute "test" | |
| class B: | |
| def __setattr__(self, name, value: int): ... | |
| b = B() | |
| b.integer = 5 | |
| class C: | |
| def __setattr__(self, name: int, value: int) -> None: ... # E: Invalid signature "Callable[[C, int, int], None]" for "__setattr__" | |
| c = C() | |
| c.check = 13 | |
| class X: | |
| __setattr__ = ... # type: Any | |
| [case testGetattrAndSetattr] | |
| from typing import Any | |
| class A: | |
| def __setattr__(self, name: str, value: Any) -> None: ... | |
| def __getattr__(self, name: str) -> Any: ... | |
| a = A() | |
| a.test = 4 | |
| t = a.test | |
| class B: | |
| def __setattr__(self, name: str, value: int) -> None: ... | |
| def __getattr__(self, name: str) -> str: ... | |
| integer = 0 | |
| b = B() | |
| b.at = '3' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| if int(): | |
| integer = b.at # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| [case testSetattrKeywordArg] | |
| from typing import Any | |
| class C: | |
| def __setattr__(self, key: str, value: Any, p: bool = False) -> None: ... | |
| c: C | |
| c.__setattr__("x", 42, p=True) | |
| -- CallableType objects | |
| -- ---------------- | |
| [case testCallableObject] | |
| class A: | |
| def __call__(self, x: 'A') -> 'A': | |
| pass | |
| class B: pass | |
| a = A() | |
| b = B() | |
| a() # E: Missing positional argument "x" in call to "__call__" of "A" | |
| a(a, a) # E: Too many arguments for "__call__" of "A" | |
| if int(): | |
| a = a(a) | |
| if int(): | |
| a = a(b) # E: Argument 1 to "__call__" of "A" has incompatible type "B"; expected "A" | |
| if int(): | |
| b = a(a) # E: Incompatible types in assignment (expression has type "A", variable has type "B") | |
| -- __new__ | |
| -- -------- | |
| [case testConstructInstanceWith__new__] | |
| from typing import Optional | |
| class C: | |
| def __new__(cls, foo: Optional[int] = None) -> 'C': | |
| obj = object.__new__(cls) | |
| return obj | |
| x = C(foo=12) | |
| x.a # E: "C" has no attribute "a" | |
| C(foo='') # E: Argument "foo" to "C" has incompatible type "str"; expected "int | None" | |
| [builtins fixtures/__new__.pyi] | |
| [case testConstructInstanceWithDynamicallyTyped__new__] | |
| class C: | |
| def __new__(cls, foo): | |
| obj = object.__new__(cls) | |
| return obj | |
| x = C(foo=12) | |
| x = C(foo='x') | |
| x.a # E: "C" has no attribute "a" | |
| C(bar='') # E: Unexpected keyword argument "bar" for "C" | |
| [builtins fixtures/__new__.pyi] | |
| [case testClassWith__new__AndCompatibilityWithType] | |
| from typing import Optional | |
| class C: | |
| def __new__(cls, foo: Optional[int] = None) -> 'C': | |
| obj = object.__new__(cls) | |
| return obj | |
| def f(x: type) -> None: pass | |
| def g(x: int) -> None: pass | |
| f(C) | |
| g(C) # E: Argument 1 to "g" has incompatible type "type[C]"; expected "int" | |
| [builtins fixtures/__new__.pyi] | |
| [case testClassWith__new__AndCompatibilityWithType2] | |
| class C: | |
| def __new__(cls, foo): | |
| obj = object.__new__(cls) | |
| return obj | |
| def f(x: type) -> None: pass | |
| def g(x: int) -> None: pass | |
| f(C) | |
| g(C) # E: Argument 1 to "g" has incompatible type "type[C]"; expected "int" | |
| [builtins fixtures/__new__.pyi] | |
| [case testGenericClassWith__new__] | |
| from typing import TypeVar, Generic | |
| T = TypeVar('T') | |
| class C(Generic[T]): | |
| def __new__(cls, foo: T) -> 'C[T]': | |
| obj = object.__new__(cls) | |
| return obj | |
| def set(self, x: T) -> None: pass | |
| c = C('') | |
| c.set('') | |
| c.set(1) # E: Argument 1 to "set" of "C" has incompatible type "int"; expected "str" | |
| [builtins fixtures/__new__.pyi] | |
| [case testOverloaded__new__] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload | |
| class C: | |
| @overload | |
| def __new__(cls, foo: int) -> 'C': | |
| obj = object.__new__(cls) | |
| return obj | |
| @overload | |
| def __new__(cls, x: str, y: str) -> 'C': | |
| obj = object.__new__(cls) | |
| return obj | |
| c = C(1) | |
| c.a # E: "C" has no attribute "a" | |
| C('', '') | |
| C('') # E: No overload variant of "C" matches argument type "str" \ | |
| # N: Possible overload variants: \ | |
| # N: def C(foo: int) -> C \ | |
| # N: def C(x: str, y: str) -> C | |
| [builtins fixtures/__new__.pyi] | |
| -- Special cases | |
| -- ------------- | |
| [case testSubclassInt] | |
| import typing | |
| class A(int): pass | |
| n = 0 | |
| if int(): | |
| n = A() | |
| a = A() | |
| if int(): | |
| a = 0 # E: Incompatible types in assignment (expression has type "int", variable has type "A") | |
| [case testForwardReferenceToNestedClass] | |
| def f(o: 'B.C') -> None: | |
| o.f('') # E: Argument 1 to "f" of "C" has incompatible type "str"; expected "int" | |
| class B: | |
| class C: | |
| def f(self, x: int) -> None: pass | |
| [out] | |
| [case testForwardReferenceToNestedClassDeep] | |
| def f(o: 'B.C.D') -> None: | |
| o.f('') # E: Argument 1 to "f" of "D" has incompatible type "str"; expected "int" | |
| class B: | |
| class C: | |
| class D: | |
| def f(self, x: int) -> None: pass | |
| [out] | |
| [case testForwardReferenceToNestedClassWithinClass] | |
| class B: | |
| def f(self, o: 'C.D') -> None: | |
| o.f('') # E: Argument 1 to "f" of "D" has incompatible type "str"; expected "int" | |
| class C: | |
| class D: | |
| def f(self, x: int) -> None: pass | |
| [out] | |
| [case testClassVsInstanceDisambiguation] | |
| class A: pass | |
| def f(x: A) -> None: pass | |
| f(A) # E: Argument 1 to "f" has incompatible type "type[A]"; expected "A" | |
| [out] | |
| -- TODO | |
| -- attribute inherited from superclass; assign in __init__ | |
| -- refer to attribute before type has been inferred (the initialization in | |
| -- __init__ has not been analyzed) | |
| [case testAnyBaseClassUnconstrainedConstructor] | |
| from typing import Any | |
| B = None # type: Any | |
| class C(B): pass | |
| C(0) | |
| C(arg=0) | |
| [out] | |
| [case testErrorMapToSupertype] | |
| import typing | |
| class X(Nope): pass # E: Name "Nope" is not defined | |
| a, b = X() # Used to crash here (#2244) | |
| -- Class-valued attributes | |
| -- ----------------------- | |
| [case testClassValuedAttributesBasics] | |
| class A: ... | |
| class B: | |
| a = A | |
| bad = lambda: 42 | |
| B().bad() # E: Attribute function "bad" with type "Callable[[], int]" does not accept self argument | |
| reveal_type(B.a) # N: Revealed type is "def () -> __main__.A" | |
| reveal_type(B().a) # N: Revealed type is "def () -> __main__.A" | |
| reveal_type(B().a()) # N: Revealed type is "__main__.A" | |
| class C: | |
| a = A | |
| def __init__(self) -> None: | |
| self.aa = self.a() | |
| reveal_type(C().aa) # N: Revealed type is "__main__.A" | |
| [out] | |
| [case testClassValuedAttributesGeneric] | |
| from typing import Generic, TypeVar, Type | |
| T = TypeVar('T') | |
| class A(Generic[T]): | |
| def __init__(self, x: T) -> None: | |
| self.x = x | |
| class B(Generic[T]): | |
| a: Type[A[T]] = A | |
| reveal_type(B[int]().a) # N: Revealed type is "type[__main__.A[builtins.int]]" | |
| B[int]().a('hi') # E: Argument 1 to "A" has incompatible type "str"; expected "int" | |
| class C(Generic[T]): | |
| a = A | |
| def __init__(self) -> None: | |
| self.aa = self.a(42) | |
| reveal_type(C().aa) # N: Revealed type is "__main__.A[builtins.int]" | |
| [out] | |
| [case testClassValuedAttributesAlias] | |
| from typing import Generic, TypeVar | |
| T = TypeVar('T') | |
| S = TypeVar('S') | |
| class A(Generic[T, S]): ... | |
| SameA = A[T, T] | |
| class B: | |
| a_any = SameA | |
| a_int = SameA[int] | |
| reveal_type(B().a_any) # N: Revealed type is "def () -> __main__.A[Any, Any]" | |
| reveal_type(B().a_int()) # N: Revealed type is "__main__.A[builtins.int, builtins.int]" | |
| class C: | |
| a_int = SameA[int] | |
| def __init__(self) -> None: | |
| self.aa = self.a_int() | |
| reveal_type(C().aa) # N: Revealed type is "__main__.A[builtins.int, builtins.int]" | |
| [out] | |
| -- Type[C] | |
| -- ------- | |
| [case testTypeUsingTypeCBasic] | |
| from typing import Type | |
| class User: pass | |
| class ProUser(User): pass | |
| def new_user(user_class: Type[User]) -> User: | |
| return user_class() | |
| reveal_type(new_user(User)) # N: Revealed type is "__main__.User" | |
| reveal_type(new_user(ProUser)) # N: Revealed type is "__main__.User" | |
| [out] | |
| [case testTypeUsingTypeCDefaultInit] | |
| from typing import Type | |
| class B: | |
| pass | |
| def f(A: Type[B]) -> None: | |
| A(0) # E: Too many arguments for "B" | |
| A() | |
| [out] | |
| [case testTypeUsingTypeCInitWithArg] | |
| from typing import Type | |
| class B: | |
| def __init__(self, a: int) -> None: pass | |
| def f(A: Type[B]) -> None: | |
| A(0) | |
| A() # E: Missing positional argument "a" in call to "B" | |
| [out] | |
| [case testTypeUsingTypeCTypeVar] | |
| from typing import Type, TypeVar | |
| class User: pass | |
| class ProUser(User): pass | |
| U = TypeVar('U', bound=User) | |
| def new_user(user_class: Type[U]) -> U: | |
| user = user_class() | |
| reveal_type(user) | |
| return user | |
| pro_user = new_user(ProUser) | |
| reveal_type(pro_user) | |
| [out] | |
| main:7: note: Revealed type is "U`-1" | |
| main:10: note: Revealed type is "__main__.ProUser" | |
| [case testTypeUsingTypeCTypeVarDefaultInit] | |
| from typing import Type, TypeVar | |
| class B: | |
| pass | |
| T = TypeVar('T', bound=B) | |
| def f(A: Type[T]) -> None: | |
| A() | |
| A(0) # E: Too many arguments for "B" | |
| [out] | |
| [case testTypeUsingTypeCTypeVarWithInit] | |
| from typing import Type, TypeVar | |
| class B: | |
| def __init__(self, a: int) -> None: pass | |
| T = TypeVar('T', bound=B) | |
| def f(A: Type[T]) -> None: | |
| A() # E: Missing positional argument "a" in call to "B" | |
| A(0) | |
| [out] | |
| [case testTypeUsingTypeCTwoTypeVars] | |
| from typing import Type, TypeVar | |
| class User: pass | |
| class ProUser(User): pass | |
| class WizUser(ProUser): pass | |
| U = TypeVar('U', bound=User) | |
| def new_user(u_c: Type[U]) -> U: pass | |
| P = TypeVar('P', bound=ProUser) | |
| def new_pro(pro_c: Type[P]) -> P: | |
| return new_user(pro_c) | |
| wiz = new_pro(WizUser) | |
| reveal_type(wiz) | |
| def error(u_c: Type[U]) -> P: # Error here, see below | |
| return new_pro(u_c) # Error here, see below | |
| [out] | |
| main:11: note: Revealed type is "__main__.WizUser" | |
| main:12: error: A function returning TypeVar should receive at least one argument containing the same TypeVar | |
| main:12: note: Consider using the upper bound "ProUser" instead | |
| main:13: error: Value of type variable "P" of "new_pro" cannot be "U" | |
| main:13: error: Incompatible return value type (got "U", expected "P") | |
| [case testTypeUsingTypeCCovariance] | |
| from typing import Type, TypeVar | |
| class User: pass | |
| class ProUser(User): pass | |
| def new_user(user_class: Type[User]) -> User: | |
| return user_class() | |
| def new_pro_user(user_class: Type[ProUser]): | |
| new_user(user_class) | |
| [out] | |
| [case testAllowCovariantArgsInConstructor] | |
| from typing import Generic, TypeVar | |
| T_co = TypeVar('T_co', covariant=True) | |
| class C(Generic[T_co]): | |
| def __init__(self, x: T_co) -> None: # This should be allowed | |
| self.x = x | |
| def meth(self) -> None: | |
| reveal_type(self.x) # N: Revealed type is "T_co`1" | |
| reveal_type(C(1).x) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/property.pyi] | |
| [out] | |
| [case testTypeUsingTypeCErrorCovariance] | |
| from typing import Type, TypeVar | |
| class User: pass | |
| def new_user(user_class: Type[User]): | |
| return user_class() | |
| def foo(arg: Type[int]): | |
| new_user(arg) # E: Argument 1 to "new_user" has incompatible type "type[int]"; expected "type[User]" | |
| [out] | |
| [case testTypeUsingTypeCUnionOverload] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, Union, overload | |
| class X: | |
| @overload | |
| def __init__(self) -> None: pass | |
| @overload | |
| def __init__(self, a: int) -> None: pass | |
| class Y: | |
| def __init__(self) -> None: pass | |
| def bar(o: Type[Union[X, Y]]): pass | |
| bar(X) | |
| bar(Y) | |
| [out] | |
| [case testTypeUsingTypeCTypeAny] | |
| from typing import Type, Any | |
| def foo(arg: Type[Any]): | |
| x = arg() | |
| x = arg(0) | |
| x = arg('', ()) | |
| reveal_type(x) # N: Revealed type is "Any" | |
| x.foo | |
| class X: pass | |
| foo(X) | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testTypeUsingTypeCTypeAnyMember] | |
| from typing import Type, Any | |
| def foo(arg: Type[Any]): | |
| x = arg.member_name | |
| arg.new_member_name = 42 | |
| # Member access is ok and types as Any | |
| reveal_type(x) # N: Revealed type is "Any" | |
| # But type[Any] is distinct from Any | |
| y: int = arg # E: Incompatible types in assignment (expression has type "type[Any]", variable has type "int") | |
| [out] | |
| [case testTypeUsingTypeCTypeAnyMemberFallback] | |
| from typing import Type, Any | |
| def foo(arg: Type[Any]): | |
| reveal_type(arg.__str__) # N: Revealed type is "def () -> builtins.str" | |
| reveal_type(arg.mro()) # N: Revealed type is "builtins.list[builtins.type]" | |
| [builtins fixtures/type.pyi] | |
| [out] | |
| [case testTypeUsingTypeCTypeNoArg] | |
| from typing import Type | |
| def foo(arg: Type): | |
| x = arg() | |
| reveal_type(x) # N: Revealed type is "Any" | |
| class X: pass | |
| foo(X) | |
| [out] | |
| [case testTypeUsingTypeCBuiltinType] | |
| from typing import Type | |
| def foo(arg: type): pass | |
| class X: pass | |
| def bar(arg: Type[X]): | |
| foo(arg) | |
| foo(X) | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testTypeUsingTypeCClassMethod] | |
| from typing import Type | |
| class User: | |
| @classmethod | |
| def foo(cls) -> int: pass | |
| def bar(self) -> int: pass | |
| def process(cls: Type[User]): | |
| reveal_type(cls.foo()) # N: Revealed type is "builtins.int" | |
| obj = cls() | |
| reveal_type(cls.bar(obj)) # N: Revealed type is "builtins.int" | |
| cls.mro() # Defined in class type | |
| cls.error # E: "type[User]" has no attribute "error" | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testTypeUsingTypeCClassMethodUnion] | |
| from typing import Type, Union | |
| class User: | |
| @classmethod | |
| def foo(cls) -> int: pass | |
| def bar(self) -> int: pass | |
| class ProUser(User): pass | |
| class BasicUser(User): pass | |
| def process(cls: Type[Union[BasicUser, ProUser]]): | |
| cls.foo() | |
| obj = cls() | |
| cls.bar(obj) | |
| cls.mro() # Defined in class type | |
| cls.error # E: Item "type" of "type[BasicUser] | type[ProUser]" has no attribute "error" | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testTypeUsingTypeCClassMethodFromTypeVar] | |
| from typing import Type, TypeVar | |
| class User: | |
| @classmethod | |
| def foo(cls) -> int: pass | |
| def bar(self) -> int: pass | |
| U = TypeVar('U', bound=User) | |
| def process(cls: Type[U]): | |
| reveal_type(cls.foo()) # N: Revealed type is "builtins.int" | |
| obj = cls() | |
| reveal_type(cls.bar(obj)) # N: Revealed type is "builtins.int" | |
| cls.mro() # Defined in class type | |
| cls.error # E: "type[U]" has no attribute "error" | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testTypeUsingTypeCClassMethodFromTypeVarUnionBound] | |
| # Ideally this would work, but not worth the effort; just don't crash | |
| from typing import Type, TypeVar, Union | |
| class User: | |
| @classmethod | |
| def foo(cls) -> int: pass | |
| def bar(self) -> int: pass | |
| class ProUser(User): pass | |
| class BasicUser(User): pass | |
| U = TypeVar('U', bound=Union[ProUser, BasicUser]) | |
| def process(cls: Type[U]): | |
| cls.foo() | |
| obj = cls() | |
| cls.bar(obj) | |
| cls.mro() # Defined in class type | |
| cls.error # E: "type[U]" has no attribute "error" | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testTypeUsingTypeCConstructorReturnFromTypeVarUnionBound] | |
| from typing import Optional, Type, TypeVar, Union | |
| class A: | |
| def __init__(self, value: str = "") -> None: pass | |
| class B: | |
| def __init__(self, value: str = "") -> None: pass | |
| T = TypeVar("T", bound=Union[A, B]) | |
| def make(ftype: Type[T], value: Optional[str]) -> T: | |
| if value is None: | |
| return ftype() | |
| return ftype(value) | |
| reveal_type(make(A, "a")) # N: Revealed type is "__main__.A" | |
| reveal_type(make(B, None)) # N: Revealed type is "__main__.B" | |
| [case testTypeUsingTypeCErrorUnsupportedType] | |
| from typing import Type, Tuple | |
| def foo(arg: Type[Tuple[int]]): | |
| arg() # E: Cannot instantiate type "type[tuple[int]]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testTypeUsingTypeCOverloadedClass] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, TypeVar, overload | |
| class User: | |
| @overload | |
| def __init__(self) -> None: pass | |
| @overload | |
| def __init__(self, arg: int) -> None: pass | |
| @classmethod | |
| def foo(cls) -> None: pass | |
| U = TypeVar('U', bound=User) | |
| def new(uc: Type[U]) -> U: | |
| uc.foo() | |
| u = uc() | |
| u.foo() | |
| if 1: | |
| u = uc(0) | |
| u.foo() | |
| uc('') # Error | |
| u.foo(0) # Error | |
| return uc() | |
| u = new(User) | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| tmp/foo.pyi:17: error: No overload variant of "User" matches argument type "str" | |
| tmp/foo.pyi:17: note: Possible overload variants: | |
| tmp/foo.pyi:17: note: def User() -> U | |
| tmp/foo.pyi:17: note: def User(arg: int) -> U | |
| tmp/foo.pyi:18: error: Too many arguments for "foo" of "User" | |
| [case testTypeUsingTypeCInUpperBound] | |
| from typing import TypeVar, Type | |
| class B: pass | |
| T = TypeVar('T', bound=Type[B]) | |
| def f(a: T): pass | |
| [out] | |
| [case testTypeUsingTypeCTuple] | |
| from typing import Type, Tuple | |
| def f(a: Type[Tuple[int, int]]): | |
| a() # E: Cannot instantiate type "type[tuple[int, int]]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testTypeUsingTypeCNamedTuple] | |
| from typing import Type, NamedTuple | |
| N = NamedTuple('N', [('x', int), ('y', int)]) | |
| def f(a: Type[N]): | |
| a() | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| main:4: error: Missing positional arguments "x", "y" in call to "N" | |
| [case testTypeUsingTypeCJoin] | |
| from typing import Type | |
| class B: pass | |
| class C(B): pass | |
| class D(B): pass | |
| def foo(c: Type[C], d: Type[D]) -> None: | |
| x = [c, d] | |
| reveal_type(x) | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| main:7: note: Revealed type is "builtins.list[type[__main__.B]]" | |
| [case testTypeEquivalentTypeAny] | |
| from typing import Type, Any | |
| a: Type[Any] | |
| b = a # type: type | |
| x: type | |
| y = x # type: Type[Any] | |
| class C: ... | |
| p: type | |
| q = p # type: Type[C] | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| [case testTypeEquivalentTypeAny2] | |
| from typing import Type, Any, TypeVar, Generic | |
| class C: ... | |
| x: type | |
| y: Type[Any] | |
| z: Type[C] | |
| lst = [x, y, z] | |
| reveal_type(lst) # N: Revealed type is "builtins.list[builtins.type]" | |
| T1 = TypeVar('T1', bound=type) | |
| T2 = TypeVar('T2', bound=Type[Any]) | |
| class C1(Generic[T1]): ... | |
| class C2(Generic[T2]): ... | |
| C1[Type[Any]], C2[type] # both these should not fail | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| [case testTypeEquivalentTypeAnyEdgeCase] | |
| class C: | |
| pass | |
| class M(type): | |
| def __init__(cls, x) -> None: | |
| type.__init__(cls, x) | |
| class Mbad(type): | |
| def __init__(cls, x) -> None: | |
| type.__init__(C(), x) # E: Argument 1 to "__init__" of "type" has incompatible type "C"; expected "type" | |
| [builtins fixtures/primitives.pyi] | |
| [out] | |
| [case testTypeMatchesOverloadedFunctions] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, overload, Any | |
| class User: pass | |
| UserType = User # type: Type[User] | |
| @overload | |
| def f(a: int) -> Any: pass | |
| @overload | |
| def f(a: object) -> int: pass | |
| reveal_type(f(User)) # N: Revealed type is "builtins.int" | |
| reveal_type(f(UserType)) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testTypeMatchesGeneralTypeInOverloadedFunctions] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, overload | |
| class User: pass | |
| UserType = User # type: Type[User] | |
| @overload | |
| def f(a: type) -> int: | |
| return 1 | |
| @overload | |
| def f(a: int) -> str: | |
| return "a" | |
| reveal_type(f(User)) # N: Revealed type is "builtins.int" | |
| reveal_type(f(UserType)) # N: Revealed type is "builtins.int" | |
| reveal_type(f(1)) # N: Revealed type is "builtins.str" | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testTypeMatchesSpecificTypeInOverloadedFunctions] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, overload | |
| class User: pass | |
| UserType = User # type: Type[User] | |
| @overload | |
| def f(a: User) -> User: | |
| return User() | |
| @overload | |
| def f(a: Type[User]) -> int: | |
| return 1 | |
| @overload | |
| def f(a: int) -> str: | |
| return "a" | |
| reveal_type(f(User)) # N: Revealed type is "builtins.int" | |
| reveal_type(f(UserType)) # N: Revealed type is "builtins.int" | |
| reveal_type(f(User())) # N: Revealed type is "foo.User" | |
| reveal_type(f(1)) # N: Revealed type is "builtins.str" | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testMixingTypeTypeInOverloadedFunctions] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, overload | |
| class User: pass | |
| @overload | |
| def f(a: User) -> Type[User]: | |
| return User | |
| @overload | |
| def f(a: Type[User]) -> User: | |
| return a() | |
| @overload | |
| def f(a: int) -> Type[User]: | |
| return User | |
| @overload | |
| def f(a: str) -> User: | |
| return User() | |
| reveal_type(f(User())) # N: Revealed type is "type[foo.User]" | |
| reveal_type(f(User)) # N: Revealed type is "foo.User" | |
| reveal_type(f(3)) # N: Revealed type is "type[foo.User]" | |
| reveal_type(f("hi")) # N: Revealed type is "foo.User" | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testGeneralTypeMatchesSpecificTypeInOverloadedFunctions] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, Any, overload | |
| class User: pass | |
| @overload | |
| def f(a: Type[User]) -> None: pass | |
| @overload | |
| def f(a: int) -> None: pass | |
| def mock_1() -> type: return User | |
| def mock_2() -> Type[Any]: return User | |
| f(User) | |
| f(mock_1()) | |
| f(mock_2()) | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testNonTypeDoesNotMatchOverloadedFunctions] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, overload | |
| class User: pass | |
| @overload | |
| def f(a: Type[User]) -> None: pass | |
| @overload | |
| def f(a: type) -> None: pass | |
| f(3) # E: No overload variant of "f" matches argument type "int" \ | |
| # N: Possible overload variants: \ | |
| # N: def f(a: type[User]) -> None \ | |
| # N: def f(a: type) -> None | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testInstancesDoNotMatchTypeInOverloadedFunctions] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, overload | |
| class User: pass | |
| @overload | |
| def f(a: Type[User]) -> None: pass | |
| @overload | |
| def f(a: int) -> None: pass | |
| f(User) | |
| f(User()) # E: No overload variant of "f" matches argument type "User" \ | |
| # N: Possible overload variants: \ | |
| # N: def f(a: type[User]) -> None \ | |
| # N: def f(a: int) -> None | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testTypeCovarianceWithOverloadedFunctions] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, overload | |
| class A: pass | |
| class B(A): pass | |
| class C(B): pass | |
| AType = A # type: Type[A] | |
| BType = B # type: Type[B] | |
| CType = C # type: Type[C] | |
| @overload | |
| def f(a: Type[B]) -> None: pass | |
| @overload | |
| def f(a: int) -> None: pass | |
| f(A) # E: Argument 1 to "f" has incompatible type "type[A]"; expected "type[B]" | |
| f(B) | |
| f(C) | |
| f(AType) # E: Argument 1 to "f" has incompatible type "type[A]"; expected "type[B]" | |
| f(BType) | |
| f(CType) | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testOverloadedCovariantTypesFail] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, overload | |
| class A: pass | |
| class B(A): pass | |
| @overload | |
| def f(a: Type[B]) -> int: pass # E: Overloaded function signatures 1 and 2 overlap with incompatible return types | |
| @overload | |
| def f(a: Type[A]) -> str: pass | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testDistinctOverloadedCovariantTypesSucceed] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, overload | |
| class A: pass | |
| class AChild(A): pass | |
| class B: pass | |
| class BChild(B): pass | |
| @overload | |
| def f(a: Type[A]) -> int: pass | |
| @overload | |
| def f(a: Type[B]) -> str: pass | |
| @overload | |
| def f(a: A) -> A: pass | |
| @overload | |
| def f(a: B) -> B: pass | |
| reveal_type(f(A)) # N: Revealed type is "builtins.int" | |
| reveal_type(f(AChild)) # N: Revealed type is "builtins.int" | |
| reveal_type(f(B)) # N: Revealed type is "builtins.str" | |
| reveal_type(f(BChild)) # N: Revealed type is "builtins.str" | |
| reveal_type(f(A())) # N: Revealed type is "foo.A" | |
| reveal_type(f(AChild())) # N: Revealed type is "foo.A" | |
| reveal_type(f(B())) # N: Revealed type is "foo.B" | |
| reveal_type(f(BChild())) # N: Revealed type is "foo.B" | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testSubtypeWithMoreOverloadsThanSupertypeSucceeds] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload | |
| class X: pass | |
| class Y: pass | |
| class Z: pass | |
| class A: | |
| @overload | |
| def f(self, x: X) -> X: pass | |
| @overload | |
| def f(self, y: Y) -> Y: pass | |
| class B(A): | |
| @overload | |
| def f(self, x: X) -> X: pass | |
| @overload | |
| def f(self, y: Y) -> Y: pass | |
| @overload | |
| def f(self, z: Z) -> Z: pass | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testSubtypeOverloadCoveringMultipleSupertypeOverloadsSucceeds] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload | |
| class A: pass | |
| class B(A): pass | |
| class C(A): pass | |
| class D: pass | |
| class Super: | |
| @overload | |
| def foo(self, a: B) -> C: pass | |
| @overload | |
| def foo(self, a: C) -> A: pass | |
| @overload | |
| def foo(self, a: D) -> D: pass | |
| class Sub(Super): | |
| @overload | |
| def foo(self, a: A) -> C: pass | |
| @overload | |
| def foo(self, a: D) -> D: pass | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testSubtypeOverloadWithOverlappingArgumentsButWrongReturnType] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import overload | |
| class A: pass | |
| class B(A): pass | |
| class C: pass | |
| class Super: | |
| @overload | |
| def foo(self, a: A) -> A: pass | |
| @overload | |
| def foo(self, a: C) -> C: pass | |
| class Sub(Super): | |
| @overload | |
| def foo(self, a: A) -> A: pass | |
| @overload | |
| def foo(self, a: B) -> C: pass # Fail | |
| @overload | |
| def foo(self, a: C) -> C: pass | |
| class Sub2(Super): | |
| @overload | |
| def foo(self, a: B) -> C: pass # Fail | |
| @overload | |
| def foo(self, a: A) -> A: pass | |
| @overload | |
| def foo(self, a: C) -> C: pass | |
| class Sub3(Super): | |
| @overload | |
| def foo(self, a: A) -> int: pass | |
| @overload | |
| def foo(self, a: A) -> A: pass | |
| @overload | |
| def foo(self, a: C) -> C: pass | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| tmp/foo.pyi:19: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader | |
| tmp/foo.pyi:24: error: Signature of "foo" incompatible with supertype "Super" | |
| tmp/foo.pyi:24: note: Superclass: | |
| tmp/foo.pyi:24: note: @overload | |
| tmp/foo.pyi:24: note: def foo(self, a: A) -> A | |
| tmp/foo.pyi:24: note: @overload | |
| tmp/foo.pyi:24: note: def foo(self, a: C) -> C | |
| tmp/foo.pyi:24: note: Subclass: | |
| tmp/foo.pyi:24: note: @overload | |
| tmp/foo.pyi:24: note: def foo(self, a: B) -> C | |
| tmp/foo.pyi:24: note: @overload | |
| tmp/foo.pyi:24: note: def foo(self, a: A) -> A | |
| tmp/foo.pyi:24: note: @overload | |
| tmp/foo.pyi:24: note: def foo(self, a: C) -> C | |
| tmp/foo.pyi:25: error: Overloaded function signatures 1 and 2 overlap with incompatible return types | |
| tmp/foo.pyi:32: error: Signature of "foo" incompatible with supertype "Super" | |
| tmp/foo.pyi:32: note: Superclass: | |
| tmp/foo.pyi:32: note: @overload | |
| tmp/foo.pyi:32: note: def foo(self, a: A) -> A | |
| tmp/foo.pyi:32: note: @overload | |
| tmp/foo.pyi:32: note: def foo(self, a: C) -> C | |
| tmp/foo.pyi:32: note: Subclass: | |
| tmp/foo.pyi:32: note: @overload | |
| tmp/foo.pyi:32: note: def foo(self, a: A) -> int | |
| tmp/foo.pyi:32: note: @overload | |
| tmp/foo.pyi:32: note: def foo(self, a: A) -> A | |
| tmp/foo.pyi:32: note: @overload | |
| tmp/foo.pyi:32: note: def foo(self, a: C) -> C | |
| tmp/foo.pyi:35: error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader | |
| [case testTypeTypeOverlapsWithObjectAndType] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, overload | |
| class User: pass | |
| @overload | |
| def f(a: Type[User]) -> int: pass # E: Overloaded function signatures 1 and 2 overlap with incompatible return types | |
| @overload | |
| def f(a: object) -> str: pass | |
| # Note: plain type is equivalent to Type[Any] so no error here | |
| @overload | |
| def g(a: Type[User]) -> int: pass | |
| @overload | |
| def g(a: type) -> str: pass | |
| @overload | |
| def h(a: Type[User]) -> int: pass # E: Overloaded function signatures 1 and 2 overlap with incompatible return types | |
| @overload | |
| def h(a: Type[object]) -> str: pass | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testTypeOverlapsWithObject] | |
| from foo import * | |
| [file foo.pyi] | |
| from typing import Type, overload | |
| class User: pass | |
| @overload | |
| def f(a: type) -> int: pass # E: Overloaded function signatures 1 and 2 overlap with incompatible return types | |
| @overload | |
| def f(a: object) -> str: pass | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testTypeConstructorReturnsTypeType] | |
| class User: | |
| @classmethod | |
| def test_class_method(cls) -> int: pass | |
| @staticmethod | |
| def test_static_method() -> str: pass | |
| def test_instance_method(self) -> None: pass | |
| u = User() | |
| reveal_type(type(u)) # N: Revealed type is "type[__main__.User]" | |
| reveal_type(type(u).test_class_method()) # N: Revealed type is "builtins.int" | |
| reveal_type(type(u).test_static_method()) # N: Revealed type is "builtins.str" | |
| type(u).test_instance_method() # E: Missing positional argument "self" in call to "test_instance_method" of "User" | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testObfuscatedTypeConstructorReturnsTypeType] | |
| from typing import TypeVar | |
| class User: pass | |
| f1 = type | |
| A = TypeVar('A') | |
| def f2(func: A) -> A: | |
| return func | |
| u = User() | |
| reveal_type(f1(u)) # N: Revealed type is "type[__main__.User]" | |
| reveal_type(f2(type)(u)) # N: Revealed type is "type[__main__.User]" | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testTypeConstructorLookalikeFails] | |
| class User: pass | |
| def fake1(a: object) -> type: | |
| return User | |
| def fake2(a: int) -> type: | |
| return User | |
| reveal_type(type(User())) # N: Revealed type is "type[__main__.User]" | |
| reveal_type(fake1(User())) # N: Revealed type is "builtins.type" | |
| reveal_type(fake2(3)) # N: Revealed type is "builtins.type" | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testOtherTypeConstructorsSucceed] | |
| def foo(self) -> int: return self.attr | |
| User = type('User', (object,), {'foo': foo, 'attr': 3}) | |
| reveal_type(User) # N: Revealed type is "builtins.type" | |
| [builtins fixtures/args.pyi] | |
| [out] | |
| [case testTypeTypeComparisonWorks] | |
| class User: pass | |
| User == User | |
| User == type(User()) | |
| type(User()) == User | |
| type(User()) == type(User()) | |
| User != User | |
| User != type(User()) | |
| type(User()) != User | |
| type(User()) != type(User()) | |
| int == int | |
| int == type(3) | |
| type(3) == int | |
| type(3) == type(3) | |
| int != int | |
| int != type(3) | |
| type(3) != int | |
| type(3) != type(3) | |
| User is User | |
| User is type(User) | |
| type(User) is User | |
| type(User) is type(User) | |
| int is int | |
| int is type(3) | |
| type(3) is int | |
| type(3) is type(3) | |
| int.__eq__(int) | |
| int.__eq__(3, 4) | |
| [builtins fixtures/args.pyi] | |
| [out] | |
| main:33: error: Too few arguments for "__eq__" of "int" | |
| main:33: error: Unsupported operand types for == ("type[int]" and "type[int]") | |
| [case testDupBaseClasses] | |
| class A: | |
| def method(self) -> str: ... | |
| class B(A, A): # E: Duplicate base class "A" | |
| attr: int | |
| b: B | |
| reveal_type(b.method()) # N: Revealed type is "Any" | |
| reveal_type(b.missing()) # N: Revealed type is "Any" | |
| reveal_type(b.attr) # N: Revealed type is "builtins.int" | |
| [case testDupBaseClassesGeneric] | |
| from typing import Generic, TypeVar | |
| T = TypeVar('T') | |
| class A(Generic[T]): | |
| def method(self) -> T: ... | |
| class B(A[int], A[str]): # E: Duplicate base class "A" | |
| attr: int | |
| reveal_type(B().method()) # N: Revealed type is "Any" | |
| reveal_type(B().attr) # N: Revealed type is "builtins.int" | |
| [case testCannotDetermineMro] | |
| class A: pass | |
| class B(A): pass | |
| class C(B): pass | |
| class D(A, B): pass # E: Cannot determine consistent method resolution order (MRO) for "D" | |
| class E(C, D): pass | |
| [case testInconsistentMroLocalRef] | |
| class A: pass | |
| class B(object, A): # E: Cannot determine consistent method resolution order (MRO) for "B" | |
| def readlines(self): pass | |
| __iter__ = readlines | |
| [case testDynamicMetaclass] | |
| class C(metaclass=int()): # E: Dynamic metaclass not supported for "C" | |
| pass | |
| [case testDynamicMetaclassCrash] | |
| class C(metaclass=int().x): # E: Dynamic metaclass not supported for "C" | |
| pass | |
| [case testVariableSubclass] | |
| class A: | |
| a = 1 # type: int | |
| class B(A): | |
| a = 1 | |
| [out] | |
| [case testVariableSubclassAssignMismatch] | |
| class A: | |
| a = 1 # type: int | |
| class B(A): | |
| a = "a" | |
| [out] | |
| main:4: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int") | |
| [case testVariableSubclassAssignment] | |
| class A: | |
| a: int | |
| class B(A): | |
| def __init__(self) -> None: | |
| self.a = "a" | |
| [out] | |
| main:5: error: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| [case testVariableSubclassTypeOverwrite] | |
| class A: | |
| a: int | |
| class B(A): | |
| a: str | |
| class C(B): | |
| a = "a" | |
| [out] | |
| main:4: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int") | |
| [case testVariableSubclassTypeOverwriteImplicit] | |
| class A: | |
| a = 1 | |
| class B(A): | |
| a: str | |
| [out] | |
| main:4: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int") | |
| [case testVariableSuperUsage] | |
| class A: | |
| a = [] # type: list | |
| class B(A): | |
| a = [1, 2] | |
| class C(B): | |
| a = B.a + [3] | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| [case testClassAllBases] | |
| from typing import Union | |
| class A: | |
| a: Union[int, str] | |
| class B(A): | |
| a = 1 | |
| class C(B): | |
| a = "str" | |
| class D(A): | |
| a = "str" | |
| [out] | |
| main:7: error: Incompatible types in assignment (expression has type "str", base class "B" defined the type as "int") | |
| [case testVariableTypeVar] | |
| from typing import TypeVar, Generic | |
| T = TypeVar('T') | |
| class A(Generic[T]): | |
| a: T | |
| class B(A[int]): | |
| a = 1 | |
| [case testVariableTypeVarInvalid] | |
| from typing import TypeVar, Generic | |
| T = TypeVar('T') | |
| class A(Generic[T]): | |
| a: T | |
| class B(A[int]): | |
| a = "abc" | |
| [out] | |
| main:6: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int") | |
| [case testVariableTypeVarIndirectly] | |
| from typing import TypeVar, Generic | |
| T = TypeVar('T') | |
| class A(Generic[T]): | |
| a: T | |
| class B(A[int]): | |
| pass | |
| class C(B): | |
| a = "a" | |
| [out] | |
| main:8: error: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int") | |
| [case testVariableTypeVarList] | |
| from typing import List, TypeVar, Generic | |
| T = TypeVar('T') | |
| class A(Generic[T]): | |
| a: List[T] | |
| b: List[T] | |
| class B(A[int]): | |
| a = [1] | |
| b = [''] | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| main:8: error: List item 0 has incompatible type "str"; expected "int" | |
| [case testVariableMethod] | |
| class A: | |
| def a(self) -> None: pass | |
| b = 1 | |
| class B(A): | |
| a = 1 # E: Incompatible types in assignment (expression has type "int", base class "A" defined the type as "Callable[[], None]") | |
| def b(self) -> None: pass # E: Signature of "b" incompatible with supertype "A" \ | |
| # N: Superclass: \ | |
| # N: int \ | |
| # N: Subclass: \ | |
| # N: def b(self) -> None | |
| [case testVariableProperty] | |
| class A: | |
| @property | |
| def a(self) -> bool: pass | |
| class B(A): | |
| a: bool | |
| class C(A): | |
| a = True | |
| class D(A): | |
| a = 1 | |
| [builtins fixtures/property.pyi] | |
| [out] | |
| main:9: error: Incompatible types in assignment (expression has type "int", base class "A" defined the type as "bool") | |
| [case testVariableOverwriteAny] | |
| from typing import Any | |
| class A: | |
| a = 1 | |
| class B(A): | |
| a = 'x' # type: Any | |
| [out] | |
| [case testInstanceMethodOverwrite] | |
| class B(): | |
| def n(self, a: int) -> None: pass | |
| class C(B): | |
| def m(self, a: int) -> None: pass | |
| n = m | |
| [out] | |
| [case testInstanceMethodOverwriteError] | |
| class B(): | |
| def n(self, a: int) -> None: pass | |
| class C(B): | |
| def m(self, a: str) -> None: pass | |
| n = m | |
| [out] | |
| main:5: error: Incompatible types in assignment (expression has type "Callable[[str], None]", base class "B" defined the type as "Callable[[int], None]") | |
| [case testInstanceMethodOverwriteTypevar] | |
| from typing import Generic, TypeVar | |
| T = TypeVar("T") | |
| class B(Generic[T]): | |
| def n(self, a: T) -> None: pass | |
| class C(B[int]): | |
| def m(self, a: int) -> None: pass | |
| n = m | |
| [case testInstanceMethodOverwriteTwice] | |
| class I: | |
| def foo(self) -> None: pass | |
| class A(I): | |
| def foo(self) -> None: pass | |
| class B(A): | |
| def bar(self) -> None: pass | |
| foo = bar | |
| class C(B): | |
| def bar(self) -> None: pass | |
| foo = bar | |
| [case testClassMethodOverwrite] | |
| class B(): | |
| @classmethod | |
| def n(self, a: int) -> None: pass | |
| class C(B): | |
| @classmethod | |
| def m(self, a: int) -> None: pass | |
| n = m | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testClassMethodOverwriteError] | |
| class B(): | |
| @classmethod | |
| def n(self, a: int) -> None: pass | |
| class C(B): | |
| @classmethod | |
| def m(self, a: str) -> None: pass | |
| n = m | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| main:7: error: Incompatible types in assignment (expression has type "Callable[[str], None]", base class "B" defined the type as "Callable[[int], None]") | |
| [case testClassSpec] | |
| from typing import Callable | |
| class A(): | |
| b: Callable[[int], int] | |
| class B(A): | |
| def c(self, a: int) -> int: pass | |
| b = c | |
| reveal_type(A().b) # N: Revealed type is "def (builtins.int) -> builtins.int" | |
| reveal_type(B().b) # N: Revealed type is "def (a: builtins.int) -> builtins.int" | |
| [case testClassSpecError] | |
| from typing import Callable | |
| class A(): | |
| b: Callable[[int], int] | |
| class B(A): | |
| def c(self, a: str) -> int: pass | |
| b = c # E: Incompatible types in assignment (expression has type "Callable[[str], int]", base class "A" defined the type as "Callable[[int], int]") | |
| [case testClassStaticMethod] | |
| class A(): | |
| @staticmethod | |
| def a(a: int) -> None: pass | |
| class B(A): | |
| @staticmethod | |
| def b(a: str) -> None: pass | |
| a = b | |
| [builtins fixtures/staticmethod.pyi] | |
| [out] | |
| main:7: error: Incompatible types in assignment (expression has type "Callable[[str], None]", base class "A" defined the type as "Callable[[int], None]") | |
| [case testClassStaticMethodIndirect] | |
| class A(): | |
| @staticmethod | |
| def a(a: int) -> None: pass | |
| c = a | |
| class B(A): | |
| @staticmethod | |
| def b(a: str) -> None: pass | |
| c = b # E: Incompatible types in assignment (expression has type "Callable[[str], None]", base class "A" defined the type as "Callable[[int], None]") | |
| a: A | |
| reveal_type(a.a) # N: Revealed type is "def (a: builtins.int)" | |
| reveal_type(a.c) # N: Revealed type is "def (a: builtins.int)" | |
| [builtins fixtures/staticmethod.pyi] | |
| [case testClassStaticMethodIndirectOverloaded] | |
| from typing import overload | |
| class A: | |
| @overload | |
| @staticmethod | |
| def a(x: int) -> int: ... | |
| @overload | |
| @staticmethod | |
| def a(x: str) -> str: ... | |
| @staticmethod | |
| def a(x): | |
| ... | |
| c = a | |
| reveal_type(A.c) # N: Revealed type is "Overload(def (x: builtins.int) -> builtins.int, def (x: builtins.str) -> builtins.str)" | |
| reveal_type(A().c) # N: Revealed type is "Overload(def (x: builtins.int) -> builtins.int, def (x: builtins.str) -> builtins.str)" | |
| [builtins fixtures/staticmethod.pyi] | |
| [case testClassStaticMethodSubclassing] | |
| class A: | |
| @staticmethod | |
| def a() -> None: pass | |
| def b(self) -> None: pass | |
| @staticmethod | |
| def c() -> None: pass | |
| class B(A): | |
| def a(self) -> None: pass # Fail | |
| @classmethod | |
| def b(cls) -> None: pass | |
| @staticmethod | |
| def c() -> None: pass | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| main:11: error: Signature of "a" incompatible with supertype "A" | |
| main:11: note: Superclass: | |
| main:11: note: @staticmethod | |
| main:11: note: def a() -> None | |
| main:11: note: Subclass: | |
| main:11: note: def a(self) -> None | |
| [case testTempNode] | |
| class A(): | |
| def a(self) -> None: pass | |
| class B(A): | |
| def b(self) -> None: pass | |
| a = c = b | |
| [case testListObject] | |
| from typing import List | |
| class A: | |
| x = [] # type: List[object] | |
| class B(A): | |
| x = [1] | |
| [builtins fixtures/list.pyi] | |
| [case testClassMemberObject] | |
| class A: | |
| x = object() | |
| class B(A): | |
| x = 1 | |
| class C(B): | |
| x = '' | |
| [out] | |
| main:6: error: Incompatible types in assignment (expression has type "str", base class "B" defined the type as "int") | |
| [case testSlots] | |
| class A: | |
| __slots__ = ("a") | |
| class B(A): | |
| __slots__ = ("a", "b") | |
| [builtins fixtures/tuple.pyi] | |
| [case testClassOrderOfError] | |
| class A: | |
| x = 1 | |
| class B(A): | |
| x = "a" # E: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int") | |
| class C(B): | |
| x = object() # E: Incompatible types in assignment (expression has type "object", base class "B" defined the type as "str") | |
| [case testClassOneErrorPerLine] | |
| class A: | |
| x = 1 | |
| class B(A): | |
| x: str = "" # E: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int") | |
| x = 1.0 # E: Incompatible types in assignment (expression has type "float", variable has type "str") | |
| class BInfer(A): | |
| x = "" # E: Incompatible types in assignment (expression has type "str", base class "A" defined the type as "int") | |
| x = 1.0 # E: Incompatible types in assignment (expression has type "float", variable has type "str") \ | |
| # E: Incompatible types in assignment (expression has type "float", base class "A" defined the type as "int") | |
| [case testClassIgnoreType_RedefinedAttributeAndGrandparentAttributeTypesNotIgnored] | |
| class A: | |
| x = 0 | |
| class B(A): | |
| x = '' # type: ignore | |
| class C(B): | |
| x = '' | |
| [case testClassIgnoreType_RedefinedAttributeTypeIgnoredInChildren] | |
| class A: | |
| x = 0 | |
| class B(A): | |
| x = '' # type: ignore | |
| class C(B): | |
| x = '' # type: ignore | |
| [case testInvalidMetaclassStructure] | |
| class X(type): pass | |
| class Y(type): pass | |
| class A(metaclass=X): pass | |
| class B(A, metaclass=Y): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \ | |
| # N: "__main__.Y" (metaclass of "__main__.B") conflicts with "__main__.X" (metaclass of "__main__.A") | |
| [case testMetaclassNoTypeReveal] | |
| class M: | |
| x = 0 # type: int | |
| class A(metaclass=M): pass # E: Metaclasses not inheriting from "type" are not supported | |
| A.x # E: "type[A]" has no attribute "x" | |
| [case testMetaclassTypeReveal] | |
| from typing import Type | |
| class M(type): | |
| x = 0 # type: int | |
| class A(metaclass=M): pass | |
| def f(TA: Type[A]): | |
| reveal_type(TA) # N: Revealed type is "type[__main__.A]" | |
| reveal_type(TA.x) # N: Revealed type is "builtins.int" | |
| [case testMetaclassConflictingInstanceVars] | |
| from typing import ClassVar | |
| class Meta(type): | |
| foo: int | |
| bar: int | |
| eggs: ClassVar[int] = 42 | |
| spam: ClassVar[int] = 42 | |
| class Foo(metaclass=Meta): | |
| foo: str | |
| bar: ClassVar[str] = 'bar' | |
| eggs: str | |
| spam: ClassVar[str] = 'spam' | |
| reveal_type(Foo.foo) # N: Revealed type is "builtins.int" | |
| reveal_type(Foo.bar) # N: Revealed type is "builtins.str" | |
| reveal_type(Foo.eggs) # N: Revealed type is "builtins.int" | |
| reveal_type(Foo.spam) # N: Revealed type is "builtins.str" | |
| class MetaSub(Meta): ... | |
| class Bar(metaclass=MetaSub): | |
| foo: str | |
| bar: ClassVar[str] = 'bar' | |
| eggs: str | |
| spam: ClassVar[str] = 'spam' | |
| reveal_type(Bar.foo) # N: Revealed type is "builtins.int" | |
| reveal_type(Bar.bar) # N: Revealed type is "builtins.str" | |
| reveal_type(Bar.eggs) # N: Revealed type is "builtins.int" | |
| reveal_type(Bar.spam) # N: Revealed type is "builtins.str" | |
| [case testSubclassMetaclass] | |
| class M1(type): | |
| x = 0 | |
| class M2(M1): pass | |
| class C(metaclass=M2): | |
| pass | |
| reveal_type(C.x) # N: Revealed type is "builtins.int" | |
| [case testMetaclassSubclass] | |
| from typing import Type | |
| class M(type): | |
| x = 0 # type: int | |
| class A(metaclass=M): pass | |
| class B(A): pass | |
| def f(TB: Type[B]): | |
| reveal_type(TB) # N: Revealed type is "type[__main__.B]" | |
| reveal_type(TB.x) # N: Revealed type is "builtins.int" | |
| [case testMetaclassAsAny] | |
| from typing import Any, ClassVar, Type | |
| MyAny: Any | |
| class WithMeta(metaclass=MyAny): | |
| x: ClassVar[int] | |
| reveal_type(WithMeta.a) # N: Revealed type is "Any" | |
| reveal_type(WithMeta.m) # N: Revealed type is "Any" | |
| reveal_type(WithMeta.x) # N: Revealed type is "builtins.int" | |
| reveal_type(WithMeta().x) # N: Revealed type is "builtins.int" | |
| WithMeta().m # E: "WithMeta" has no attribute "m" | |
| WithMeta().a # E: "WithMeta" has no attribute "a" | |
| t: Type[WithMeta] | |
| t.unknown # OK | |
| [case testMetaclassAsAnyWithAFlag] | |
| # flags: --disallow-subclassing-any | |
| from typing import Any, ClassVar, Type | |
| MyAny: Any | |
| class WithMeta(metaclass=MyAny): # E: Class cannot use "MyAny" as a metaclass (has type "Any") | |
| x: ClassVar[int] | |
| reveal_type(WithMeta.a) # N: Revealed type is "Any" | |
| reveal_type(WithMeta.m) # N: Revealed type is "Any" | |
| reveal_type(WithMeta.x) # N: Revealed type is "builtins.int" | |
| reveal_type(WithMeta().x) # N: Revealed type is "builtins.int" | |
| WithMeta().m # E: "WithMeta" has no attribute "m" | |
| WithMeta().a # E: "WithMeta" has no attribute "a" | |
| t: Type[WithMeta] | |
| t.unknown # OK | |
| [case testUnpackIterableClassWithOverloadedIter] | |
| from typing import Generic, overload, Iterator, TypeVar, Union | |
| AnyNum = TypeVar('AnyNum', int, float) | |
| class Foo(Generic[AnyNum]): | |
| @overload | |
| def __iter__(self: Foo[int]) -> Iterator[float]: ... | |
| @overload | |
| def __iter__(self: Foo[float]) -> Iterator[int]: ... | |
| def __iter__(self) -> Iterator[Union[float, int]]: | |
| ... | |
| a, b, c = Foo[int]() | |
| reveal_type(a) # N: Revealed type is "builtins.float" | |
| reveal_type(b) # N: Revealed type is "builtins.float" | |
| reveal_type(c) # N: Revealed type is "builtins.float" | |
| x, y = Foo[float]() | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| reveal_type(y) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/list.pyi] | |
| [case testUnpackIterableClassWithOverloadedIter2] | |
| from typing import Union, TypeVar, Generic, overload, Iterator | |
| X = TypeVar('X') | |
| class Foo(Generic[X]): | |
| @overload | |
| def __iter__(self: Foo[str]) -> Iterator[int]: ... # type: ignore | |
| @overload | |
| def __iter__(self: Foo[X]) -> Iterator[str]: ... | |
| def __iter__(self) -> Iterator[Union[int, str]]: | |
| ... | |
| a, b, c = Foo[str]() | |
| reveal_type(a) # N: Revealed type is "builtins.int" | |
| reveal_type(b) # N: Revealed type is "builtins.int" | |
| reveal_type(c) # N: Revealed type is "builtins.int" | |
| x, y = Foo[float]() | |
| reveal_type(x) # N: Revealed type is "builtins.str" | |
| reveal_type(y) # N: Revealed type is "builtins.str" | |
| [builtins fixtures/list.pyi] | |
| [case testUnpackIterableRegular] | |
| from typing import TypeVar, Generic, Iterator | |
| X = TypeVar('X') | |
| class Foo(Generic[X]): | |
| def __iter__(self) -> Iterator[X]: | |
| ... | |
| a, b = Foo[int]() | |
| reveal_type(a) # N: Revealed type is "builtins.int" | |
| reveal_type(b) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/list.pyi] | |
| [case testUnpackNotIterableClass] | |
| class Foo: ... | |
| a, b, c = Foo() # E: "Foo" object is not iterable | |
| [builtins fixtures/list.pyi] | |
| [case testMetaclassIterable] | |
| from typing import Iterable, Iterator | |
| class ImplicitMeta(type): | |
| def __iter__(self) -> Iterator[int]: yield 1 | |
| class Implicit(metaclass=ImplicitMeta): pass | |
| for _ in Implicit: pass | |
| reveal_type(list(Implicit)) # N: Revealed type is "builtins.list[builtins.int]" | |
| class ExplicitMeta(type, Iterable[int]): | |
| def __iter__(self) -> Iterator[int]: yield 1 | |
| class Explicit(metaclass=ExplicitMeta): pass | |
| for _ in Explicit: pass | |
| reveal_type(list(Explicit)) # N: Revealed type is "builtins.list[builtins.int]" | |
| [builtins fixtures/list.pyi] | |
| [case testMetaclassTuple] | |
| from typing import Tuple | |
| class M(Tuple[int]): pass | |
| class C(metaclass=M): pass # E: Invalid metaclass "M" | |
| [builtins fixtures/tuple.pyi] | |
| [case testMetaclassOperatorBeforeReversed] | |
| class X: | |
| def __radd__(self, x: int) -> int: ... | |
| class Meta(type): | |
| def __add__(cls, x: X) -> str: ... | |
| class Concrete(metaclass=Meta): | |
| pass | |
| reveal_type(Concrete + X()) # N: Revealed type is "builtins.str" | |
| Concrete + "hello" # E: Unsupported operand types for + ("type[Concrete]" and "str") | |
| [case testMetaclassOperatorTypeVar] | |
| from typing import Type, TypeVar | |
| class MetaClass(type): | |
| def __mul__(cls, other: int) -> str: | |
| return "" | |
| class Test(metaclass=MetaClass): | |
| pass | |
| S = TypeVar("S", bound=Test) | |
| def f(x: Type[Test]) -> str: | |
| return x * 0 | |
| def g(x: Type[S]) -> str: | |
| return reveal_type(x * 0) # N: Revealed type is "builtins.str" | |
| [case testMetaclassGetitem] | |
| import types | |
| class M(type): | |
| def __getitem__(self, key) -> int: return 1 | |
| class A(metaclass=M): pass | |
| reveal_type(A[M]) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/tuple.pyi] | |
| [case testMetaclassSelfType] | |
| from typing import TypeVar, Type | |
| class M(type): pass | |
| T = TypeVar('T') | |
| class M1(M): | |
| def foo(cls: Type[T]) -> T: ... | |
| class A(metaclass=M1): pass | |
| reveal_type(A.foo()) # N: Revealed type is "__main__.A" | |
| [case testMetaclassAndSkippedImport] | |
| # flags: --ignore-missing-imports | |
| from missing import M | |
| class A(metaclass=M): | |
| y = 0 | |
| reveal_type(A.y) # N: Revealed type is "builtins.int" | |
| reveal_type(A.x) # N: Revealed type is "Any" | |
| [case testValidTypeAliasAsMetaclass] | |
| from typing_extensions import TypeAlias | |
| Explicit: TypeAlias = type | |
| Implicit = type | |
| class E(metaclass=Explicit): ... | |
| class I(metaclass=Implicit): ... | |
| [builtins fixtures/classmethod.pyi] | |
| [case testValidTypeAliasOfTypeAliasAsMetaclass] | |
| from typing_extensions import TypeAlias | |
| Explicit: TypeAlias = type | |
| Implicit = type | |
| A1: TypeAlias = Explicit | |
| A2 = Explicit | |
| A3: TypeAlias = Implicit | |
| A4 = Implicit | |
| class C1(metaclass=A1): ... | |
| class C2(metaclass=A2): ... | |
| class C3(metaclass=A3): ... | |
| class C4(metaclass=A4): ... | |
| [builtins fixtures/classmethod.pyi] | |
| [case testTypeAliasWithArgsAsMetaclass] | |
| from typing import Generic, TypeVar | |
| from typing_extensions import TypeAlias | |
| T = TypeVar('T') | |
| class Meta(Generic[T]): ... | |
| Explicit: TypeAlias = Meta[T] | |
| Implicit = Meta[T] | |
| class E(metaclass=Explicit): ... # E: Invalid metaclass "Explicit" | |
| class I(metaclass=Implicit): ... # E: Invalid metaclass "Implicit" | |
| [builtins fixtures/classmethod.pyi] | |
| [case testTypeAliasNonTypeAsMetaclass] | |
| from typing_extensions import TypeAlias | |
| Explicit: TypeAlias = int | |
| Implicit = int | |
| class E(metaclass=Explicit): ... # E: Metaclasses not inheriting from "type" are not supported | |
| class I(metaclass=Implicit): ... # E: Metaclasses not inheriting from "type" are not supported | |
| [builtins fixtures/classmethod.pyi] | |
| [case testInvalidVariableAsMetaclass] | |
| from typing import Any | |
| M = 0 # type: int | |
| MM = 0 | |
| class A(metaclass=M): # E: Invalid metaclass "M" | |
| y = 0 | |
| class B(metaclass=MM): # E: Invalid metaclass "MM" | |
| y = 0 | |
| reveal_type(A.y) # N: Revealed type is "builtins.int" | |
| A.x # E: "type[A]" has no attribute "x" | |
| [case testAnyAsBaseOfMetaclass] | |
| from typing import Any, Type | |
| M = None # type: Any | |
| class MM(M): pass | |
| class A(metaclass=MM): | |
| y = 0 | |
| @classmethod | |
| def f(cls) -> None: pass | |
| def g(self) -> None: pass | |
| def h(a: Type[A], b: Type[object]) -> None: | |
| h(a, a) | |
| h(b, a) # E: Argument 1 to "h" has incompatible type "type[object]"; expected "type[A]" | |
| a.f(1) # E: Too many arguments for "f" of "A" | |
| reveal_type(a.y) # N: Revealed type is "builtins.int" | |
| x = A # type: MM | |
| reveal_type(A.y) # N: Revealed type is "builtins.int" | |
| reveal_type(A.x) # N: Revealed type is "Any" | |
| A.f(1) # E: Too many arguments for "f" of "A" | |
| A().g(1) # E: Too many arguments for "g" of "A" | |
| [builtins fixtures/classmethod.pyi] | |
| [case testMetaclassTypeCallable] | |
| class M(type): | |
| x = 5 | |
| class A(metaclass=M): pass | |
| reveal_type(type(A).x) # N: Revealed type is "builtins.int" | |
| [case testMetaclassStrictSupertypeOfTypeWithClassmethods] | |
| from typing import Type, TypeVar | |
| TA = TypeVar('TA', bound='A') | |
| TTA = TypeVar('TTA', bound='Type[A]') | |
| TM = TypeVar('TM', bound='M') | |
| class M(type): | |
| def g1(cls: 'Type[A]') -> A: pass # E: The erased type of self "type[__main__.A]" is not a supertype of its class "__main__.M" | |
| def g2(cls: Type[TA]) -> TA: pass # E: The erased type of self "type[__main__.A]" is not a supertype of its class "__main__.M" | |
| def g3(cls: TTA) -> TTA: pass # E: The erased type of self "type[__main__.A]" is not a supertype of its class "__main__.M" | |
| def g4(cls: TM) -> TM: pass | |
| m: M | |
| class A(metaclass=M): | |
| def foo(self): pass | |
| reveal_type(A.g1) # N: Revealed type is "def () -> __main__.A" | |
| reveal_type(A.g2) # N: Revealed type is "def () -> __main__.A" | |
| reveal_type(A.g3) # N: Revealed type is "def () -> def () -> __main__.A" | |
| reveal_type(A.g4) # N: Revealed type is "def () -> def () -> __main__.A" | |
| class B(metaclass=M): | |
| def foo(self): pass | |
| B.g1 # E: Invalid self argument "type[B]" to attribute function "g1" with type "Callable[[type[A]], A]" | |
| B.g2 # E: Invalid self argument "type[B]" to attribute function "g2" with type "Callable[[type[TA]], TA]" | |
| B.g3 # E: Invalid self argument "type[B]" to attribute function "g3" with type "Callable[[TTA], TTA]" | |
| reveal_type(B.g4) # N: Revealed type is "def () -> def () -> __main__.B" | |
| # 4 examples of unsoundness - instantiation, classmethod, staticmethod and ClassVar: | |
| ta: Type[A] = m # E: Incompatible types in assignment (expression has type "M", variable has type "type[A]") | |
| a: A = ta() | |
| reveal_type(ta.g1) # N: Revealed type is "def () -> __main__.A" | |
| reveal_type(ta.g2) # N: Revealed type is "def () -> __main__.A" | |
| reveal_type(ta.g3) # N: Revealed type is "def () -> type[__main__.A]" | |
| reveal_type(ta.g4) # N: Revealed type is "def () -> type[__main__.A]" | |
| x: M = ta | |
| x.g1 # E: Invalid self argument "M" to attribute function "g1" with type "Callable[[type[A]], A]" | |
| x.g2 # E: Invalid self argument "M" to attribute function "g2" with type "Callable[[type[TA]], TA]" | |
| x.g3 # E: Invalid self argument "M" to attribute function "g3" with type "Callable[[TTA], TTA]" | |
| reveal_type(x.g4) # N: Revealed type is "def () -> __main__.M" | |
| def r(ta: Type[TA], tta: TTA) -> None: | |
| x: M = ta | |
| y: M = tta | |
| class Class(metaclass=M): | |
| @classmethod | |
| def f1(cls: Type[Class]) -> None: pass | |
| @classmethod | |
| def f2(cls: M) -> None: pass | |
| cl: Type[Class] = m # E: Incompatible types in assignment (expression has type "M", variable has type "type[Class]") | |
| reveal_type(cl.f1) # N: Revealed type is "def ()" | |
| reveal_type(cl.f2) # N: Revealed type is "def ()" | |
| x1: M = cl | |
| class Static(metaclass=M): | |
| @staticmethod | |
| def f() -> None: pass | |
| s: Type[Static] = m # E: Incompatible types in assignment (expression has type "M", variable has type "type[Static]") | |
| reveal_type(s.f) # N: Revealed type is "def ()" | |
| x2: M = s | |
| from typing import ClassVar | |
| class Cvar(metaclass=M): | |
| x = 1 # type: ClassVar[int] | |
| cv: Type[Cvar] = m # E: Incompatible types in assignment (expression has type "M", variable has type "type[Cvar]") | |
| cv.x | |
| x3: M = cv | |
| [builtins fixtures/classmethod.pyi] | |
| [case testMetaclassOverloadResolution] | |
| from typing import Type, overload | |
| class A: pass | |
| class EM(type): pass | |
| class E(metaclass=EM): pass | |
| class EM1(type): pass | |
| class E1(metaclass=EM1): pass | |
| @overload | |
| def f(x: EM) -> int: ... | |
| @overload | |
| def f(x: EM1) -> A: ... | |
| @overload | |
| def f(x: str) -> str: ... | |
| def f(x: object) -> object: return '' | |
| e: EM | |
| reveal_type(f(e)) # N: Revealed type is "builtins.int" | |
| et: Type[E] | |
| reveal_type(f(et)) # N: Revealed type is "builtins.int" | |
| e1: EM1 | |
| reveal_type(f(e1)) # N: Revealed type is "__main__.A" | |
| e1t: Type[E1] | |
| reveal_type(f(e1t)) # N: Revealed type is "__main__.A" | |
| reveal_type(f('')) # N: Revealed type is "builtins.str" | |
| [case testTypeCErasesGenericsFromC] | |
| from typing import Generic, Type, TypeVar | |
| K = TypeVar('K') | |
| V = TypeVar('V') | |
| class ExampleDict(Generic[K, V]): ... | |
| D = TypeVar('D') | |
| def mkdict(dict_type: Type[D]) -> D: ... | |
| reveal_type(mkdict(ExampleDict)) # N: Revealed type is "__main__.ExampleDict[Any, Any]" | |
| [case testTupleForwardBase] | |
| from m import a | |
| a[0]() # E: "int" not callable | |
| [file m.py] | |
| from typing import Tuple | |
| a: A | |
| class A(Tuple[int, str]): pass | |
| [builtins fixtures/tuple.pyi] | |
| -- Synthetic types crashes | |
| -- ----------------------- | |
| [case testCrashOnSelfRecursiveNamedTupleVar] | |
| from typing import NamedTuple | |
| def test() -> None: | |
| N = NamedTuple('N', [('x', N)]) # E: Cannot resolve name "N" (possible cyclic definition) \ | |
| # N: Recursive types are not allowed at function scope | |
| n: N | |
| reveal_type(n) # N: Revealed type is "tuple[Any, fallback=__main__.N@4]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testCrashOnSelfRecursiveTypedDictVar] | |
| from typing import TypedDict | |
| A = TypedDict('A', {'a': 'A'}) # type: ignore | |
| a: A | |
| [builtins fixtures/isinstancelist.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [case testCrashInJoinOfSelfRecursiveNamedTuples] | |
| from typing import NamedTuple | |
| class N(NamedTuple): | |
| x: N # type: ignore | |
| class M(NamedTuple): | |
| x: M # type: ignore | |
| n: N | |
| m: M | |
| lst = [n, m] | |
| [builtins fixtures/isinstancelist.pyi] | |
| [case testCorrectJoinOfSelfRecursiveTypedDicts] | |
| from typing import TypedDict | |
| def test() -> None: | |
| class N(TypedDict): | |
| x: N # E: Cannot resolve name "N" (possible cyclic definition) \ | |
| # N: Recursive types are not allowed at function scope | |
| class M(TypedDict): | |
| x: M # E: Cannot resolve name "M" (possible cyclic definition) \ | |
| # N: Recursive types are not allowed at function scope | |
| n: N | |
| m: M | |
| lst = [n, m] | |
| reveal_type(lst[0]['x']) # N: Revealed type is "Any" | |
| [builtins fixtures/isinstancelist.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [case testCrashInForwardRefToNamedTupleWithIsinstance] | |
| from typing import Dict, NamedTuple | |
| NameDict = Dict[str, 'NameInfo'] | |
| class NameInfo(NamedTuple): | |
| ast: bool | |
| def parse_ast(name_dict: NameDict) -> None: | |
| if isinstance(name_dict[''], int): | |
| pass | |
| reveal_type(name_dict['test']) # N: Revealed type is "tuple[builtins.bool, fallback=__main__.NameInfo]" | |
| [builtins fixtures/isinstancelist.pyi] | |
| [typing fixtures/typing-medium.pyi] | |
| [case testCrashInForwardRefToTypedDictWithIsinstance] | |
| from typing import Dict, TypedDict | |
| NameDict = Dict[str, 'NameInfo'] | |
| class NameInfo(TypedDict): | |
| ast: bool | |
| def parse_ast(name_dict: NameDict) -> None: | |
| if isinstance(name_dict[''], int): | |
| pass | |
| reveal_type(name_dict['']['ast']) # N: Revealed type is "builtins.bool" | |
| [builtins fixtures/isinstancelist.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [case testCorrectIsinstanceInForwardRefToNewType] | |
| from typing import Dict, NewType | |
| NameDict = Dict[str, 'NameInfo'] | |
| class Base: | |
| ast: bool | |
| NameInfo = NewType('NameInfo', Base) | |
| def parse_ast(name_dict: NameDict) -> None: | |
| if isinstance(name_dict[''], int): | |
| pass | |
| x = name_dict[''] | |
| reveal_type(x) # N: Revealed type is "__main__.NameInfo" | |
| if int(): | |
| x = NameInfo(Base()) # OK | |
| x = Base() # E: Incompatible types in assignment (expression has type "Base", variable has type "NameInfo") | |
| [builtins fixtures/isinstancelist.pyi] | |
| [typing fixtures/typing-medium.pyi] | |
| [case testNoCrashForwardRefToBrokenDoubleNewType] | |
| from typing import Any, Dict, List, NewType | |
| Foo = NewType('NotFoo', int) # E: String argument 1 "NotFoo" to NewType(...) does not match variable name "Foo" | |
| Foos = NewType('Foos', List[Foo]) # type: ignore | |
| def frob(foos: Dict[Any, Foos]) -> None: | |
| foo = foos.get(1) | |
| assert foo | |
| dict(foo) | |
| [builtins fixtures/dict.pyi] | |
| [out] | |
| [case testNoCrashForwardRefToBrokenDoubleNewTypeClass] | |
| from typing import Any, Dict, List, NewType | |
| Foo = NewType('NotFoo', int) # type: ignore | |
| Foos = NewType('Foos', List[Foo]) # type: ignore | |
| x: C | |
| class C: | |
| def frob(self, foos: Dict[Any, Foos]) -> None: | |
| foo = foos.get(1) | |
| assert foo | |
| dict(foo) | |
| reveal_type(x.frob) # N: Revealed type is "def (foos: builtins.dict[Any, __main__.Foos])" | |
| [builtins fixtures/dict.pyi] | |
| [out] | |
| [case testNewTypeFromForwardNamedTuple] | |
| from typing import NewType, NamedTuple, Tuple | |
| NT = NewType('NT', 'N') | |
| class N(NamedTuple): | |
| x: int | |
| x: NT = N(1) # E: Incompatible types in assignment (expression has type "N", variable has type "NT") | |
| x = NT(N(1)) | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testNewTypeFromForwardTypedDict] | |
| from typing import NewType, Tuple, TypedDict | |
| NT = NewType('NT', 'N') # E: Argument 2 to NewType(...) must be subclassable (got "N") | |
| class N(TypedDict): | |
| x: int | |
| [builtins fixtures/dict.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [out] | |
| [case testCorrectAttributeInForwardRefToNamedTuple] | |
| from typing import NamedTuple | |
| proc: Process | |
| reveal_type(proc.state) # N: Revealed type is "builtins.int" | |
| def get_state(proc: 'Process') -> int: | |
| return proc.state | |
| class Process(NamedTuple): | |
| state: int | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testCorrectItemTypeInForwardRefToTypedDict] | |
| from typing import TypedDict | |
| proc: Process | |
| reveal_type(proc['state']) # N: Revealed type is "builtins.int" | |
| def get_state(proc: 'Process') -> int: | |
| return proc['state'] | |
| class Process(TypedDict): | |
| state: int | |
| [builtins fixtures/isinstancelist.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [out] | |
| [case testCorrectDoubleForwardNamedTuple] | |
| from typing import NamedTuple | |
| x: A | |
| class A(NamedTuple): | |
| one: 'B' | |
| other: int | |
| class B(NamedTuple): | |
| attr: str | |
| y: A | |
| y = x | |
| reveal_type(x.one.attr) # N: Revealed type is "builtins.str" | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testCrashOnDoubleForwardTypedDict] | |
| from typing import TypedDict | |
| x: A | |
| class A(TypedDict): | |
| one: 'B' | |
| other: int | |
| class B(TypedDict): | |
| attr: str | |
| reveal_type(x['one']['attr']) # N: Revealed type is "builtins.str" | |
| [builtins fixtures/isinstancelist.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [out] | |
| [case testCrashOnForwardUnionOfNamedTuples] | |
| from typing import Union, NamedTuple | |
| Node = Union['Foo', 'Bar'] | |
| class Foo(NamedTuple): | |
| x: int | |
| class Bar(NamedTuple): | |
| x: int | |
| def foo(node: Node) -> int: | |
| x = node | |
| reveal_type(node) # N: Revealed type is "tuple[builtins.int, fallback=__main__.Foo] | tuple[builtins.int, fallback=__main__.Bar]" | |
| return x.x | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testCrashOnForwardUnionOfTypedDicts] | |
| from typing import TypedDict, Union | |
| NodeType = Union['Foo', 'Bar'] | |
| class Foo(TypedDict): | |
| x: int | |
| class Bar(TypedDict): | |
| x: int | |
| def foo(node: NodeType) -> int: | |
| x = node | |
| return x['x'] | |
| [builtins fixtures/isinstancelist.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [out] | |
| [case testSupportForwardUnionOfNewTypes] | |
| from typing import Union, NewType | |
| x: Node | |
| reveal_type(x.x) # N: Revealed type is "builtins.int" | |
| class A: | |
| x: int | |
| class B: | |
| x: int | |
| Node = Union['Foo', 'Bar'] | |
| Foo = NewType('Foo', A) | |
| Bar = NewType('Bar', B) | |
| def foo(node: Node) -> Node: | |
| x = node | |
| return Foo(A()) | |
| [out] | |
| [case testForwardReferencesInNewTypeMRORecomputed] | |
| from typing import NewType | |
| x: Foo | |
| Foo = NewType('Foo', 'B') | |
| class A: | |
| x: int | |
| class B(A): | |
| pass | |
| reveal_type(x.x) # N: Revealed type is "builtins.int" | |
| [out] | |
| [case testCrashOnComplexNamedTupleUnionProperty] | |
| from typing import NamedTuple, Union | |
| x: AOrB | |
| AOrB = Union['A', 'B'] | |
| class A(NamedTuple): | |
| x: int | |
| class B(object): | |
| def __init__(self, a: AOrB) -> None: | |
| self.a = a | |
| @property | |
| def x(self) -> int: | |
| return self.a.x | |
| reveal_type(x.x) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/property.pyi] | |
| [out] | |
| [case testCorrectIsinstanceWithForwardUnion] | |
| from typing import Union, NamedTuple | |
| ForwardUnion = Union['TP', int] | |
| class TP(NamedTuple('TP', [('x', int)])): pass | |
| def f(x: ForwardUnion) -> None: | |
| reveal_type(x) # N: Revealed type is "tuple[builtins.int, fallback=__main__.TP] | builtins.int" | |
| if isinstance(x, TP): | |
| reveal_type(x) # N: Revealed type is "tuple[builtins.int, fallback=__main__.TP]" | |
| [builtins fixtures/isinstance.pyi] | |
| [out] | |
| [case testCrashInvalidArgsSyntheticClassSyntax] | |
| from typing import List, NamedTuple, TypedDict | |
| class TD(TypedDict): | |
| x: List[int, str] # E: "list" expects 1 type argument, but 2 given | |
| class NM(NamedTuple): | |
| x: List[int, str] # E: "list" expects 1 type argument, but 2 given | |
| # These two should never crash, reveals are in the next test | |
| TD({'x': []}) | |
| NM(x=[]) | |
| [builtins fixtures/dict.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [out] | |
| [case testCrashInvalidArgsSyntheticClassSyntaxReveals] | |
| from typing import List, NamedTuple, TypedDict | |
| class TD(TypedDict): | |
| x: List[int, str] # E: "list" expects 1 type argument, but 2 given | |
| class NM(NamedTuple): | |
| x: List[int, str] # E: "list" expects 1 type argument, but 2 given | |
| x: TD | |
| x1 = TD({'x': []}) | |
| y: NM | |
| y1 = NM(x=[]) | |
| reveal_type(x) # N: Revealed type is "TypedDict('__main__.TD', {'x': builtins.list[Any]})" | |
| reveal_type(x1) # N: Revealed type is "TypedDict('__main__.TD', {'x': builtins.list[Any]})" | |
| reveal_type(y) # N: Revealed type is "tuple[builtins.list[Any], fallback=__main__.NM]" | |
| reveal_type(y1) # N: Revealed type is "tuple[builtins.list[Any], fallback=__main__.NM]" | |
| [builtins fixtures/dict.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [out] | |
| [case testCrashInvalidArgsSyntheticFunctionSyntax] | |
| from typing import List, NewType, NamedTuple, TypedDict | |
| TD = TypedDict('TD', {'x': List[int, str]}) # E: "list" expects 1 type argument, but 2 given | |
| NM = NamedTuple('NM', [('x', List[int, str])]) # E: "list" expects 1 type argument, but 2 given | |
| NT = NewType('NT', List[int, str]) # E: "list" expects 1 type argument, but 2 given | |
| # These three should not crash | |
| TD({'x': []}) | |
| NM(x=[]) | |
| NT([]) | |
| [builtins fixtures/dict.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [out] | |
| [case testCrashForwardSyntheticClassSyntax] | |
| from typing import NamedTuple, TypedDict | |
| class A1(NamedTuple): | |
| b: 'B' | |
| x: int | |
| class A2(TypedDict): | |
| b: 'B' | |
| x: int | |
| class B: | |
| pass | |
| x: A1 | |
| y: A2 | |
| reveal_type(x.b) # N: Revealed type is "__main__.B" | |
| reveal_type(y['b']) # N: Revealed type is "__main__.B" | |
| [builtins fixtures/dict.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [out] | |
| [case testCrashForwardSyntheticFunctionSyntax] | |
| from typing import NamedTuple, TypedDict | |
| A1 = NamedTuple('A1', [('b', 'B'), ('x', int)]) | |
| A2 = TypedDict('A2', {'b': 'B', 'x': int}) | |
| class B: | |
| pass | |
| x: A1 | |
| y: A2 | |
| reveal_type(x.b) # N: Revealed type is "__main__.B" | |
| reveal_type(y['b']) # N: Revealed type is "__main__.B" | |
| [builtins fixtures/dict.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [out] | |
| -- Special support for six | |
| -- ----------------------- | |
| [case testSixMetaclass] | |
| import six | |
| class M(type): | |
| x = 5 | |
| class A(six.with_metaclass(M)): pass | |
| @six.add_metaclass(M) | |
| class B: pass | |
| reveal_type(type(A).x) # N: Revealed type is "builtins.int" | |
| reveal_type(type(B).x) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/tuple.pyi] | |
| [case testFromSixMetaclass] | |
| from six import with_metaclass, add_metaclass | |
| class M(type): | |
| x = 5 | |
| class A(with_metaclass(M)): pass | |
| @add_metaclass(M) | |
| class B: pass | |
| reveal_type(type(A).x) # N: Revealed type is "builtins.int" | |
| reveal_type(type(B).x) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/tuple.pyi] | |
| [case testSixMetaclassImportFrom] | |
| import six | |
| from metadefs import M | |
| class A(six.with_metaclass(M)): pass | |
| @six.add_metaclass(M) | |
| class B: pass | |
| reveal_type(type(A).x) # N: Revealed type is "builtins.int" | |
| reveal_type(type(B).x) # N: Revealed type is "builtins.int" | |
| [file metadefs.py] | |
| class M(type): | |
| x = 5 | |
| [builtins fixtures/tuple.pyi] | |
| [case testSixMetaclassImport] | |
| import six | |
| import metadefs | |
| class A(six.with_metaclass(metadefs.M)): pass | |
| @six.add_metaclass(metadefs.M) | |
| class B: pass | |
| reveal_type(type(A).x) # N: Revealed type is "builtins.int" | |
| reveal_type(type(B).x) # N: Revealed type is "builtins.int" | |
| [file metadefs.py] | |
| class M(type): | |
| x = 5 | |
| [builtins fixtures/tuple.pyi] | |
| [case testSixMetaclassAndBase] | |
| from typing import Iterable, Iterator | |
| import six | |
| class M(type, Iterable[int]): | |
| x = 5 | |
| def __iter__(self) -> Iterator[int]: ... | |
| class A: | |
| def foo(self): pass | |
| class B: | |
| def bar(self): pass | |
| class C1(six.with_metaclass(M, A)): pass | |
| @six.add_metaclass(M) | |
| class D1(A): pass | |
| class C2(six.with_metaclass(M, A, B)): pass | |
| @six.add_metaclass(M) | |
| class D2(A, B): pass | |
| reveal_type(type(C1).x) # N: Revealed type is "builtins.int" | |
| reveal_type(type(D1).x) # N: Revealed type is "builtins.int" | |
| reveal_type(type(C2).x) # N: Revealed type is "builtins.int" | |
| reveal_type(type(D2).x) # N: Revealed type is "builtins.int" | |
| C1().foo() | |
| D1().foo() | |
| C1().bar() # E: "C1" has no attribute "bar" | |
| D1().bar() # E: "D1" has no attribute "bar" | |
| for x in C1: reveal_type(x) # N: Revealed type is "builtins.int" | |
| for x in C2: reveal_type(x) # N: Revealed type is "builtins.int" | |
| C2().foo() | |
| D2().foo() | |
| C2().bar() | |
| D2().bar() | |
| C2().baz() # E: "C2" has no attribute "baz" | |
| D2().baz() # E: "D2" has no attribute "baz" | |
| [builtins fixtures/tuple.pyi] | |
| [case testSixMetaclassGenerics] | |
| from typing import Generic, GenericMeta, TypeVar | |
| import six | |
| class DestroyableMeta(type): | |
| pass | |
| class Destroyable(six.with_metaclass(DestroyableMeta)): | |
| pass | |
| T_co = TypeVar('T_co', bound='Destroyable', covariant=True) | |
| class ArcMeta(GenericMeta, DestroyableMeta): | |
| pass | |
| class Arc(six.with_metaclass(ArcMeta, Generic[T_co], Destroyable)): | |
| pass | |
| @six.add_metaclass(ArcMeta) | |
| class Arc1(Generic[T_co], Destroyable): | |
| pass | |
| class MyDestr(Destroyable): | |
| pass | |
| reveal_type(Arc[MyDestr]()) # N: Revealed type is "__main__.Arc[__main__.MyDestr]" | |
| reveal_type(Arc1[MyDestr]()) # N: Revealed type is "__main__.Arc1[__main__.MyDestr]" | |
| [builtins fixtures/bool.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testSixMetaclassErrors] | |
| import six | |
| class M(type): pass | |
| class A(object): pass | |
| def f() -> type: return M | |
| class C1(six.with_metaclass(M), object): pass # E: Unsupported dynamic base class "six.with_metaclass" | |
| class C2(C1, six.with_metaclass(M)): pass # E: Unsupported dynamic base class "six.with_metaclass" | |
| class C3(six.with_metaclass(A)): pass # E: Metaclasses not inheriting from "type" are not supported | |
| @six.add_metaclass(A) # E: Metaclasses not inheriting from "type" are not supported \ | |
| # E: Argument 1 to "add_metaclass" has incompatible type "type[A]"; expected "type[type]" | |
| class D3(A): pass | |
| class C4(six.with_metaclass(M), metaclass=M): pass # E: Multiple metaclass definitions | |
| @six.add_metaclass(M) | |
| class D4(metaclass=M): pass # E: Multiple metaclass definitions | |
| class C5(six.with_metaclass(f())): pass # E: Dynamic metaclass not supported for "C5" | |
| @six.add_metaclass(f()) # E: Dynamic metaclass not supported for "D5" | |
| class D5: pass | |
| @six.add_metaclass(M) | |
| class CD(six.with_metaclass(M)): pass # E: Multiple metaclass definitions | |
| class M1(type): pass | |
| class Q1(metaclass=M1): pass | |
| @six.add_metaclass(M) | |
| class CQA(Q1): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \ | |
| # N: "__main__.M" (metaclass of "__main__.CQA") conflicts with "__main__.M1" (metaclass of "__main__.Q1") | |
| class CQW(six.with_metaclass(M, Q1)): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \ | |
| # N: "__main__.M" (metaclass of "__main__.CQW") conflicts with "__main__.M1" (metaclass of "__main__.Q1") | |
| [builtins fixtures/tuple.pyi] | |
| [case testSixMetaclassAny] | |
| import t # type: ignore | |
| import six | |
| class E(metaclass=t.M): pass | |
| class F(six.with_metaclass(t.M)): pass | |
| @six.add_metaclass(t.M) | |
| class G: pass | |
| [builtins fixtures/tuple.pyi] | |
| [case testSixMetaclassGenericBase] | |
| import six | |
| import abc | |
| from typing import TypeVar, Generic | |
| T = TypeVar("T") | |
| class C(six.with_metaclass(abc.ABCMeta, Generic[T])): | |
| pass | |
| class D(six.with_metaclass(abc.ABCMeta, C[T])): | |
| pass | |
| [builtins fixtures/tuple.pyi] | |
| -- Special support for future.utils | |
| -- -------------------------------- | |
| [case testFutureMetaclass] | |
| import future.utils | |
| class M(type): | |
| x = 5 | |
| class A(future.utils.with_metaclass(M)): pass | |
| reveal_type(type(A).x) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/tuple.pyi] | |
| [case testFromFutureMetaclass] | |
| from future.utils import with_metaclass | |
| class M(type): | |
| x = 5 | |
| class A(with_metaclass(M)): pass | |
| reveal_type(type(A).x) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/tuple.pyi] | |
| [case testFutureMetaclassImportFrom] | |
| import future.utils | |
| from metadefs import M | |
| class A(future.utils.with_metaclass(M)): pass | |
| reveal_type(type(A).x) # N: Revealed type is "builtins.int" | |
| [file metadefs.py] | |
| class M(type): | |
| x = 5 | |
| [builtins fixtures/tuple.pyi] | |
| [case testFutureMetaclassImport] | |
| import future.utils | |
| import metadefs | |
| class A(future.utils.with_metaclass(metadefs.M)): pass | |
| reveal_type(type(A).x) # N: Revealed type is "builtins.int" | |
| [file metadefs.py] | |
| class M(type): | |
| x = 5 | |
| [builtins fixtures/tuple.pyi] | |
| [case testFutureMetaclassAndBase] | |
| from typing import Iterable, Iterator | |
| import future.utils | |
| class M(type, Iterable[int]): | |
| x = 5 | |
| def __iter__(self) -> Iterator[int]: ... | |
| class A: | |
| def foo(self): pass | |
| class B: | |
| def bar(self): pass | |
| class C1(future.utils.with_metaclass(M, A)): pass | |
| class C2(future.utils.with_metaclass(M, A, B)): pass | |
| reveal_type(type(C1).x) # N: Revealed type is "builtins.int" | |
| reveal_type(type(C2).x) # N: Revealed type is "builtins.int" | |
| C1().foo() | |
| C1().bar() # E: "C1" has no attribute "bar" | |
| for x in C1: reveal_type(x) # N: Revealed type is "builtins.int" | |
| for x in C2: reveal_type(x) # N: Revealed type is "builtins.int" | |
| C2().foo() | |
| C2().bar() | |
| C2().baz() # E: "C2" has no attribute "baz" | |
| [builtins fixtures/tuple.pyi] | |
| [case testFutureMetaclassGenerics] | |
| from typing import Generic, GenericMeta, TypeVar | |
| import future.utils | |
| class DestroyableMeta(type): | |
| pass | |
| class Destroyable(future.utils.with_metaclass(DestroyableMeta)): | |
| pass | |
| T_co = TypeVar('T_co', bound='Destroyable', covariant=True) | |
| class ArcMeta(GenericMeta, DestroyableMeta): | |
| pass | |
| class Arc(future.utils.with_metaclass(ArcMeta, Generic[T_co], Destroyable)): | |
| pass | |
| class MyDestr(Destroyable): | |
| pass | |
| reveal_type(Arc[MyDestr]()) # N: Revealed type is "__main__.Arc[__main__.MyDestr]" | |
| [builtins fixtures/bool.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testFutureMetaclassErrors] | |
| import future.utils | |
| class M(type): pass | |
| class A(object): pass | |
| def f() -> type: return M | |
| class C1(future.utils.with_metaclass(M), object): pass # E: Unsupported dynamic base class "future.utils.with_metaclass" | |
| class C2(C1, future.utils.with_metaclass(M)): pass # E: Unsupported dynamic base class "future.utils.with_metaclass" | |
| class C3(future.utils.with_metaclass(A)): pass # E: Metaclasses not inheriting from "type" are not supported | |
| class C4(future.utils.with_metaclass(M), metaclass=M): pass # E: Multiple metaclass definitions | |
| class C5(future.utils.with_metaclass(f())): pass # E: Dynamic metaclass not supported for "C5" | |
| class M1(type): pass | |
| class Q1(metaclass=M1): pass | |
| class CQW(future.utils.with_metaclass(M, Q1)): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \ | |
| # N: "__main__.M" (metaclass of "__main__.CQW") conflicts with "__main__.M1" (metaclass of "__main__.Q1") | |
| [builtins fixtures/tuple.pyi] | |
| [case testFutureMetaclassAny] | |
| import t # type: ignore | |
| import future.utils | |
| class E(metaclass=t.M): pass | |
| class F(future.utils.with_metaclass(t.M)): pass | |
| -- Misc | |
| -- ---- | |
| [builtins fixtures/tuple.pyi] | |
| [case testCorrectEnclosingClassPushedInDeferred] | |
| class C: | |
| def __getattr__(self, attr: str) -> int: | |
| x: F | |
| return x.f | |
| class F: | |
| def __init__(self, f: int) -> None: | |
| self.f = f | |
| [out] | |
| [case testCorrectEnclosingClassPushedInDeferred2] | |
| from typing import TypeVar | |
| T = TypeVar('T', bound='C') | |
| class C: | |
| def m(self: T) -> T: | |
| class Inner: | |
| x: F | |
| f = x.f | |
| return self | |
| class F: | |
| def __init__(self, f: int) -> None: | |
| self.f = f | |
| [out] | |
| [case testCorrectEnclosingClassPushedInDeferred3] | |
| class A: | |
| def f(self) -> None: | |
| def g(x: int) -> int: | |
| return y | |
| y = int() | |
| [out] | |
| [case testMetaclassMemberAccessViaType] | |
| from typing import Type | |
| class M(type): | |
| def m(cls, x: int) -> int: | |
| pass | |
| class C(metaclass=M): | |
| pass | |
| x = C | |
| y: Type[C] = C | |
| reveal_type(type(C).m) # N: Revealed type is "def (cls: __main__.M, x: builtins.int) -> builtins.int" | |
| reveal_type(type(x).m) # N: Revealed type is "def (cls: __main__.M, x: builtins.int) -> builtins.int" | |
| reveal_type(type(y).m) # N: Revealed type is "def (cls: __main__.M, x: builtins.int) -> builtins.int" | |
| [out] | |
| [case testMetaclassMemberAccessViaType2] | |
| from typing import Any, Type | |
| class M(type): | |
| def m(cls, x: int) -> int: | |
| pass | |
| B: Any | |
| class C(B, metaclass=M): | |
| pass | |
| x: Type[C] | |
| reveal_type(x.m) # N: Revealed type is "def (x: builtins.int) -> builtins.int" | |
| reveal_type(x.whatever) # N: Revealed type is "Any" | |
| [out] | |
| [case testMetaclassMemberAccessViaType3] | |
| from typing import Any, Type, TypeVar | |
| T = TypeVar('T') | |
| class C(Any): | |
| def bar(self: T) -> Type[T]: pass | |
| def foo(self) -> None: | |
| reveal_type(self.bar()) # N: Revealed type is "type[__main__.C]" | |
| reveal_type(self.bar().__name__) # N: Revealed type is "builtins.str" | |
| [builtins fixtures/type.pyi] | |
| [out] | |
| [case testClassDecoratorIsTypeChecked] | |
| from typing import Callable, Type | |
| def decorate(x: int) -> Callable[[type], type]: | |
| ... | |
| def decorate_forward_ref() -> Callable[[Type[A]], Type[A]]: | |
| ... | |
| @decorate(y=17) # E: Unexpected keyword argument "y" for "decorate" | |
| @decorate() # E: Missing positional argument "x" in call to "decorate" | |
| @decorate(22, 25) # E: Too many arguments for "decorate" | |
| @decorate_forward_ref() | |
| @decorate(11) | |
| class A: pass | |
| @decorate # E: Argument 1 to "decorate" has incompatible type "type[A2]"; expected "int" | |
| class A2: pass | |
| [case testClassDecoratorIncorrect] | |
| def not_a_class_decorator(x: int) -> int: ... | |
| @not_a_class_decorator(7) # E: "int" not callable | |
| class A3: pass | |
| not_a_function = 17 | |
| @not_a_function() # E: "int" not callable | |
| class B: pass | |
| @not_a_function # E: "int" not callable | |
| class B2: pass | |
| b = object() | |
| @b.nothing # E: "object" has no attribute "nothing" | |
| class C: pass | |
| @undefined # E: Name "undefined" is not defined | |
| class D: pass | |
| [case testSlotsCompatibility] | |
| class A: | |
| __slots__ = () | |
| class B(A): | |
| __slots__ = ('a', 'b') | |
| class C: | |
| __slots__ = ('x',) | |
| class D(B, C): # E: Class "D" has incompatible disjoint bases | |
| __slots__ = ('aa', 'bb', 'cc') | |
| [builtins fixtures/tuple.pyi] | |
| [case testRevealLocalsOnClassVars] | |
| class C1(object): | |
| t = 'a' | |
| y = 3.0 | |
| class Inner(object): pass | |
| reveal_locals() | |
| [out] | |
| main:5: note: Revealed local types are: | |
| main:5: note: t: builtins.str | |
| main:5: note: y: builtins.float | |
| [case testAbstractClasses] | |
| import a | |
| import b | |
| [file a.pyi] | |
| from abc import ABCMeta, abstractmethod | |
| from typing import Protocol | |
| class A: # OK, has @abstractmethod | |
| @abstractmethod | |
| def f(self) -> None: | |
| pass | |
| class B(A): # E: Class a.B has abstract attributes "f" # N: If it is meant to be abstract, add 'abc.ABCMeta' as an explicit metaclass | |
| pass | |
| class C(A, metaclass=ABCMeta): # OK, has ABCMeta as a metaclass | |
| pass | |
| class D(A): # OK, implements the abstract method | |
| def f(self) -> None: | |
| pass | |
| class E(Protocol): # OK, is a protocol | |
| @abstractmethod | |
| def f(self) -> None: | |
| pass | |
| class F(E, Protocol): # OK, is a protocol | |
| pass | |
| # Custom metaclass subclassing `ABCMeta`, see #13561 | |
| class CustomMeta(ABCMeta): | |
| pass | |
| class G(A, metaclass=CustomMeta): # Ok, has CustomMeta as a metaclass | |
| pass | |
| [file b.py] | |
| # All of these are OK because this is not a stub file. | |
| from abc import ABCMeta, abstractmethod | |
| from typing import Protocol | |
| class A: | |
| @abstractmethod | |
| def f(self) -> None: | |
| pass | |
| class B(A): | |
| pass | |
| class C(A, metaclass=ABCMeta): | |
| pass | |
| class D(A): | |
| def f(self) -> None: | |
| pass | |
| class E(Protocol): | |
| @abstractmethod | |
| def f(self) -> None: | |
| pass | |
| class F(E, Protocol): | |
| pass | |
| class CustomMeta(ABCMeta): | |
| pass | |
| class G(A, metaclass=CustomMeta): | |
| pass | |
| [case testClassMethodOverride] | |
| from typing import Callable, Any | |
| def deco(f: Callable[..., Any]) -> Callable[..., Any]: ... | |
| class B: | |
| @classmethod | |
| def meth(cls, x: int) -> int: ... | |
| class C(B): | |
| @classmethod | |
| @deco | |
| def meth(cls, x: int) -> int: ... | |
| [builtins fixtures/classmethod.pyi] | |
| [out] | |
| [case testGetAttrImportAnnotation] | |
| import a | |
| x: a.A | |
| y: a.A.B.C | |
| reveal_type(x) # N: Revealed type is "Any" | |
| reveal_type(y) # N: Revealed type is "Any" | |
| [file a.pyi] | |
| from typing import Any | |
| def __getattr__(attr: str) -> Any: ... | |
| [builtins fixtures/module.pyi] | |
| [out] | |
| [case testGetAttrImportBaseClass] | |
| import a | |
| class B(a.A): ... | |
| [file a.pyi] | |
| from typing import Any | |
| def __getattr__(attr: str) -> Any: ... | |
| [builtins fixtures/module.pyi] | |
| [out] | |
| [case testGetAttrDescriptor] | |
| from typing import TypeVar, Generic, Any | |
| T = TypeVar('T') | |
| class C(Generic[T]): | |
| normal: T | |
| def __getattr__(self, attr: str) -> T: ... | |
| class Descr: | |
| def __get__(self, inst: Any, owner: Any) -> int: ... | |
| class D(C[Descr]): | |
| other: Descr | |
| d: D | |
| reveal_type(d.normal) # N: Revealed type is "builtins.int" | |
| reveal_type(d.dynamic) # N: Revealed type is "__main__.Descr" | |
| reveal_type(D.other) # N: Revealed type is "builtins.int" | |
| D.dynamic # E: "type[D]" has no attribute "dynamic" | |
| [out] | |
| [case testSelfDescriptorAssign] | |
| from typing import Any | |
| class Descr: | |
| def __get__(self, inst: Any, owner: Any) -> int: ... | |
| class C: | |
| def __init__(self, x: Descr) -> None: | |
| self.x = x | |
| c = C(Descr()) | |
| reveal_type(c.x) # N: Revealed type is "__main__.Descr" | |
| [out] | |
| [case testForwardInstanceWithWrongArgCount] | |
| from typing import TypeVar, Generic | |
| T = TypeVar('T') | |
| class G(Generic[T]): ... | |
| A = G | |
| x: A[B[int, int]] # E: "G" expects 1 type argument, but 2 given | |
| B = G | |
| [out] | |
| [case testForwardInstanceWithNoArgs] | |
| from typing import TypeVar, Generic | |
| T = TypeVar('T') | |
| class G(Generic[T]): ... | |
| A = G | |
| x: A[B] | |
| reveal_type(x) # N: Revealed type is "__main__.G[__main__.G[Any]]" | |
| B = G | |
| [out] | |
| [case testForwardInstanceWithBound] | |
| # flags: --show-column-numbers | |
| from typing import TypeVar, Generic | |
| T = TypeVar('T', bound=str) | |
| class G(Generic[T]): ... | |
| A = G | |
| x: A[B[int]] # E | |
| B = G | |
| [out] | |
| main:8:6: error: Type argument "G[int]" of "G" must be a subtype of "str" | |
| main:8:8: error: Type argument "int" of "G" must be a subtype of "str" | |
| [case testExtremeForwardReferencing] | |
| from typing import TypeVar, Generic | |
| T = TypeVar('T', covariant=True) | |
| class B(Generic[T]): ... | |
| y: A | |
| z: A[int] | |
| x = [y, z] | |
| reveal_type(x) # N: Revealed type is "builtins.list[__main__.B[Any]]" | |
| A = B | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| [case testNoneAnyFallback] | |
| from typing import Any | |
| dynamic: Any | |
| class C(dynamic): pass | |
| x: None = C() # E: Incompatible types in assignment (expression has type "C", variable has type "None") | |
| [out] | |
| [case testNoneAnyFallbackDescriptor] | |
| from typing import Any | |
| from d import Descr | |
| dynamic: Any | |
| class C(dynamic): | |
| id = Descr(int) | |
| name = Descr(str) | |
| c: C | |
| reveal_type(c.id) # N: Revealed type is "builtins.int" | |
| reveal_type(C.name) # N: Revealed type is "d.Descr[builtins.str]" | |
| [file d.pyi] | |
| from typing import Any, overload, Generic, TypeVar, Type | |
| T = TypeVar('T') | |
| class Descr(Generic[T]): | |
| def __init__(self, tp: Type[T]) -> None: ... | |
| @overload | |
| def __get__(self, inst: None, owner: Any) -> Descr[T]: ... | |
| @overload | |
| def __get__(self, inst: object, owner: Any) -> T: ... | |
| [out] | |
| [case testClassCustomPropertyWorks] | |
| from typing import TypeVar, Generic, Callable, Any | |
| V = TypeVar('V') | |
| class classproperty(Generic[V]): | |
| def __init__(self, getter: Callable[[Any], V]) -> None: | |
| self.getter = getter | |
| def __get__(self, instance: Any, owner: Any) -> V: | |
| return self.getter(owner) | |
| class C: | |
| @classproperty | |
| def foo(cls) -> int: | |
| return 42 | |
| reveal_type(C.foo) # N: Revealed type is "builtins.int" | |
| reveal_type(C().foo) # N: Revealed type is "builtins.int" | |
| [out] | |
| [case testMultipleInheritanceCycle] | |
| import b | |
| [file a.py] | |
| from b import B | |
| class A: ... | |
| class C(A, B): ... | |
| class D(C): ... | |
| class Other: ... | |
| [file b.py] | |
| from a import Other | |
| class B: ... | |
| [out] | |
| [case testMultipleInheritanceCycle2] | |
| import b | |
| [file a.py] | |
| from b import B | |
| class A: ... | |
| class C(A, B): ... | |
| class D(C): ... | |
| class Other: ... | |
| a: A | |
| b: B | |
| c: C | |
| d: D | |
| d = A() # E: Incompatible types in assignment (expression has type "A", variable has type "D") | |
| if int(): | |
| d = B() # E: Incompatible types in assignment (expression has type "B", variable has type "D") | |
| if int(): | |
| d = C() # E: Incompatible types in assignment (expression has type "C", variable has type "D") | |
| a = D() | |
| b = D() | |
| c = D() | |
| [file b.py] | |
| from a import Other | |
| class B: ... | |
| [out] | |
| [case testAllowPropertyAndInit1] | |
| class C: | |
| def __init__(self, x: int) -> None: | |
| self.x = x | |
| @property | |
| def x(self) -> int: pass | |
| @x.setter | |
| def x(self, x: int) -> None: pass | |
| [builtins fixtures/property.pyi] | |
| [out] | |
| [case testAllowPropertyAndInit2] | |
| class C: | |
| @property | |
| def x(self) -> int: pass | |
| @x.setter | |
| def x(self, x: int) -> None: pass | |
| def __init__(self, x: int) -> None: | |
| self.x = x | |
| [builtins fixtures/property.pyi] | |
| [case testAllowPropertyAndInit3] | |
| class C: | |
| def __init__(self, x: int) -> None: | |
| self.x = x # type: ignore | |
| @property # Should be no error here | |
| def x(self) -> int: pass | |
| [builtins fixtures/property.pyi] | |
| [out] | |
| [case testClassMethodBeforeInit1] | |
| class Foo: | |
| @classmethod | |
| def bar(cls) -> Foo: | |
| return cls("bar") | |
| def __init__(self, baz: str) -> None: | |
| self.baz = baz | |
| [builtins fixtures/classmethod.pyi] | |
| [case testClassMethodBeforeInit2] | |
| class Foo: | |
| @classmethod | |
| def bar(cls) -> Foo: | |
| return cls(Bar()) | |
| def __init__(self, baz: 'Bar') -> None: | |
| self.baz = baz | |
| class Bar: pass | |
| [builtins fixtures/classmethod.pyi] | |
| [case testClassMethodBeforeInit3] | |
| from typing import overload | |
| class Foo: | |
| @classmethod | |
| @overload | |
| def bar(cls, x: int) -> Foo: ... | |
| @classmethod | |
| @overload | |
| def bar(cls, x: str) -> Foo: ... | |
| @classmethod | |
| def bar(cls, x: object) -> Foo: | |
| return cls(x) | |
| def __init__(self, baz: object) -> None: | |
| self.baz = baz | |
| [builtins fixtures/classmethod.pyi] | |
| [case testNewAndInit1] | |
| class A: | |
| def __init__(self, x: int) -> None: | |
| pass | |
| class B(A): | |
| def __new__(cls) -> B: | |
| pass | |
| B() | |
| [case testNewAndInit2] | |
| from typing import Any | |
| class A: | |
| def __new__(cls, *args: Any) -> 'A': | |
| ... | |
| class B(A): | |
| def __init__(self, x: int) -> None: | |
| pass | |
| reveal_type(B) # N: Revealed type is "def (x: builtins.int) -> __main__.B" | |
| [builtins fixtures/tuple.pyi] | |
| [case testNewAndInit3] | |
| from typing import Any | |
| class A: | |
| def __new__(cls, *args: Any) -> 'A': | |
| ... | |
| def __init__(self, x: int) -> None: | |
| pass | |
| reveal_type(A) # N: Revealed type is "def (x: builtins.int) -> __main__.A" | |
| [builtins fixtures/tuple.pyi] | |
| [case testCyclicDecorator] | |
| import b | |
| [file a.py] | |
| import b | |
| import c | |
| class A(b.B): | |
| @c.deco | |
| def meth(self) -> int: ... | |
| [file b.py] | |
| import a | |
| import c | |
| class B: | |
| @c.deco | |
| def meth(self) -> int: ... | |
| [file c.py] | |
| from typing import TypeVar, Tuple, Callable | |
| T = TypeVar('T') | |
| def deco(f: Callable[..., T]) -> Callable[..., Tuple[T, int]]: ... | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testCyclicOverload] | |
| import b | |
| [file a.pyi] | |
| import b | |
| from typing import overload | |
| class A(b.B): | |
| @overload | |
| def meth(self, x: int) -> int: ... | |
| @overload | |
| def meth(self, x: str) -> str: ... | |
| [file b.pyi] | |
| import a | |
| from typing import overload | |
| class B: | |
| @overload | |
| def meth(self, x: int) -> int: ... | |
| @overload | |
| def meth(self, x: str) -> str: ... | |
| [out] | |
| [case testCyclicOverloadDeferred] | |
| import b | |
| [file a.py] | |
| import b | |
| from typing import overload, Union | |
| class A(b.B): | |
| @overload | |
| def meth(self, x: int) -> int: ... | |
| @overload | |
| def meth(self, x: str) -> str: ... | |
| def meth(self, x) -> Union[int, str]: | |
| reveal_type(other.x) # N: Revealed type is "builtins.int" | |
| return 0 | |
| other: Other | |
| class Other: | |
| def __init__(self) -> None: | |
| self.x = f() | |
| def f() -> int: ... | |
| [file b.py] | |
| import a | |
| from typing import overload | |
| class B: | |
| @overload | |
| def meth(self, x: int) -> int: ... | |
| @overload | |
| def meth(self, x: str) -> str: ... | |
| def meth(self, x): | |
| pass | |
| [out] | |
| [case testCyclicOverrideAny] | |
| import a | |
| [file b.py] | |
| import a | |
| class Sub(a.Base): | |
| def x(self) -> int: pass | |
| [file a.py] | |
| import b | |
| class Base: | |
| def __init__(self): | |
| self.x = 1 | |
| [out] | |
| [case testCyclicOverrideChecked] | |
| import a | |
| [file b.py] | |
| import a | |
| class Sub(a.Base): | |
| def x(self) -> int: pass # E: Signature of "x" incompatible with supertype "Base" \ | |
| # N: Superclass: \ | |
| # N: int \ | |
| # N: Subclass: \ | |
| # N: def x(self) -> int | |
| [file a.py] | |
| import b | |
| class Base: | |
| def __init__(self) -> None: | |
| self.x = 1 | |
| [out] | |
| [case testCyclicOverrideCheckedDecorator] | |
| import a | |
| [file b.py] | |
| import a | |
| import c | |
| class Sub(a.Base): | |
| @c.deco | |
| def x(self) -> int: pass # E: Signature of "x" incompatible with supertype "Base" \ | |
| # N: Superclass: \ | |
| # N: int \ | |
| # N: Subclass: \ | |
| # N: def x(*Any, **Any) -> tuple[int, int] | |
| [file a.py] | |
| import b | |
| import c | |
| class Base: | |
| def __init__(self) -> None: | |
| self.x = 1 | |
| [file c.py] | |
| from typing import TypeVar, Tuple, Callable | |
| T = TypeVar('T') | |
| def deco(f: Callable[..., T]) -> Callable[..., Tuple[T, int]]: ... | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testCyclicOverrideCheckedDecoratorDeferred] | |
| import a | |
| [file b.py] | |
| import a | |
| import c | |
| class Sub(a.Base): | |
| @c.deco | |
| def x(self) -> int: pass # E: Signature of "x" incompatible with supertype "Base" \ | |
| # N: Superclass: \ | |
| # N: int \ | |
| # N: Subclass: \ | |
| # N: def x(*Any, **Any) -> tuple[int, int] | |
| [file a.py] | |
| import b | |
| import c | |
| class Base: | |
| def __init__(self) -> None: | |
| self.x = f() | |
| def f() -> int: ... | |
| [file c.py] | |
| from typing import TypeVar, Tuple, Callable | |
| T = TypeVar('T') | |
| def deco(f: Callable[..., T]) -> Callable[..., Tuple[T, int]]: ... | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testCyclicOverrideAnyDecoratorDeferred] | |
| import a | |
| [file b.py] | |
| import a | |
| import c | |
| class Sub(a.Base): | |
| @c.deco | |
| def x(self) -> int: pass | |
| [file a.py] | |
| from b import Sub | |
| import c | |
| class Base: | |
| def __init__(self) -> None: | |
| self.x = f() | |
| def f() -> int: ... | |
| [file c.py] | |
| from typing import Any, Callable | |
| def deco(f: Callable[..., Any]) -> Any: ... | |
| [out] | |
| [case testCyclicDecoratorDoubleDeferred] | |
| import b | |
| [file a.py] | |
| import b | |
| import c | |
| class A(b.B): | |
| @c.deco | |
| def meth(self) -> int: | |
| reveal_type(other.x) # N: Revealed type is "builtins.int" | |
| return 0 | |
| other: Other | |
| class Other: | |
| def __init__(self) -> None: | |
| self.x = f() | |
| def f() -> int: ... | |
| [file b.py] | |
| from a import A | |
| import c | |
| class B: | |
| @c.deco | |
| def meth(self) -> int: | |
| pass | |
| [file c.py] | |
| from typing import TypeVar, Tuple, Callable | |
| T = TypeVar('T') | |
| def deco(f: Callable[..., T]) -> Callable[..., Tuple[T, int]]: ... | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testCyclicDecoratorSuper] | |
| import b | |
| [file a.py] | |
| import b | |
| import c | |
| class A(b.B): | |
| @c.deco | |
| def meth(self) -> int: | |
| y = super().meth() | |
| reveal_type(y) # N: Revealed type is "tuple[builtins.int, builtins.int]" | |
| return 0 | |
| [file b.py] | |
| from a import A | |
| import c | |
| class B: | |
| @c.deco | |
| def meth(self) -> int: | |
| pass | |
| [file c.py] | |
| from typing import TypeVar, Tuple, Callable | |
| T = TypeVar('T') | |
| def deco(f: Callable[..., T]) -> Callable[..., Tuple[T, int]]: ... | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testCyclicDecoratorBothDeferred] | |
| import b | |
| [file a.py] | |
| import b | |
| import c | |
| class A(b.B): | |
| @c.deco | |
| def meth(self) -> int: | |
| pass | |
| [file b.py] | |
| from a import A | |
| import c | |
| class B: | |
| @c.deco | |
| def meth(self) -> int: | |
| reveal_type(other.x) # N: Revealed type is "builtins.int" | |
| return 0 | |
| other: Other | |
| class Other: | |
| def __init__(self) -> None: | |
| self.x = f() | |
| def f() -> int: ... | |
| [file c.py] | |
| from typing import TypeVar, Tuple, Callable | |
| T = TypeVar('T') | |
| def deco(f: Callable[..., T]) -> Callable[..., Tuple[T, int]]: ... | |
| [builtins fixtures/tuple.pyi] | |
| [out] | |
| [case testCyclicDecoratorSuperDeferred] | |
| import b | |
| [file a.py] | |
| import b | |
| import c | |
| class A(b.B): | |
| @c.deco | |
| def meth(self) -> int: | |
| y = super().meth() | |
| reveal_type(y) # N: Revealed type is "tuple[builtins.int, builtins.int]" | |
| reveal_type(other.x) # N: Revealed type is "builtins.int" | |
| return 0 | |
| other: Other | |
| class Other: | |
| def __init__(self) -> None: | |
| self.x = f() | |
| def f() -> int: ... | |
| [file b.py] | |
| from a import A | |
| import c | |
| class B: | |
| @c.deco | |
| def meth(self) -> int: | |
| pass | |
| [file c.py] | |
| from typing import TypeVar, Tuple, Callable | |
| T = TypeVar('T') | |
| def deco(f: Callable[..., T]) -> Callable[..., Tuple[T, int]]: ... | |
| [builtins fixtures/tuple.pyi] | |
| [case testOverrideWithUntypedNotChecked] | |
| class Parent: | |
| def foo(self, x): | |
| ... | |
| def bar(self, x): | |
| ... | |
| def baz(self, x: int) -> str: | |
| return "" | |
| class Child(Parent): | |
| def foo(self, y): # OK: names not checked | |
| ... | |
| def bar(self, x, y): | |
| ... | |
| def baz(self, x, y): | |
| return "" | |
| [builtins fixtures/tuple.pyi] | |
| [case testOverrideWithUntypedCheckedWithCheckUntypedDefs] | |
| # flags: --check-untyped-defs | |
| class Parent: | |
| def foo(self, x): | |
| ... | |
| def bar(self, x): | |
| ... | |
| def baz(self, x: int) -> str: | |
| return "" | |
| class Child(Parent): | |
| def foo(self, y): # OK: names not checked | |
| ... | |
| def bar(self, x, y) -> None: # E: Signature of "bar" incompatible with supertype "Parent" \ | |
| # N: Superclass: \ | |
| # N: def bar(self, x: Any) -> Any \ | |
| # N: Subclass: \ | |
| # N: def bar(self, x: Any, y: Any) -> None | |
| ... | |
| def baz(self, x, y): # E: Signature of "baz" incompatible with supertype "Parent" \ | |
| # N: Superclass: \ | |
| # N: def baz(self, x: int) -> str \ | |
| # N: Subclass: \ | |
| # N: def baz(self, x: Any, y: Any) -> Any | |
| return "" | |
| [builtins fixtures/tuple.pyi] | |
| [case testOptionalDescriptorsBinder] | |
| from typing import Type, TypeVar, Optional | |
| T = TypeVar('T') | |
| class IntDescr: | |
| def __get__(self, obj: T, typ: Type[T]) -> Optional[int]: ... | |
| def __set__(self, obj: T, value: Optional[int]) -> None: ... | |
| class C: | |
| spec = IntDescr() | |
| def meth_spec(self) -> None: | |
| if self.spec is None: | |
| self.spec = 0 | |
| reveal_type(self.spec) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/bool.pyi] | |
| [case testUnionDescriptorsBinder] | |
| from typing import Type, TypeVar, Union | |
| T = TypeVar('T') | |
| class A: ... | |
| class B: ... | |
| class UnionDescr: | |
| def __get__(self, obj: T, typ: Type[T]) -> Union[A, B]: ... | |
| def __set__(self, obj: T, value: Union[A, B]) -> None: ... | |
| class C: | |
| spec = UnionDescr() | |
| def meth_spec(self) -> None: | |
| self.spec = A() | |
| reveal_type(self.spec) # N: Revealed type is "__main__.A" | |
| [builtins fixtures/bool.pyi] | |
| [case testSubclassDescriptorsBinder] | |
| from typing import Type, TypeVar, Optional | |
| T = TypeVar('T') | |
| class A: ... | |
| class B(A): ... | |
| class SubDescr: | |
| def __get__(self, obj: T, typ: Type[T]) -> A: ... | |
| def __set__(self, obj: T, value: A) -> None: ... | |
| class C: | |
| spec = SubDescr() | |
| def meth_spec(self) -> None: | |
| self.spec = B() | |
| reveal_type(self.spec) # N: Revealed type is "__main__.B" | |
| [builtins fixtures/bool.pyi] | |
| [case testDecoratedDunderGet] | |
| from typing import Any, Callable, TypeVar, Type | |
| F = TypeVar('F', bound=Callable) | |
| T = TypeVar('T') | |
| def decorator(f: F) -> F: | |
| return f | |
| def change(f: Callable) -> Callable[..., int]: | |
| pass | |
| def untyped(f): | |
| return f | |
| class A: ... | |
| class Descr1: | |
| @decorator | |
| def __get__(self, obj: T, typ: Type[T]) -> A: ... | |
| class Descr2: | |
| @change | |
| def __get__(self, obj: T, typ: Type[T]) -> A: ... | |
| class Descr3: | |
| @untyped | |
| def __get__(self, obj: T, typ: Type[T]) -> A: ... | |
| class C: | |
| spec1 = Descr1() | |
| spec2 = Descr2() | |
| spec3 = Descr3() | |
| c: C | |
| reveal_type(c.spec1) # N: Revealed type is "__main__.A" | |
| reveal_type(c.spec2) # N: Revealed type is "builtins.int" | |
| reveal_type(c.spec3) # N: Revealed type is "Any" | |
| [builtins fixtures/bool.pyi] | |
| [case testDecoratedDunderSet] | |
| from typing import Any, Callable, TypeVar, Type | |
| F = TypeVar('F', bound=Callable) | |
| T = TypeVar('T') | |
| def decorator(f: F) -> F: | |
| return f | |
| def change(f: Callable) -> Callable[[Any, Any, int], None]: | |
| pass | |
| def untyped(f): | |
| return f | |
| class A: ... | |
| class Descr1: | |
| @decorator | |
| def __set__(self, obj: T, value: A) -> None: ... | |
| class Descr2: | |
| @change | |
| def __set__(self, obj: T, value: A) -> None: ... | |
| class Descr3: | |
| @untyped | |
| def __set__(self, obj: T, value: A) -> None: ... | |
| class C: | |
| spec1 = Descr1() | |
| spec2 = Descr2() | |
| spec3 = Descr3() | |
| c: C | |
| c.spec1 = A() | |
| c.spec1 = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "A") | |
| c.spec2 = A() # E: Incompatible types in assignment (expression has type "A", variable has type "int") | |
| c.spec2 = 1 | |
| c.spec3 = A() | |
| c.spec3 = 1 | |
| [builtins fixtures/bool.pyi] | |
| [case testClassLevelImport] | |
| # flags: --ignore-missing-imports | |
| class Test: | |
| import a | |
| def __init__(self) -> None: | |
| some_module = self.a | |
| [out] | |
| [case testIsInstanceTypeVsMetaclass] | |
| from typing import Type | |
| class Meta(type): | |
| pass | |
| class Thing(metaclass=Meta): | |
| pass | |
| def foo(x: Type[Thing]) -> Type[Thing]: | |
| assert isinstance(x, Meta) | |
| return x | |
| [builtins fixtures/isinstancelist.pyi] | |
| [case testIsInstanceTypeVsUnionOfType] | |
| from typing import Type, Union | |
| class AA: pass | |
| class AB: pass | |
| class M: pass | |
| class A(M, AA): pass | |
| class B(M, AB): pass | |
| AOrB = Union[A, B] | |
| class T(object): | |
| def __init__(self, typ: Type[AOrB] = A) -> None: | |
| assert isinstance(typ, type(M)) | |
| self.typ: Type[AOrB] = typ | |
| [builtins fixtures/isinstancelist.pyi] | |
| [case testIsInstanceTypeIsSubclass] | |
| from typing import Union, Type | |
| class C: ... | |
| x: Union[C, Type[C]] | |
| if isinstance(x, type) and issubclass(x, C): | |
| reveal_type(x) # N: Revealed type is "type[__main__.C]" | |
| [builtins fixtures/isinstancelist.pyi] | |
| [case testIsInstanceTypeByAssert] | |
| class A: | |
| x = 42 | |
| i: type = A | |
| assert issubclass(i, A) | |
| reveal_type(i.x) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/isinstancelist.pyi] | |
| [case testIsInstanceTypeTypeVar] | |
| from typing import Type, TypeVar, Generic, ClassVar | |
| class Base: ... | |
| class Sub(Base): | |
| other: ClassVar[int] | |
| T = TypeVar('T', bound=Base) | |
| class C(Generic[T]): | |
| def meth(self, cls: Type[T]) -> None: | |
| if not issubclass(cls, Sub): | |
| return | |
| reveal_type(cls) # N: Revealed type is "type[T`1]" | |
| reveal_type(cls.other) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/isinstance.pyi] | |
| [case testIsInstanceTypeSubclass] | |
| from typing import Type, Optional | |
| class Base: ... | |
| class One(Base): | |
| x: int | |
| class Other(Base): | |
| x: int | |
| def test() -> None: | |
| x: Optional[Type[Base]] | |
| if int(): | |
| x = One | |
| elif int(): | |
| x = Other | |
| else: | |
| return | |
| reveal_type(x) # N: Revealed type is "(def () -> __main__.One) | (def () -> __main__.Other)" | |
| reveal_type(x.x) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/isinstancelist.pyi] | |
| [case testMemberRedefinition] | |
| class C: | |
| def __init__(self) -> None: | |
| self.foo = 12 | |
| self.foo: int = 12 # E: Attribute "foo" already defined on line 3 | |
| [case testMemberRedefinitionDefinedInClass] | |
| class C: | |
| foo = 12 | |
| def __init__(self) -> None: | |
| self.foo: int = 12 # E: Attribute "foo" already defined on line 2 | |
| [case testAbstractInit] | |
| from abc import abstractmethod, ABCMeta | |
| class A(metaclass=ABCMeta): | |
| @abstractmethod | |
| def __init__(self, a: int) -> None: | |
| pass | |
| class B(A): | |
| pass | |
| class C(B): | |
| def __init__(self, a: int) -> None: | |
| self.c = a | |
| a = A(1) # E: Cannot instantiate abstract class "A" with abstract attribute "__init__" | |
| A.c # E: "type[A]" has no attribute "c" | |
| b = B(2) # E: Cannot instantiate abstract class "B" with abstract attribute "__init__" | |
| B.c # E: "type[B]" has no attribute "c" | |
| c = C(3) | |
| c.c | |
| C.c # E: Cannot access instance-only attribute "c" on class object | |
| [case testAccessInstanceVarOnClass] | |
| class A: | |
| def __init__(self) -> None: | |
| self.x = 0 | |
| A.x # E: Cannot access instance-only attribute "x" on class object | |
| A.x = 1 # We allow this, since it works at runtime, even though it is weird | |
| class B: | |
| x = 1 | |
| class C(B): | |
| def __init__(self) -> None: | |
| self.x: int = 2 | |
| C.x # Again, this works at runtime, so we don't prohibit this | |
| [case testDecoratedConstructors] | |
| from typing import TypeVar, Callable, Any | |
| F = TypeVar('F', bound=Callable[..., Any]) | |
| def dec(f: F) -> F: ... | |
| class A: | |
| @dec | |
| def __init__(self, x: int) -> None: ... | |
| class B: | |
| @dec | |
| def __new__(cls, x: int) -> B: ... | |
| reveal_type(A) # N: Revealed type is "def (x: builtins.int) -> __main__.A" | |
| reveal_type(B) # N: Revealed type is "def (x: builtins.int) -> __main__.B" | |
| [case testDecoratedConstructorsBad] | |
| from typing import Callable, Any | |
| def dec(f: Callable[[Any, int], Any]) -> int: ... | |
| class A: | |
| @dec # E: Unsupported decorated constructor type | |
| def __init__(self, x: int) -> None: ... | |
| class B: | |
| @dec # E: Unsupported decorated constructor type | |
| def __new__(cls, x: int) -> B: ... | |
| [case testIgnorePrivateAttributesTypeCheck] | |
| class B: | |
| __foo_: int | |
| class C(B): | |
| __foo_: str | |
| [out] | |
| [case testIgnorePrivateMethodsTypeCheck] | |
| class B: | |
| def __foo_(self) -> int: ... | |
| class C(B): | |
| def __foo_(self) -> str: ... | |
| [out] | |
| [case testCheckForPrivateMethodsWhenPublicCheck] | |
| class B: | |
| __foo__: int | |
| class C(B): | |
| __foo__: str | |
| [out] | |
| main:4: error: Incompatible types in assignment (expression has type "str", base class "B" defined the type as "int") | |
| [case testIgnorePrivateMethodsTypeCheck2] | |
| class A: | |
| def __foo_(self) -> int: ... | |
| class B: | |
| def __foo_(self) -> str: ... | |
| class C(A, B): pass | |
| [out] | |
| [case testAttributeDefOrder1] | |
| import a | |
| [file a.py] | |
| from b import C | |
| class D(C): | |
| def g(self) -> None: | |
| self.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| def f(self) -> None: | |
| reveal_type(self.x) # N: Revealed type is "builtins.int" | |
| [file b.py] | |
| import a | |
| class C: | |
| def __init__(self) -> None: | |
| self.x = 0 | |
| [targets b, a, b.C.__init__, a.D.g, a.D.f, __main__] | |
| [case testAttributeDefOrder2] | |
| class D(C): | |
| def g(self) -> None: | |
| self.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| def f(self) -> None: | |
| reveal_type(self.x) # N: Revealed type is "builtins.int" | |
| class C: | |
| def __init__(self) -> None: | |
| self.x = 0 | |
| class E(C): | |
| def g(self) -> None: | |
| self.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| def f(self) -> None: | |
| reveal_type(self.x) # N: Revealed type is "builtins.int" | |
| [targets __main__, __main__, __main__.C.__init__, __main__.D.g, __main__.D.f, __main__.E.g, __main__.E.f] | |
| [case testAttributeDefOrderNestedClass] | |
| class E(D): | |
| def e(self) -> None: | |
| self.x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| class D: | |
| def d(self) -> None: pass | |
| class N: | |
| def n(self) -> None: pass | |
| def d2(self) -> None: | |
| self.x = 0 | |
| [case testOrderBySubclassingMultipleLevels] | |
| class E(D): | |
| def e(self) -> None: ... | |
| class D(B): | |
| def d(self) -> None: ... | |
| class N: | |
| def n(self) -> None: ... | |
| def d2(self) -> None: ... | |
| def f() -> None: ... | |
| class C(A): | |
| def c(self) -> None: ... | |
| class B(A): | |
| def b(self) -> None: ... | |
| class A: | |
| def a(self) -> None: ... | |
| [targets __main__, __main__, __main__, __main__, __main__.D.N.n, __main__.f, __main__.A.a, __main__.C.c, __main__.B.b, __main__.D.d, __main__.D.d2, __main__.E.e] | |
| [case testNewReturnType1] | |
| class A: | |
| def __new__(cls) -> B: | |
| pass | |
| class B(A): pass | |
| reveal_type(A()) # N: Revealed type is "__main__.B" | |
| reveal_type(B()) # N: Revealed type is "__main__.B" | |
| [case testNewReturnType2] | |
| from typing import Any | |
| # make sure that __new__ method that return implicit Any are ignored when | |
| # determining the return type | |
| class A: | |
| def __new__(cls): | |
| pass | |
| class B: | |
| def __new__(cls, x: int = 0) -> Any: | |
| pass | |
| class C: | |
| def __new__(cls, x: int = 0): | |
| pass | |
| reveal_type(A()) # N: Revealed type is "__main__.A" | |
| reveal_type(B()) # N: Revealed type is "Any" | |
| reveal_type(B(1)) # N: Revealed type is "Any" | |
| reveal_type(C()) # N: Revealed type is "__main__.C" | |
| reveal_type(C(1)) # N: Revealed type is "__main__.C" | |
| [case testNewReturnType3] | |
| # Check for invalid __new__ typing | |
| class A: | |
| def __new__(cls) -> int: # E: Incompatible return type for "__new__" (returns "int", but must return a subtype of "A") | |
| pass | |
| reveal_type(A()) # N: Revealed type is "builtins.int" | |
| [case testNewReturnType4] | |
| from typing import TypeVar, Type | |
| # Check for __new__ using type vars | |
| TX = TypeVar('TX', bound='X') | |
| class X: | |
| def __new__(lol: Type[TX], x: int) -> TX: | |
| pass | |
| class Y(X): pass | |
| reveal_type(X(20)) # N: Revealed type is "__main__.X" | |
| reveal_type(Y(20)) # N: Revealed type is "__main__.Y" | |
| [case testNewReturnType5] | |
| from typing import Any, TypeVar, Generic, overload | |
| T = TypeVar('T') | |
| class O(Generic[T]): | |
| @overload | |
| def __new__(cls) -> O[int]: | |
| pass | |
| @overload | |
| def __new__(cls, x: int) -> O[str]: | |
| pass | |
| def __new__(cls, x: int = 0) -> O[Any]: | |
| pass | |
| reveal_type(O()) # N: Revealed type is "__main__.O[builtins.int]" | |
| reveal_type(O(10)) # N: Revealed type is "__main__.O[builtins.str]" | |
| [case testNewReturnType6] | |
| from typing import Tuple, Optional | |
| # Check for some cases that aren't allowed | |
| class X: | |
| def __new__(cls) -> Optional[Y]: # E: "__new__" must return a class instance (got "Y | None") | |
| pass | |
| class Y: | |
| def __new__(cls) -> Optional[int]: # E: "__new__" must return a class instance (got "int | None") | |
| pass | |
| [case testNewReturnType7] | |
| from typing import NamedTuple | |
| # ... test __new__ returning tuple type | |
| class A: | |
| def __new__(cls) -> 'B': | |
| pass | |
| N = NamedTuple('N', [('x', int)]) | |
| class B(A, N): pass | |
| reveal_type(A()) # N: Revealed type is "tuple[builtins.int, fallback=__main__.B]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testNewReturnType8] | |
| from typing import TypeVar, Any | |
| # test type var from a different argument | |
| TX = TypeVar('TX', bound='X') | |
| class X: | |
| def __new__(cls, x: TX) -> TX: # E: "__new__" must return a class instance (got "TX") | |
| pass | |
| [case testNewReturnType9] | |
| class A: | |
| def __new__(cls) -> A: | |
| pass | |
| class B(A): | |
| pass | |
| reveal_type(B()) # N: Revealed type is "__main__.B" | |
| [case testNewReturnType10] | |
| # https://github.com/python/mypy/issues/11398 | |
| from typing import Type | |
| class MyMetaClass(type): | |
| def __new__(cls, name, bases, attrs) -> Type['MyClass']: | |
| pass | |
| class MyClass(metaclass=MyMetaClass): | |
| pass | |
| [case testNewReturnType11] | |
| # https://github.com/python/mypy/issues/11398 | |
| class MyMetaClass(type): | |
| def __new__(cls, name, bases, attrs) -> type: | |
| pass | |
| class MyClass(metaclass=MyMetaClass): | |
| pass | |
| [case testNewReturnType12] | |
| # https://github.com/python/mypy/issues/11398 | |
| from typing import Type | |
| class MyMetaClass(type): | |
| def __new__(cls, name, bases, attrs) -> int: # E: Incompatible return type for "__new__" (returns "int", but must return a subtype of "type") | |
| pass | |
| class MyClass(metaclass=MyMetaClass): | |
| pass | |
| [case testNewReturnType13] | |
| from typing import Protocol | |
| class Foo(Protocol): | |
| def foo(self) -> str: ... | |
| class A: | |
| def __new__(cls) -> Foo: ... # E: Incompatible return type for "__new__" (returns "Foo", but must return a subtype of "A") | |
| reveal_type(A()) # N: Revealed type is "__main__.Foo" | |
| reveal_type(A().foo()) # N: Revealed type is "builtins.str" | |
| [case testNewReturnType14] | |
| from __future__ import annotations | |
| class A: | |
| def __new__(cls) -> int: raise # E: Incompatible return type for "__new__" (returns "int", but must return a subtype of "A") | |
| class B(A): | |
| @classmethod | |
| def foo(cls) -> int: raise | |
| reveal_type(B.foo()) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/classmethod.pyi] | |
| [case testNewReturnType15] | |
| from typing import Generic, Type, TypeVar | |
| T = TypeVar("T") | |
| class A(Generic[T]): | |
| def __new__(cls) -> B[int]: ... | |
| @classmethod | |
| def foo(cls: Type[A[T]]) -> T: ... | |
| class B(A[T]): ... | |
| # The Never without error is not ideal, but matches the behavior without custom __new__(). | |
| reveal_type(B.foo()) # N: Revealed type is "Never" | |
| reveal_type(B[str].foo()) # N: Revealed type is "builtins.str" | |
| class C(A[str]): ... | |
| reveal_type(C.foo()) # N: Revealed type is "builtins.str" | |
| [builtins fixtures/classmethod.pyi] | |
| [case testNewReturnType16] | |
| from typing import Generic, TypeVar | |
| T = TypeVar("T") | |
| class A(Generic[T]): | |
| def __new__(cls, *args, **kwargs) -> T: # E: "__new__" must return a class instance (got "T") | |
| ... | |
| class Model: | |
| pass | |
| reveal_type(A[Model]()) # N: Revealed type is "__main__.Model" | |
| class B(A[Model]): | |
| pass | |
| reveal_type(B()) # N: Revealed type is "__main__.Model" | |
| [builtins fixtures/dict.pyi] | |
| [case testNewReturnType17] | |
| class C: | |
| def __new__(self) -> D: | |
| return D() | |
| class D(C): | |
| x: int | |
| C.x # E: "type[C]" has no attribute "x" | |
| [case testNewReturnType18] | |
| class A: | |
| def __new__(cls) -> A: | |
| return A() | |
| class B(A): | |
| def __new__(cls) -> A: # E: Incompatible return type for "__new__" (returns "A", but must return a subtype of "B") | |
| return super().__new__(cls) | |
| class C(B): ... | |
| # Always respect explicit return type after giving an error. | |
| reveal_type(B()) # N: Revealed type is "__main__.A" | |
| reveal_type(C()) # N: Revealed type is "__main__.A" | |
| # Ignore "implicit" return type to preserve backwards compatibility. | |
| class D(A): ... | |
| reveal_type(D()) # N: Revealed type is "__main__.D" | |
| [case testNewReturnType19] | |
| from typing import TypeVar | |
| T = TypeVar("T") | |
| def f(tp: type[T]) -> T: ... | |
| class C: | |
| def __new__(cls) -> int: ... # type: ignore[misc] | |
| reveal_type(f(C)) # N: Revealed type is "__main__.C" | |
| [case testNewReturnTypeCallableSubtyping] | |
| from typing import Callable, Protocol | |
| class Foo: | |
| def foo(self) -> None: ... | |
| class A: | |
| def __new__(cls) -> Foo: ... # type: ignore | |
| ta: type[A] | |
| tf: type[Foo] | |
| class PA(Protocol): | |
| def __call__(self) -> A: ... | |
| class PFoo(Protocol): | |
| def __call__(self) -> Foo: ... | |
| def f(x: Callable[[], A]) -> None: ... | |
| def g(x: Callable[[], Foo]) -> None: ... | |
| def fp(x: PA) -> None: ... | |
| def gp(x: PFoo) -> None: ... | |
| def h(x: type[A]) -> None: ... | |
| def i(x: type[Foo]) -> None: ... | |
| f(A) # E: Argument 1 to "f" has incompatible type "type[A]"; expected "Callable[[], A]" | |
| g(A) | |
| fp(A) # E: Argument 1 to "fp" has incompatible type "type[A]"; expected "PA" \ | |
| # N: "A" has constructor incompatible with "__call__" of "PA" \ | |
| # N: Following member(s) of "A" have conflicts: \ | |
| # N: Expected: \ | |
| # N: def __call__() -> A \ | |
| # N: Got: \ | |
| # N: def A() -> Foo \ | |
| # N: "PA.__call__" has type "Callable[[], A]" | |
| gp(A) | |
| h(A) | |
| i(A) # E: Argument 1 to "i" has incompatible type "type[A]"; expected "type[Foo]" | |
| f(Foo) # E: Argument 1 to "f" has incompatible type "type[Foo]"; expected "Callable[[], A]" | |
| g(Foo) | |
| fp(Foo) # E: Argument 1 to "fp" has incompatible type "type[Foo]"; expected "PA" \ | |
| # N: "Foo" has constructor incompatible with "__call__" of "PA" \ | |
| # N: Following member(s) of "Foo" have conflicts: \ | |
| # N: Expected: \ | |
| # N: def __call__() -> A \ | |
| # N: Got: \ | |
| # N: def Foo() -> Foo \ | |
| # N: "PA.__call__" has type "Callable[[], A]" | |
| gp(Foo) | |
| h(Foo) # E: Argument 1 to "h" has incompatible type "type[Foo]"; expected "type[A]" | |
| i(Foo) | |
| f(ta) # E: Argument 1 to "f" has incompatible type "type[A]"; expected "Callable[[], A]" | |
| g(ta) | |
| fp(ta) # E: Argument 1 to "fp" has incompatible type "type[A]"; expected "PA" \ | |
| # N: "A" has constructor incompatible with "__call__" of "PA" \ | |
| # N: Following member(s) of "A" have conflicts: \ | |
| # N: Expected: \ | |
| # N: def __call__() -> A \ | |
| # N: Got: \ | |
| # N: def A() -> Foo \ | |
| # N: "PA.__call__" has type "Callable[[], A]" | |
| gp(ta) | |
| h(ta) | |
| i(ta) # E: Argument 1 to "i" has incompatible type "type[A]"; expected "type[Foo]" | |
| f(tf) # E: Argument 1 to "f" has incompatible type "type[Foo]"; expected "Callable[[], A]" | |
| g(tf) | |
| fp(tf) # E: Argument 1 to "fp" has incompatible type "type[Foo]"; expected "PA" \ | |
| # N: "Foo" has constructor incompatible with "__call__" of "PA" \ | |
| # N: Following member(s) of "Foo" have conflicts: \ | |
| # N: Expected: \ | |
| # N: def __call__() -> A \ | |
| # N: Got: \ | |
| # N: def Foo() -> Foo \ | |
| # N: "PA.__call__" has type "Callable[[], A]" | |
| gp(tf) | |
| h(tf) # E: Argument 1 to "h" has incompatible type "type[Foo]"; expected "type[A]" | |
| i(tf) | |
| [case testNewReturnTypeCallableJoins] | |
| from typing import TypeVar | |
| class Base: ... | |
| class Foo(Base): ... | |
| class Bar(Base): ... | |
| class Base2: ... | |
| class A(Base2): | |
| def __new__(cls) -> Foo: ... # type: ignore | |
| class B(Base2): | |
| def __new__(cls) -> Bar: ... # type: ignore | |
| T = TypeVar("T") | |
| def join(x: T, y: T) -> T: ... | |
| reveal_type(join(A, Foo)) # N: Revealed type is "def () -> __main__.Foo" | |
| reveal_type(join(Foo, A)) # N: Revealed type is "def () -> __main__.Foo" | |
| reveal_type(join(A, B)) # N: Revealed type is "def () -> __main__.Base" | |
| reveal_type(join(B, A)) # N: Revealed type is "def () -> __main__.Base" | |
| # This tests the type repr in error messages. | |
| j = join(A, B) | |
| x: int = j # E: Incompatible types in assignment (expression has type "type[Base2]", variable has type "int") | |
| [case testNewReturnTypeCallableInference] | |
| from typing import Callable, TypeVar | |
| class A: | |
| def __new__(cls) -> int: ... # type: ignore | |
| T = TypeVar("T") | |
| def foo(f: Callable[[], T]) -> T: ... | |
| def bar(t: type[T]) -> T: ... | |
| ta: type[A] | |
| reveal_type(foo(A)) # N: Revealed type is "builtins.int" | |
| reveal_type(foo(ta)) # N: Revealed type is "builtins.int" | |
| reveal_type(bar(A)) # N: Revealed type is "__main__.A" | |
| reveal_type(bar(ta)) # N: Revealed type is "__main__.A" | |
| [case testNewReturnTypeCallableNarrowing] | |
| from typing import Callable, TypeVar | |
| class A: ... | |
| class B(A): | |
| more = 1 | |
| def __new__(cls) -> A: ... # type: ignore | |
| x: A | |
| if isinstance(x, B): | |
| reveal_type(x) # N: Revealed type is "__main__.B" | |
| tx: type[A] | |
| if issubclass(tx, B): | |
| reveal_type(tx) # N: Revealed type is "type[__main__.B]" | |
| [builtins fixtures/isinstancelist.pyi] | |
| [case testNewReturnTypeOverloadNarrowing] | |
| from typing import TypeVar, Generic, Union, overload | |
| T = TypeVar("T", int, str) | |
| class Series(Generic[T]): | |
| @overload | |
| def __new__(cls, dtype: int) -> IntSeries: ... | |
| @overload | |
| def __new__(cls, dtype: type[T]) -> Series[T]: ... | |
| @overload | |
| def __new__(cls, dtype=...) -> Series: ... | |
| def __new__(cls, dtype=...) -> Series: | |
| ... | |
| class IntSeries(Series[int]): ... | |
| class Index: | |
| @overload | |
| def __new__(cls, dtype: int) -> IntIndex: ... | |
| @overload | |
| def __new__(cls, dtype=...) -> Index: ... | |
| def __new__(cls, dtype=...) -> Index: | |
| ... | |
| class IntIndex(Index): ... | |
| def foo(x: Union[Series, int, Index]): | |
| if isinstance(x, (Series, Index)): | |
| reveal_type(x) # N: Revealed type is "__main__.Series[Any] | __main__.Index" | |
| else: | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/isinstancelist.pyi] | |
| [case testMetaclassPlaceholderNode] | |
| from sympy.assumptions import ManagedProperties | |
| from sympy.ops import AssocOp | |
| reveal_type(AssocOp.x) # N: Revealed type is "sympy.basic.Basic" | |
| reveal_type(AssocOp.y) # N: Revealed type is "builtins.int" | |
| [file sympy/__init__.py] | |
| [file sympy/assumptions.py] | |
| from .basic import Basic | |
| class ManagedProperties(type): | |
| x: Basic | |
| y: int | |
| # The problem is with the next line, | |
| # it creates the following order (classname, metaclass): | |
| # 1. Basic NameExpr(ManagedProperties) | |
| # 2. AssocOp None | |
| # 3. ManagedProperties None | |
| # 4. Basic NameExpr(ManagedProperties [sympy.assumptions.ManagedProperties]) | |
| # So, `AssocOp` will still have `metaclass_type` as `None` | |
| # and all its `mro` types will have `declared_metaclass` as `None`. | |
| from sympy.ops import AssocOp | |
| [file sympy/basic.py] | |
| from .assumptions import ManagedProperties | |
| class Basic(metaclass=ManagedProperties): ... | |
| [file sympy/ops.py] | |
| from sympy.basic import Basic | |
| class AssocOp(Basic): ... | |
| [case testMetaclassSubclassSelf] | |
| # This does not make much sense, but we must not crash: | |
| import a | |
| [file m.py] | |
| from a import A # E: Module "a" has no attribute "A" | |
| class Meta(A): pass | |
| [file a.py] | |
| from m import Meta | |
| class A(metaclass=Meta): pass | |
| [case testMetaclassConflict] | |
| class MyMeta1(type): ... | |
| class MyMeta2(type): ... | |
| class MyMeta3(type): ... | |
| class A(metaclass=MyMeta1): ... | |
| class B(metaclass=MyMeta2): ... | |
| class C(metaclass=type): ... | |
| class A1(A): ... | |
| class E: ... | |
| class CorrectMeta(MyMeta1, MyMeta2): ... | |
| class CorrectSubclass1(A1, B, E, metaclass=CorrectMeta): ... | |
| class CorrectSubclass2(A, B, E, metaclass=CorrectMeta): ... | |
| class CorrectSubclass3(B, A, metaclass=CorrectMeta): ... | |
| class ChildOfCorrectSubclass1(CorrectSubclass1): ... | |
| class CorrectWithType1(C, A1): ... | |
| class CorrectWithType2(B, C): ... | |
| class Conflict1(A1, B, E): ... # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \ | |
| # N: "__main__.MyMeta1" (metaclass of "__main__.A") conflicts with "__main__.MyMeta2" (metaclass of "__main__.B") | |
| class Conflict2(A, B): ... # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \ | |
| # N: "__main__.MyMeta1" (metaclass of "__main__.A") conflicts with "__main__.MyMeta2" (metaclass of "__main__.B") | |
| class Conflict3(B, A): ... # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \ | |
| # N: "__main__.MyMeta2" (metaclass of "__main__.B") conflicts with "__main__.MyMeta1" (metaclass of "__main__.A") | |
| class ChildOfConflict1(Conflict3): ... | |
| class ChildOfConflict2(Conflict3, metaclass=CorrectMeta): ... | |
| class ConflictingMeta(MyMeta1, MyMeta3): ... | |
| class Conflict4(A1, B, E, metaclass=ConflictingMeta): ... # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \ | |
| # N: "__main__.ConflictingMeta" (metaclass of "__main__.Conflict4") conflicts with "__main__.MyMeta2" (metaclass of "__main__.B") | |
| class ChildOfCorrectButWrongMeta(CorrectSubclass1, metaclass=ConflictingMeta): # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \ | |
| # N: "__main__.ConflictingMeta" (metaclass of "__main__.ChildOfCorrectButWrongMeta") conflicts with "__main__.CorrectMeta" (metaclass of "__main__.CorrectSubclass1") | |
| ... | |
| [case testMetaClassConflictIssue14033] | |
| class M1(type): pass | |
| class M2(type): pass | |
| class Mx(M1, M2): pass | |
| class A1(metaclass=M1): pass | |
| class A2(A1): pass | |
| class B1(metaclass=M2): pass | |
| class C1(metaclass=Mx): pass | |
| class TestABC(A2, B1, C1): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \ | |
| # N: "__main__.M1" (metaclass of "__main__.A1") conflicts with "__main__.M2" (metaclass of "__main__.B1") | |
| class TestBAC(B1, A2, C1): pass # E: Metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases \ | |
| # N: "__main__.M2" (metaclass of "__main__.B1") conflicts with "__main__.M1" (metaclass of "__main__.A1") | |
| # should not warn again for children | |
| class ChildOfTestABC(TestABC): pass | |
| # no metaclass is assumed if super class has a metaclass conflict | |
| class ChildOfTestABCMetaMx(TestABC, metaclass=Mx): pass | |
| class ChildOfTestABCMetaM1(TestABC, metaclass=M1): pass | |
| class TestABCMx(A2, B1, C1, metaclass=Mx): pass | |
| class TestBACMx(B1, A2, C1, metaclass=Mx): pass | |
| class TestACB(A2, C1, B1): pass | |
| class TestBCA(B1, C1, A2): pass | |
| class TestCAB(C1, A2, B1): pass | |
| class TestCBA(C1, B1, A2): pass | |
| [case testGenericOverride] | |
| from typing import Generic, TypeVar, Any | |
| T = TypeVar('T') | |
| class B(Generic[T]): | |
| x: T | |
| class C(B): | |
| def __init__(self) -> None: | |
| self.x: Any | |
| [case testGenericOverridePreciseInvalid] | |
| from typing import Generic, TypeVar, Any | |
| T = TypeVar('T') | |
| class B(Generic[T]): | |
| x: T | |
| class C(B[str]): | |
| def __init__(self) -> None: | |
| self.x: int # E: Incompatible types in assignment (expression has type "int", base class "B" defined the type as "str") | |
| [case testGenericOverridePreciseValid] | |
| from typing import Generic, TypeVar | |
| T = TypeVar('T') | |
| class B(Generic[T]): | |
| x: T | |
| class C(B[float]): | |
| def __init__(self) -> None: | |
| self.x: int # We currently allow covariant overriding. | |
| [case testGenericOverrideGeneric] | |
| from typing import Generic, TypeVar, List | |
| T = TypeVar('T') | |
| class B(Generic[T]): | |
| x: T | |
| class C(B[T]): | |
| def __init__(self) -> None: | |
| self.x: List[T] # E: Incompatible types in assignment (expression has type "list[T]", base class "B" defined the type as "T") | |
| [builtins fixtures/list.pyi] | |
| [case testGenericOverrideGenericChained] | |
| from typing import Generic, TypeVar, Tuple | |
| T = TypeVar('T') | |
| S = TypeVar('S') | |
| class A(Generic[T]): | |
| x: T | |
| class B(A[Tuple[T, S]]): ... | |
| class C(B[int, T]): | |
| def __init__(self) -> None: | |
| # TODO: error message could be better. | |
| self.x: Tuple[str, T] # E: Incompatible types in assignment (expression has type "tuple[str, T]", base class "A" defined the type as "tuple[int, T]") | |
| [builtins fixtures/tuple.pyi] | |
| [case testInitSubclassWrongType] | |
| class Base: | |
| default_name: str | |
| def __init_subclass__(cls, default_name: str): | |
| super().__init_subclass__() | |
| cls.default_name = default_name | |
| return | |
| class Child(Base, default_name=5): # E: Argument "default_name" to "__init_subclass__" of "Base" has incompatible type "int"; expected "str" | |
| pass | |
| [builtins fixtures/object_with_init_subclass.pyi] | |
| [case testInitSubclassTooFewArgs] | |
| class Base: | |
| default_name: str | |
| def __init_subclass__(cls, default_name: str, **kwargs): | |
| super().__init_subclass__() | |
| cls.default_name = default_name | |
| return | |
| class Child(Base): # E: Missing positional argument "default_name" in call to "__init_subclass__" of "Base" | |
| pass | |
| [builtins fixtures/object_with_init_subclass.pyi] | |
| [case testInitSubclassTooFewArgs2] | |
| class Base: | |
| default_name: str | |
| def __init_subclass__(cls, default_name: str, thing: int): | |
| super().__init_subclass__() | |
| cls.default_name = default_name | |
| return | |
| # TODO implement this, so that no error is raised? | |
| d = {"default_name": "abc", "thing": 0} | |
| class Child(Base, **d): # E: Missing positional arguments "default_name", "thing" in call to "__init_subclass__" of "Base" | |
| pass | |
| [builtins fixtures/object_with_init_subclass.pyi] | |
| [case testInitSubclassOK] | |
| class Base: | |
| default_name: str | |
| thing: int | |
| def __init_subclass__(cls, default_name: str, thing:int, **kwargs): | |
| super().__init_subclass__() | |
| cls.default_name = default_name | |
| return | |
| class Child(Base, thing=5, default_name=""): | |
| pass | |
| [builtins fixtures/object_with_init_subclass.pyi] | |
| [case testInitSubclassWithMetaclassOK] | |
| class Base: | |
| thing: int | |
| def __init_subclass__(cls, thing: int): | |
| cls.thing = thing | |
| class Child(Base, metaclass=type, thing=0): | |
| pass | |
| [builtins fixtures/object_with_init_subclass.pyi] | |
| [case testInitSubclassWithCustomMetaclassOK] | |
| class M(type): ... | |
| class Child(metaclass=M, thing=0): | |
| pass | |
| [builtins fixtures/object_with_init_subclass.pyi] | |
| [case testTooManyArgsForObject] | |
| class A(thing=5): | |
| pass | |
| [out] | |
| main:1: error: Unexpected keyword argument "thing" for "__init_subclass__" of "object" | |
| [builtins fixtures/object_with_init_subclass.pyi] | |
| [case testInitSubclassWithImports] | |
| from init_subclass.a import Base | |
| class Child(Base, thing=5): # E: Missing positional argument "default_name" in call to "__init_subclass__" of "Base" | |
| pass | |
| [file init_subclass/a.py] | |
| class Base: | |
| default_name: str | |
| thing: int | |
| def __init_subclass__(cls, default_name: str, thing:int, **kwargs): | |
| pass | |
| [file init_subclass/__init__.py] | |
| [builtins fixtures/object_with_init_subclass.pyi] | |
| [case testInitSubclassWithImportsOK] | |
| from init_subclass.a import MidBase | |
| class Main(MidBase, test=True): pass | |
| [file init_subclass/a.py] | |
| class Base: | |
| def __init_subclass__(cls, **kwargs) -> None: pass | |
| class MidBase(Base): pass | |
| [file init_subclass/__init__.py] | |
| [builtins fixtures/object_with_init_subclass.pyi] | |
| [case testInitSubclassUnannotated] | |
| class A: | |
| def __init_subclass__(cls, *args, **kwargs): | |
| super().__init_subclass__(*args, **kwargs) | |
| class B(A): | |
| pass | |
| reveal_type(A.__init_subclass__) # N: Revealed type is "def (*args: Any, **kwargs: Any) -> Any" | |
| [builtins fixtures/object_with_init_subclass.pyi] | |
| [case testInitSubclassUnannotatedMulti] | |
| from typing import ClassVar, List, Type | |
| class A: | |
| registered_classes: ClassVar[List[Type[A]]] = [] | |
| def __init_subclass__(cls, *args, register=True, **kwargs): | |
| if register: | |
| cls.registered_classes.append(cls) | |
| super().__init_subclass__(*args, **kwargs) | |
| class B(A): ... | |
| class C(A, register=False): ... | |
| class D(C): ... | |
| [builtins fixtures/object_with_init_subclass.pyi] | |
| [case testClassMethodUnannotated] | |
| class C: | |
| def __new__(cls): ... | |
| @classmethod | |
| def meth(cls): ... | |
| reveal_type(C.meth) # N: Revealed type is "def () -> Any" | |
| reveal_type(C.__new__) # N: Revealed type is "def (cls: type[__main__.C]) -> Any" | |
| [builtins fixtures/classmethod.pyi] | |
| [case testOverrideGenericSelfClassMethod] | |
| from typing import Generic, TypeVar, Type, List | |
| T = TypeVar('T', bound='A') | |
| class A: | |
| @classmethod | |
| def meth(cls: Type[T]) -> List[T]: ... | |
| class B(A): | |
| @classmethod | |
| def meth(cls: Type[T]) -> List[T]: ... | |
| [builtins fixtures/isinstancelist.pyi] | |
| [case testCheckUntypedDefsSelf1] | |
| # flags: --check-untyped-defs | |
| from typing import Generic, TypeVar | |
| T = TypeVar('T') | |
| class Desc: | |
| def __get__(self, x, y): | |
| # type: (...) -> bool | |
| pass | |
| class Foo: | |
| y = Desc() | |
| def __init__(self): | |
| self.x = 0 | |
| def foo(self): | |
| reveal_type(self.x) # N: Revealed type is "builtins.int" | |
| reveal_type(self.y) # N: Revealed type is "builtins.bool" | |
| self.bar() | |
| self.baz() # E: "Foo" has no attribute "baz" | |
| @classmethod | |
| def bar(cls): | |
| cls.baz() # E: "type[Foo]" has no attribute "baz" | |
| class C(Generic[T]): | |
| x: T | |
| def meth(self): | |
| self.x + 1 # E: Unsupported left operand type for + ("T") | |
| [builtins fixtures/classmethod.pyi] | |
| [case testCheckUntypedDefsSelf2] | |
| # flags: --check-untyped-defs | |
| class Foo: | |
| def __init__(self): | |
| self.x = None | |
| self.y = [] | |
| reveal_type(Foo().x) # N: Revealed type is "Any | None" | |
| reveal_type(Foo().y) # N: Revealed type is "builtins.list[Any]" | |
| [builtins fixtures/list.pyi] | |
| [case testCheckUntypedDefsSelf3] | |
| # flags: --check-untyped-defs | |
| class Foo: | |
| def bad(): # E: Method must have at least one argument. Did you forget the "self" argument? | |
| self.x = 0 # E: Name "self" is not defined | |
| [case testMethodSelfArgumentChecks] | |
| from typing import Callable, ParamSpec, TypeVar | |
| T = TypeVar("T") | |
| P = ParamSpec("P") | |
| def to_number_1(fn: Callable[[], int]) -> int: | |
| return 0 | |
| def to_number_2(fn: Callable[[int], int]) -> int: | |
| return 0 | |
| def to_same_callable(fn: Callable[P, T]) -> Callable[P, T]: | |
| return fn | |
| class A: | |
| def undecorated() -> None: ... # E: Method must have at least one argument. Did you forget the "self" argument? | |
| def undecorated_not_self(x: int) -> None: ... # E: "self" parameter missing for a non-static method (or an invalid type for self) | |
| 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" | |
| @to_number_1 | |
| def fn1() -> int: | |
| return 0 | |
| @to_number_1 # E: Argument 1 to "to_number_1" has incompatible type "Callable[[int], int]"; expected "Callable[[], int]" | |
| def fn2(_x: int) -> int: | |
| return 0 | |
| @to_number_2 # E: Argument 1 to "to_number_2" has incompatible type "Callable[[], int]"; expected "Callable[[int], int]" | |
| def fn3() -> int: | |
| return 0 | |
| @to_number_2 | |
| def fn4(_x: int) -> int: | |
| return 0 | |
| @to_number_2 # E: Argument 1 to "to_number_2" has incompatible type "Callable[[str], int]"; expected "Callable[[int], int]" | |
| def fn5(_x: str) -> int: | |
| return 0 | |
| @to_same_callable | |
| def g1() -> None: ... # E: Method must have at least one argument. Did you forget the "self" argument? | |
| @to_same_callable | |
| def g2(x: int) -> None: ... # E: "self" parameter missing for a non-static method (or an invalid type for self) | |
| @to_same_callable | |
| def g3(self: int) -> None: ... # E: The erased type of self "builtins.int" is not a supertype of its class "__main__.A" | |
| reveal_type(A().fn1) # N: Revealed type is "builtins.int" | |
| reveal_type(A().fn2) # N: Revealed type is "builtins.int" | |
| reveal_type(A().fn3) # N: Revealed type is "builtins.int" | |
| reveal_type(A().fn4) # N: Revealed type is "builtins.int" | |
| reveal_type(A().fn5) # N: Revealed type is "builtins.int" | |
| reveal_type(A().g1) # E: Attribute function "g1" with type "Callable[[], None]" does not accept self argument \ | |
| # N: Revealed type is "def ()" | |
| reveal_type(A().g2) # E: Invalid self argument "A" to attribute function "g2" with type "Callable[[int], None]" \ | |
| # N: Revealed type is "def ()" | |
| reveal_type(A().g3) # E: Invalid self argument "A" to attribute function "g3" with type "Callable[[int], None]" \ | |
| # N: Revealed type is "def ()" | |
| [builtins fixtures/tuple.pyi] | |
| [case testMethodSelfArgumentChecksConcatenate] | |
| from typing import Callable, ParamSpec, TypeVar | |
| from typing_extensions import Concatenate | |
| T = TypeVar("T") | |
| P = ParamSpec("P") | |
| R = TypeVar("R") | |
| def to_same_callable(fn: Callable[Concatenate[T, P], R]) -> Callable[Concatenate[T, P], R]: | |
| return fn | |
| def remove_first(fn: Callable[Concatenate[T, P], R]) -> Callable[P, R]: | |
| ... | |
| def add_correct_first(fn: Callable[P, R]) -> Callable[Concatenate["C", P], R]: | |
| ... | |
| def add_wrong_first(fn: Callable[P, R]) -> Callable[Concatenate[int, P], R]: | |
| ... | |
| class A: | |
| @to_same_callable # E: Argument 1 to "to_same_callable" has incompatible type "Callable[[], int]"; expected "Callable[[T], int]" | |
| def fn1() -> int: | |
| return 0 | |
| @to_same_callable | |
| def fn2(_x: int) -> int: # E: "self" parameter missing for a non-static method (or an invalid type for self) | |
| return 0 | |
| @to_same_callable | |
| def fn3(self, _x: int) -> int: | |
| return 0 | |
| reveal_type(A().fn1) # N: Revealed type is "def () -> builtins.int" | |
| reveal_type(A().fn2) # E: Invalid self argument "A" to attribute function "fn2" with type "Callable[[int], int]" \ | |
| # N: Revealed type is "def () -> builtins.int" | |
| reveal_type(A().fn3) # N: Revealed type is "def (_x: builtins.int) -> builtins.int" | |
| class B: | |
| @remove_first # E: Argument 1 to "remove_first" has incompatible type "Callable[[], int]"; expected "Callable[[T], int]" | |
| def fn1() -> int: # E: Method must have at least one argument. Did you forget the "self" argument? | |
| return 0 | |
| @remove_first | |
| def fn2(_x: int) -> int: # E: Method must have at least one argument. Did you forget the "self" argument? | |
| return 0 | |
| @remove_first | |
| def fn3(self, _x: int) -> int: # E: "self" parameter missing for a non-static method (or an invalid type for self) | |
| return 0 | |
| @remove_first | |
| def fn4(self, new_self: 'B') -> int: | |
| return 0 | |
| reveal_type(B().fn1) # E: Attribute function "fn1" with type "Callable[[], int]" does not accept self argument \ | |
| # N: Revealed type is "def () -> builtins.int" | |
| reveal_type(B().fn2) # E: Attribute function "fn2" with type "Callable[[], int]" does not accept self argument \ | |
| # N: Revealed type is "def () -> builtins.int" | |
| reveal_type(B().fn3) # E: Invalid self argument "B" to attribute function "fn3" with type "Callable[[int], int]" \ | |
| # N: Revealed type is "def () -> builtins.int" | |
| reveal_type(B().fn4) # N: Revealed type is "def () -> builtins.int" | |
| class C: | |
| @add_correct_first | |
| def fn1() -> int: | |
| return 0 | |
| @add_correct_first | |
| def fn2(_x: int) -> int: | |
| return 0 | |
| @add_correct_first | |
| def fn3(self, _x: int) -> int: | |
| return 0 | |
| reveal_type(C().fn1) # N: Revealed type is "def () -> builtins.int" | |
| reveal_type(C().fn2) # N: Revealed type is "def (_x: builtins.int) -> builtins.int" | |
| reveal_type(C().fn3) # N: Revealed type is "def (self: __main__.C, _x: builtins.int) -> builtins.int" | |
| class D: | |
| @add_wrong_first | |
| def fn1() -> int: # E: "self" parameter missing for a non-static method (or an invalid type for self) | |
| return 0 | |
| @add_wrong_first | |
| def fn2(_x: int) -> int: # E: "self" parameter missing for a non-static method (or an invalid type for self) | |
| return 0 | |
| @add_wrong_first | |
| def fn3(self, _x: int) -> int: # E: "self" parameter missing for a non-static method (or an invalid type for self) | |
| return 0 | |
| reveal_type(D().fn1) # E: Invalid self argument "D" to attribute function "fn1" with type "Callable[[int], int]" \ | |
| # N: Revealed type is "def () -> builtins.int" | |
| reveal_type(D().fn2) # E: Invalid self argument "D" to attribute function "fn2" with type "Callable[[int, int], int]" \ | |
| # N: Revealed type is "def (_x: builtins.int) -> builtins.int" | |
| reveal_type(D().fn3) # E: Invalid self argument "D" to attribute function "fn3" with type "Callable[[int, D, int], int]" \ | |
| # N: Revealed type is "def (self: __main__.D, _x: builtins.int) -> builtins.int" | |
| [builtins fixtures/tuple.pyi] | |
| [case testMethodSelfArgumentChecksInUntyped] | |
| from typing import Callable, ParamSpec, TypeVar | |
| T = TypeVar("T") | |
| P = ParamSpec("P") | |
| def to_same_callable(fn: Callable[P, T]) -> Callable[P, T]: | |
| return fn | |
| def unchecked(): | |
| class Bad: | |
| def fn() -> None: ... # E: Method must have at least one argument. Did you forget the "self" argument? | |
| def fn2(x: int) -> None: ... # E: "self" parameter missing for a non-static method (or an invalid type for self) | |
| # TODO: would be nice to make this error, but now we see the func | |
| # being decorated as Any, not as a callable | |
| @to_same_callable | |
| def gaaa() -> None: ... | |
| @to_same_callable | |
| def gaaa2(x: int) -> None: ... | |
| class Ok: | |
| def fn(): ... | |
| def fn2(x): ... | |
| @to_same_callable | |
| def g(): ... | |
| @to_same_callable | |
| def g2(x): ... | |
| def checked() -> None: | |
| class Bad: | |
| def fn() -> None: ... # E: Method must have at least one argument. Did you forget the "self" argument? | |
| def fn2(x: int) -> None: ... # E: "self" parameter missing for a non-static method (or an invalid type for self) | |
| @to_same_callable | |
| def g() -> None: ... # E: Method must have at least one argument. Did you forget the "self" argument? | |
| @to_same_callable | |
| def g2(x: int) -> None: ... # E: "self" parameter missing for a non-static method (or an invalid type for self) | |
| class AlsoBad: | |
| def fn(): ... # E: Method must have at least one argument. Did you forget the "self" argument? | |
| def fn2(x): ... | |
| @to_same_callable | |
| def g(): ... # E: Method must have at least one argument. Did you forget the "self" argument? | |
| @to_same_callable | |
| def g2(x): ... | |
| class Ok: | |
| def fn(): ... # E: Method must have at least one argument. Did you forget the "self" argument? | |
| def fn2(x): ... | |
| @to_same_callable | |
| def g(): ... # E: Method must have at least one argument. Did you forget the "self" argument? | |
| @to_same_callable | |
| def g2(x): ... | |
| [builtins fixtures/tuple.pyi] | |
| [case testTypeAfterAttributeAccessWithDisallowAnyExpr] | |
| # flags: --disallow-any-expr | |
| def access_before_declaration(self) -> None: | |
| obj = Foo('bar') | |
| obj.value | |
| x = 1 | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| x = x + 1 | |
| class Foo: | |
| def __init__(self, value: str) -> None: | |
| self.value = value | |
| def access_after_declaration(self) -> None: | |
| obj = Foo('bar') | |
| obj.value | |
| x = 1 | |
| reveal_type(x) # N: Revealed type is "builtins.int" | |
| x = x + 1 | |
| [case testIsSubClassNarrowDownTypesOfTypeVariables] | |
| from typing import Type, TypeVar, Generic | |
| class Base: | |
| field: int = 42 | |
| TypeT = TypeVar("TypeT", bound=type) | |
| TypeT1 = TypeVar("TypeT1", bound=Type[Base]) | |
| class C1: | |
| def method(self, other: type) -> int: | |
| if issubclass(other, Base): | |
| reveal_type(other) # N: Revealed type is "type[__main__.Base]" | |
| return other.field | |
| return 0 | |
| class C2(Generic[TypeT]): | |
| def method(self, other: TypeT) -> int: | |
| if issubclass(other, Base): | |
| reveal_type(other) # N: Revealed type is "TypeT`1" | |
| return other.field | |
| return 0 | |
| class C3(Generic[TypeT1]): | |
| def method(self, other: TypeT1) -> int: | |
| if issubclass(other, Base): | |
| reveal_type(other) # N: Revealed type is "TypeT1`1" | |
| return other.field | |
| return 0 | |
| [builtins fixtures/isinstancelist.pyi] | |
| [case testPropertyWithExtraMethod] | |
| def dec(f): | |
| return f | |
| class A: | |
| @property | |
| def x(self): ... | |
| @x.setter | |
| def x(self, value) -> None: ... | |
| def x(self) -> None: ... # E: Unexpected definition for property "x" | |
| @property | |
| def y(self) -> int: ... | |
| @y.setter | |
| def y(self, value: int) -> None: ... | |
| @dec # E: Only supported top decorators are "@y.setter" and "@y.deleter" | |
| def y(self) -> None: ... | |
| reveal_type(A().y) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/property.pyi] | |
| [case testEnclosingScopeLambdaNoCrash] | |
| class C: | |
| x = lambda x: x.y.g() | |
| [case testEnclosingScopeLambdaNoCrashExplicit] | |
| from typing import Callable | |
| class C: | |
| x: Callable[[C], int] = lambda x: x.y.g() # E: "C" has no attribute "y" | |
| [case testOpWithInheritedFromAny-xfail] | |
| from typing import Any | |
| C: Any | |
| class D(C): | |
| pass | |
| class D1(C): | |
| def __add__(self, rhs: float) -> D1: | |
| return self | |
| reveal_type(0.5 + C) # N: Revealed type is "Any" | |
| reveal_type(0.5 + D()) # N: Revealed type is "Any" | |
| reveal_type(D() + 0.5) # N: Revealed type is "Any" | |
| reveal_type("str" + D()) # N: Revealed type is "builtins.str" | |
| reveal_type(D() + "str") # N: Revealed type is "Any" | |
| reveal_type(0.5 + D1()) # N: Revealed type is "Any" | |
| reveal_type(D1() + 0.5) # N: Revealed type is "__main__.D1" | |
| [builtins fixtures/primitives.pyi] | |
| [case testRefMethodWithDecorator] | |
| from typing import Type, final | |
| class A: | |
| pass | |
| class B: | |
| @staticmethod | |
| def A() -> Type[A]: ... | |
| @staticmethod | |
| def B() -> Type[A]: # E: Function "__main__.B.A" is not valid as a type \ | |
| # N: Perhaps you need "Callable[...]" or a callback protocol? | |
| return A | |
| class C: | |
| @final | |
| @staticmethod | |
| def A() -> Type[A]: | |
| return A | |
| [builtins fixtures/staticmethod.pyi] | |
| [case testRefMethodWithOverloadDecorator] | |
| from typing import Type, overload | |
| class A: | |
| pass | |
| class B: | |
| @classmethod | |
| @overload | |
| def A(cls, x: int) -> Type[A]: ... | |
| @classmethod | |
| @overload | |
| def A(cls, x: str) -> Type[A]: ... | |
| @classmethod | |
| def A(cls, x: object) -> Type[A]: ... | |
| def B(cls, x: int) -> Type[A]: ... # E: Function "__main__.B.A" is not valid as a type \ | |
| # N: Perhaps you need "Callable[...]" or a callback protocol? | |
| [builtins fixtures/classmethod.pyi] | |
| [case testFinalClassWithAbstractAttributes] | |
| from abc import abstractmethod, ABCMeta | |
| from typing import final | |
| @final | |
| class A(metaclass=ABCMeta): # E: Final class __main__.A has abstract attributes "bar", "foo" | |
| @abstractmethod | |
| def foo(self): | |
| pass | |
| @property | |
| @abstractmethod | |
| def bar(self): | |
| pass | |
| [builtins fixtures/property.pyi] | |
| [case testFinalClassWithoutABCMeta] | |
| from abc import abstractmethod | |
| from typing import final | |
| @final | |
| class A(): # E: Final class __main__.A has abstract attributes "bar", "foo" | |
| @abstractmethod | |
| def foo(self): | |
| pass | |
| @property | |
| @abstractmethod | |
| def bar(self): | |
| pass | |
| [builtins fixtures/property.pyi] | |
| [case testFinalClassInheritedAbstractAttributes] | |
| from abc import abstractmethod, ABCMeta | |
| from typing import final | |
| class A(metaclass=ABCMeta): | |
| @abstractmethod | |
| def foo(self): | |
| pass | |
| @final | |
| class B(A): # E: Final class __main__.B has abstract attributes "foo" | |
| pass | |
| [case testUndefinedBaseclassInNestedClass] | |
| class C: | |
| class C1(XX): pass # E: Name "XX" is not defined | |
| [case testArgsKwargsInheritance] | |
| from typing import Any | |
| class A(object): | |
| def f(self, *args: Any, **kwargs: Any) -> int: ... | |
| class B(A): | |
| def f(self, x: int) -> int: ... | |
| [builtins fixtures/dict.pyi] | |
| [case testClassScopeImports] | |
| class Foo: | |
| from mod import plain_function # E: Unsupported class scoped import | |
| from mod import plain_var | |
| reveal_type(Foo.plain_function) # N: Revealed type is "Any" | |
| reveal_type(Foo().plain_function) # N: Revealed type is "Any" | |
| reveal_type(Foo.plain_var) # N: Revealed type is "builtins.int" | |
| reveal_type(Foo().plain_var) # N: Revealed type is "builtins.int" | |
| [file mod.py] | |
| def plain_function(x: int, y: int) -> int: ... | |
| plain_var: int | |
| [case testClassScopeImportModule] | |
| class Foo: | |
| import mod | |
| reveal_type(Foo.mod) # N: Revealed type is "types.ModuleType" | |
| reveal_type(Foo.mod.foo) # N: Revealed type is "builtins.int" | |
| [file mod.py] | |
| foo: int | |
| [case testClassScopeImportAlias] | |
| class Foo: | |
| from mod import function # E: Unsupported class scoped import | |
| foo = function | |
| from mod import var1 | |
| bar = var1 | |
| from mod import var2 | |
| baz = var2 | |
| from mod import var3 | |
| qux = var3 | |
| reveal_type(Foo.foo) # N: Revealed type is "Any" | |
| reveal_type(Foo.function) # N: Revealed type is "Any" | |
| reveal_type(Foo.bar) # N: Revealed type is "builtins.int" | |
| reveal_type(Foo.var1) # N: Revealed type is "builtins.int" | |
| reveal_type(Foo.baz) # N: Revealed type is "mod.C" | |
| reveal_type(Foo.var2) # N: Revealed type is "mod.C" | |
| reveal_type(Foo.qux) # N: Revealed type is "builtins.int" | |
| reveal_type(Foo.var3) # N: Revealed type is "builtins.int" | |
| [file mod.py] | |
| def function(x: int, y: int) -> int: ... | |
| var1: int | |
| class C: ... | |
| var2: C | |
| A = int | |
| var3: A | |
| [case testClassScopeImportModuleStar] | |
| class Foo: | |
| from mod import * # E: Unsupported class scoped import | |
| reveal_type(Foo.foo) # N: Revealed type is "builtins.int" | |
| reveal_type(Foo.bar) # N: Revealed type is "Any" | |
| reveal_type(Foo.baz) # E: "type[Foo]" has no attribute "baz" \ | |
| # N: Revealed type is "Any" | |
| [file mod.py] | |
| foo: int | |
| def bar(x: int) -> int: ... | |
| [case testClassScopeImportAccessibleInMethods] | |
| class A: | |
| import mod | |
| from mod import var | |
| def __new__(cls) -> "A": | |
| reveal_type(cls.mod) # N: Revealed type is "types.ModuleType" | |
| reveal_type(cls.var) # N: Revealed type is "builtins.int" | |
| reveal_type(cls.mod.var) # N: Revealed type is "builtins.int" | |
| return cls() | |
| def pos_or_named_self(self) -> None: | |
| reveal_type(self.mod) # N: Revealed type is "types.ModuleType" | |
| reveal_type(self.var) # N: Revealed type is "builtins.int" | |
| reveal_type(self.mod.var) # N: Revealed type is "builtins.int" | |
| def pos_only_self(self, /) -> None: | |
| reveal_type(self.mod) # N: Revealed type is "types.ModuleType" | |
| reveal_type(self.var) # N: Revealed type is "builtins.int" | |
| reveal_type(self.mod.var) # N: Revealed type is "builtins.int" | |
| @classmethod | |
| def clsmethod(cls) -> None: | |
| reveal_type(cls.mod) # N: Revealed type is "types.ModuleType" | |
| reveal_type(cls.var) # N: Revealed type is "builtins.int" | |
| reveal_type(cls.mod.var) # N: Revealed type is "builtins.int" | |
| [file mod.py] | |
| var = 1 | |
| [builtins fixtures/module.pyi] | |
| [case testClassScopeImportFunctionNested] | |
| class Foo: | |
| class Bar: | |
| from mod import baz # E: Unsupported class scoped import | |
| reveal_type(Foo.Bar.baz) # N: Revealed type is "Any" | |
| reveal_type(Foo.Bar().baz) # N: Revealed type is "Any" | |
| [file mod.py] | |
| def baz(x: int) -> int: ... | |
| [case testClassScopeImportUndefined] | |
| class Foo: | |
| from unknown import foo # E: Cannot find implementation or library stub for module named "unknown" \ | |
| # N: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports | |
| reveal_type(Foo.foo) # N: Revealed type is "Any" | |
| reveal_type(Foo().foo) # N: Revealed type is "Any" | |
| [case testClassScopeImportWithFollowImports] | |
| # flags: --follow-imports=skip | |
| class Foo: | |
| from mod import foo | |
| reveal_type(Foo().foo) # N: Revealed type is "Any" | |
| [file mod.py] | |
| def foo(x: int, y: int) -> int: ... | |
| [case testClassScopeImportVarious] | |
| class Foo: | |
| from mod1 import foo # E: Unsupported class scoped import | |
| from mod2 import foo | |
| from mod1 import meth1 # E: Unsupported class scoped import | |
| def meth1(self, a: str) -> str: ... # E: Name "meth1" already defined on line 5 | |
| def meth2(self, a: str) -> str: ... | |
| from mod1 import meth2 # E: Incompatible import of "meth2" (imported name has type "Callable[[int], int]", local name has type "Callable[[Foo, str], str]") | |
| class Bar: | |
| from mod1 import foo # E: Unsupported class scoped import | |
| import mod1 | |
| reveal_type(Foo.foo) # N: Revealed type is "Any" | |
| reveal_type(Bar.foo) # N: Revealed type is "Any" | |
| reveal_type(mod1.foo) # N: Revealed type is "def (x: builtins.int, y: builtins.int) -> builtins.int" | |
| [file mod1.py] | |
| def foo(x: int, y: int) -> int: ... | |
| def meth1(x: int) -> int: ... | |
| def meth2(x: int) -> int: ... | |
| [file mod2.py] | |
| def foo(z: str) -> int: ... | |
| [case testClassScopeImportWithError] | |
| class Foo: | |
| from mod import meth1 # E: Unsupported class scoped import | |
| from mod import meth2 # E: Unsupported class scoped import | |
| from mod import T | |
| reveal_type(Foo.T) # N: Revealed type is "typing.TypeVar" | |
| [file mod.pyi] | |
| from typing import Any, TypeVar, overload | |
| @overload | |
| def meth1(self: Any, y: int) -> int: ... | |
| @overload | |
| def meth1(self: Any, y: str) -> str: ... | |
| T = TypeVar("T") | |
| def meth2(self: Any, y: T) -> T: ... | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testNewAndInitNoReturn] | |
| from typing import NoReturn | |
| class A: | |
| def __new__(cls) -> NoReturn: ... | |
| class B: | |
| def __init__(self) -> NoReturn: ... | |
| class C: | |
| def __new__(cls) -> "C": ... | |
| def __init__(self) -> NoReturn: ... | |
| class D: | |
| def __new__(cls) -> NoReturn: ... | |
| def __init__(self) -> NoReturn: ... | |
| if object(): | |
| reveal_type(A()) # N: Revealed type is "Never" | |
| if object(): | |
| reveal_type(B()) # N: Revealed type is "Never" | |
| if object(): | |
| reveal_type(C()) # N: Revealed type is "Never" | |
| if object(): | |
| reveal_type(D()) # N: Revealed type is "Never" | |
| [case testOverloadedNewAndInitNoReturn] | |
| from typing import NoReturn, overload | |
| class A: | |
| @overload | |
| def __new__(cls) -> NoReturn: ... | |
| @overload | |
| def __new__(cls, a: int) -> "A": ... | |
| def __new__(cls, a: int = ...) -> "A": ... | |
| class B: | |
| @overload | |
| def __init__(self) -> NoReturn: ... | |
| @overload | |
| def __init__(self, a: int) -> None: ... | |
| def __init__(self, a: int = ...) -> None: ... | |
| class C: | |
| def __new__(cls, a: int = ...) -> "C": ... | |
| @overload | |
| def __init__(self) -> NoReturn: ... | |
| @overload | |
| def __init__(self, a: int) -> None: ... | |
| def __init__(self, a: int = ...) -> None: ... | |
| class D: | |
| @overload | |
| def __new__(cls) -> NoReturn: ... | |
| @overload | |
| def __new__(cls, a: int) -> "D": ... | |
| def __new__(cls, a: int = ...) -> "D": ... | |
| @overload | |
| def __init__(self) -> NoReturn: ... | |
| @overload | |
| def __init__(self, a: int) -> None: ... | |
| def __init__(self, a: int = ...) -> None: ... | |
| if object(): | |
| reveal_type(A()) # N: Revealed type is "Never" | |
| reveal_type(A(1)) # N: Revealed type is "__main__.A" | |
| if object(): | |
| reveal_type(B()) # N: Revealed type is "Never" | |
| reveal_type(B(1)) # N: Revealed type is "__main__.B" | |
| if object(): | |
| reveal_type(C()) # N: Revealed type is "Never" | |
| reveal_type(C(1)) # N: Revealed type is "__main__.C" | |
| if object(): | |
| reveal_type(D()) # N: Revealed type is "Never" | |
| reveal_type(D(1)) # N: Revealed type is "__main__.D" | |
| [case testClassScopeImportWithWrapperAndError] | |
| class Foo: | |
| from mod import foo # E: Unsupported class scoped import | |
| [file mod.py] | |
| from typing import Any, Callable, TypeVar | |
| FuncT = TypeVar("FuncT", bound=Callable[..., Any]) | |
| def identity_wrapper(func: FuncT) -> FuncT: | |
| return func | |
| @identity_wrapper | |
| def foo(self: Any) -> str: | |
| return "" | |
| [case testParentClassWithTypeAliasAndSubclassWithMethod] | |
| from typing import Any, Callable, TypeVar | |
| class Parent: | |
| foo = Callable[..., int] | |
| class bar: | |
| pass | |
| import typing as baz | |
| foobar = TypeVar("foobar") | |
| class Child(Parent): | |
| def foo(self, val: int) -> int: # E: Signature of "foo" incompatible with supertype "Parent" \ | |
| # N: Superclass: \ | |
| # N: <typing special form> \ | |
| # N: Subclass: \ | |
| # N: def foo(self, val: int) -> int | |
| return val | |
| def bar(self, val: str) -> str: # E: Signature of "bar" incompatible with supertype "Parent" \ | |
| # N: Superclass: \ | |
| # N: def bar() -> bar \ | |
| # N: Subclass: \ | |
| # N: def bar(self, val: str) -> str | |
| return val | |
| def baz(self, val: float) -> float: # E: Signature of "baz" incompatible with supertype "Parent" \ | |
| # N: Superclass: \ | |
| # N: Module \ | |
| # N: Subclass: \ | |
| # N: def baz(self, val: float) -> float | |
| return val | |
| def foobar(self) -> bool: # E: Signature of "foobar" incompatible with supertype "Parent" \ | |
| # N: Superclass: \ | |
| # N: TypeVar \ | |
| # N: Subclass: \ | |
| # N: def foobar(self) -> bool | |
| return False | |
| x: Parent.foo = lambda: 5 | |
| y: Parent.bar = Parent.bar() | |
| z: Parent.baz.Any = 1 | |
| child = Child() | |
| a: int = child.foo(1) | |
| b: str = child.bar("abc") | |
| c: float = child.baz(3.4) | |
| d: bool = child.foobar() | |
| [builtins fixtures/module.pyi] | |
| [typing fixtures/typing-full.pyi] | |
| [case testGenericTupleTypeCreation] | |
| from typing import Generic, Tuple, TypeVar | |
| T = TypeVar("T") | |
| S = TypeVar("S") | |
| class C(Tuple[T, S]): | |
| def __init__(self, x: T, y: S) -> None: ... | |
| def foo(self, arg: T) -> S: ... | |
| cis: C[int, str] | |
| reveal_type(cis) # N: Revealed type is "tuple[builtins.int, builtins.str, fallback=__main__.C[builtins.int, builtins.str]]" | |
| cii = C(0, 1) | |
| reveal_type(cii) # N: Revealed type is "tuple[builtins.int, builtins.int, fallback=__main__.C[builtins.int, builtins.int]]" | |
| reveal_type(cis.foo) # N: Revealed type is "def (arg: builtins.int) -> builtins.str" | |
| [builtins fixtures/tuple.pyi] | |
| [case testGenericTupleTypeSubclassing] | |
| from typing import Generic, Tuple, TypeVar, List | |
| T = TypeVar("T") | |
| class C(Tuple[T, T]): ... | |
| class D(C[List[T]]): ... | |
| di: D[int] | |
| reveal_type(di) # N: Revealed type is "tuple[builtins.list[builtins.int], builtins.list[builtins.int], fallback=__main__.D[builtins.int]]" | |
| [builtins fixtures/tuple.pyi] | |
| [case testOverrideAttrWithSettableProperty] | |
| class Foo: | |
| def __init__(self) -> None: | |
| self.x = 42 | |
| class Bar(Foo): | |
| @property | |
| def x(self) -> int: ... | |
| @x.setter | |
| def x(self, value: int) -> None: ... | |
| [builtins fixtures/property.pyi] | |
| [case testOverrideAttrWithSettablePropertyAnnotation] | |
| class Foo: | |
| x: int | |
| class Bar(Foo): | |
| @property | |
| def x(self) -> int: ... | |
| @x.setter | |
| def x(self, value: int) -> None: ... | |
| [builtins fixtures/property.pyi] | |
| [case testOverridePropertyDifferentSetterBoth] | |
| class B: ... | |
| class C(B): ... | |
| class B1: | |
| @property | |
| def foo(self) -> str: ... | |
| @foo.setter | |
| def foo(self, x: C) -> None: ... | |
| class C1(B1): | |
| @property | |
| def foo(self) -> str: ... | |
| @foo.setter | |
| def foo(self, x: B) -> None: ... | |
| class B2: | |
| @property | |
| def foo(self) -> str: ... | |
| @foo.setter | |
| def foo(self, x: B) -> None: ... | |
| class C2(B2): | |
| @property | |
| def foo(self) -> str: ... | |
| @foo.setter # E: Incompatible override of a setter type \ | |
| # N: (base class "B2" defined the type as "B", \ | |
| # N: override has type "C") \ | |
| # N: Setter types should behave contravariantly | |
| def foo(self, x: C) -> None: ... | |
| class B3: | |
| @property | |
| def foo(self) -> C: ... | |
| @foo.setter | |
| def foo(self, x: C) -> None: ... | |
| class C3(B3): | |
| @property | |
| def foo(self) -> C: ... | |
| @foo.setter | |
| def foo(self, x: B) -> None: ... | |
| class B4: | |
| @property | |
| def foo(self) -> C: ... | |
| @foo.setter | |
| def foo(self, x: B) -> None: ... | |
| class C4(B4): | |
| @property | |
| def foo(self) -> C: ... | |
| @foo.setter # E: Incompatible override of a setter type \ | |
| # N: (base class "B4" defined the type as "B", \ | |
| # N: override has type "C") \ | |
| # N: Setter types should behave contravariantly | |
| def foo(self, x: C) -> None: ... | |
| class B5: | |
| @property | |
| def foo(self) -> str: ... | |
| @foo.setter | |
| def foo(self, x: B) -> None: ... | |
| class C5(B5): | |
| @property # E: Signature of "foo" incompatible with supertype "B5" \ | |
| # N: Superclass: \ | |
| # N: str \ | |
| # N: Subclass: \ | |
| # N: C | |
| def foo(self) -> C: ... | |
| @foo.setter # E: Incompatible override of a setter type \ | |
| # N: (base class "B5" defined the type as "B", \ | |
| # N: override has type "str") | |
| def foo(self, x: str) -> None: ... | |
| class B6: | |
| @property | |
| def foo(self) -> B: ... | |
| @foo.setter | |
| def foo(self, x: B) -> None: ... | |
| class C6(B6): | |
| @property | |
| def foo(self) -> C: ... | |
| @foo.setter | |
| def foo(self, x: B) -> None: ... | |
| [builtins fixtures/property.pyi] | |
| [case testOverridePropertyDifferentSetterVarSuper] | |
| class B: ... | |
| class C(B): ... | |
| class B1: | |
| foo: B | |
| class C1(B1): | |
| @property | |
| def foo(self) -> B: ... | |
| @foo.setter # E: Incompatible override of a setter type \ | |
| # N: (base class "B1" defined the type as "B", \ | |
| # N: override has type "C") \ | |
| # N: Setter types should behave contravariantly | |
| def foo(self, x: C) -> None: ... | |
| class B2: | |
| foo: C | |
| class C2(B2): | |
| @property | |
| def foo(self) -> C: ... | |
| @foo.setter | |
| def foo(self, x: B) -> None: ... | |
| class B3: | |
| foo: B | |
| class C3(B3): | |
| @property | |
| def foo(self) -> C: ... | |
| @foo.setter | |
| def foo(self, x: B) -> None: ... | |
| [builtins fixtures/property.pyi] | |
| [case testOverridePropertyDifferentSetterVarSub] | |
| class B: ... | |
| class C(B): ... | |
| class B1: | |
| @property | |
| def foo(self) -> B: ... | |
| @foo.setter | |
| def foo(self, x: C) -> None: ... | |
| class C1(B1): | |
| foo: C | |
| class B2: | |
| @property | |
| def foo(self) -> B: ... | |
| @foo.setter | |
| def foo(self, x: C) -> None: ... | |
| class C2(B2): | |
| foo: B | |
| class B3: | |
| @property | |
| def foo(self) -> C: ... | |
| @foo.setter | |
| def foo(self, x: B) -> None: ... | |
| class C3(B3): | |
| foo: C # E: Incompatible override of a setter type \ | |
| # N: (base class "B3" defined the type as "B", \ | |
| # N: override has type "C") \ | |
| # N: Setter types should behave contravariantly | |
| [builtins fixtures/property.pyi] | |
| [case testOverridePropertyInvalidSetter] | |
| class B1: | |
| @property | |
| def foo(self) -> int: ... | |
| @foo.setter | |
| def foo(self, x: str) -> None: ... | |
| class C1(B1): | |
| @property | |
| def foo(self) -> int: ... | |
| @foo.setter | |
| def foo(self) -> None: ... # E: Invalid property setter signature | |
| class B2: | |
| @property | |
| def foo(self) -> int: ... | |
| @foo.setter | |
| def foo(self) -> None: ... # E: Invalid property setter signature | |
| class C2(B2): | |
| @property | |
| def foo(self) -> int: ... | |
| @foo.setter | |
| def foo(self, x: str) -> None: ... | |
| class B3: | |
| @property | |
| def foo(self) -> int: ... | |
| @foo.setter | |
| def foo(self) -> None: ... # E: Invalid property setter signature | |
| class C3(B3): | |
| foo: int | |
| [builtins fixtures/property.pyi] | |
| [case testOverridePropertyGeneric] | |
| from typing import TypeVar, Generic | |
| T = TypeVar("T") | |
| class B1(Generic[T]): | |
| @property | |
| def foo(self) -> int: ... | |
| @foo.setter | |
| def foo(self, x: T) -> None: ... | |
| class C1(B1[str]): | |
| @property | |
| def foo(self) -> int: ... | |
| @foo.setter # E: Incompatible override of a setter type \ | |
| # N: (base class "B1" defined the type as "str", \ | |
| # N: override has type "int") | |
| def foo(self, x: int) -> None: ... | |
| class B2: | |
| @property | |
| def foo(self) -> int: ... | |
| @foo.setter | |
| def foo(self: T, x: T) -> None: ... | |
| class C2(B2): | |
| @property | |
| def foo(self) -> int: ... | |
| @foo.setter # E: Incompatible override of a setter type \ | |
| # N: (base class "B2" defined the type as "C2", \ | |
| # N: override has type "int") | |
| def foo(self, x: int) -> None: ... | |
| [builtins fixtures/property.pyi] | |
| [case testOverrideMethodProperty] | |
| class B: | |
| def foo(self) -> int: | |
| ... | |
| class C(B): | |
| @property | |
| def foo(self) -> int: # E: Signature of "foo" incompatible with supertype "B" \ | |
| # N: Superclass: \ | |
| # N: def foo(self) -> int \ | |
| # N: Subclass: \ | |
| # N: int | |
| ... | |
| [builtins fixtures/property.pyi] | |
| [case testOverridePropertyMethod] | |
| class B: | |
| @property | |
| def foo(self) -> int: | |
| ... | |
| class C(B): | |
| def foo(self) -> int: # E: Signature of "foo" incompatible with supertype "B" \ | |
| # N: Superclass: \ | |
| # N: int \ | |
| # N: Subclass: \ | |
| # N: def foo(self) -> int | |
| ... | |
| [builtins fixtures/property.pyi] | |
| [case testAllowArgumentAsBaseClass] | |
| from typing import Any, Type | |
| def e(b) -> None: | |
| class D(b): ... | |
| def f(b: Any) -> None: | |
| class D(b): ... | |
| def g(b: Type[Any]) -> None: | |
| class D(b): ... | |
| def h(b: type) -> None: | |
| class D(b): ... | |
| [case testNoCrashOnSelfWithForwardRefGenericClass] | |
| from typing import Generic, Sequence, TypeVar, Self | |
| _T = TypeVar('_T', bound="Foo") | |
| class Foo: | |
| foo: int | |
| class Element(Generic[_T]): | |
| elements: Sequence[Self] | |
| class Bar(Foo): ... | |
| e: Element[Bar] | |
| reveal_type(e.elements) # N: Revealed type is "typing.Sequence[__main__.Element[__main__.Bar]]" | |
| [case testIterableUnpackingWithGetAttr] | |
| from typing import Union, Tuple | |
| class C: | |
| def __getattr__(self, name): | |
| pass | |
| class D: | |
| def f(self) -> C: | |
| return C() | |
| def g(self) -> None: | |
| # iter(x) looks up `__iter__` on the type of x rather than x itself, | |
| # so this is correct behaviour. | |
| # Instances of C should not be treated as being iterable, | |
| # despite having a __getattr__ method | |
| # that could allow for arbitrary attributes to be accessed on instances, | |
| # since `type(C()).__iter__` still raises AttributeError at runtime, | |
| # and that's what matters. | |
| a, b = self.f() # E: "C" has no attribute "__iter__" (not iterable) | |
| [builtins fixtures/tuple.pyi] | |
| [case testUsingNumbersType] | |
| from numbers import Number, Complex, Real, Rational, Integral | |
| def f1(x: Number) -> None: pass | |
| f1(1) # E: Argument 1 to "f1" has incompatible type "int"; expected "Number" \ | |
| # N: Types from "numbers" are not supported for static type checking \ | |
| # N: See https://peps.python.org/pep-0484/#the-numeric-tower \ | |
| # N: Consider using a protocol instead, such as typing.SupportsFloat | |
| def f2(x: Complex) -> None: pass | |
| f2(1) # E: Argument 1 to "f2" has incompatible type "int"; expected "Complex" \ | |
| # N: Types from "numbers" are not supported for static type checking \ | |
| # N: See https://peps.python.org/pep-0484/#the-numeric-tower \ | |
| # N: Consider using a protocol instead, such as typing.SupportsFloat | |
| def f3(x: Real) -> None: pass | |
| f3(1) # E: Argument 1 to "f3" has incompatible type "int"; expected "Real" \ | |
| # N: Types from "numbers" are not supported for static type checking \ | |
| # N: See https://peps.python.org/pep-0484/#the-numeric-tower \ | |
| # N: Consider using a protocol instead, such as typing.SupportsFloat | |
| def f4(x: Rational) -> None: pass | |
| f4(1) # E: Argument 1 to "f4" has incompatible type "int"; expected "Rational" \ | |
| # N: Types from "numbers" are not supported for static type checking \ | |
| # N: See https://peps.python.org/pep-0484/#the-numeric-tower \ | |
| # N: Consider using a protocol instead, such as typing.SupportsFloat | |
| def f5(x: Integral) -> None: pass | |
| f5(1) # E: Argument 1 to "f5" has incompatible type "int"; expected "Integral" \ | |
| # N: Types from "numbers" are not supported for static type checking \ | |
| # N: See https://peps.python.org/pep-0484/#the-numeric-tower \ | |
| # N: Consider using a protocol instead, such as typing.SupportsFloat | |
| [case testImplicitClassScopedNames] | |
| class C: | |
| reveal_type(__module__) # N: Revealed type is "builtins.str" | |
| reveal_type(__qualname__) # N: Revealed type is "builtins.str" | |
| def f(self) -> None: | |
| __module__ # E: Name "__module__" is not defined | |
| __qualname__ # E: Name "__qualname__" is not defined | |
| x: __module__ # E: Variable "__main__.C.__module__" is not valid as a type \ | |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases | |
| y: __qualname__ # E: Variable "__main__.C.__qualname__" is not valid as a type \ | |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases | |
| [case testPropertySetterType] | |
| class A: | |
| @property | |
| def f(self) -> int: | |
| return 1 | |
| @f.setter | |
| def f(self, x: str) -> None: | |
| pass | |
| a = A() | |
| a.f = '' # OK | |
| reveal_type(a.f) # N: Revealed type is "builtins.int" | |
| a.f = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "str") | |
| reveal_type(a.f) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/property.pyi] | |
| [case testPropertySetterTypeGeneric] | |
| from typing import TypeVar, Generic, List | |
| T = TypeVar("T") | |
| class B(Generic[T]): | |
| @property | |
| def foo(self) -> int: ... | |
| @foo.setter | |
| def foo(self, x: T) -> None: ... | |
| class C(B[List[T]]): ... | |
| a = C[str]() | |
| a.foo = ["foo", "bar"] | |
| reveal_type(a.foo) # N: Revealed type is "builtins.int" | |
| a.foo = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "list[str]") | |
| reveal_type(a.foo) # N: Revealed type is "builtins.int" | |
| [builtins fixtures/property.pyi] | |
| [case testPropertyDeleterNoSetterOK] | |
| class C: | |
| @property | |
| def x(self) -> int: | |
| return 0 | |
| @x.deleter | |
| def x(self) -> None: | |
| pass | |
| [builtins fixtures/property.pyi] | |
| [case testPropertySetterSuperclassDeferred] | |
| from typing import Callable, TypeVar | |
| class B: | |
| def __init__(self) -> None: | |
| self.foo = f() | |
| class C(B): | |
| @property | |
| def foo(self) -> str: ... | |
| @foo.setter # E: Incompatible override of a setter type \ | |
| # N: (base class "B" defined the type as "str", \ | |
| # N: override has type "int") | |
| def foo(self, x: int) -> None: ... | |
| T = TypeVar("T") | |
| def deco(fn: Callable[[], list[T]]) -> Callable[[], T]: ... | |
| @deco | |
| def f() -> list[str]: ... | |
| [builtins fixtures/property.pyi] | |
| [case testPropertySetterSuperclassDeferred2] | |
| import a | |
| [file a.py] | |
| import b | |
| class D(b.C): | |
| @property | |
| def foo(self) -> str: ... | |
| @foo.setter # E: Incompatible override of a setter type \ | |
| # N: (base class "C" defined the type as "str", \ | |
| # N: override has type "int") | |
| def foo(self, x: int) -> None: ... | |
| [file b.py] | |
| from a import D | |
| class C: | |
| @property | |
| def foo(self) -> str: ... | |
| @foo.setter | |
| def foo(self, x: str) -> None: ... | |
| [builtins fixtures/property.pyi] | |
| [case testPropertySetterDecorated] | |
| from typing import Callable, TypeVar, Generic | |
| class B: | |
| def __init__(self) -> None: | |
| self.foo: str | |
| self.bar: int | |
| class C(B): | |
| @property | |
| def foo(self) -> str: ... | |
| @foo.setter # E: Incompatible override of a setter type \ | |
| # N: (base class "B" defined the type as "str", \ | |
| # N: override has type "int") | |
| @deco | |
| def foo(self, x: int, y: int) -> None: ... | |
| @property | |
| def bar(self) -> int: ... | |
| @bar.setter | |
| @deco | |
| def bar(self, x: int, y: int) -> None: ... | |
| @property | |
| def baz(self) -> int: ... | |
| @baz.setter | |
| @deco_untyped | |
| def baz(self, x: int) -> None: ... | |
| @property | |
| def tricky(self) -> int: ... | |
| @tricky.setter | |
| @deco_instance | |
| def tricky(self, x: int) -> None: ... | |
| c: C | |
| c.baz = "yes" # OK, because of untyped decorator | |
| c.tricky = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "list[int]") | |
| T = TypeVar("T") | |
| def deco(fn: Callable[[T, int, int], None]) -> Callable[[T, int], None]: ... | |
| def deco_untyped(fn): ... | |
| class Wrapper(Generic[T]): | |
| def __call__(self, s: T, x: list[int]) -> None: ... | |
| def deco_instance(fn: Callable[[T, int], None]) -> Wrapper[T]: ... | |
| [builtins fixtures/property.pyi] | |
| [case testPropertyDeleterBodyChecked] | |
| class C: | |
| @property | |
| def foo(self) -> int: ... | |
| @foo.deleter | |
| def foo(self) -> None: | |
| 1() # E: "int" not callable | |
| @property | |
| def bar(self) -> int: ... | |
| @bar.setter | |
| def bar(self, x: str) -> None: ... | |
| @bar.deleter | |
| def bar(self) -> None: | |
| 1() # E: "int" not callable | |
| [builtins fixtures/property.pyi] | |
| [case testSettablePropertyGetterDecorated] | |
| from typing import Callable, TypeVar, Generic | |
| class C: | |
| @property | |
| @deco | |
| def foo(self, ok: int) -> str: ... | |
| @foo.setter | |
| def foo(self, x: str) -> None: ... | |
| @property | |
| @deco_instance | |
| def bar(self, ok: int) -> int: ... | |
| @bar.setter | |
| def bar(self, x: int) -> None: ... | |
| @property | |
| @deco_untyped | |
| def baz(self) -> int: ... | |
| @baz.setter | |
| def baz(self, x: int) -> None: ... | |
| c: C | |
| reveal_type(c.foo) # N: Revealed type is "builtins.list[builtins.str]" | |
| reveal_type(c.bar) # N: Revealed type is "builtins.list[builtins.int]" | |
| reveal_type(c.baz) # N: Revealed type is "Any" | |
| T = TypeVar("T") | |
| R = TypeVar("R") | |
| def deco(fn: Callable[[T, int], R]) -> Callable[[T], list[R]]: ... | |
| def deco_untyped(fn): ... | |
| class Wrapper(Generic[T, R]): | |
| def __call__(self, s: T) -> list[R]: ... | |
| def deco_instance(fn: Callable[[T, int], R]) -> Wrapper[T, R]: ... | |
| [builtins fixtures/property.pyi] | |
| [case testOverridePropertyWithDescriptor] | |
| from typing import Any | |
| class StrProperty: | |
| def __get__(self, instance: Any, owner: Any) -> str: ... | |
| class Base: | |
| @property | |
| def id(self) -> str: ... | |
| class BadBase: | |
| @property | |
| def id(self) -> int: ... | |
| class Derived(Base): | |
| id = StrProperty() | |
| class BadDerived(BadBase): | |
| id = StrProperty() # E: Incompatible types in assignment (expression has type "str", base class "BadBase" defined the type as "int") | |
| [builtins fixtures/property.pyi] | |
| [case testLambdaInOverrideInference] | |
| class B: | |
| def f(self, x: int) -> int: ... | |
| class C(B): | |
| f = lambda s, x: x | |
| reveal_type(C().f) # N: Revealed type is "def (x: builtins.int) -> builtins.int" | |
| [case testGenericDecoratorInOverrideInference] | |
| from typing import Any, Callable, TypeVar | |
| from typing_extensions import ParamSpec, Concatenate | |
| P = ParamSpec("P") | |
| T = TypeVar("T") | |
| def wrap(f: Callable[Concatenate[Any, P], T]) -> Callable[Concatenate[Any, P], T]: ... | |
| class Base: | |
| def g(self, a: int) -> int: | |
| return a + 1 | |
| class Derived(Base): | |
| def _g(self, a: int) -> int: | |
| return a + 2 | |
| g = wrap(_g) | |
| reveal_type(Derived().g) # N: Revealed type is "def (a: builtins.int) -> builtins.int" | |
| [builtins fixtures/paramspec.pyi] | |
| [case testClassVarOverrideWithSubclass] | |
| class A: ... | |
| class B(A): ... | |
| class AA: | |
| cls = A | |
| class BB(AA): | |
| cls = B | |
| [case testSelfReferenceWithinMethodFunction] | |
| class B: | |
| x: str | |
| class C(B): | |
| def meth(self) -> None: | |
| def cb() -> None: | |
| self.x: int = 1 # E: Incompatible types in assignment (expression has type "int", base class "B" defined the type as "str") | |
| [case testOverloadedDescriptorSelected] | |
| from typing import Generic, TypeVar, Any, overload | |
| T_co = TypeVar("T_co", covariant=True) | |
| class Field(Generic[T_co]): | |
| @overload | |
| def __get__(self: Field[bool], instance: None, owner: Any) -> BoolField: ... | |
| @overload | |
| def __get__(self: Field[int], instance: None, owner: Any) -> NumField: ... | |
| @overload | |
| def __get__(self: Field[Any], instance: None, owner: Any) -> AnyField[T_co]: ... | |
| @overload | |
| def __get__(self, instance: Any, owner: Any) -> T_co: ... | |
| def __get__(self, instance: Any, owner: Any) -> Any: | |
| pass | |
| class BoolField(Field[bool]): ... | |
| class NumField(Field[int]): ... | |
| class AnyField(Field[T_co]): ... | |
| class Custom: ... | |
| class Fields: | |
| bool_f: Field[bool] | |
| int_f: Field[int] | |
| custom_f: Field[Custom] | |
| reveal_type(Fields.bool_f) # N: Revealed type is "__main__.BoolField" | |
| reveal_type(Fields.int_f) # N: Revealed type is "__main__.NumField" | |
| reveal_type(Fields.custom_f) # N: Revealed type is "__main__.AnyField[__main__.Custom]" | |
| [case testRecursivePropertyWithInvalidSetterNoCrash] | |
| class NoopPowerResource: | |
| _hardware_type: int | |
| @property | |
| def hardware_type(self) -> int: | |
| return self._hardware_type | |
| @hardware_type.setter | |
| def hardware_type(self) -> None: # E: Invalid property setter signature | |
| self.hardware_type = None # Note: intentionally recursive | |
| [builtins fixtures/property.pyi] | |
| [case testOverrideErrorReportingNoDuplicates] | |
| from typing import Callable, TypeVar | |
| def nested() -> None: | |
| class B: | |
| def meth(self, x: str) -> int: ... | |
| class C(B): | |
| def meth(self) -> str: # E: Signature of "meth" incompatible with supertype "B" \ | |
| # N: Superclass: \ | |
| # N: def meth(self, x: str) -> int \ | |
| # N: Subclass: \ | |
| # N: def meth(self) -> str | |
| pass | |
| x = defer() | |
| T = TypeVar("T") | |
| def deco(fn: Callable[[], T]) -> Callable[[], list[T]]: ... | |
| @deco | |
| def defer() -> int: ... | |
| [builtins fixtures/list.pyi] | |
| [case testPropertyAllowsDeleterBeforeSetter] | |
| class C: | |
| @property | |
| def foo(self) -> str: ... | |
| @foo.deleter | |
| def foo(self) -> None: ... | |
| @foo.setter | |
| def foo(self, val: int) -> None: ... | |
| @property | |
| def bar(self) -> int: ... | |
| @bar.deleter | |
| def bar(self) -> None: ... | |
| @bar.setter | |
| def bar(self, value: int, val: int) -> None: ... # E: Invalid property setter signature | |
| C().foo = "no" # E: Incompatible types in assignment (expression has type "str", variable has type "int") | |
| C().bar = "fine" | |
| [builtins fixtures/property.pyi] | |
| [case testCorrectConstructorTypeWithAnyFallback] | |
| from typing import Generic, TypeVar | |
| class B(Unknown): # type: ignore | |
| def __init__(self) -> None: ... | |
| class C(B): ... | |
| reveal_type(C) # N: Revealed type is "def () -> __main__.C" | |
| T = TypeVar("T") | |
| class BG(Generic[T], Unknown): # type: ignore | |
| def __init__(self) -> None: ... | |
| class CGI(BG[int]): ... | |
| class CGT(BG[T]): ... | |
| reveal_type(CGI) # N: Revealed type is "def () -> __main__.CGI" | |
| reveal_type(CGT) # N: Revealed type is "def [T] () -> __main__.CGT[T`1]" | |
| [case testSettablePropertyAlias] | |
| from typing import Any, TypeVar | |
| class A: | |
| @property | |
| def prop(self: Any) -> str: ... | |
| @prop.setter | |
| def prop(self, val: str) -> None: ... | |
| T = TypeVar("T") | |
| class AT: | |
| @property | |
| def prop(self: T) -> T: ... | |
| @prop.setter | |
| def prop(self: T, val: list[T]) -> None: ... | |
| class B: | |
| prop: str | |
| prop_t: str | |
| class C(B): | |
| prop = A.prop | |
| prop_t = AT.prop # E: Incompatible types in assignment (expression has type "C", base class "B" defined the type as "str") | |
| reveal_type(C().prop) # N: Revealed type is "builtins.str" | |
| C().prop = "no" # E: Invalid self argument "C" to attribute function "prop" with type "Callable[[A, str], None]" | |
| reveal_type(C().prop_t) # N: Revealed type is "__main__.C" | |
| C().prop_t = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "list[C]") | |
| [builtins fixtures/property.pyi] | |
| [case testClassEqDecoratedAbstractNote] | |
| from abc import abstractmethod | |
| class C: | |
| @abstractmethod | |
| def __eq__(self, other: C) -> bool: ... | |
| [builtins fixtures/plugin_attrs.pyi] | |
| [out] | |
| main:5: error: Argument 1 of "__eq__" is incompatible with supertype "builtins.object"; supertype defines the argument type as "object" | |
| main:5: note: This violates the Liskov substitution principle | |
| main:5: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides | |
| main:5: note: It is recommended for "__eq__" to work with arbitrary objects, for example: | |
| main:5: note: def __eq__(self, other: object) -> bool: | |
| main:5: note: if not isinstance(other, C): | |
| main:5: note: return NotImplemented | |
| main:5: note: return <logic to compare two C instances> | |
| [case testLambdaInAttributeCallValue] | |
| # https://github.com/python/mypy/issues/19632 | |
| import foo | |
| def nop(fn: object) -> foo.Bar: | |
| return foo.Bar() | |
| class Bar: | |
| foo: foo.Bar = nop( | |
| lambda: 0 | |
| ) | |
| [file foo.py] | |
| class Bar: | |
| ... | |
| [case testConstructorWithoutStrictOptionalNoCache] | |
| import mod | |
| a = mod.NT(x=None) # OK | |
| [file typ.py] | |
| from typing import NamedTuple, Optional | |
| NT = NamedTuple("NT", [("x", Optional[str])]) | |
| [file mod.py] | |
| # mypy: no-strict-optional | |
| from typ import NT | |
| def f() -> NT: | |
| return NT(x='') | |
| [builtins fixtures/tuple.pyi] | |
| [case testClassNestedInFunctionNotLeaking] | |
| from a import X # E: Module "a" has no attribute "X" | |
| reveal_type(X) # N: Revealed type is "Any" | |
| [file a.py] | |
| def f() -> None: | |
| class X: | |
| ... | |
| undefined # E: Name "undefined" is not defined | |
| [case testPartialNoneTypeClassMethod] | |
| # flags: --local-partial-types | |
| class C: | |
| x = None | |
| @classmethod | |
| def foo(cls) -> None: | |
| if not cls.x: | |
| cls.x = 1 | |
| reveal_type(C.x) # N: Revealed type is "builtins.int | None" | |
| [builtins fixtures/classmethod.pyi] | |
| [case testTypeVarDefaultErrorLocation] | |
| from typing import Generic | |
| from lib import T | |
| # some spaces | |
| class C(Generic[T]): ... | |
| [file lib.py] | |
| from typing import TypeVar | |
| T = TypeVar("T", default=int, bound=str) # E: TypeVar default must be a subtype of the bound type |