blob: c3295b79e4edd3cd69194775b65c0e1cf4eaee0b [file] [log] [blame] [edit]
-- 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 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 "A" and "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
[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]
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]
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 mypy_extensions 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]
[out]
<m.Point.__init__> -> m
<m.Point.__new__> -> m
<m.Point> -> <m.foo>, <m.p>, m, m.foo
<m.p> -> m
[case testTypedDict2]
from mypy_extensions 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]
[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 mypy_extensions 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]
[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 testDecoratorDepsDeeepNested]
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 testDataclassDepsOldVersion]
# flags: --python-version 3.7
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.__mypy-replace> -> <m.B.__mypy-replace>, 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.y> -> m
<m.B> -> m.B
<m.Z> -> m
<dataclasses.dataclass> -> m
<dataclasses> -> m
[case testDataclassDeps]
# flags: --python-version 3.10
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.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.y> -> m
<m.B> -> m.B
<m.Z> -> m
<dataclasses.dataclass> -> m
<dataclasses> -> m