[Python-Dev] Breaking undocumented API
Steven D'Aprano
steve at pearwood.info
Thu Nov 11 19:16:16 CET 2010
Nick Coghlan wrote:
> My personal opinion is that we should be trying to get the standard
> library to the point where __all__ definitions are unnecessary - if a
> name isn't in __all__, it should start with an underscore (and if that
> is true, then the __all__ definition becomes effectively redundant).
You don't *need* to define __all__ -- if you don't, import * will import
everything that doesn't start with a leading underscore. __all__ is only
useful when you want more control over what is or isn't imported. If you
don't need that control, just don't define __all__, and the problem is
solved.
> That way, all sources of information (docs, dir(), help(), import *)
> give the same answer as to what constitutes the public API.
I disagree with the underlying assumption that import * need necessarily
import the entire public API. That's not how I use it in my modules, and
the option should be available to std library modules as well.
When I create a module, I distinguish between three categories of functions:
* private, which start with an underscore;
* the core public API, which is listed in __all__; and
* support/helper functions, which are not part of the core functionality
of the module but are public.
If you import * you will get just the core functions. If you want the
support functions, you need to use the fully qualified module.name, or
otherwise import them yourself.
This division of public functions into first and second class API
functions is a deliberate design choice on my part. I expect the core
functionality to be fully documented. Helper and support functions may
not be -- there should be some docs, but doing so is a lower priority.
The support functions are public, and available for use, if you go
looking for them, but I neither encourage nor discourage users from
doing so.
I don't see any reason that the standard library should not be permitted
to use the same convention.
Another couple of objections to getting rid of __all__:
If you're proxying modules or built-ins, you may not be able to use a
_private name, but you may not want import * to pick up your proxies.
I find it annoying to see this:
import module as _module
_module.func()
(instead of import module and merely leaving module out of __all__)
I accept that some standard library authors may choose this convention,
but I don't want to see it become mandatory.
--
Steven
More information about the Python-Dev
mailing list