| -- Test cases for generating fine-grained dependencies for statements. |
| -- |
| -- The dependencies are used for fined-grained incremental checking. |
| -- |
| -- See the comment at the top of deps.test for more documentation. |
| |
| [case testIfStmt] |
| def f1() -> int: pass |
| def f2() -> None: pass |
| def f3() -> int: pass |
| def f4() -> None: pass |
| def f5() -> None: pass |
| |
| def g() -> None: |
| if f1(): |
| f2() |
| elif f3(): |
| f4() |
| else: |
| f5() |
| [out] |
| <m.f1> -> m.g |
| <m.f2> -> m.g |
| <m.f3> -> m.g |
| <m.f4> -> m.g |
| <m.f5> -> m.g |
| |
| [case testWhileStmt] |
| def f1() -> int: pass |
| def f2() -> None: pass |
| def f3() -> None: pass |
| |
| def g() -> None: |
| while f1(): |
| f2() |
| else: |
| f3() |
| [out] |
| <m.f1> -> m.g |
| <m.f2> -> m.g |
| <m.f3> -> m.g |
| |
| [case testAssertStmt] |
| def f1() -> int: pass |
| def f2() -> str: pass |
| def f3() -> int: pass |
| |
| def g() -> None: |
| assert f1(), f2() |
| assert f3() |
| [out] |
| <m.f1> -> m.g |
| <m.f2> -> m.g |
| <m.f3> -> m.g |
| |
| [case testRaiseStmt] |
| def f1() -> BaseException: pass |
| def f2() -> BaseException: pass |
| |
| def g1() -> None: |
| raise f1() |
| |
| def g2() -> None: |
| raise f1() from f2() |
| [builtins fixtures/exception.pyi] |
| [out] |
| <m.f1> -> m.g1, m.g2 |
| <m.f2> -> m.g2 |
| |
| [case testTryFinallyStmt] |
| def f1() -> None: pass |
| def f2() -> None: pass |
| |
| def g() -> None: |
| try: |
| f1() |
| finally: |
| f2() |
| [out] |
| <m.f1> -> m.g |
| <m.f2> -> m.g |
| |
| [case testForStmt] |
| from typing import Iterator |
| |
| class A: |
| def __iter__(self) -> Iterator[int]: pass |
| |
| def f1() -> None: pass |
| def f2() -> None: pass |
| |
| def g() -> None: |
| a: A |
| for x in a: |
| f1() |
| else: |
| f2() |
| [builtins fixtures/list.pyi] |
| [out] |
| <m.A.__getitem__> -> m.g |
| <m.A.__iter__> -> m.g |
| <m.A> -> m.A, m.g |
| <m.f1> -> m.g |
| <m.f2> -> m.g |
| |
| [case testTryExceptStmt] |
| class A(BaseException): pass |
| class B(BaseException): |
| def f(self) -> None: pass |
| |
| def f1() -> None: pass |
| def f2() -> None: pass |
| def f3() -> None: pass |
| |
| def g() -> None: |
| try: |
| f1() |
| except A: |
| f2() |
| except B as e: |
| e.f() |
| else: |
| f3() |
| [builtins fixtures/exception.pyi] |
| [out] |
| -- The dependencies on the ctor are basically spurious but not a problem |
| <m.A.__init__> -> m.g |
| <m.A.__new__> -> m.g |
| <m.A> -> m.A, m.g |
| <m.B.__init__> -> m.g |
| <m.B.__new__> -> m.g |
| <m.B.f> -> m.g |
| <m.B> -> m.B, m.g |
| <m.f1> -> m.g |
| <m.f2> -> m.g |
| <m.f3> -> m.g |
| |
| [case testTryExceptStmt2] |
| class A(BaseException): pass |
| class B(BaseException): |
| def f(self) -> None: pass |
| |
| def f1() -> None: pass |
| def f2() -> None: pass |
| |
| def g() -> None: |
| try: |
| f1() |
| except (A, B): |
| f2() |
| [builtins fixtures/exception.pyi] |
| [out] |
| -- The dependencies on the ctor are basically spurious but not a problem |
| <m.A.__init__> -> m.g |
| <m.A.__new__> -> m.g |
| <m.A> -> m.A, m.g |
| <m.B.__init__> -> m.g |
| <m.B.__new__> -> m.g |
| <m.B> -> m.B, m.g |
| <m.f1> -> m.g |
| <m.f2> -> m.g |
| |
| [case testWithStmt] |
| from typing import Any |
| class A: |
| def __enter__(self) -> 'B': pass |
| def __exit__(self, a, b, c) -> None: pass |
| |
| class B: |
| def f(self) -> None: pass |
| |
| def g() -> None: |
| a: A |
| with a as x: |
| x.f() |
| [out] |
| <m.A.__enter__> -> m.g |
| <m.A.__exit__> -> m.g |
| <m.A> -> m.A, m.g |
| <m.B.f> -> m.g |
| <m.B> -> <m.A.__enter__>, m.A.__enter__, m.B |
| |
| [case testWithStmt2] |
| from typing import Any |
| class A: |
| def __enter__(self) -> 'C': pass |
| def __exit__(self, a, b, c) -> None: pass |
| class B: |
| def __enter__(self) -> 'D': pass |
| def __exit__(self, a, b, c) -> None: pass |
| |
| class C: pass |
| class D: pass |
| |
| def g() -> None: |
| a: A |
| b: B |
| with a as x, b as y: |
| pass |
| [out] |
| <m.A.__enter__> -> m.g |
| <m.A.__exit__> -> m.g |
| <m.A> -> m.A, m.g |
| <m.B.__enter__> -> m.g |
| <m.B.__exit__> -> m.g |
| <m.B> -> m.B, m.g |
| <m.C> -> <m.A.__enter__>, m.A.__enter__, m.C |
| <m.D> -> <m.B.__enter__>, m.B.__enter__, m.D |
| |
| [case testWithStmtAnnotation] |
| from typing import Any |
| class A: |
| def __enter__(self) -> Any: pass |
| def __exit__(self, a, b, c) -> None: pass |
| |
| class B: pass |
| |
| def f(b: B) -> None: pass |
| |
| def g() -> None: |
| a: A |
| with a as x: # type: B |
| f(x) |
| [out] |
| <m.A.__enter__> -> m.g |
| <m.A.__exit__> -> m.g |
| <m.A> -> m.A, m.g |
| <m.B> -> <m.f>, m.B, m.f, m.g |
| <m.f> -> m.g |
| |
| [case testForStmtAnnotation] |
| class A: |
| def __iter__(self): pass |
| |
| class B: |
| def f(self) -> None: pass |
| |
| def g() -> None: |
| a: A |
| for x in a: # type: B |
| x.f() |
| [builtins fixtures/list.pyi] |
| [out] |
| <m.A.__getitem__> -> m.g |
| <m.A.__iter__> -> m.g |
| <m.A> -> m.A, m.g |
| <m.B.f> -> m.g |
| <m.B> -> m.B, m.g |
| |
| [case testMultipleAssignment] |
| from typing import Iterator |
| class A: |
| def __iter__(self) -> Iterator[int]: pass |
| |
| def f() -> None: |
| a: A |
| x, y = a |
| [out] |
| <m.A.__iter__> -> <m.A>, m.f |
| <m.A> -> m.A, m.f, typing.Iterable |
| |
| [case testMultipleLvalues] |
| class A: |
| def f(self) -> None: |
| self.x = 1 |
| self.y = 1 |
| |
| def g() -> None: |
| a: A |
| a.x = a.y = 1 |
| [out] |
| <m.A.x> -> m.A.f, m.g |
| <m.A.y> -> m.A.f, m.g |
| <m.A> -> m.A, m.g |
| |
| [case testNestedLvalues] |
| class A: |
| def f(self) -> None: |
| self.x = 1 |
| self.y = '' |
| |
| def g() -> None: |
| a: A |
| a.x, a.y = 1, '' |
| [out] |
| <m.A.x> -> m.A.f, m.g |
| <m.A.y> -> m.A.f, m.g |
| <m.A> -> m.A, m.g |
| |
| [case testForAndSetItem] |
| class A: |
| def __setitem__(self, x: int, y: int) -> None: pass |
| |
| def f(): pass |
| |
| def g() -> None: |
| a: A |
| for a[0] in f(): |
| pass |
| [builtins fixtures/list.pyi] |
| [out] |
| <m.A.__getitem__> -> m.g |
| <m.A.__setitem__> -> m.g |
| <m.A> -> m.A, m.g |
| <m.f> -> m.g |
| |
| [case testMultipleAssignmentAndFor] |
| from typing import Iterator, Iterable |
| |
| class A: |
| def f(self) -> None: |
| self.x = 1 |
| self.y = 1 |
| |
| class B: |
| def __iter__(self) -> Iterator[int]: pass |
| |
| def f() -> Iterable[B]: pass |
| |
| def g() -> None: |
| a: A |
| for a.x, a.y in f(): |
| pass |
| [builtins fixtures/list.pyi] |
| [out] |
| <m.A.x> -> m.A.f, m.g |
| <m.A.y> -> m.A.f, m.g |
| <m.A> -> m.A, m.g |
| <m.B.__getitem__> -> m.g |
| <m.B.__iter__> -> <m.B>, m.g |
| <m.B> -> <m.f>, m.B, m.f, typing.Iterable |
| <m.f> -> m.g |
| |
| [case testNestedSetItem] |
| class A: |
| def __setitem__(self, x: int, y: int) -> None: pass |
| class B: |
| def __setitem__(self, x: int, y: int) -> None: pass |
| |
| def f(): pass |
| |
| def g() -> None: |
| a: A |
| b: B |
| a[0], b[0] = f() |
| [out] |
| <m.A.__getitem__> -> m.g |
| <m.A.__setitem__> -> m.g |
| <m.A> -> m.A, m.g |
| <m.B.__getitem__> -> m.g |
| <m.B.__setitem__> -> m.g |
| <m.B> -> m.B, m.g |
| <m.f> -> m.g |
| |
| [case testOperatorAssignmentStmt] |
| class A: |
| def __add__(self, other: 'B') -> 'A': pass |
| |
| class B: pass |
| |
| def f() -> B: pass |
| |
| def g() -> None: |
| a: A |
| a += f() |
| [out] |
| <m.A.__add__> -> m.g |
| <m.A.__iadd__> -> m.g |
| <m.A> -> <m.A.__add__>, m.A, m.A.__add__, m.g |
| <m.B> -> <m.A.__add__>, <m.f>, m.A.__add__, m.B, m.f |
| <m.f> -> m.g |
| |
| [case testOperatorAssignmentStmtSetItem] |
| class A: |
| def __add__(self, other: 'B') -> 'A': pass |
| |
| class B: pass |
| |
| class C: |
| def __getitem__(self, x: int) -> A: pass |
| def __setitem__(self, x: int, y: A) -> None: pass |
| |
| def f() -> int: pass |
| |
| def g() -> None: |
| b: B |
| c: C |
| c[f()] += b |
| [out] |
| <m.A.__add__> -> m.g |
| <m.A.__iadd__> -> m.g |
| <m.A> -> <m.A.__add__>, <m.C.__getitem__>, <m.C.__setitem__>, m.A, m.A.__add__, m.C.__getitem__, m.C.__setitem__ |
| <m.B> -> <m.A.__add__>, m.A.__add__, m.B, m.g |
| <m.C.__getitem__> -> m.g |
| <m.C.__setitem__> -> m.g |
| <m.C> -> m.C, m.g |
| <m.f> -> m.g |
| |
| [case testYieldStmt] |
| from typing import Iterator |
| |
| class A: pass |
| |
| def f1() -> A: pass |
| |
| def g() -> Iterator[A]: |
| yield f1() |
| [builtins fixtures/list.pyi] |
| [out] |
| <m.A> -> <m.f1>, <m.g>, m.A, m.f1, m.g |
| <m.f1> -> m.g |
| |
| [case testDelStmt] |
| class A: |
| def f(self) -> None: |
| self.x = 1 |
| |
| def f() -> A: pass |
| |
| def g() -> None: |
| del f().x |
| [out] |
| <m.A.x> -> m.A.f, m.g |
| <m.A> -> <m.f>, m.A, m.f |
| <m.f> -> m.g |
| |
| [case testDelStmtWithIndexing] |
| class A: |
| def __delitem__(self, x: int) -> None: pass |
| |
| def f1() -> A: pass |
| def f2() -> int: pass |
| |
| def g() -> None: |
| del f1()[f2()] |
| [out] |
| <m.A.__delitem__> -> m.g |
| -- __getitem__ is redundant but harmless |
| <m.A.__getitem__> -> m.g |
| <m.A> -> <m.f1>, m.A, m.f1 |
| <m.f1> -> m.g |
| <m.f2> -> m.g |
| |
| [case testYieldFrom] |
| from typing import Iterator |
| class A: |
| def __iter__(self) -> Iterator[int]: pass |
| def f() -> Iterator[int]: |
| yield from A() |
| [out] |
| <m.A.__init__> -> m.f |
| <m.A.__iter__> -> <m.A>, m.f |
| <m.A.__new__> -> m.f |
| <m.A> -> m.A, m.f, typing.Iterable |
| |
| [case testFunctionDecorator] |
| from typing import Callable |
| def dec(f: Callable[[int], int]) -> Callable[[str], str]: |
| pass |
| |
| def f() -> int: pass |
| |
| @dec |
| def g(x: int) -> int: |
| return f() |
| [out] |
| <m.dec> -> m |
| <m.f> -> m.g |
| <m.g> -> m |
| |
| [case testMethodDecorator] |
| from typing import Callable, Any |
| def dec(f: Callable[[Any, int], int]) -> Callable[[Any, str], str]: |
| pass |
| |
| def f() -> int: pass |
| |
| class A: |
| @dec |
| def g(self, x: int) -> int: |
| return f() |
| [out] |
| <m.A.g> -> m |
| <m.A> -> m.A |
| <m.dec> -> m |
| <m.f> -> m.A.g |
| |
| [case testNestedFunction] |
| class A: pass |
| |
| def h() -> None: pass |
| |
| def f() -> None: |
| def g(x: A) -> None: |
| h() |
| [out] |
| <m.A> -> <m.f>, m.A, m.f |
| <m.h> -> m.f |
| |
| [case testPlatformCheck] |
| import a |
| import sys |
| |
| def f() -> int: |
| if sys.platform == 'nonexistent': |
| return a.g() |
| else: |
| return 1 |
| [file a.py] |
| [builtins fixtures/ops.pyi] |
| [out] |
| <a> -> m |
| <sys.platform> -> m.f |
| <sys> -> m, m.f |
| |
| [case testOverload] |
| from typing import overload |
| |
| class A: pass |
| class B(A): pass |
| |
| @overload |
| def f(x: B) -> B: ... |
| @overload |
| def f(x: A) -> A: ... |
| |
| def f(x: A) -> A: |
| g() |
| return x |
| |
| def g() -> None: pass |
| [builtins fixtures/isinstancelist.pyi] |
| [out] |
| <m.A.(abstract)> -> <m.B.__init__>, m |
| <m.A.__init__> -> <m.B.__init__> |
| <m.A.__new__> -> <m.B.__new__> |
| <m.A> -> <m.f>, m, m.A, m.B, m.f |
| <m.B> -> <m.f>, m.B, m.f |
| <m.g> -> m.f |
| |
| [case testOverloadedMethod] |
| from typing import overload |
| |
| class A: pass |
| class B(A): pass |
| |
| class C: |
| @overload |
| def f(self, x: B) -> B: ... |
| @overload |
| def f(self, x: A) -> A: ... |
| |
| def f(self, x: A) -> A: |
| self.g() |
| return x |
| |
| def g(self) -> None: pass |
| [builtins fixtures/isinstancelist.pyi] |
| [out] |
| <m.A.(abstract)> -> <m.B.__init__>, m |
| <m.A.__init__> -> <m.B.__init__> |
| <m.A.__new__> -> <m.B.__new__> |
| <m.A> -> <m.C.f>, m, m.A, m.B, m.C.f |
| <m.B> -> <m.C.f>, m.B, m.C.f |
| <m.C.g> -> m.C.f |
| <m.C> -> m.C |
| |
| [case testConditionalFunctionDefinition] |
| import sys |
| |
| class A: pass |
| class B: pass |
| |
| if sys.platform == 'nonexistent': |
| def f(x: A) -> None: |
| g() |
| else: |
| def f(x: B) -> None: |
| h() |
| |
| def g() -> None: pass |
| def h() -> None: pass |
| [builtins fixtures/ops.pyi] |
| [out] |
| <m.A> -> m.A |
| <m.B> -> <m.f>, m.B, m.f |
| <m.h> -> m.f |
| <sys.platform> -> m |
| <sys> -> m |
| |
| [case testConditionalMethodDefinition] |
| import sys |
| |
| class A: pass |
| class B: pass |
| |
| class C: |
| if sys.platform == 'nonexistent': |
| def f(self, x: A) -> None: |
| self.g() |
| else: |
| def f(self, x: B) -> None: |
| self.h() |
| |
| def g(self) -> None: pass |
| def h(self) -> None: pass |
| [builtins fixtures/ops.pyi] |
| [out] |
| <m.A> -> m.A |
| <m.B> -> <m.C.f>, m.B, m.C.f |
| <m.C.h> -> m.C.f |
| <m.C> -> m.C |
| <sys.platform> -> m |
| <sys> -> m |
| |
| [case testNewType] |
| from typing import NewType |
| from m import C |
| |
| N = NewType('N', C) |
| |
| def f(n: N) -> None: |
| pass |
| [file m.py] |
| class C: |
| x: int |
| [out] |
| <m.N> -> <m.f>, m, m.f |
| <m.C.(abstract)> -> <m.N.__init__>, m |
| <m.C.__init__> -> <m.N.__init__> |
| <m.C.__new__> -> <m.N.__new__> |
| <m.C.x> -> <m.N.x> |
| <m.C> -> m, m.N |
| <m> -> m |