Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use error subcodes to differentiate import errors #14740

Merged
merged 3 commits into from
Aug 10, 2023
Merged
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
11 changes: 10 additions & 1 deletion mypy/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -2776,7 +2776,16 @@ def module_not_found(
else:
daemon = manager.options.fine_grained_incremental
msg, notes = reason.error_message_templates(daemon)
errors.report(line, 0, msg.format(module=target), code=codes.IMPORT)
if reason == ModuleNotFoundReason.NOT_FOUND:
code = codes.IMPORT_NOT_FOUND
elif (
reason == ModuleNotFoundReason.FOUND_WITHOUT_TYPE_HINTS
or reason == ModuleNotFoundReason.APPROVED_STUBS_NOT_INSTALLED
):
code = codes.IMPORT_UNTYPED
else:
code = codes.IMPORT
errors.report(line, 0, msg.format(module=target), code=code)
top_level, second_level = get_top_two_prefixes(target)
if second_level in legacy_bundled_packages or second_level in non_bundled_packages:
top_level = second_level
Expand Down
6 changes: 6 additions & 0 deletions mypy/errorcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ def __str__(self) -> str:
IMPORT: Final = ErrorCode(
"import", "Require that imported module can be found or has stubs", "General"
)
IMPORT_NOT_FOUND: Final = ErrorCode(
"import-not-found", "Require that imported module can be found", "General", sub_code_of=IMPORT
)
IMPORT_UNTYPED: Final = ErrorCode(
"import-untyped", "Require that imported module has stubs", "General", sub_code_of=IMPORT
)
NO_REDEF: Final = ErrorCode("no-redef", "Check that each name is defined once", "General")
FUNC_RETURNS_VALUE: Final = ErrorCode(
"func-returns-value", "Check that called function returns a value in value context", "General"
Expand Down
8 changes: 6 additions & 2 deletions mypy/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from typing_extensions import Final, Literal, TypeAlias as _TypeAlias

from mypy import errorcodes as codes
from mypy.errorcodes import IMPORT, ErrorCode
from mypy.errorcodes import IMPORT, IMPORT_NOT_FOUND, IMPORT_UNTYPED, ErrorCode
from mypy.message_registry import ErrorMessage
from mypy.options import Options
from mypy.scope import Scope
Expand Down Expand Up @@ -491,7 +491,11 @@ def add_error_info(self, info: ErrorInfo) -> None:
if info.message in self.only_once_messages:
return
self.only_once_messages.add(info.message)
if self.seen_import_error and info.code is not IMPORT and self.has_many_errors():
if (
self.seen_import_error
and info.code not in (IMPORT, IMPORT_UNTYPED, IMPORT_NOT_FOUND)
and self.has_many_errors()
):
# Missing stubs can easily cause thousands of errors about
# Any types, especially when upgrading to mypy 0.900,
# which no longer bundles third-party library stubs. Avoid
Expand Down
14 changes: 7 additions & 7 deletions test-data/unit/check-errorcodes.test
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ from defusedxml import xyz # type: ignore[import]

[case testErrorCodeBadIgnore]
import nostub # type: ignore xyz # E: Invalid "type: ignore" comment [syntax] \
# E: Cannot find implementation or library stub for module named "nostub" [import] \
# E: Cannot find implementation or library stub for module named "nostub" [import-not-found] \
# N: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
import nostub # type: ignore[ # E: Invalid "type: ignore" comment [syntax]
import nostub # type: ignore[foo # E: Invalid "type: ignore" comment [syntax]
Expand Down Expand Up @@ -209,7 +209,7 @@ def f(x, # type: int # type: ignore[
pass
[out]
main:2: error: Invalid "type: ignore" comment [syntax]
main:2: error: Cannot find implementation or library stub for module named "nostub" [import]
main:2: error: Cannot find implementation or library stub for module named "nostub" [import-not-found]
main:2: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
main:3: error: Invalid "type: ignore" comment [syntax]
main:4: error: Invalid "type: ignore" comment [syntax]
Expand Down Expand Up @@ -520,12 +520,12 @@ if int() is str(): # E: Non-overlapping identity check (left operand type: "int
[builtins fixtures/primitives.pyi]

[case testErrorCodeMissingModule]
from defusedxml import xyz # E: Cannot find implementation or library stub for module named "defusedxml" [import]
from nonexistent import foobar # E: Cannot find implementation or library stub for module named "nonexistent" [import]
import nonexistent2 # E: Cannot find implementation or library stub for module named "nonexistent2" [import]
from nonexistent3 import * # E: Cannot find implementation or library stub for module named "nonexistent3" [import]
from defusedxml import xyz # E: Cannot find implementation or library stub for module named "defusedxml" [import-not-found]
from nonexistent import foobar # E: Cannot find implementation or library stub for module named "nonexistent" [import-not-found]
import nonexistent2 # E: Cannot find implementation or library stub for module named "nonexistent2" [import-not-found]
from nonexistent3 import * # E: Cannot find implementation or library stub for module named "nonexistent3" [import-not-found]
from pkg import bad # E: Module "pkg" has no attribute "bad" [attr-defined]
from pkg.bad2 import bad3 # E: Cannot find implementation or library stub for module named "pkg.bad2" [import] \
from pkg.bad2 import bad3 # E: Cannot find implementation or library stub for module named "pkg.bad2" [import-not-found] \
# N: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
[file pkg/__init__.py]

Expand Down