-- 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=/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='/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=/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="/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=/test-data/unit/plugins/fnplugin.py, /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=['/test-data/unit/plugins/fnplugin.py', '/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=/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=['/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 = /test-data/unit/plugins/noentry.py [out] tmp/mypy.ini:2: error: Plugin "/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=/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 = /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=/test-data/unit/plugins/badreturn.py [out] tmp/mypy.ini:3: error: Type object expected as the return value of "plugin"; got None (in /test-data/unit/plugins/badreturn.py) [case testInvalidPluginEntryPointReturnValue2] # flags: --config-file tmp/mypy.ini def f(): pass f() [file mypy.ini] \[mypy] plugins=/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 /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=/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" reveal_type(magic.no_assignment_field) # N: Revealed type is "builtins.float" magic.no_assignment_field = "bad" # E: Cannot assign to field 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 no_assignment_field: float class DerivedMagic(Magic): ... [file mypy.ini] \[mypy] plugins=/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=/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=/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=/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 "builtins.int | None" reveal_type(c.y) # N: Revealed type is "builtins.int" reveal_type(c.z) # N: Revealed type is "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=/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=/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=/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=/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=/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=/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=/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=/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=/test-data/unit/plugins/method_sig_hook.py [builtins fixtures/tuple.pyi] [case testMethodSignatureHookNamesFullyQualified] # flags: --config-file tmp/mypy.ini from typing import NamedTuple, TypedDict 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=/test-data/unit/plugins/fully_qualified_test_hook.py [builtins fixtures/classmethod.pyi] [typing fixtures/typing-typeddict.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=/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=/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=/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=/test-data/unit/plugins/dyn_class.py [case testDynamicClassHookFromClassMethod] # flags: --config-file tmp/mypy.ini from mod import QuerySet, Manager, GenericQuerySet MyManager = Manager.from_queryset(QuerySet) ManagerFromGenericQuerySet = GenericQuerySet[int].as_manager() reveal_type(MyManager()) # N: Revealed type is "__main__.MyManager" reveal_type(MyManager().attr) # N: Revealed type is "builtins.str" reveal_type(ManagerFromGenericQuerySet()) # N: Revealed type is "__main__.ManagerFromGenericQuerySet" reveal_type(ManagerFromGenericQuerySet().attr) # N: Revealed type is "builtins.int" queryset: GenericQuerySet[int] = ManagerFromGenericQuerySet() 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]): ... T = TypeVar("T") class GenericQuerySet(Generic[T]): attr: T @classmethod def as_manager(cls): ... [builtins fixtures/classmethod.pyi] [file mypy.ini] \[mypy] plugins=/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=/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=/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=/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=/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=/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=/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=/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=/test-data/unit/plugins/depshook.py [case testCustomizeMroTrivial] # flags: --config-file tmp/mypy.ini class A: pass [file mypy.ini] \[mypy] plugins=/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=/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=/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=/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=/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=/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" [builtins fixtures/enum.pyi] [file mypy.ini] \[mypy] plugins=/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=/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 = b'bytes' class Cls(B, metaclass=M): pass reveal_type(Cls.attr) # N: Revealed type is "builtins.int" [file mypy.ini] \[mypy] plugins=/test-data/unit/plugins/class_attr_hook.py [case testClassAttrPluginPartialType] # flags: --config-file tmp/mypy.ini --no-local-partial-types class Cls: attr = None def f(self) -> int: return Cls.attr + 1 [file mypy.ini] \[mypy] plugins=/test-data/unit/plugins/class_attr_hook.py [case testAddClassMethodPlugin] # flags: --config-file tmp/mypy.ini class BaseAddMethod: pass class MyClass(BaseAddMethod): pass reveal_type(MyClass.foo_classmethod) # N: Revealed type is "def ()" reveal_type(MyClass.foo_staticmethod) # N: Revealed type is "def (builtins.int) -> builtins.str" my_class = MyClass() reveal_type(my_class.foo_classmethod) # N: Revealed type is "def ()" reveal_type(my_class.foo_staticmethod) # N: Revealed type is "def (builtins.int) -> builtins.str" [file mypy.ini] \[mypy] plugins=/test-data/unit/plugins/add_classmethod.py [case testAddOverloadedMethodPlugin] # flags: --config-file tmp/mypy.ini class AddOverloadedMethod: pass class MyClass(AddOverloadedMethod): pass reveal_type(MyClass.method) # N: Revealed type is "Overload(def (self: __main__.MyClass, arg: builtins.int) -> builtins.str, def (self: __main__.MyClass, arg: builtins.str) -> builtins.int)" reveal_type(MyClass.clsmethod) # N: Revealed type is "Overload(def (arg: builtins.int) -> builtins.str, def (arg: builtins.str) -> builtins.int)" reveal_type(MyClass.stmethod) # N: Revealed type is "Overload(def (arg: builtins.int) -> builtins.str, def (arg: builtins.str) -> builtins.int)" my_class = MyClass() reveal_type(my_class.method) # N: Revealed type is "Overload(def (arg: builtins.int) -> builtins.str, def (arg: builtins.str) -> builtins.int)" reveal_type(my_class.clsmethod) # N: Revealed type is "Overload(def (arg: builtins.int) -> builtins.str, def (arg: builtins.str) -> builtins.int)" reveal_type(my_class.stmethod) # N: Revealed type is "Overload(def (arg: builtins.int) -> builtins.str, def (arg: builtins.str) -> builtins.int)" [file mypy.ini] \[mypy] plugins=/test-data/unit/plugins/add_overloaded_method.py [case testAddMethodPluginExplicitOverride] # flags: --python-version 3.12 --config-file tmp/mypy.ini from typing import override, TypeVar T = TypeVar('T', bound=type) def inject_foo(t: T) -> T: # Imitates: # t.foo_implicit = some_method return t class BaseWithoutFoo: pass @inject_foo class ChildWithFoo(BaseWithoutFoo): pass reveal_type(ChildWithFoo.foo_implicit) # N: Revealed type is "def (self: __main__.ChildWithFoo)" @inject_foo class SomeWithFoo(ChildWithFoo): pass reveal_type(SomeWithFoo.foo_implicit) # N: Revealed type is "def (self: __main__.SomeWithFoo)" class ExplicitOverride(SomeWithFoo): @override def foo_implicit(self) -> None: pass class ImplicitOverride(SomeWithFoo): def foo_implicit(self) -> None: pass # E: Method "foo_implicit" is not using @override but is overriding a method in class "__main__.SomeWithFoo" [file mypy.ini] \[mypy] plugins=/test-data/unit/plugins/add_method.py enable_error_code = explicit-override [typing fixtures/typing-override.pyi] [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=/test-data/unit/plugins/custom_errorcode.py [case testPyprojectPluginsTrailingComma] # flags: --config-file tmp/pyproject.toml [file pyproject.toml] # This test checks that trailing commas in string-based `plugins` are allowed. \[tool.mypy] plugins = """ /test-data/unit/plugins/function_sig_hook.py, /test-data/unit/plugins/method_in_decorator.py, """ [out] [case magicMethodReverse] # flags: --config-file tmp/mypy.ini from typing import Literal op1: Literal[3] = 3 op2: Literal[4] = 4 c = op1 + op2 reveal_type(c) # N: Revealed type is "Literal[7]" [file mypy.ini] \[mypy] plugins=/test-data/unit/plugins/magic_method.py [builtins fixtures/ops.pyi]