| -- Test cases for generating dependencies between ASTs nodes. | |
| -- | |
| -- The dependencies are used for fined-grained incremental checking and | |
| -- the daemon mode. | |
| -- | |
| -- The output of each test case includes the dependency map for whitelisted | |
| -- modules (includes the main module and the modules 'pkg' and 'pkg.mod' at | |
| -- least). | |
| -- | |
| -- Dependencies are formatted as "<trigger> -> affected locations". | |
| -- | |
| -- Look at the docstring of mypy.server.deps for an explanation of | |
| -- how fine-grained dependencies are represented. | |
| [case testCallFunction] | |
| def f() -> None: | |
| g() | |
| def g() -> None: | |
| pass | |
| [out] | |
| <m.g> -> m.f | |
| [case testCallMethod] | |
| def f(a: A) -> None: | |
| a.g() | |
| class A: | |
| def g(self) -> None: pass | |
| [out] | |
| <m.A.g> -> m.f | |
| <m.A> -> <m.f>, m.A, m.f | |
| [case testAccessAttribute] | |
| def f(a: A) -> None: | |
| a.x | |
| class A: | |
| def g(self) -> None: | |
| self.x = 1 | |
| [out] | |
| <m.A.x> -> m.A.g, m.f | |
| <m.A> -> <m.f>, m.A, m.f | |
| [case testConstructInstance] | |
| def f() -> None: | |
| A() | |
| class A: pass | |
| [out] | |
| <m.A.__init__> -> m.f | |
| <m.A.__new__> -> m.f | |
| <m.A> -> m.A, m.f | |
| [case testAccessModuleAttribute] | |
| class A: pass | |
| x = A() | |
| def f() -> None: | |
| x | |
| [out] | |
| <m.A.__init__> -> m | |
| <m.A.__new__> -> m | |
| <m.A> -> <m.x>, m, m.A | |
| <m.x> -> m, m.f | |
| [case testAccessModuleAttribute2] | |
| import n | |
| def f() -> None: | |
| n.x | |
| [file n.py] | |
| x = 1 | |
| [out] | |
| <n.x> -> m.f | |
| <n> -> m, m.f | |
| [case testAccessReexportedModuleAttribute] | |
| import pkg | |
| pkg.f() | |
| [file pkg/__init__.py] | |
| from pkg.sub import * | |
| [file pkg/sub.py] | |
| def f() -> None: pass | |
| [out] | |
| <pkg.f> -> m | |
| <pkg.sub.f> -> m | |
| <pkg.sub[wildcard]> -> pkg | |
| <pkg> -> m | |
| [case testImport] | |
| import n | |
| [file n.py] | |
| x = 1 | |
| [out] | |
| <n> -> m | |
| [case testCallImportedFunction] | |
| import n | |
| n.f() | |
| [file n.py] | |
| def f() -> None: pass | |
| [out] | |
| <n.f> -> m | |
| <n> -> m | |
| [case testImportModuleAs] | |
| import n as x | |
| x.f() | |
| [file n.py] | |
| def f() -> None: pass | |
| [out] | |
| <n.f> -> m | |
| <n> -> m | |
| [case testCallImportedFunctionInFunction] | |
| import n | |
| def g() -> None: | |
| n.f() | |
| [file n.py] | |
| def f() -> None: pass | |
| [out] | |
| <n.f> -> m.g | |
| <n> -> m, m.g | |
| [case testInheritanceSimple] | |
| class A: | |
| pass | |
| class B(A): | |
| pass | |
| [out] | |
| <m.A.(abstract)> -> <m.B.__init__>, m | |
| <m.A.__init__> -> <m.B.__init__> | |
| <m.A.__new__> -> <m.B.__new__> | |
| <m.A> -> m, m.A, m.B | |
| <m.B> -> m.B | |
| [case testInheritanceWithMethodAndAttribute] | |
| class A: | |
| pass | |
| class B(A): | |
| def f(self) -> None: | |
| self.x = 1 | |
| [out] | |
| <m.A.(abstract)> -> <m.B.__init__>, m | |
| <m.A.__init__> -> <m.B.__init__> | |
| <m.A.__new__> -> <m.B.__new__> | |
| <m.A.f> -> m.B.f | |
| <m.A.x> -> <m.B.x> | |
| <m.A> -> m, m.A, m.B | |
| <m.B.x> -> m.B.f | |
| <m.B> -> m.B | |
| [case testInheritanceWithMethodAndAttributeAndDeepHierarchy] | |
| class A: | |
| pass | |
| class B(A): | |
| pass | |
| class C(B): | |
| def f(self) -> None: | |
| self.x = 1 | |
| [out] | |
| <m.A.(abstract)> -> <m.B.__init__>, <m.C.__init__>, m | |
| <m.A.__init__> -> <m.B.__init__>, <m.C.__init__> | |
| <m.A.__new__> -> <m.B.__new__>, <m.C.__new__> | |
| <m.A.f> -> m.C.f | |
| <m.A.x> -> <m.C.x> | |
| <m.A> -> m, m.A, m.B | |
| <m.B.(abstract)> -> <m.C.__init__>, m | |
| <m.B.__init__> -> <m.C.__init__> | |
| <m.B.__new__> -> <m.C.__new__> | |
| <m.B.f> -> m.C.f | |
| <m.B.x> -> <m.C.x> | |
| <m.B> -> m, m.B, m.C | |
| <m.C.x> -> m.C.f | |
| <m.C> -> m.C | |
| [case testInheritAttribute] | |
| import n | |
| class B(n.A): | |
| def f(self) -> None: | |
| a = 1 | |
| a = self.x | |
| [file n.py] | |
| class A: | |
| def g(self) -> None: | |
| self.x = 1 | |
| [out] | |
| <m.B.x> -> m.B.f | |
| <m.B> -> m.B | |
| <n.A.(abstract)> -> <m.B.__init__>, m | |
| <n.A.__init__> -> <m.B.__init__> | |
| <n.A.__new__> -> <m.B.__new__> | |
| <n.A.f> -> m.B.f | |
| <n.A.g> -> <m.B.g> | |
| <n.A.x> -> <m.B.x> | |
| <n.A> -> m, m.B | |
| <n> -> m | |
| [case testInheritMethod] | |
| class A: | |
| def g(self) -> None: pass | |
| class B(A): | |
| def f(self) -> None: | |
| self.g() | |
| [out] | |
| <m.A.(abstract)> -> <m.B.__init__>, m | |
| <m.A.__init__> -> <m.B.__init__> | |
| <m.A.__new__> -> <m.B.__new__> | |
| <m.A.f> -> m.B.f | |
| <m.A.g> -> <m.B.g> | |
| <m.A> -> m, m.A, m.B | |
| <m.B.g> -> m.B.f | |
| <m.B> -> m.B | |
| [case testPackage] | |
| import a.b | |
| def f() -> None: | |
| a.b.g() | |
| [file a/__init__.py] | |
| [file a/b.py] | |
| def g() -> None: pass | |
| [out] | |
| <a.b.g> -> m.f | |
| <a.b> -> m, m.f | |
| <a> -> m.f | |
| [case testClassInPackage] | |
| import a.b | |
| def f(x: a.b.A) -> None: | |
| x.g() | |
| x.y | |
| [file a/__init__.py] | |
| [file a/b.py] | |
| class A: | |
| def g(self) -> None: | |
| self.y = 1 | |
| [out] | |
| <a.b.A.g> -> m.f | |
| <a.b.A.y> -> m.f | |
| <a.b.A> -> <m.f>, m.f | |
| <a.b> -> m | |
| [case testPackage__init__] | |
| import a | |
| def f() -> None: | |
| a.g() | |
| [file a/__init__.py] | |
| def g() -> None: pass | |
| [out] | |
| <a.g> -> m.f | |
| <a> -> m, m.f | |
| [case testClassInPackage__init__] | |
| import a | |
| def f(x: a.A) -> None: | |
| x.g() | |
| x.y | |
| [file a/__init__.py] | |
| class A: | |
| def g(self) -> None: | |
| self.y = 1 | |
| [out] | |
| <a.A.g> -> m.f | |
| <a.A.y> -> m.f | |
| <a.A> -> <m.f>, m.f | |
| <a> -> m | |
| [case testConstructor] | |
| class A: | |
| def __init__(self, x: C) -> None: pass | |
| class C: pass | |
| def f() -> None: | |
| A(C()) | |
| [out] | |
| <m.A.__init__> -> m.f | |
| <m.A.__new__> -> m.f | |
| <m.A> -> m.A, m.f | |
| <m.C.__init__> -> m.f | |
| <m.C.__new__> -> m.f | |
| <m.C> -> <m.A.__init__>, m.A.__init__, m.C, m.f | |
| [case testNonTrivialConstructor] | |
| class C: | |
| def __init__(self) -> None: | |
| self.x = 1 | |
| [out] | |
| <m.C.x> -> m.C.__init__ | |
| <m.C> -> m.C | |
| [case testImportFrom] | |
| from n import f | |
| def g() -> None: | |
| f() | |
| [file n.py] | |
| def f() -> None: pass | |
| [out] | |
| <n.f> -> m, m.g | |
| <n> -> m | |
| [case testImportFromAs] | |
| from n import f as ff | |
| def g() -> None: | |
| ff() | |
| [file n.py] | |
| def f() -> None: pass | |
| [out] | |
| <n.f> -> m, m.g | |
| <n> -> m | |
| [case testNestedClass] | |
| def f() -> None: | |
| b = A.B() | |
| b.f() | |
| class A: | |
| class B: | |
| def f(self) -> None: pass | |
| [out] | |
| <m.A.B.__init__> -> m.f | |
| <m.A.B.__new__> -> m.f | |
| <m.A.B.f> -> m.f | |
| <m.A.B> -> m.A.B, m.f | |
| <m.A> -> m.A, m.f | |
| [case testNestedClassAttribute] | |
| def f() -> None: | |
| b = A.B() | |
| b.x | |
| class A: | |
| class B: | |
| def f(self) -> None: | |
| self.x = 1 | |
| [out] | |
| <m.A.B.__init__> -> m.f | |
| <m.A.B.__new__> -> m.f | |
| <m.A.B.x> -> m.A.B.f, m.f | |
| <m.A.B> -> m.A.B, m.f | |
| <m.A> -> m.A, m.f | |
| [case testNestedClassInAnnotation] | |
| def f(x: A.B) -> None: | |
| pass | |
| class A: | |
| class B: pass | |
| [out] | |
| <m.A.B> -> <m.f>, m.A.B, m.f | |
| <m.A> -> m.A | |
| [case testNestedClassInAnnotation2] | |
| def f(x: A.B) -> None: | |
| x.f() | |
| class A: | |
| class B: | |
| def f(self) -> None: pass | |
| [out] | |
| <m.A.B.f> -> m.f | |
| <m.A.B> -> <m.f>, m.A.B, m.f | |
| <m.A> -> m.A | |
| [case NestedFunctionType] | |
| from mod import A, B, C, D | |
| def outer() -> None: | |
| def inner(x: A, *args: B, **kwds: C) -> D: | |
| pass | |
| [file mod.py] | |
| class A: pass | |
| class B: pass | |
| class C: pass | |
| class D: pass | |
| [builtins fixtures/dict.pyi] | |
| [out] | |
| <mod.A> -> <m.outer>, m, m.outer | |
| <mod.B> -> <m.outer>, m, m.outer | |
| <mod.C> -> <m.outer>, m, m.outer | |
| <mod.D> -> <m.outer>, m, m.outer | |
| <mod> -> m | |
| [case NestedFunctionBody] | |
| from mod import A, B, C | |
| def outer() -> None: | |
| def inner() -> None: | |
| A() | |
| x: B | |
| y: C | |
| y.x | |
| [file mod.py] | |
| class A: pass | |
| class B: pass | |
| class C: | |
| x: int | |
| [builtins fixtures/dict.pyi] | |
| [out] | |
| <mod.A.__init__> -> m.outer | |
| <mod.A.__new__> -> m.outer | |
| <mod.A> -> m, m.outer | |
| <mod.B> -> m, m.outer | |
| <mod.C.x> -> m.outer | |
| <mod.C> -> m, m.outer | |
| <mod> -> m | |
| [case testDefaultArgValue] | |
| def f1(x: int) -> int: pass | |
| def f2() -> int: pass | |
| def g(x: int = f1(f2())) -> None: pass | |
| [out] | |
| <m.f1> -> m.g | |
| <m.f2> -> m.g | |
| [case testIsInstance] | |
| class A: | |
| def g(self) -> None: pass | |
| def f(x: object) -> None: | |
| if isinstance(x, A): | |
| x.g() | |
| def ff(x: object) -> None: | |
| if isinstance(x, A): | |
| pass | |
| [builtins fixtures/isinstancelist.pyi] | |
| [out] | |
| -- The dependencies on the ctor are basically spurious but not a problem | |
| <m.A.g> -> m.f | |
| <m.A> -> m.A, m.f, m.ff | |
| [case testUnreachableIsInstance] | |
| class A: | |
| x: int | |
| class B: | |
| x: str | |
| def f(x: A) -> None: | |
| if isinstance(x, B): | |
| x.y | |
| [builtins fixtures/isinstancelist.pyi] | |
| [out] | |
| <m.A> -> <m.f>, m.A, m.f | |
| <m.B> -> m.B, m.f | |
| [case testIsInstanceAdHocIntersectionDeps] | |
| class A: | |
| x: int | |
| class B: | |
| y: int | |
| def f(x: A) -> None: | |
| if isinstance(x, B): | |
| x.y | |
| [builtins fixtures/isinstancelist.pyi] | |
| [out] | |
| <m.<subclass of "m.A" and "m.B">.y> -> m.f | |
| <m.A> -> <m.f>, m.A, m.f | |
| <m.B> -> m.B, m.f | |
| [case testAttributeWithClassType1] | |
| from n import A | |
| class B: | |
| def h(self, z: A) -> None: | |
| self.z = z | |
| [file n.py] | |
| class A: pass | |
| [out] | |
| <m.B.z> -> m.B.h | |
| <m.B> -> m.B | |
| <n.A> -> <m.B.h>, <m.B.z>, m, m.B.h | |
| <n> -> m | |
| [case testAttributeWithClassType2] | |
| from m import A | |
| class B: | |
| def f(self) -> None: | |
| self.x = A() | |
| [file m.py] | |
| class A: pass | |
| [out] | |
| <m.B.x> -> m.B.f | |
| <m.B> -> m.B | |
| <m.A.__init__> -> m.B.f | |
| <m.A.__new__> -> m.B.f | |
| <m.A> -> <m.B.x>, m, m.B.f | |
| <m> -> m | |
| [case testAttributeWithClassType3] | |
| from n import A, x | |
| class B: | |
| def g(self) -> None: | |
| self.x = x | |
| [file n.py] | |
| class A: pass | |
| x = A() | |
| [out] | |
| <m.B.x> -> m.B.g | |
| <m.B> -> m.B | |
| <n.A> -> <m.B.x>, m | |
| <n.x> -> m, m.B.g | |
| <n> -> m | |
| [case testAttributeWithClassType4] | |
| from n import A | |
| class B: | |
| def g(self) -> None: | |
| self.x: A | |
| [file n.py] | |
| class A: pass | |
| [out] | |
| <m.B.x> -> m.B.g | |
| <m.B> -> m.B | |
| <n.A> -> <m.B.x>, m, m.B.g | |
| <n> -> m | |
| [case testClassBody] | |
| def f() -> int: pass | |
| def g() -> int: pass | |
| def h() -> int: pass | |
| class A: | |
| h() | |
| if f(): | |
| g() | |
| [out] | |
| <m.A> -> m.A | |
| <m.f> -> m | |
| <m.g> -> m | |
| <m.h> -> m | |
| [case testVariableInitializedInClass] | |
| from n import A | |
| class B: | |
| x = None # type: A # type: ignore | |
| [file n.py] | |
| class A: pass | |
| [out] | |
| <m.B> -> m.B | |
| <n.A> -> <m.B.x>, m | |
| <n> -> m | |
| [case testVariableAnnotationInClass] | |
| from n import A | |
| class B: | |
| x: A | |
| def f(self) -> None: | |
| y = self.x | |
| [file n.py] | |
| class A: pass | |
| [out] | |
| <m.B.x> -> m.B.f | |
| <m.B> -> m.B | |
| <n.A> -> <m.B.x>, m | |
| <n> -> m | |
| [case testGlobalVariableInitialized] | |
| from n import A | |
| x = A() | |
| [file n.py] | |
| class A: pass | |
| [out] | |
| <m.x> -> m | |
| <n.A.__init__> -> m | |
| <n.A.__new__> -> m | |
| <n.A> -> <m.x>, m | |
| <n> -> m | |
| [case testGlobalVariableAnnotation] | |
| from n import A | |
| x: A | |
| [file n.py] | |
| class A: pass | |
| [out] | |
| <m.x> -> m | |
| <n.A> -> <m.x>, m | |
| <n> -> m | |
| [case testProperty] | |
| class B: pass | |
| class A: | |
| @property | |
| def x(self) -> B: pass | |
| def f(a: A) -> None: | |
| b = a.x | |
| [builtins fixtures/property.pyi] | |
| [out] | |
| <m.A.x> -> m, m.f | |
| <m.A> -> <m.f>, m.A, m.f | |
| <m.B> -> <m.A.x>, m.A.x, m.B | |
| [case testUnreachableAssignment] | |
| from typing import List, Tuple | |
| def f() -> None: pass | |
| class C: | |
| def __init__(self, x: int) -> None: | |
| if isinstance(x, int): | |
| self.y = 1 | |
| else: | |
| self.y = f() | |
| [builtins fixtures/isinstancelist.pyi] | |
| [out] | |
| <m.C.y> -> m.C.__init__ | |
| <m.C> -> m.C | |
| <m.f> -> m.C.__init__ | |
| [case testPartialNoneTypeAttributeCrash1] | |
| # flags: --no-local-partial-types | |
| class C: pass | |
| class A: | |
| x = None | |
| def f(self) -> None: | |
| self.x = C() | |
| [out] | |
| <m.A.x> -> m.A.f | |
| <m.A> -> m.A | |
| <m.C.__init__> -> m.A.f | |
| <m.C.__new__> -> m.A.f | |
| <m.C> -> <m.A.x>, m.A.f, m.C | |
| [case testPartialNoneTypeAttributeCrash2] | |
| # flags: --no-local-partial-types | |
| class C: pass | |
| class A: | |
| x = None | |
| def f(self) -> None: | |
| self.x = C() | |
| [out] | |
| <m.A.x> -> m.A.f | |
| <m.A> -> m.A | |
| <m.C.__init__> -> m.A.f | |
| <m.C.__new__> -> m.A.f | |
| <m.C> -> <m.A.x>, m.A.f, m.C | |
| [case testRelativeImport] | |
| import pkg # Magic package name in test runner | |
| [file pkg/__init__.py] | |
| from . import mod | |
| from .a import x | |
| [file pkg/mod.py] | |
| from . import a | |
| [file pkg/a.py] | |
| x = 1 | |
| [out] | |
| <pkg.a.x> -> pkg | |
| <pkg.a> -> pkg, pkg.mod | |
| <pkg.mod> -> pkg | |
| <pkg> -> m, pkg, pkg.mod | |
| [case testTypedDict] | |
| from typing import TypedDict | |
| Point = TypedDict('Point', {'x': int, 'y': int}) | |
| p = Point(dict(x=42, y=1337)) | |
| def foo(x: Point) -> int: | |
| return x['x'] + x['y'] | |
| [builtins fixtures/dict.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [out] | |
| <m.Point.__init__> -> m | |
| <m.Point.__new__> -> m | |
| <m.Point> -> <m.foo>, <m.p>, m, m.foo | |
| <m.p> -> m | |
| [case testTypedDict2] | |
| from typing import TypedDict | |
| class A: pass | |
| Point = TypedDict('Point', {'x': int, 'y': A}) | |
| p = Point(dict(x=42, y=A())) | |
| def foo(x: Point) -> int: | |
| return x['x'] | |
| [builtins fixtures/dict.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [out] | |
| <m.A.__init__> -> m | |
| <m.A.__new__> -> m | |
| <m.A> -> <m.Point>, <m.foo>, <m.p>, m, m.A, m.foo | |
| <m.Point.__init__> -> m | |
| <m.Point.__new__> -> m | |
| <m.Point> -> <m.foo>, <m.p>, m, m.foo | |
| <m.p> -> m | |
| [case testTypedDict3] | |
| from typing import TypedDict | |
| class A: pass | |
| class Point(TypedDict): | |
| x: int | |
| y: A | |
| p = Point(dict(x=42, y=A())) | |
| def foo(x: Point) -> int: | |
| return x['x'] | |
| [builtins fixtures/dict.pyi] | |
| [typing fixtures/typing-typeddict.pyi] | |
| [out] | |
| <m.A.__init__> -> m | |
| <m.A.__new__> -> m | |
| <m.A> -> <m.Point>, <m.foo>, <m.p>, m, m.A, m.foo | |
| <m.Point.__init__> -> m | |
| <m.Point.__new__> -> m | |
| <m.Point> -> <m.foo>, <m.p>, m, m.Point, m.foo | |
| <m.p> -> m | |
| [case testImportStar] | |
| from a import * | |
| [file a.py] | |
| x = 0 | |
| [out] | |
| <a[wildcard]> -> m | |
| [case testDecoratorDepsMod] | |
| import mod | |
| @mod.deca | |
| @mod.decb(mod.C()) | |
| def func(x: int) -> int: | |
| pass | |
| [file mod.py] | |
| from typing import Callable, TypeVar | |
| F = TypeVar('F', bound=Callable) | |
| def deca(func: Callable[[int], int]) -> Callable[[str], str]: | |
| pass | |
| def decb(arg: C) -> Callable[[F], F]: | |
| pass | |
| class C: | |
| pass | |
| [out] | |
| <m.func> -> m | |
| <mod.C.__init__> -> m | |
| <mod.C.__new__> -> m | |
| <mod.C> -> m | |
| <mod.deca> -> m | |
| <mod.decb> -> m | |
| <mod> -> m | |
| [case testDecoratorDepsFunc] | |
| import mod | |
| def outer() -> None: | |
| @mod.deca | |
| @mod.decb(mod.C()) | |
| def func(x: int) -> int: | |
| pass | |
| [file mod.py] | |
| from typing import Callable, TypeVar | |
| F = TypeVar('F', bound=Callable) | |
| def deca(func: Callable[[int], int]) -> Callable[[str], str]: | |
| pass | |
| def decb(arg: C) -> Callable[[F], F]: | |
| pass | |
| class C: | |
| pass | |
| [out] | |
| <mod.C.__init__> -> m.outer | |
| <mod.C.__new__> -> m.outer | |
| <mod.C> -> m.outer | |
| <mod.deca> -> m.outer | |
| <mod.decb> -> m.outer | |
| <mod> -> m, m.outer | |
| [case testDecoratorDepsDeepNested] | |
| import mod | |
| def outer() -> None: | |
| def inner() -> None: | |
| @mod.dec | |
| def func(x: int) -> int: | |
| pass | |
| [file mod.py] | |
| from typing import Callable | |
| def dec(func: Callable[[int], int]) -> Callable[[str], str]: | |
| pass | |
| [out] | |
| <mod.dec> -> m.outer | |
| <mod> -> m, m.outer | |
| [case testDecoratorDepsNestedClass] | |
| import mod | |
| class Outer: | |
| class Inner: | |
| c = mod.C() | |
| @c.dec | |
| def func(self, x: int) -> int: | |
| pass | |
| [file mod.py] | |
| from typing import Callable | |
| class C: | |
| def dec(self, func: Callable[..., int]) -> Callable[..., str]: | |
| pass | |
| [out] | |
| <m.Outer.Inner.func> -> m | |
| <m.Outer.Inner> -> m.Outer.Inner | |
| <m.Outer> -> m.Outer | |
| <mod.C.__init__> -> m | |
| <mod.C.__new__> -> m | |
| <mod.C.dec> -> m | |
| <mod.C> -> <m.Outer.Inner.c>, m | |
| <mod> -> m | |
| [case testDecoratorDepsClassInFunction] | |
| import mod | |
| def outer() -> None: | |
| class Inner: | |
| c = mod.C() | |
| @c.dec | |
| def func(self, x: int) -> int: | |
| pass | |
| [file mod.py] | |
| from typing import Callable | |
| class C: | |
| def dec(self, func: Callable[..., int]) -> Callable[..., str]: | |
| pass | |
| [out] | |
| <m.outer> -> m.outer | |
| <mod.C.__init__> -> m.outer | |
| <mod.C.__new__> -> m.outer | |
| <mod.C.dec> -> m.outer | |
| <mod.C> -> <m.outer.c>, m.outer | |
| <mod> -> m, m.outer | |
| [case DecoratorDepsMethod] | |
| import mod | |
| class D: | |
| @mod.deca | |
| @mod.decb(mod.C()) | |
| def func(self, x: int) -> int: | |
| pass | |
| [file mod.py] | |
| from typing import Callable, TypeVar | |
| F = TypeVar('F', bound=Callable) | |
| def deca(func: Callable[..., int]) -> Callable[..., str]: | |
| pass | |
| def decb(arg: C) -> Callable[[F], F]: | |
| pass | |
| class C: | |
| pass | |
| [out] | |
| <m.D.func> -> m | |
| <m.D> -> m.D | |
| <mod.C.__init__> -> m | |
| <mod.C.__new__> -> m | |
| <mod.C> -> m | |
| <mod.deca> -> m | |
| <mod.decb> -> m | |
| <mod> -> m | |
| [case testMissingModuleClass1] | |
| from b import A # type: ignore | |
| def f(x: A) -> None: | |
| x.foo() | |
| [out] | |
| <m.A> -> <m.f>, m.f | |
| <b.A> -> m | |
| <b> -> m | |
| [case testMissingModuleClass2] | |
| from p.b import A # type: ignore | |
| def f(x: A) -> None: | |
| x.foo() | |
| [out] | |
| <m.A> -> <m.f>, m.f | |
| <p.b.A> -> m | |
| <p.b> -> m | |
| [case testIgnoredMissingModuleAttribute] | |
| import a | |
| a.x # type: ignore | |
| import b.c | |
| b.c.x # type: ignore | |
| from b import c | |
| c.y # type: ignore | |
| [file a.py] | |
| [file b/__init__.py] | |
| [file b/c.py] | |
| [builtins fixtures/module.pyi] | |
| [out] | |
| <a.x> -> m | |
| <a> -> m | |
| <b.c.x> -> m | |
| <b.c.y> -> m | |
| <b.c> -> m | |
| <b> -> m | |
| <types.ModuleType.__await__> -> <types.ModuleType> | |
| <types.ModuleType> -> typing.Awaitable | |
| [case testIgnoredMissingInstanceAttribute] | |
| from a import C | |
| C().x # type: ignore | |
| [file a.py] | |
| class C: pass | |
| [out] | |
| <a.C.__await__> -> <a.C> | |
| <a.C.__init__> -> m | |
| <a.C.__new__> -> m | |
| <a.C.x> -> m | |
| <a.C> -> m, typing.Awaitable | |
| <a> -> m | |
| [case testIgnoredMissingClassAttribute] | |
| from a import C | |
| C.x # type: ignore | |
| [file a.py] | |
| class C: pass | |
| [out] | |
| <a.C.x> -> m | |
| <a.C> -> m | |
| <a> -> m | |
| [case testDepsFromOverloadMod] | |
| # __dump_all__ | |
| import mod | |
| x = mod.f | |
| [file mod.py] | |
| from typing import overload, Any | |
| import submod | |
| @overload | |
| def f(x: int) -> submod.A: pass | |
| @overload | |
| def f(x: str) -> submod.B: pass | |
| def f(x) -> Any: | |
| y: submod.C | |
| y.x | |
| [file submod.py] | |
| class A: pass | |
| class B: pass | |
| class C: | |
| x: D | |
| class D: pass | |
| [out] | |
| <m.x> -> m | |
| <mod.f> -> m | |
| <mod> -> m | |
| <submod.A> -> <m.x>, <mod.f>, mod.f, submod.A | |
| <submod.B> -> <m.x>, <mod.f>, mod.f, submod.B | |
| <submod.C.x> -> mod.f | |
| <submod.C> -> mod.f, submod.C | |
| <submod.D> -> <submod.C.x>, submod, submod.D | |
| <submod> -> mod | |
| [case testDepsFromOverloadFunc] | |
| import mod | |
| def f() -> None: | |
| x = mod.f | |
| [file mod.py] | |
| from typing import overload | |
| @overload | |
| def f(x: int) -> None: pass | |
| @overload | |
| def f(x: str) -> str: pass | |
| def f(x): | |
| pass | |
| [out] | |
| <mod.f> -> m.f | |
| <mod> -> m, m.f | |
| [case testDepsToOverloadMod] | |
| from typing import overload, Any | |
| import mod | |
| @overload | |
| def f(x: int) -> None: pass | |
| @overload | |
| def f(x: str) -> str: pass | |
| def f(x: Any) -> Any: | |
| mod.g() | |
| [file mod.py] | |
| def g() -> int: | |
| pass | |
| [out] | |
| <mod.g> -> m.f | |
| <mod> -> m, m.f | |
| [case testDepsToOverloadFunc] | |
| from typing import overload, Any | |
| import mod | |
| def outer() -> None: | |
| @overload | |
| def f(x: int) -> mod.A: pass | |
| @overload | |
| def f(x: str) -> mod.B: pass | |
| def f(x: Any) -> Any: | |
| mod.g() | |
| [file mod.py] | |
| def g() -> int: | |
| pass | |
| class A: pass | |
| class B: pass | |
| [out] | |
| <mod.A> -> <m.outer>, m.outer | |
| <mod.B> -> <m.outer>, m.outer | |
| <mod.g> -> m.outer | |
| <mod> -> m, m.outer | |
| [case testDepsFromOverloadToOverload] | |
| from typing import overload, Any | |
| import mod | |
| def outer() -> None: | |
| @overload | |
| def f(x: int) -> None: pass | |
| @overload | |
| def f(x: str) -> str: pass | |
| def f(x: Any) -> Any: | |
| mod.g(str()) | |
| [file mod.py] | |
| from typing import overload | |
| @overload | |
| def g(x: int) -> None: pass | |
| @overload | |
| def g(x: str) -> str: pass | |
| def g(x): | |
| pass | |
| [out] | |
| <mod.g> -> m.outer | |
| <mod> -> m, m.outer | |
| [case testDepsFromOverloadToOverloadDefaultClass] | |
| from typing import overload, Any | |
| import mod | |
| class Outer: | |
| @overload | |
| def f(self, x: int) -> None: pass | |
| @overload | |
| def f(self, x: str, cb=mod.g) -> str: pass | |
| def f(self, *args: Any, **kwargs: Any) -> Any: | |
| pass | |
| [file mod.py] | |
| from typing import overload | |
| @overload | |
| def g(x: int) -> None: pass | |
| @overload | |
| def g(x: str) -> str: pass | |
| def g(x): | |
| pass | |
| [builtins fixtures/dict.pyi] | |
| [out] | |
| <m.Outer> -> m.Outer | |
| <mod.g> -> m.Outer.f | |
| <mod> -> m, m.Outer.f | |
| [case testDepsFromOverloadToOverloadDefaultNested] | |
| from typing import overload, Any | |
| import mod | |
| def outer() -> None: | |
| @overload | |
| def f(x: int) -> None: pass | |
| @overload | |
| def f(x: str, cb=mod.g) -> str: pass | |
| def f(*args: Any, **kwargs: Any) -> Any: | |
| pass | |
| [file mod.py] | |
| from typing import overload | |
| @overload | |
| def g(x: int) -> None: pass | |
| @overload | |
| def g(x: str) -> str: pass | |
| def g(x): | |
| pass | |
| [builtins fixtures/dict.pyi] | |
| [out] | |
| <mod.g> -> m.outer | |
| <mod> -> m, m.outer | |
| [case testDepsToOverloadGeneric] | |
| # __dump_all__ | |
| import mod | |
| from typing import overload, Any | |
| @overload | |
| def f(x: mod.TA) -> mod.TA: pass | |
| @overload | |
| def f(x: mod.TB, y: int) -> mod.TB: pass | |
| def f(*args: Any, **kwargs: Any) -> Any: | |
| pass | |
| [file mod.py] | |
| from typing import TypeVar | |
| import submod | |
| TA = TypeVar('TA', submod.A, submod.B) | |
| TB = TypeVar('TB', bound=submod.C) | |
| [file submod.py] | |
| class A: pass | |
| class B: pass | |
| class C: pass | |
| [builtins fixtures/dict.pyi] | |
| [out] | |
| <mod.TA> -> <m.f>, m.f | |
| <mod.TB> -> <m.f>, m.f | |
| <mod> -> m | |
| <submod.A> -> <m.f>, <mod.TA>, m.f, mod, submod.A | |
| <submod.B> -> <m.f>, <mod.TA>, m.f, mod, submod.B | |
| <submod.C> -> <m.f>, <mod.TB>, m.f, mod, submod.C | |
| <submod> -> mod | |
| [case testDepsOverloadBothExternalAndImplementationType] | |
| import mod | |
| from typing import overload | |
| @overload | |
| def f(x: mod.A) -> mod.A: pass | |
| @overload | |
| def f(x: mod.B) -> mod.B: pass | |
| def f(x: mod.Base) -> mod.Base: | |
| pass | |
| [file mod.py] | |
| class Base: | |
| pass | |
| class A(Base): | |
| pass | |
| class B(Base): | |
| pass | |
| [out] | |
| <mod.A> -> <m.f>, m.f | |
| <mod.B> -> <m.f>, m.f | |
| <mod.Base> -> <m.f>, m.f | |
| <mod> -> m | |
| [case testCustomIterator] | |
| class A: | |
| def __iter__(self) -> B: pass | |
| class B: | |
| def __iter__(self) -> B: pass | |
| def __next__(self) -> C: pass | |
| class C: | |
| pass | |
| def f() -> None: | |
| for x in A(): pass | |
| [out] | |
| <m.A.__getitem__> -> m.f | |
| <m.A.__init__> -> m.f | |
| <m.A.__iter__> -> m.f | |
| <m.A.__new__> -> m.f | |
| <m.A> -> m.A, m.f | |
| <m.B.__next__> -> m.f | |
| <m.B> -> <m.A.__iter__>, <m.B.__iter__>, m.A.__iter__, m.B, m.B.__iter__ | |
| <m.C> -> <m.B.__next__>, m.B.__next__, m.C | |
| [case testDepsLiskovClass] | |
| from mod import A, C | |
| class D(C): | |
| x: A | |
| [file mod.py] | |
| class C: | |
| x: B | |
| class B: | |
| pass | |
| class A(B): | |
| pass | |
| [out] | |
| <m.D.x> -> m | |
| <m.D> -> m.D | |
| <mod.A> -> <m.D.x>, m | |
| <mod.C.(abstract)> -> <m.D.__init__>, m | |
| <mod.C.__init__> -> <m.D.__init__> | |
| <mod.C.__new__> -> <m.D.__new__> | |
| <mod.C.x> -> <m.D.x> | |
| <mod.C> -> m, m.D | |
| <mod> -> m | |
| [case testDepsLiskovMethod] | |
| from mod import A, C | |
| class D(C): | |
| def __init__(self) -> None: | |
| self.x: A | |
| [file mod.py] | |
| class C: | |
| def __init__(self) -> None: | |
| self.x: B | |
| class B: | |
| pass | |
| class A(B): | |
| pass | |
| [out] | |
| <m.D.x> -> m.D.__init__ | |
| <m.D> -> m.D | |
| <mod.A> -> <m.D.x>, m, m.D.__init__ | |
| <mod.C.(abstract)> -> <m.D.__init__>, m | |
| <mod.C.__init__> -> <m.D.__init__>, m.D.__init__ | |
| <mod.C.__new__> -> <m.D.__new__> | |
| <mod.C.x> -> <m.D.x> | |
| <mod.C> -> m, m.D | |
| <mod> -> m | |
| [case testIndexedStarLvalue] | |
| from typing import List, Tuple | |
| class B: | |
| def __setitem__(self, i: int, v: List[str]) -> None: pass | |
| def g() -> Tuple[int, str, str]: pass | |
| def f(b: B) -> None: | |
| a, *b[0] = g() | |
| [builtins fixtures/list.pyi] | |
| [out] | |
| <m.B.__getitem__> -> m.f | |
| <m.B.__setitem__> -> m.f | |
| <m.B> -> <m.f>, m.B, m.f | |
| <m.g> -> m.f | |
| [case testLogicalDecorator] | |
| # flags: --logical-deps | |
| from mod import dec | |
| @dec | |
| def f() -> None: | |
| pass | |
| [file mod.py] | |
| from typing import Callable | |
| def dec(f: Callable[[], None]) -> Callable[[], None]: | |
| pass | |
| [out] | |
| <mod.dec> -> <m.f>, m | |
| [case testLogicalDecoratorWithArgs] | |
| # flags: --logical-deps | |
| from mod import dec | |
| @dec(str()) | |
| def f() -> None: | |
| pass | |
| [file mod.py] | |
| from typing import Callable | |
| def dec(arg: str) -> Callable[[Callable[[], None]], Callable[[], None]]: | |
| pass | |
| [out] | |
| <mod.dec> -> <m.f>, m | |
| [case testLogicalDecoratorMember] | |
| # flags: --logical-deps | |
| import mod | |
| @mod.dec | |
| def f() -> None: | |
| pass | |
| [file mod.py] | |
| from typing import Callable | |
| def dec(f: Callable[[], None]) -> Callable[[], None]: | |
| pass | |
| [out] | |
| <mod.dec> -> <m.f>, m | |
| <mod> -> m | |
| [case testLogicalDefinition] | |
| # flags: --logical-deps | |
| from mod import func | |
| b = func() | |
| [file mod.py] | |
| def func() -> int: | |
| pass | |
| [out] | |
| <m.b> -> m | |
| <mod.func> -> <m.b>, m | |
| [case testLogicalDefinitionIrrelevant] | |
| # flags: --logical-deps | |
| from mod import func | |
| def outer() -> None: | |
| a = func() | |
| b: int = func() | |
| c = int() | |
| c = func() | |
| [file mod.py] | |
| def func() -> int: | |
| pass | |
| [out] | |
| <m.b> -> m | |
| <m.c> -> m | |
| <mod.func> -> m, m.outer | |
| [case testLogicalDefinitionMember] | |
| # flags: --logical-deps | |
| import mod | |
| b = mod.func() | |
| [file mod.py] | |
| def func() -> int: | |
| pass | |
| [out] | |
| <m.b> -> m | |
| <mod.func> -> <m.b>, m | |
| <mod> -> m | |
| [case testLogicalDefinitionClass] | |
| # flags: --logical-deps | |
| from mod import Cls | |
| b = Cls() | |
| [file mod.py] | |
| class Base: | |
| def __init__(self) -> None: pass | |
| class Cls(Base): pass | |
| [out] | |
| <m.b> -> m | |
| <mod.Base.__init__> -> <m.b> | |
| <mod.Cls.__init__> -> m | |
| <mod.Cls.__new__> -> m | |
| <mod.Cls> -> <m.b>, m | |
| [case testLogicalBaseAttribute] | |
| # flags: --logical-deps | |
| from mod import C | |
| class D(C): | |
| x: int | |
| [file mod.py] | |
| class C: | |
| x: int | |
| y: int | |
| [out] | |
| <m.D.x> -> m | |
| <m.D> -> m.D | |
| <mod.C.x> -> <m.D.x> | |
| <mod.C> -> m, m.D | |
| [case testLogicalIgnoredImport1] | |
| # flags: --logical-deps --ignore-missing-imports | |
| import foo | |
| def f() -> None: | |
| foo.x | |
| [out] | |
| <foo.x> -> m.f | |
| <foo> -> m, m.f | |
| [case testLogicalIgnoredImport2] | |
| # flags: --logical-deps --ignore-missing-imports | |
| import foo.bar | |
| import a.b.c.d | |
| def f() -> None: | |
| foo.bar.x | |
| foo.bar.x.y | |
| a.b.c.d.e | |
| [out] | |
| <a.b.c.d.e> -> m.f | |
| <a.b.c.d> -> m, m.f | |
| <a.b.c> -> m.f | |
| <a.b> -> m.f | |
| <a> -> m.f | |
| <foo.bar.x.y> -> m.f | |
| <foo.bar.x> -> m.f | |
| <foo.bar> -> m, m.f | |
| <foo> -> m.f | |
| [case testLogicalIgnoredFromImport] | |
| # flags: --logical-deps --ignore-missing-imports | |
| from foo.bar import f, C | |
| def g() -> None: | |
| f() | |
| C.ff() | |
| def gg(x: C) -> None: | |
| z = x.y | |
| z.zz | |
| [out] | |
| <foo.bar.C.ff> -> m.g | |
| <foo.bar.C.y> -> m.gg | |
| <foo.bar.C> -> <m.gg>, m.g, m.gg | |
| <foo.bar.f> -> m.g | |
| [case testLogical__init__] | |
| # flags: --logical-deps | |
| class A: | |
| def __init__(self) -> None: pass | |
| class B(A): pass | |
| class C(B): pass | |
| class D(A): | |
| def __init__(self, x: int) -> None: pass | |
| def f() -> None: | |
| A() | |
| def g() -> None: | |
| C() | |
| def h() -> None: | |
| D(1) | |
| [out] | |
| <m.A.__init__> -> m.f | |
| <m.A.__new__> -> m.f | |
| <m.A> -> m, m.A, m.B, m.D, m.f | |
| <m.B> -> m, m.B, m.C | |
| <m.C.__init__> -> m.g | |
| <m.C.__new__> -> m.g | |
| <m.C> -> m.C, m.g | |
| <m.D.__init__> -> m.h | |
| <m.D.__new__> -> m.h | |
| <m.D> -> m.D, m.h | |
| [case testDataclassDeps] | |
| from dataclasses import dataclass | |
| Z = int | |
| @dataclass | |
| class A: | |
| x: Z | |
| @dataclass | |
| class B(A): | |
| y: int | |
| [builtins fixtures/dataclasses.pyi] | |
| [out] | |
| <m.A.(abstract)> -> <m.B.__init__>, m | |
| <m.A.__dataclass_fields__> -> <m.B.__dataclass_fields__> | |
| <m.A.__init__> -> <m.B.__init__>, m.B.__init__ | |
| <m.A.__match_args__> -> <m.B.__match_args__> | |
| <m.A.__mypy-replace> -> <m.B.__mypy-replace>, m, m.B.__mypy-replace | |
| <m.A.__new__> -> <m.B.__new__> | |
| <m.A.x> -> <m.B.x> | |
| <m.A.y> -> <m.B.y> | |
| <m.A> -> m, m.A, m.B | |
| <m.A[wildcard]> -> m | |
| <m.B.__mypy-replace> -> m | |
| <m.B.y> -> m | |
| <m.B> -> m.B | |
| <m.Z> -> m | |
| <dataclasses.dataclass> -> m | |
| <dataclasses> -> m | |
| [case testPEP695TypeAliasDeps] | |
| # flags: --python-version=3.12 | |
| from a import C, E | |
| type A = C | |
| type A2 = A | |
| type A3 = E | |
| [file a.py] | |
| class C: pass | |
| class D: pass | |
| type E = D | |
| [out] | |
| <m.A2> -> m | |
| <m.A3> -> m | |
| <m.A> -> m | |
| <a.C.__init__> -> m | |
| <a.C.__new__> -> m | |
| <a.C> -> m | |
| <a.E> -> m | |
| <a> -> m | |
| [builtins fixtures/tuple.pyi] | |
| [typing fixtures/typing-full.pyi] |