blob: 9a0668f98c213cbd02fb8a041cbe4ecf11aed8bf [file] [log] [blame] [edit]
-- Test cases for user-defined plugins
--
-- Note: Plugins used by tests live under test-data/unit/plugins. Defining
-- plugin files in test cases does not work reliably.
[case testFunctionPluginFile]
# flags: --config-file tmp/mypy.ini
def f() -> str: ...
reveal_type(f()) # N: Revealed type is "builtins.int"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/fnplugin.py
[case testFunctionPluginFilePyProjectTOML]
# flags: --config-file tmp/pyproject.toml
def f() -> str: ...
reveal_type(f()) # N: Revealed type is "builtins.int"
[file pyproject.toml]
\[tool.mypy]
plugins='<ROOT>/test-data/unit/plugins/fnplugin.py'
[case testFunctionPlugin]
# flags: --config-file tmp/mypy.ini
def f() -> str: ...
reveal_type(f()) # N: Revealed type is "builtins.int"
[file mypy.ini]
\[mypy]
plugins=fnplugin
[case testFunctionPluginPyProjectTOML]
# flags: --config-file tmp/pyproject.toml
def f() -> str: ...
reveal_type(f()) # N: Revealed type is "builtins.int"
[file pyproject.toml]
\[tool.mypy]
plugins = 'fnplugin'
[case testFunctionPluginFullnameIsNotNone]
# flags: --config-file tmp/mypy.ini
from typing import Callable, TypeVar
f: Callable[[], None]
T = TypeVar('T')
def g(x: T) -> T: return x # This strips out the name of a callable
g(f)()
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/fnplugin.py
[case testFunctionPluginFullnameIsNotNonePyProjectTOML]
# flags: --config-file tmp/pyproject.toml
from typing import Callable, TypeVar
f: Callable[[], None]
T = TypeVar('T')
def g(x: T) -> T: return x # This strips out the name of a callable
g(f)()
[file pyproject.toml]
\[tool.mypy]
plugins="<ROOT>/test-data/unit/plugins/fnplugin.py"
[case testTwoPlugins]
# flags: --config-file tmp/mypy.ini
def f(): ...
def g(): ...
def h(): ...
reveal_type(f()) # N: Revealed type is "builtins.int"
reveal_type(g()) # N: Revealed type is "builtins.str"
reveal_type(h()) # N: Revealed type is "Any"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/fnplugin.py,
<ROOT>/test-data/unit/plugins/plugin2.py
[case testTwoPluginsPyProjectTOML]
# flags: --config-file tmp/pyproject.toml
def f(): ...
def g(): ...
def h(): ...
reveal_type(f()) # N: Revealed type is "builtins.int"
reveal_type(g()) # N: Revealed type is "builtins.str"
reveal_type(h()) # N: Revealed type is "Any"
[file pyproject.toml]
\[tool.mypy]
plugins=['<ROOT>/test-data/unit/plugins/fnplugin.py',
'<ROOT>/test-data/unit/plugins/plugin2.py'
]
[case testTwoPluginsMixedType]
# flags: --config-file tmp/mypy.ini
def f(): ...
def g(): ...
def h(): ...
reveal_type(f()) # N: Revealed type is "builtins.int"
reveal_type(g()) # N: Revealed type is "builtins.str"
reveal_type(h()) # N: Revealed type is "Any"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/fnplugin.py, plugin2
[case testTwoPluginsMixedTypePyProjectTOML]
# flags: --config-file tmp/pyproject.toml
def f(): ...
def g(): ...
def h(): ...
reveal_type(f()) # N: Revealed type is "builtins.int"
reveal_type(g()) # N: Revealed type is "builtins.str"
reveal_type(h()) # N: Revealed type is "Any"
[file pyproject.toml]
\[tool.mypy]
plugins=['<ROOT>/test-data/unit/plugins/fnplugin.py', 'plugin2']
[case testMissingPluginFile]
# flags: --config-file tmp/mypy.ini
[file mypy.ini]
\[mypy]
plugins=missing.py
[out]
tmp/mypy.ini:2: error: Can't find plugin "tmp/missing.py"
--' (work around syntax highlighting)
[case testMissingPlugin]
# flags: --config-file tmp/mypy.ini
[file mypy.ini]
\[mypy]
plugins=missing
[out]
tmp/mypy.ini:2: error: Error importing plugin "missing": No module named 'missing'
[case testMultipleSectionsDefinePlugin]
# flags: --config-file tmp/mypy.ini
[file mypy.ini]
\[acme]
plugins=acmeplugin
\[mypy]
plugins=missing.py
\[another]
plugins=another_plugin
[out]
tmp/mypy.ini:4: error: Can't find plugin "tmp/missing.py"
--' (work around syntax highlighting)
[case testInvalidPluginExtension]
# flags: --config-file tmp/mypy.ini
[file mypy.ini]
\[mypy]
plugins=dir/badext.pyi
[file dir/badext.pyi]
[out]
tmp/mypy.ini:2: error: Plugin "badext.pyi" does not have a .py extension
[case testMissingPluginEntryPoint]
# flags: --config-file tmp/mypy.ini
[file mypy.ini]
\[mypy]
plugins = <ROOT>/test-data/unit/plugins/noentry.py
[out]
tmp/mypy.ini:2: error: Plugin "<ROOT>/test-data/unit/plugins/noentry.py" does not define entry point function "plugin"
[case testCustomPluginEntryPointFile]
# flags: --config-file tmp/mypy.ini
def f() -> str: ...
reveal_type(f()) # N: Revealed type is "builtins.int"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/customentry.py:register
[case testCustomPluginEntryPointFileTrailingComma]
# flags: --config-file tmp/mypy.ini
def f() -> str: ...
reveal_type(f()) # N: Revealed type is "builtins.int"
[file mypy.ini]
\[mypy]
plugins =
<ROOT>/test-data/unit/plugins/customentry.py:register,
[case testCustomPluginEntryPoint]
# flags: --config-file tmp/mypy.ini
def f() -> str: ...
reveal_type(f()) # N: Revealed type is "builtins.int"
[file mypy.ini]
\[mypy]
plugins=customentry:register
[case testInvalidPluginEntryPointReturnValue]
# flags: --config-file tmp/mypy.ini
def f(): pass
f()
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/badreturn.py
[out]
tmp/mypy.ini:3: error: Type object expected as the return value of "plugin"; got None (in <ROOT>/test-data/unit/plugins/badreturn.py)
[case testInvalidPluginEntryPointReturnValue2]
# flags: --config-file tmp/mypy.ini
def f(): pass
f()
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/badreturn2.py
[out]
tmp/mypy.ini:2: error: Return value of "plugin" must be a subclass of "mypy.plugin.Plugin" (in <ROOT>/test-data/unit/plugins/badreturn2.py)
[case testAttributeTypeHookPlugin]
# flags: --config-file tmp/mypy.ini
from typing import Callable
from m import Signal, DerivedSignal
s: Signal[Callable[[int], None]] = Signal()
s(1)
s('') # E: Argument 1 has incompatible type "str"; expected "int"
ds: DerivedSignal[Callable[[int], None]] = DerivedSignal()
ds('') # E: Argument 1 has incompatible type "str"; expected "int"
[file m.py]
from typing import TypeVar, Generic, Callable
T = TypeVar('T', bound=Callable[..., None])
class Signal(Generic[T]):
__call__: Callable[..., None] # This type is replaced by the plugin
class DerivedSignal(Signal[T]): ...
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/attrhook.py
[case testAttributeTypeHookPluginUntypedDecoratedGetattr]
# flags: --config-file tmp/mypy.ini
from m import Magic, DerivedMagic
magic = Magic()
reveal_type(magic.magic_field) # N: Revealed type is "builtins.str"
reveal_type(magic.non_magic_method()) # N: Revealed type is "builtins.int"
reveal_type(magic.non_magic_field) # N: Revealed type is "builtins.int"
magic.nonexistent_field # E: Field does not exist
reveal_type(magic.fallback_example) # N: Revealed type is "Any"
derived = DerivedMagic()
reveal_type(derived.magic_field) # N: Revealed type is "builtins.str"
derived.nonexistent_field # E: Field does not exist
reveal_type(derived.fallback_example) # N: Revealed type is "Any"
[file m.py]
from typing import Any, Callable
def decorator(f):
pass
class Magic:
# Triggers plugin infrastructure:
@decorator
def __getattr__(self, x: Any) -> Any: ...
def non_magic_method(self) -> int: ...
non_magic_field: int
class DerivedMagic(Magic): ...
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/attrhook2.py
[case testAttributeTypeHookPluginDecoratedGetattr]
# flags: --config-file tmp/mypy.ini
from m import Magic, DerivedMagic
magic = Magic()
reveal_type(magic.magic_field) # N: Revealed type is "builtins.str"
reveal_type(magic.non_magic_method()) # N: Revealed type is "builtins.int"
reveal_type(magic.non_magic_field) # N: Revealed type is "builtins.int"
magic.nonexistent_field # E: Field does not exist
reveal_type(magic.fallback_example) # N: Revealed type is "builtins.bool"
derived = DerivedMagic()
reveal_type(derived.magic_field) # N: Revealed type is "builtins.str"
derived.nonexistent_field # E: Field does not exist
reveal_type(derived.fallback_example) # N: Revealed type is "builtins.bool"
[file m.py]
from typing import Any, Callable
def decorator(f: Callable) -> Callable[[Any, str], bool]:
pass
class Magic:
# Triggers plugin infrastructure:
@decorator
def __getattr__(self, x: Any) -> Any: ...
def non_magic_method(self) -> int: ...
non_magic_field: int
class DerivedMagic(Magic): ...
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/attrhook2.py
[case testAttributeHookPluginForDynamicClass]
# flags: --config-file tmp/mypy.ini
from m import Magic, DerivedMagic
magic = Magic()
reveal_type(magic.magic_field) # N: Revealed type is "builtins.str"
reveal_type(magic.non_magic_method()) # N: Revealed type is "builtins.int"
reveal_type(magic.non_magic_field) # N: Revealed type is "builtins.int"
magic.nonexistent_field # E: Field does not exist
reveal_type(magic.fallback_example) # N: Revealed type is "Any"
derived = DerivedMagic()
reveal_type(derived.magic_field) # N: Revealed type is "builtins.str"
derived.nonexistent_field # E: Field does not exist
reveal_type(magic.fallback_example) # N: Revealed type is "Any"
[file m.py]
from typing import Any
class Magic:
# Triggers plugin infrastructure:
def __getattr__(self, x: Any) -> Any: ...
def non_magic_method(self) -> int: ...
non_magic_field: int
class DerivedMagic(Magic): ...
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/attrhook2.py
[case testTypeAnalyzeHookPlugin]
# flags: --config-file tmp/mypy.ini
from typing import Callable
from mypy_extensions import DefaultArg
from m import Signal
s: Signal[[int, DefaultArg(str, 'x')]] = Signal()
reveal_type(s) # N: Revealed type is "m.Signal[def (builtins.int, x: builtins.str =)]"
s.x # E: "Signal[Callable[[int, str], None]]" has no attribute "x"
ss: Signal[int, str] # E: Invalid "Signal" type (expected "Signal[[t, ...]]")
[file m.py]
from typing import TypeVar, Generic, Callable
T = TypeVar('T', bound=Callable[..., None])
class Signal(Generic[T]):
__call__: Callable[..., None]
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/type_anal_hook.py
[builtins fixtures/dict.pyi]
[case testFunctionPluginHookForClass]
# flags: --config-file tmp/mypy.ini
import mod
from mod import AttrInt
Alias = AttrInt
AnotherAlias = mod.Attr
class C:
x = Alias()
y = mod.AttrInt(required=True)
z = AnotherAlias(int, required=False)
c = C()
reveal_type(c.x) # N: Revealed type is "Union[builtins.int, None]"
reveal_type(c.y) # N: Revealed type is "builtins.int"
reveal_type(c.z) # N: Revealed type is "Union[builtins.int, None]"
[file mod.py]
from typing import Generic, TypeVar, Type
T = TypeVar('T')
class Attr(Generic[T]):
def __init__(self, tp: Type[T], required: bool = False) -> None:
pass
def __get__(self, instance: object, owner: type) -> T:
pass
class AttrInt(Attr[int]):
def __init__(self, required: bool = False) -> None:
pass
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/class_callable.py
[builtins fixtures/bool.pyi]
[out]
[case testFunctionPluginHookForReturnedCallable]
# flags: --config-file tmp/mypy.ini
from m import decorator1, decorator2
@decorator1()
def f() -> None: pass
@decorator2()
def g() -> None: pass
reveal_type(f) # N: Revealed type is "def (*Any, **Any) -> builtins.str"
reveal_type(g) # N: Revealed type is "def (*Any, **Any) -> builtins.int"
[file m.py]
from typing import Callable
def decorator1() -> Callable[..., Callable[..., int]]: pass
def decorator2() -> Callable[..., Callable[..., int]]: pass
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/named_callable.py
[case testFunctionMethodContextsHasArgNames]
# flags: --config-file tmp/mypy.ini
from mod import Class, func
reveal_type(Class().method(arg1=1, arg2=2, classname='builtins.str')) # N: Revealed type is "builtins.str"
reveal_type(Class.myclassmethod(arg1=1, arg2=2, classname='builtins.str')) # N: Revealed type is "builtins.str"
reveal_type(Class.mystaticmethod(arg1=1, arg2=2, classname='builtins.str')) # N: Revealed type is "builtins.str"
reveal_type(Class.method(self=Class(), arg1=1, arg2=2, classname='builtins.str')) # N: Revealed type is "builtins.str"
reveal_type(func(arg1=1, arg2=2, classname='builtins.str')) # N: Revealed type is "builtins.str"
[file mod.py]
from typing import Any
class Class:
def method(self, classname: str, arg1: Any, arg2: Any) -> Any:
pass
@classmethod
def myclassmethod(cls, classname: str, arg1: Any, arg2: Any):
pass
@staticmethod
def mystaticmethod(classname: str, arg1: Any, arg2: Any):
pass
def func(classname: str, arg1: Any, arg2: Any) -> Any:
pass
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/arg_names.py
[builtins fixtures/classmethod.pyi]
[case testFunctionMethodContextsHasArgNamesPositionals]
# flags: --config-file tmp/mypy.ini
from mod import Class, func
reveal_type(Class().method('builtins.str', arg1=1, arg2=2)) # N: Revealed type is "builtins.str"
reveal_type(Class.myclassmethod('builtins.str', arg1=1, arg2=2)) # N: Revealed type is "builtins.str"
reveal_type(Class.mystaticmethod('builtins.str', arg1=1, arg2=2)) # N: Revealed type is "builtins.str"
reveal_type(Class.method(Class(), 'builtins.str', arg1=1, arg2=2)) # N: Revealed type is "builtins.str"
reveal_type(func('builtins.str', arg1=1, arg2=2)) # N: Revealed type is "builtins.str"
[file mod.py]
from typing import Any
class Class:
def method(self, classname: str, arg1: Any, arg2: Any) -> Any:
pass
@classmethod
def myclassmethod(cls, classname: str, arg1: Any, arg2: Any):
pass
@staticmethod
def mystaticmethod(classname: str, arg1: Any, arg2: Any):
pass
def func(classname: str, arg1: Any, arg2: Any) -> Any:
pass
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/arg_names.py
[builtins fixtures/classmethod.pyi]
[case testFunctionMethodContextsHasArgNamesInitMethod]
# flags: --config-file tmp/mypy.ini
from mod import ClassInit, Outer
reveal_type(ClassInit('builtins.str')) # N: Revealed type is "builtins.str"
reveal_type(ClassInit(classname='builtins.str')) # N: Revealed type is "builtins.str"
reveal_type(Outer.NestedClassInit(classname='builtins.str')) # N: Revealed type is "builtins.str"
[file mod.py]
from typing import Any
class ClassInit:
def __init__(self, classname: str):
pass
class Outer:
class NestedClassInit:
def __init__(self, classname: str):
pass
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/arg_names.py
[case testFunctionMethodContextsHasArgNamesUnfilledArguments]
# flags: --config-file tmp/mypy.ini
from mod import ClassUnfilled, func_unfilled
reveal_type(ClassUnfilled().method(classname='builtins.str', arg1=1)) # N: Revealed type is "builtins.str"
reveal_type(ClassUnfilled().method(arg2=1, classname='builtins.str')) # N: Revealed type is "builtins.str"
reveal_type(ClassUnfilled().method('builtins.str')) # N: Revealed type is "builtins.str"
reveal_type(func_unfilled(classname='builtins.str', arg1=1)) # N: Revealed type is "builtins.str"
reveal_type(func_unfilled(arg2=1, classname='builtins.str')) # N: Revealed type is "builtins.str"
reveal_type(func_unfilled('builtins.str')) # N: Revealed type is "builtins.str"
[file mod.py]
from typing import Any
class ClassUnfilled:
def method(self, classname: str, arg1: Any = None, arg2: Any = None) -> Any:
pass
def func_unfilled(classname: str, arg1: Any = None, arg2: Any = None) -> Any:
pass
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/arg_names.py
[case testFunctionMethodContextsHasArgNamesStarExpressions]
# flags: --config-file tmp/mypy.ini
from mod import ClassStarExpr, func_star_expr
reveal_type(ClassStarExpr().method(classname='builtins.str', arg1=1)) # N: Revealed type is "builtins.str"
reveal_type(ClassStarExpr().method('builtins.str', arg1=1)) # N: Revealed type is "builtins.str"
reveal_type(ClassStarExpr().method('builtins.str', arg1=1, arg2=1)) # N: Revealed type is "builtins.str"
reveal_type(ClassStarExpr().method('builtins.str', 2, 3, 4, arg1=1, arg2=1)) # N: Revealed type is "builtins.str"
reveal_type(func_star_expr(classname='builtins.str', arg1=1)) # N: Revealed type is "builtins.str"
reveal_type(func_star_expr('builtins.str', arg1=1)) # N: Revealed type is "builtins.str"
reveal_type(func_star_expr('builtins.str', 2, 3, 4, arg1=1, arg2=2)) # N: Revealed type is "builtins.str"
[file mod.py]
from typing import Any
class ClassStarExpr:
def method(self, classname: str, *args, **kwargs) -> Any:
pass
def func_star_expr(classname: str, *args, **kwargs) -> Any:
pass
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/arg_names.py
[builtins fixtures/dict.pyi]
[case testFunctionMethodContextArgNamesForInheritedMethods]
# flags: --config-file tmp/mypy.ini
from mod import ClassChild
reveal_type(ClassChild().method(classname='builtins.str', arg1=1, arg2=1)) # N: Revealed type is "builtins.str"
reveal_type(ClassChild().method(arg1=1, classname='builtins.str', arg2=1)) # N: Revealed type is "builtins.str"
reveal_type(ClassChild().method('builtins.str', arg1=1, arg2=1)) # N: Revealed type is "builtins.str"
reveal_type(ClassChild.myclassmethod('builtins.str')) # N: Revealed type is "builtins.str"
[file mod.py]
from typing import Any
class Base:
def method(self, classname: str, arg1: Any, arg2: Any) -> Any:
pass
@classmethod
def myclassmethod(cls, classname: str) -> Any:
pass
class ClassChild(Base):
pass
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/arg_names.py
[builtins fixtures/classmethod.pyi]
[case testMethodSignatureHook]
# flags: --config-file tmp/mypy.ini
from typing import Iterator
class Foo:
# Test that method signature hooks are applied in various cases: explicit method calls, and
# implicit dunder method calls through language syntax.
# The plugin's method signature hook should turn all str occurrences into int.
def __init__(self) -> None: ...
def __getitem__(self, index: str) -> str: ...
def __setitem__(self, index: str, value: str) -> None: ...
def __iter__(self) -> Iterator[str]: ...
def __next__(self) -> str: ...
def __call__(self, *args: str) -> str: ...
def m(self, arg: str) -> str: ...
foo = Foo()
reveal_type(foo.m(2)) # N: Revealed type is "builtins.int"
reveal_type(foo[3]) # N: Revealed type is "builtins.int"
reveal_type(foo(4, 5, 6)) # N: Revealed type is "builtins.int"
foo[4] = 5
for x in foo:
reveal_type(x) # N: Revealed type is "builtins.int"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/method_sig_hook.py
[builtins fixtures/tuple.pyi]
[case testMethodSignatureHookNamesFullyQualified]
# flags: --config-file tmp/mypy.ini
from mypy_extensions import TypedDict
from typing import NamedTuple
class FullyQualifiedTestClass:
@classmethod
def class_method(self) -> str: ...
def instance_method(self) -> str: ...
class FullyQualifiedTestTypedDict(TypedDict):
foo: str
FullyQualifiedTestNamedTuple = NamedTuple('FullyQualifiedTestNamedTuple', [('foo', str)])
# Check the return types to ensure that the method signature hook is called in each case
reveal_type(FullyQualifiedTestClass.class_method()) # N: Revealed type is "builtins.int"
reveal_type(FullyQualifiedTestClass().instance_method()) # N: Revealed type is "builtins.int"
reveal_type(FullyQualifiedTestNamedTuple('')._asdict()) # N: Revealed type is "builtins.int"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/fully_qualified_test_hook.py
[builtins fixtures/classmethod.pyi]
[case testDynamicClassPlugin]
# flags: --config-file tmp/mypy.ini
from mod import declarative_base, Column, Instr
Base = declarative_base()
class Model(Base):
x: Column[int]
class Other:
x: Column[int]
reveal_type(Model().x) # N: Revealed type is "mod.Instr[builtins.int]"
reveal_type(Other().x) # N: Revealed type is "mod.Column[builtins.int]"
[file mod.py]
from typing import Generic, TypeVar
def declarative_base(): ...
T = TypeVar('T')
class Column(Generic[T]): ...
class Instr(Generic[T]): ...
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/dyn_class.py
[case testDynamicClassPluginChainCall]
# flags: --config-file tmp/mypy.ini
from mod import declarative_base, Column, Instr
Base = declarative_base().with_optional_xxx()
class Model(Base):
x: Column[int]
reveal_type(Model().x) # N: Revealed type is "mod.Instr[builtins.int]"
[file mod.py]
from typing import Generic, TypeVar
class Base:
def with_optional_xxx(self) -> Base: ...
def declarative_base() -> Base: ...
T = TypeVar('T')
class Column(Generic[T]): ...
class Instr(Generic[T]): ...
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/dyn_class.py
[case testDynamicClassPluginChainedAssignment]
# flags: --config-file tmp/mypy.ini
from mod import declarative_base
Base1 = Base2 = declarative_base()
class C1(Base1): ...
class C2(Base2): ...
[file mod.py]
def declarative_base(): ...
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/dyn_class.py
[case testDynamicClassPluginNegatives]
# flags: --config-file tmp/mypy.ini
from mod import non_declarative_base
Bad1 = non_declarative_base()
class C1(Bad1): ... # E: Variable "__main__.Bad1" is not valid as a type \
# N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases \
# E: Invalid base class "Bad1"
[file mod.py]
def non_declarative_base(): ...
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/dyn_class.py
[case testDynamicClassHookFromClassMethod]
# flags: --config-file tmp/mypy.ini
from mod import QuerySet, Manager
MyManager = Manager.from_queryset(QuerySet)
reveal_type(MyManager()) # N: Revealed type is "__main__.MyManager"
reveal_type(MyManager().attr) # N: Revealed type is "builtins.str"
def func(manager: MyManager) -> None:
reveal_type(manager) # N: Revealed type is "__main__.MyManager"
reveal_type(manager.attr) # N: Revealed type is "builtins.str"
func(MyManager())
[file mod.py]
from typing import Generic, TypeVar, Type
class QuerySet:
attr: str
class Manager:
@classmethod
def from_queryset(cls, queryset_cls: Type[QuerySet]): ...
[builtins fixtures/classmethod.pyi]
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/dyn_class_from_method.py
[case testBaseClassPluginHookWorksIncremental]
# flags: --config-file tmp/mypy.ini
import a
[file a.py]
from base import Base
class C(Base): ...
[file a.py.2]
from base import Base
class C(Base): ...
reveal_type(C().__magic__)
Base.__magic__
[file base.py]
from lib import declarative_base
Base = declarative_base()
[file lib.py]
from typing import Any
def declarative_base() -> Any: ...
[file mypy.ini]
\[mypy]
python_version=3.6
plugins=<ROOT>/test-data/unit/plugins/common_api_incremental.py
[out]
[out2]
tmp/a.py:3: note: Revealed type is "builtins.str"
tmp/a.py:4: error: "Type[Base]" has no attribute "__magic__"
[case testArgKindsMethod]
# flags: --config-file tmp/mypy.ini
class Class:
def method(self, *args, **kwargs):
pass
Class().method(1, *[2], **{'a': 1}) # E: [[0, 2], [4]]
[builtins fixtures/dict.pyi]
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/arg_kinds.py
[case testArgKindsFunction]
# flags: --config-file tmp/mypy.ini
def func(*args, **kwargs):
pass
func(1, 2, [3, 4], *[5, 6, 7], **{'a': 1}) # E: [[0, 0, 0, 2], [4]]
[builtins fixtures/dict.pyi]
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/arg_kinds.py
[case testHookCallableInstance]
# flags: --config-file tmp/mypy.ini
from typing import Generic, TypeVar
T = TypeVar("T")
class Class(Generic[T]):
def __init__(self, one: T): ...
def __call__(self, two: T) -> int: ...
reveal_type(Class("hi")("there")) # N: Revealed type is "builtins.str"
instance = Class(3.14)
reveal_type(instance(2)) # N: Revealed type is "builtins.float"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/callable_instance.py
[case testGetMethodHooksOnUnions]
# flags: --config-file tmp/mypy.ini --no-strict-optional
from typing import Union
class Foo:
def meth(self, x: str) -> str: ...
class Bar:
def meth(self, x: int) -> float: ...
class Other:
meth: int
x: Union[Foo, Bar, Other]
if isinstance(x.meth, int):
reveal_type(x.meth) # N: Revealed type is "builtins.int"
else:
reveal_type(x.meth(int())) # N: Revealed type is "builtins.int"
[builtins fixtures/isinstancelist.pyi]
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/union_method.py
[case testGetMethodHooksOnUnionsStrictOptional]
# flags: --config-file tmp/mypy.ini
from typing import Union
class Foo:
def meth(self, x: str) -> str: ...
class Bar:
def meth(self, x: int) -> float: ...
class Other:
meth: int
x: Union[Foo, Bar, Other]
if isinstance(x.meth, int):
reveal_type(x.meth) # N: Revealed type is "builtins.int"
else:
reveal_type(x.meth(int())) # N: Revealed type is "builtins.int"
[builtins fixtures/isinstancelist.pyi]
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/union_method.py
[case testGetMethodHooksOnUnionsSpecial]
# flags: --config-file tmp/mypy.ini
from typing import Union
class Foo:
def __getitem__(self, x: str) -> str: ...
class Bar:
def __getitem__(self, x: int) -> float: ...
x: Union[Foo, Bar]
reveal_type(x[int()]) # N: Revealed type is "builtins.int"
[builtins fixtures/isinstancelist.pyi]
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/union_method.py
[case testPluginDependencies]
# flags: --config-file tmp/mypy.ini
# The top level file here doesn't do anything, but the plugin should add
# a dependency on err that will cause err to be processed and an error reported.
[file err.py]
1 + 'lol' # E: Unsupported operand types for + ("int" and "str")
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/depshook.py
[case testCustomizeMroTrivial]
# flags: --config-file tmp/mypy.ini
class A: pass
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/customize_mro.py
[case testDescriptorMethods]
# flags: --config-file tmp/mypy.ini
class Desc:
def __get__(self, obj, cls):
pass
def __set__(self, obj, val):
pass
class Cls:
attr = Desc()
reveal_type(Cls().attr) # N: Revealed type is "builtins.int"
reveal_type(Cls.attr) # N: Revealed type is "builtins.str"
Cls().attr = 3
Cls().attr = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "int")
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/descriptor.py
[case testFunctionSigPluginFile]
# flags: --config-file tmp/mypy.ini
def dynamic_signature(arg1: str) -> str: ...
a: int = 1
reveal_type(dynamic_signature(a)) # N: Revealed type is "builtins.int"
b: bytes = b'foo'
reveal_type(dynamic_signature(b)) # N: Revealed type is "builtins.bytes"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/function_sig_hook.py
[case testPluginCalledCorrectlyWhenMethodInDecorator]
# flags: --config-file tmp/mypy.ini
from typing import TypeVar, Callable
T = TypeVar('T')
class Foo:
def a(self, x: Callable[[], T]) -> Callable[[], T]: ...
b = Foo()
@b.a
def f() -> None:
pass
reveal_type(f()) # N: Revealed type is "builtins.str"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/method_in_decorator.py
[case testClassAttrPluginClassVar]
# flags: --config-file tmp/mypy.ini
from typing import Type
class Cls:
attr = 'test'
unchanged = 'test'
reveal_type(Cls().attr) # N: Revealed type is "builtins.str"
reveal_type(Cls.attr) # N: Revealed type is "builtins.int"
reveal_type(Cls.unchanged) # N: Revealed type is "builtins.str"
x: Type[Cls]
reveal_type(x.attr) # N: Revealed type is "builtins.int"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/class_attr_hook.py
[case testClassAttrPluginMethod]
# flags: --config-file tmp/mypy.ini
class Cls:
def attr(self) -> None:
pass
reveal_type(Cls.attr) # N: Revealed type is "builtins.int"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/class_attr_hook.py
[case testClassAttrPluginEnum]
# flags: --config-file tmp/mypy.ini
import enum
class Cls(enum.Enum):
attr = 'test'
reveal_type(Cls.attr) # N: Revealed type is "builtins.int"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/class_attr_hook.py
[case testClassAttrPluginMetaclassAnyBase]
# flags: --config-file tmp/mypy.ini
from typing import Any, Type
class M(type):
attr = 'test'
B: Any
class Cls(B, metaclass=M):
pass
reveal_type(Cls.attr) # N: Revealed type is "builtins.int"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/class_attr_hook.py
[case testClassAttrPluginMetaclassRegularBase]
# flags: --config-file tmp/mypy.ini
from typing import Any, Type
class M(type):
attr = 'test'
class B:
attr = None
class Cls(B, metaclass=M):
pass
reveal_type(Cls.attr) # N: Revealed type is "builtins.int"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/class_attr_hook.py
[case testClassAttrPluginPartialType]
# flags: --config-file tmp/mypy.ini
class Cls:
attr = None
def f(self) -> int:
return Cls.attr + 1
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/class_attr_hook.py
[case testAddClassMethodPlugin]
# flags: --config-file tmp/mypy.ini
class BaseAddMethod: pass
class MyClass(BaseAddMethod):
pass
my_class = MyClass()
reveal_type(MyClass.foo_classmethod) # N: Revealed type is "def ()"
reveal_type(MyClass.foo_staticmethod) # N: Revealed type is "def (builtins.int) -> builtins.str"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/add_classmethod.py
[case testCustomErrorCodePlugin]
# flags: --config-file tmp/mypy.ini --show-error-codes
def main() -> int:
return 2
main() # E: Custom error [custom]
reveal_type(1) # N: Revealed type is "Literal[1]?"
[file mypy.ini]
\[mypy]
plugins=<ROOT>/test-data/unit/plugins/custom_errorcode.py