Skip to content

Commit d7b2451

Browse files
authored
Fixes to stubtest's new check for missing stdlib modules (#15960)
- It's not easy to predict where stdlib modules are going to be located. (It varies between platforms, and between venvs and conda envs; on some platforms it's in a completely different directory to the Python executable.) - Some modules appear to raise `SystemExit` when stubtest tries to import them in CI, leading stubtest to instantly exit without logging a message to the terminal. - Importing some `test.*` submodules leads to unraisable exceptions being printed to the terminal at the end of the stubtest run, which is somewhat annoying.
1 parent efecd59 commit d7b2451

File tree

1 file changed

+30
-11
lines changed

1 file changed

+30
-11
lines changed

mypy/stubtest.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import typing
2424
import typing_extensions
2525
import warnings
26+
from collections import defaultdict
2627
from contextlib import redirect_stderr, redirect_stdout
2728
from functools import singledispatch
2829
from pathlib import Path
@@ -1679,16 +1680,22 @@ def get_importable_stdlib_modules() -> set[str]:
16791680
all_stdlib_modules = sys.stdlib_module_names
16801681
else:
16811682
all_stdlib_modules = set(sys.builtin_module_names)
1682-
python_exe_dir = Path(sys.executable).parent
1683+
modules_by_finder: defaultdict[importlib.machinery.FileFinder, set[str]] = defaultdict(set)
16831684
for m in pkgutil.iter_modules():
1684-
finder = m.module_finder
1685-
if isinstance(finder, importlib.machinery.FileFinder):
1686-
finder_path = Path(finder.path)
1687-
if (
1688-
python_exe_dir in finder_path.parents
1689-
and "site-packages" not in finder_path.parts
1690-
):
1691-
all_stdlib_modules.add(m.name)
1685+
if isinstance(m.module_finder, importlib.machinery.FileFinder):
1686+
modules_by_finder[m.module_finder].add(m.name)
1687+
for finder, module_group in modules_by_finder.items():
1688+
if (
1689+
"site-packages" not in Path(finder.path).parents
1690+
# if "_queue" is present, it's most likely the module finder
1691+
# for stdlib extension modules;
1692+
# if "queue" is present, it's most likely the module finder
1693+
# for pure-Python stdlib modules.
1694+
# In either case, we'll want to add all the modules that the finder has to offer us.
1695+
# This is a bit hacky, but seems to work well in a cross-platform way.
1696+
and {"_queue", "queue"} & module_group
1697+
):
1698+
all_stdlib_modules.update(module_group)
16921699

16931700
importable_stdlib_modules: set[str] = set()
16941701
for module_name in all_stdlib_modules:
@@ -1719,13 +1726,25 @@ def get_importable_stdlib_modules() -> set[str]:
17191726
# The idlelib.* submodules are similarly annoying in opening random tkinter windows,
17201727
# and we're unlikely to ever add stubs for idlelib in typeshed
17211728
# (see discussion in https://github.com/python/typeshed/pull/9193)
1722-
if submodule_name.endswith(".__main__") or submodule_name.startswith("idlelib."):
1729+
#
1730+
# test.* modules do weird things like raising exceptions in __del__ methods,
1731+
# leading to unraisable exceptions being logged to the terminal
1732+
# as a warning at the end of the stubtest run
1733+
if (
1734+
submodule_name.endswith(".__main__")
1735+
or submodule_name.startswith("idlelib.")
1736+
or submodule_name.startswith("test.")
1737+
):
17231738
continue
17241739

17251740
try:
17261741
silent_import_module(submodule_name)
1742+
except KeyboardInterrupt:
1743+
raise
17271744
# importing multiprocessing.popen_forkserver on Windows raises AttributeError...
1728-
except Exception:
1745+
# some submodules also appear to raise SystemExit as well on some Python versions
1746+
# (not sure exactly which)
1747+
except BaseException:
17291748
continue
17301749
else:
17311750
importable_stdlib_modules.add(submodule_name)

0 commit comments

Comments
 (0)