Skip to content

Commit 1e9cd08

Browse files
committed
Determine supported Python major versions by reading METADATA.toml
1 parent a59efd9 commit 1e9cd08

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

mypy/build.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2497,11 +2497,11 @@ def module_not_found(manager: BuildManager, line: int, caller_state: State,
24972497
errors.report(line, 0, note, severity='note', only_once=True, code=codes.IMPORT)
24982498
else:
24992499
msg, notes = reason.error_message_templates()
2500-
errors.report(line, 0, msg.format(target), code=codes.IMPORT)
2500+
pyver = '%d.%d' % manager.options.python_version
2501+
errors.report(line, 0, msg.format(module=target, pyver=pyver), code=codes.IMPORT)
25012502
top_level = target.partition('.')[0]
25022503
for note in notes:
2503-
if '{}' in note:
2504-
note = note.format(legacy_bundled_packages[top_level])
2504+
note = note.format(stub_dist=legacy_bundled_packages[top_level])
25052505
errors.report(line, 0, note, severity='note', only_once=True, code=codes.IMPORT)
25062506
if reason is ModuleNotFoundReason.STUBS_NOT_INSTALLED:
25072507
manager.missing_stub_packages.add(legacy_bundled_packages[top_level])

mypy/modulefinder.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,14 @@ class ModuleNotFoundReason(Enum):
5555
def error_message_templates(self) -> Tuple[str, List[str]]:
5656
doc_link = "See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports"
5757
if self is ModuleNotFoundReason.NOT_FOUND:
58-
msg = 'Cannot find implementation or library stub for module named "{}"'
58+
msg = 'Cannot find implementation or library stub for module named "{module}"'
5959
notes = [doc_link]
6060
elif self is ModuleNotFoundReason.FOUND_WITHOUT_TYPE_HINTS:
61-
msg = 'Skipping analyzing "{}": found module but no type hints or library stubs'
61+
msg = 'Skipping analyzing "{module}": found module but no type hints or library stubs'
6262
notes = [doc_link]
6363
elif self is ModuleNotFoundReason.STUBS_NOT_INSTALLED:
64-
msg = 'Library stubs not installed for "{}"'
65-
notes = ['Hint: "python3 -m pip install {}"',
64+
msg = 'Library stubs not installed for "{module}" (or incompatible with Python {pyver})'
65+
notes = ['Hint: "python3 -m pip install {stub_dist}"',
6666
'(or run "mypy --install-types" to install all missing stub packages)',
6767
doc_link]
6868
else:
@@ -230,7 +230,7 @@ def _find_module(self, id: str, use_typeshed: bool) -> ModuleSearchResult:
230230
for pkg_dir in self.search_paths.package_path:
231231
stub_name = components[0] + '-stubs'
232232
stub_dir = os.path.join(pkg_dir, stub_name)
233-
if fscache.isdir(stub_dir):
233+
if fscache.isdir(stub_dir) and self._is_compatible_stub_package(stub_dir):
234234
stub_typed_file = os.path.join(stub_dir, 'py.typed')
235235
stub_components = [stub_name] + components[1:]
236236
path = os.path.join(pkg_dir, *stub_components[:-1])
@@ -360,6 +360,24 @@ def _find_module(self, id: str, use_typeshed: bool) -> ModuleSearchResult:
360360
else:
361361
return ModuleNotFoundReason.NOT_FOUND
362362

363+
def _is_compatible_stub_package(self, stub_dir: str) -> bool:
364+
"""Does a stub package support the target Python version?
365+
366+
Stub packages may contain a metadata file which specifies
367+
whether the stubs are compatible with Python 2 and 3.
368+
"""
369+
metadata_fnam = os.path.join(stub_dir, 'METADATA.toml')
370+
if os.path.isfile(metadata_fnam) and self.options:
371+
# Delay import for a possible minor performance win.
372+
import toml
373+
with open(metadata_fnam, 'r') as f:
374+
metadata = toml.load(f)
375+
if self.options.python_version[0] == 2:
376+
return bool(metadata.get('python2', False))
377+
else:
378+
return bool(metadata.get('python3', True))
379+
return True
380+
363381
def find_modules_recursive(self, module: str) -> List[BuildSource]:
364382
module_path = self.find_module(module)
365383
if isinstance(module_path, ModuleNotFoundReason):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy