From 73c5bf1783a31d9b44e3308a3b40078ed9a08795 Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Mon, 6 Apr 2020 13:16:01 -0700 Subject: [PATCH] Fix crash when the same file is processed under multiple names Fixes #4881. --- mypy/build.py | 16 ++++++++++++++++ test-data/unit/cmdline.test | 15 +++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/mypy/build.py b/mypy/build.py index 2a5bb16af7ca..921dcd968546 100644 --- a/mypy/build.py +++ b/mypy/build.py @@ -2736,6 +2736,11 @@ def load_graph(sources: List[BuildSource], manager: BuildManager, graph[st.id] = st new.append(st) entry_points.add(bs.module) + + # Note: Running this each time could be slow in the daemon. If it's a problem, we + # can do more work to maintain this incrementally. + seen_files = {st.path: st for st in graph.values() if st.path} + # Collect dependencies. We go breadth-first. # More nodes might get added to new as we go, but that's fine. for st in new: @@ -2781,6 +2786,17 @@ def load_graph(sources: List[BuildSource], manager: BuildManager, if dep in st.dependencies_set: st.suppress_dependency(dep) else: + if newst.path in seen_files: + manager.errors.report( + -1, 0, + "Source file found twice under different module names: '{}' and '{}'". + format(seen_files[newst.path].id, newst.id), + blocker=True) + manager.errors.raise_error() + + if newst.path: + seen_files[newst.path] = newst + assert newst.id not in graph, newst.id graph[newst.id] = newst new.append(newst) diff --git a/test-data/unit/cmdline.test b/test-data/unit/cmdline.test index fb70f80e837f..9bcb66a78a7f 100644 --- a/test-data/unit/cmdline.test +++ b/test-data/unit/cmdline.test @@ -1067,3 +1067,18 @@ test.py:5: note: Subscripting classes that are not generic at runtime may requir [out] mypy: stubgen does not support .pyd files: 'a.pyd' == Return code: 2 + +[case testDuplicateModules] +# cmd: mypy src +[file mypy.ini] +\[mypy] +mypy_path = src +[file src/__init__.py] +[file src/a.py] +import foo.bar +[file src/foo/__init__.py] +[file src/foo/bar.py] +1+'x' +[out] +src/foo/bar.py: error: Source file found twice under different module names: 'src.foo.bar' and 'foo.bar' +== Return code: 2