Skip to content

Commit

Permalink
Make per-module ignore_missing_imports work for libs which had bundle…
Browse files Browse the repository at this point in the history
…d stubs

This makes `ignore_missing_imports` special by making it work a bit
differently, depending on whether it's set globally or per module.

The new behavior is less surprising. This makes it possible to ignore
arbitrary missing third-party stub packages, even those which used to
have bundled stubs.

Fixes #10283.
  • Loading branch information
JukkaL committed Jun 4, 2021
1 parent 28718fa commit c7b642d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
4 changes: 3 additions & 1 deletion mypy/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -2448,7 +2448,9 @@ def find_module_and_diagnose(manager: BuildManager,
# otherwise updating mypy can silently result in new false
# negatives.
global_ignore_missing_imports = manager.options.ignore_missing_imports
if top_level in legacy_bundled_packages and global_ignore_missing_imports:
if (top_level in legacy_bundled_packages
and global_ignore_missing_imports
and not options.ignore_missing_imports_per_module):
ignore_missing_imports = False

if skip_diagnose:
Expand Down
6 changes: 6 additions & 0 deletions mypy/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ def __init__(self) -> None:
self.no_silence_site_packages = False
self.no_site_packages = False
self.ignore_missing_imports = False
# Is ignore_missing_imports set in a per-module section
self.ignore_missing_imports_per_module = False
self.follow_imports = 'normal' # normal|silent|skip|error
# Whether to respect the follow_imports setting even for stub files.
# Intended to be used for disabling specific stubs.
Expand Down Expand Up @@ -321,6 +323,10 @@ def apply_changes(self, changes: Dict[str, object]) -> 'Options':
replace_object_state(new_options, self, copy_dict=True)
for key, value in changes.items():
setattr(new_options, key, value)
if changes.get("ignore_missing_imports"):
# This is the only option for which a per-module and a global
# option sometimes beheave differently.
new_options.ignore_missing_imports_per_module = True
return new_options

def build_per_module_cache(self) -> None:
Expand Down
31 changes: 31 additions & 0 deletions test-data/unit/check-modules.test
Original file line number Diff line number Diff line change
Expand Up @@ -2982,3 +2982,34 @@ T = TypeVar("T")
class F(M):
x: C
class C: ...

[case testIgnoreErrorFromMissingStubs1]
# flags: --config-file tmp/pyproject.toml
import certifi
from foobar1 import x
import foobar2
[file pyproject.toml]
\[tool.mypy]
ignore_missing_imports = true
\[[tool.mypy.overrides]]
module = "certifi"
ignore_missing_imports = true
\[[tool.mypy.overrides]]
module = "foobar1"
ignore_missing_imports = true

[case testIgnoreErrorFromMissingStubs2]
# flags: --config-file tmp/pyproject.toml
import certifi
from foobar1 import x
import foobar2 # E: Cannot find implementation or library stub for module named "foobar2" \
# N: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
[file pyproject.toml]
\[tool.mypy]
ignore_missing_imports = false
\[[tool.mypy.overrides]]
module = "certifi"
ignore_missing_imports = true
\[[tool.mypy.overrides]]
module = "foobar1"
ignore_missing_imports = true

0 comments on commit c7b642d

Please sign in to comment.