Skip to content
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Revert "Remove specific doc references"
This reverts commit 31d1a8f.

Signed-off-by: Filipe Laíns <lains@riseup.net>
  • Loading branch information
FFY00 committed Dec 10, 2025
commit c343d328b90068df086b3482c498130fff305b82
8 changes: 4 additions & 4 deletions Doc/library/importlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ ABC hierarchy::
.. method:: discover(parent=None)

An optional method which searches for possible specs with given *parent*
module spec. If *parent* is *None*, ``discover`` will search for top-level
modules.
module spec. If *parent* is *None*, :meth:`MetaPathFinder.discover` will
search for top-level modules.

Returns an iterable of possible specs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would this be the first time we have a public API yielding things from importlib, do we actually want to do that or should this return a list?

callers consuming the results might be writing code that makes changes that could impact future results... yielding could get messy.

what are the intended use cases for the API? if it's something we expect callers to short circuit and stop iterating on after the first match maybe yield makes sense, but then we should probably just have an explicit direct discover_first API for that instead.

@FFY00 FFY00 Dec 17, 2025 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is something I considered.

The main use-case is finding a similar-named module to show as a hint on ModuleNotFoundError (eg. "Did you meant numpy?", when trying to import numby), so I think it would make sense to make this new API a generator, or at least some kind of lazy container.

For cases such as you describe, the user could just consume the full generator into a list to avoid any issue. Still leaving opportunity for the code that could leverage the benefit of this being a lazy API — scaning directories with a lot of files can take a while, not to mention the other exotic finders out there that may operate over the network or something like that.

I am not fundamentally opposed to make this method return a list, but I can't see the value in the trade-of if we document it properly.

callers consuming the results might be writing code that makes changes that could impact future results... yielding could get messy.

While this is technically possible, I would find it extremely uncommon. And I think it should be reasonable to assume that people who are knowledgeable enough to do that, would probably be aware of the downsides of making changes to the import machinery, while consuming the API

but then we should probably just have an explicit direct discover_first API for that instead

And what would that look like? Would it take a predicate function and return the first entry that matches?


So, would have a warning in the documentation regarding your concern be a good enough compromise?

@ncoghlan ncoghlan Jan 1, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, for the "nearest matching module name" error message case, you just want to keep the closest match, so even though all the names need to be checked, you only need to keep a reference to one of them (the closest so far).

Since the potential number of results may be absurdly high in some situations, and the iterable form provides more options for consumers to handle that appropriately, I do think it makes sense to make it an iterable. The warning in the docs should explain why it's an iterable, since consumers that unconditionally convert the result to a list can run into problems regardless.

As far as prior examples of iterable import APIs goes, importlib.resources.contents was the first example I found in a quick look (covering a very similar situation, just for non-module resources rather than submodules)


Expand Down Expand Up @@ -320,8 +320,8 @@ ABC hierarchy::
.. method:: discover(parent=None)

An optional method which searches for possible specs with given *parent*
module spec. If *parent* is *None*, ``discover`` will search for top-level
modules.
module spec. If *parent* is *None*, :meth:`PathEntryFinder.discover` will
search for top-level modules.

Returns an iterable of possible specs.

Expand Down