Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions mypy/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,16 @@ def report(
return info

def _add_error_info(self, file: str, info: ErrorInfo) -> None:
assert file not in self.flushed_files
# A file can be revisited under a second module name after an earlier
# pass has flushed its diagnostics. Do not duplicate an error that has
# already been emitted for the same physical file, even if the two
# module states use different path spellings.
normalized_file = os.path.normcase(os.path.abspath(file))
if any(
os.path.normcase(os.path.abspath(flushed_file)) == normalized_file
for flushed_file in self.flushed_files
):
return
# process the stack of ErrorWatchers before modifying any internal state
# in case we need to filter out the error entirely
if self._filter_error(file, info):
Expand Down Expand Up @@ -1094,7 +1103,10 @@ def format_messages(

Use a form suitable for displaying to the user.
"""
self.flushed_files.add(path)
normalized_path = os.path.normcase(os.path.abspath(path))
if normalized_path in self.flushed_files:
return []
self.flushed_files.add(normalized_path)
if formatter is not None:
errors = create_errors(error_tuples)
return [formatter.report_error(err) for err in errors]
Expand Down Expand Up @@ -1129,7 +1141,7 @@ def new_messages(self) -> list[str]:
"""
msgs = []
for path in self.error_info_map.keys():
if path not in self.flushed_files:
if os.path.normcase(os.path.abspath(path)) not in self.flushed_files:
error_tuples = self.file_messages(path)
msgs.extend(
self.format_messages(path, error_tuples, formatter=self.error_formatter)
Expand Down
20 changes: 20 additions & 0 deletions test-data/unit/cmdline.test
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,26 @@ src/foo/bar.py: note: a) adding `__init__.py` somewhere,
src/foo/bar.py: note: b) using `--explicit-package-bases` or adjusting `MYPYPATH`
== Return code: 2

[case testDuplicatePackageRootsReportsTypeError]
# cmd: mypy --config-file pyproject.toml
[file pyproject.toml]
\[tool.mypy]
python_version = "3.10"
strict = true
mypy_path = ["src", "src/outer/inner"]
packages = ["outer", "example"]
explicit_package_bases = true
[file src/outer/__init__.py]
[file src/outer/inner/example/__init__.py]
[file src/outer/inner/example/module.py]
def takes_int(value: int) -> None:
pass

def broken() -> None:
takes_int("not an int")
[out]
src/outer/inner/example/module.py:5: error: Argument 1 to "takes_int" has incompatible type "str"; expected "int"

[case testEnableInvalidErrorCode]
# cmd: mypy --enable-error-code YOLO test.py
[file test.py]
Expand Down
Loading