| -- Test cases for building caches for fine-grained mode using incremental | |
| -- builds. | |
| -- | |
| -- These tests are run only with the cache. | |
| -- | |
| -- '# num_build_steps: N' specifies how many regular build steps (without the daemon) | |
| -- to do before switching to running using the daemon. Default is 1. | |
| -- Add file | |
| -- -------- | |
| [case testIncrCacheBasic1] | |
| # num_build_steps: 2 | |
| import a | |
| [file a.py] | |
| from b import x | |
| def f() -> int: | |
| return 0 | |
| [file b.py] | |
| x = 1 | |
| [file a.py.2] | |
| from b import x | |
| def f() -> int: | |
| return 0 + x | |
| [file b.py.3] | |
| x = 'hi' | |
| [out] | |
| == | |
| == | |
| a.py:3: error: Unsupported operand types for + ("int" and "str") | |
| [case testIncrCacheBasic2] | |
| # num_build_steps: 2 | |
| import a | |
| [file a.py] | |
| from b import x | |
| def f() -> int: | |
| return 0+x | |
| [file b.py] | |
| x = 1 | |
| [file b.py.2] | |
| from c import x | |
| [file c.py.2] | |
| x = 1 | |
| [file c.py.3] | |
| x = 'hi' | |
| [out] | |
| == | |
| == | |
| a.py:3: error: Unsupported operand types for + ("int" and "str") | |
| [case testIncrCacheDoubleChange1] | |
| # num_build_steps: 2 | |
| import b | |
| import c | |
| [file a.py] | |
| def f(x: int) -> None: | |
| pass | |
| [file b.py] | |
| from a import f | |
| f(10) | |
| [file c.py] | |
| from a import f | |
| f(10) | |
| [file a.py.2] | |
| def f(x: int) -> None: | |
| pass | |
| # nothing changed | |
| [file a.py.3] | |
| def f(x: str) -> None: | |
| pass | |
| [out] | |
| == | |
| == | |
| c.py:2: error: Argument 1 to "f" has incompatible type "int"; expected "str" | |
| b.py:2: error: Argument 1 to "f" has incompatible type "int"; expected "str" | |
| [case testIncrCacheProtocol1] | |
| # num_build_steps: 2 | |
| import a | |
| [file a.py] | |
| import b | |
| from typing import Protocol | |
| class P(Protocol): | |
| x: int | |
| def f() -> None: | |
| def g(x: P) -> None: | |
| pass | |
| g(b.C()) | |
| [file c.py] | |
| [file c.py.2] | |
| # yo | |
| [file b.py] | |
| class C: | |
| x: int | |
| [file b.py.3] | |
| class C: | |
| x: str | |
| -- If we did a *full* reload (because the proto cache failed to load), | |
| -- nothing would show up as stale | |
| [stale2 b] | |
| [rechecked2 a, b] | |
| [out] | |
| == | |
| == | |
| a.py:8: error: Argument 1 to "g" has incompatible type "C"; expected "P" | |
| a.py:8: note: Following member(s) of "C" have conflicts: | |
| a.py:8: note: x: expected "int", got "str" | |
| [case testIncrCacheProtocol2] | |
| # num_build_steps: 3 | |
| import a | |
| [file a.py] | |
| import b | |
| from typing import Protocol | |
| class P(Protocol): | |
| x: int | |
| class Q(Protocol): | |
| x: int | |
| def f() -> None: | |
| def g(x: P) -> None: | |
| pass | |
| g(b.C()) | |
| [file c.py] | |
| [file c.py.2] | |
| # uh | |
| [file c.py.3] | |
| from a import Q | |
| import b | |
| def f() -> None: | |
| def g(x: Q) -> None: | |
| pass | |
| g(b.C()) | |
| [file b.py] | |
| class C: | |
| x: int | |
| [file b.py.4] | |
| class C: | |
| x: str | |
| -- If we did a *full* reload (because the proto cache failed to load), | |
| -- nothing would show up as stale | |
| [stale3 b] | |
| [rechecked3 a, b, c] | |
| [out] | |
| == | |
| == | |
| == | |
| c.py:6: error: Argument 1 to "g" has incompatible type "C"; expected "Q" | |
| c.py:6: note: Following member(s) of "C" have conflicts: | |
| c.py:6: note: x: expected "int", got "str" | |
| a.py:10: error: Argument 1 to "g" has incompatible type "C"; expected "P" | |
| a.py:10: note: Following member(s) of "C" have conflicts: | |
| a.py:10: note: x: expected "int", got "str" | |
| [case testIncrCacheProtocol3] | |
| # num_build_steps: 2 | |
| import a | |
| [file a.py] | |
| import b | |
| from typing import Protocol | |
| class P(Protocol): | |
| x: int | |
| def f() -> None: | |
| def g(x: P) -> None: | |
| pass | |
| g(b.C()) | |
| [file c.py] | |
| [file c.py.2] | |
| # yo | |
| [file b.py] | |
| class C: | |
| x: int | |
| [file b.py.3] | |
| class C: | |
| x: int | |
| y: int | |
| [file b.py.4] | |
| class C: | |
| x: str | |
| y: int | |
| -- If we did a *full* reload (because the proto cache failed to load), | |
| -- nothing would show up as stale | |
| [stale2 b] | |
| [rechecked2 b] | |
| [stale3 b] | |
| [rechecked3 a, b] | |
| [out] | |
| == | |
| == | |
| == | |
| a.py:8: error: Argument 1 to "g" has incompatible type "C"; expected "P" | |
| a.py:8: note: Following member(s) of "C" have conflicts: | |
| a.py:8: note: x: expected "int", got "str" | |
| [case testIncrCacheBustedProtocol] | |
| # flags: --no-sqlite-cache | |
| [file a.py] | |
| [file b.py] | |
| -- This is a heinous hack, but we simulate having a invalid cache by clobbering | |
| -- the proto deps file with something with mtime mismatches. | |
| [file ../.mypy_cache/3.10/@deps.meta.json.2] | |
| {"snapshot": {"__main__": "a7c958b001a45bd6a2a320f4e53c4c16", "a": "d41d8cd98f00b204e9800998ecf8427e", "b": "d41d8cd98f00b204e9800998ecf8427e", "builtins": "c532c89da517a4b779bcf7a964478d67"}, "deps_meta": {"@root": {"path": "@root.deps.json", "mtime": 0}, "__main__": {"path": "__main__.deps.json", "mtime": 0}, "a": {"path": "a.deps.json", "mtime": 0}, "b": {"path": "b.deps.json", "mtime": 0}, "builtins": {"path": "builtins.deps.json", "mtime": 0}}} | |
| [file b.py.2] | |
| # uh | |
| -- A full reload shows up as nothing getting rechecked by fine-grained mode. | |
| -- If we did not do a full reload, b would be stale and checked in fine-grained mode | |
| [stale] | |
| [rechecked] | |
| [out] | |
| == | |
| [case testInvalidateCachePart] | |
| # flags: --no-sqlite-cache | |
| # cmd: mypy a1.py a2.py b.py p/__init__.py p/c.py | |
| [file a1.py] | |
| import p | |
| from b import x | |
| from p.c import C | |
| [file a2.py] | |
| import p | |
| from b import x | |
| from p.c import C | |
| [file b.py] | |
| x = 10 | |
| [file p/__init__.py] | |
| [file p/c.py] | |
| class C: pass | |
| [delete ../.mypy_cache/3.10/b.meta.ff.2] | |
| [delete ../.mypy_cache/3.10/p/c.meta.ff.2] | |
| [out] | |
| == |