Proposal:
In certain scenarios, such as implementing error suggestions for ModuleNotFoundError, it would be helpful to have the ability to ask the finder to search for possible specs.
I propose adding a new optional discover method to MetaPathFinder and PathEntryFinder, as follows:
.. method:: discover(parent=None) An optional method which searches for possible specs with given *parent*. If *parent* is *None*, :meth:`MetaPathFinder.discover` will search for top-level modules. Returns an iterable of possible specs.
Python 3.15.0a0 free-threading build (heads/main:744ec1d6c39, Oct 10 2025, 06:22:11) [GCC 15.2.1 20250813] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> path_finder = sys.meta_path[-1] >>> import sysconfig >>> for spec in path_finder.discover(sysconfig): ... print(spec) ... ModuleSpec(name='sysconfig.__init__', loader=<_frozen_importlib_external.SourceFileLoader object at 0x20000922c20>, origin='/home/anubis/git/cpython/Lib/sysconfig/__init__.py') ModuleSpec(name='sysconfig.__main__', loader=<_frozen_importlib_external.SourceFileLoader object at 0x20000922ca0>, origin='/home/anubis/git/cpython/Lib/sysconfig/__main__.py') >>> import urllib >>> for spec in path_finder.discover(urllib): ... print(spec) ... ModuleSpec(name='urllib.robotparser', loader=<_frozen_importlib_external.SourceFileLoader object at 0x20000922220>, origin='/home/anubis/git/cpython/Lib/urllib/robotparser.py') ModuleSpec(name='urllib.response', loader=<_frozen_importlib_external.SourceFileLoader object at 0x20000920d20>, origin='/home/anubis/git/cpython/Lib/urllib/response.py') ModuleSpec(name='urllib.__init__', loader=<_frozen_importlib_external.SourceFileLoader object at 0x20000921ba0>, origin='/home/anubis/git/cpython/Lib/urllib/__init__.py') ModuleSpec(name='urllib.request', loader=<_frozen_importlib_external.SourceFileLoader object at 0x20000920520>, origin='/home/anubis/git/cpython/Lib/urllib/request.py') ModuleSpec(name='urllib.parse', loader=<_frozen_importlib_external.SourceFileLoader object at 0x20000921520>, origin='/home/anubis/git/cpython/Lib/urllib/parse.py') ModuleSpec(name='urllib.error', loader=<_frozen_importlib_external.SourceFileLoader object at 0x200009214a0>, origin='/home/anubis/git/cpython/Lib/urllib/error.py')
Possibly, we could also add a helper function that searches sys.meta_path, similarly to importlib.util.find_spec. Although I don't think it is strictly necessary.
def discover(parent=None): for finder in sys.meta_path: try: discover = getattr(finder, 'discover') except AttributeError: continue yield from discover(parent)
This allows us to implement suggestions in traceback using the import system abstractions — see https://github.com/FFY00/cpython/tree/ModuleNotFoundError-suggestions.
Python 3.15.0a0 free-threading build (heads/main:744ec1d6c39, Oct 10 2025, 06:22:11) [GCC 15.2.1 20250813] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import asd Traceback (most recent call last): File "<python-input-0>", line 1, in <module> import asd ModuleNotFoundError: No module named 'asd'. Did you mean: 'ast'? >>> import importlib.utill Traceback (most recent call last): File "<python-input-1>", line 1, in <module> import importlib.utill ModuleNotFoundError: No module named 'importlib.utill'. Did you mean: 'importlib.util'?
Has this already been discussed elsewhere?
No response given
Links to previous discussion of this feature:
No response