diff --git a/mypy/dmypy_server.py b/mypy/dmypy_server.py index 066fbf9bed2d..fe16536fa403 100644 --- a/mypy/dmypy_server.py +++ b/mypy/dmypy_server.py @@ -769,7 +769,7 @@ def find_reachable_changed_modules( state = graph[nxt.module] ancestors = state.ancestors or [] for dep in state.dependencies + ancestors: - if dep not in seen: + if dep not in seen and dep in graph: seen.add(dep) worklist.append(BuildSource(graph[dep].path, graph[dep].id, followed=True)) return changed, new_files @@ -779,7 +779,11 @@ def direct_imports( ) -> list[BuildSource]: """Return the direct imports of module not included in seen.""" state = graph[module[0]] - return [BuildSource(graph[dep].path, dep, followed=True) for dep in state.dependencies] + return [ + BuildSource(graph[dep].path, dep, followed=True) + for dep in state.dependencies + if dep in graph + ] def find_added_suppressed( self, graph: mypy.build.Graph, seen: set[str], search_paths: SearchPaths diff --git a/test-data/unit/daemon.test b/test-data/unit/daemon.test index 448af5d08002..5fb4eaca55d8 100644 --- a/test-data/unit/daemon.test +++ b/test-data/unit/daemon.test @@ -802,3 +802,36 @@ Found 1 error in 1 file (checked 1 source file) [file test.py] from xml.etree.ElementTree import Element 1 + 'a' + +[case testDaemonRecheckMissingGraphDependency] +-- Dropping pkg.tests from the graph leaves a stale ancestors edge behind, which +-- a later recheck used to dereference unconditionally (KeyError: 'pkg.tests'). +$ dmypy start -- --no-error-summary +Daemon started +$ dmypy check src/ +src/pkg/example.py:2: error: Name "x" already defined on line 1 [no-redef] +== Return code: 1 +$ dmypy recheck +src/pkg/example.py:2: error: Incompatible import of "x" (imported name has type "int", local name has type "str") [assignment] +== Return code: 1 +$ dmypy recheck +src/pkg/example.py:2: error: Incompatible import of "x" (imported name has type "int", local name has type "str") [assignment] +== Return code: 1 +[file mypy.ini] +\[mypy] +follow_imports = normal +mypy_path = src +files = src/pkg/ +exclude = (?x)( + \./.* + | tests + ) +\[mypy-pkg.tests.*] +follow_imports = skip +[file src/pkg/__init__.py] +[file src/pkg/example.py] +x = "1" +from pkg.tests.test_something import x +[file src/pkg/tests/__init__.py] +[file src/pkg/tests/test_something.py] +x = 1