PEP 842: Module Exports

There are a few reasons libraries define __all__ for their hub modules:

  • it lets type checkers know the imports are actually exports and not unused
  • it ensures that underscore-marked symbols are present in dir and imported by wildcard imports
  • it can be useful for programmatically knowing what’s being exported

Reasons 1 and 2 are already in the admittedly long PEP.

I don’t get any of those. 1 is just a # noqa comment without actually writing # noqa. (There’s no point linting for unused imports in a place that’s supposed to have unused imports.) The first half of 2 works without __all__. 3 and the other half of 2 only make sense if you deliberately have public API with underscore prefixes.

Good questions. Adding to __all__ is overwhelmingly preferred to sprinkling your imports with noqa. My guess is that it’s because it declares intent (“it’s in the public interface”). noqa is typically a last resort.

Even a hub module is not supposed to have unused imports. Hub modules contain both “exports”:

from .x.y import z
# ...
__all__ = ["z", ...]

And sometimes even imports, for example warnings to warn on imports that will change.

Those imports should not be unused, but they don’t belong in __all__ either.

Yeah, it’s pretty rare, but it happens: from multiprocessing.spawn import _main

only supports import and from ... import directives

That risks repeating the mistake of .pth files IMO.

It sounds like we’re getting off-topic at this point. Can somebody (@davidism?) lock this thread? I’ll make a new thread after my revisions are merged. (I plan to merge them later today or tomorrow, if there aren’t any objections to the Sphinx plugin that I wrote for highlighting the new syntax.)

3 Likes