[Python-Dev] Breaking undocumented API

Steven D'Aprano steve at pearwood.info
Mon Nov 8 23:17:40 CET 2010


Ron Adam wrote:

> My understanding is that anything with an actual docstring is part of 
> the public API.

I frequently add docstrings to _private functions. Just because it is 
private doesn't mean I don't want documentation for it, and it is very 
handy for running doctests.

Yes, I test my internal functions *wink*

The convention I use is:

* If __all__ exists, anything in that is public.
* Anything not listed in __all__ but without a leading underscore is 
public, but not part of the module's API; e.g. utility functions, 
imported modules, globals (but hopefully not too many of the last). That 
means I don't expect you to use it, but you can if you want.
* Anything with a _private name is internal use only. That includes 
modules. Any attribute of a private object is also private.

If a class is flagged as private, _MyClass, you wouldn't expect that 
_MyClass.attribute were public just because the attribute name wasn't 
also flagged with an underscore. So why treat _module.name as public?


> +1 on the help disclaimer for objects with leading underscores.

I don't know that it will be that useful, but I don't think it will help 
that much. +0.

> Currently help() does not see comments when they are used in place of a 
> docstring.  I think it would be easy to have help notate things with no 
> docstrings as "Warning: Undocumented <object>. Use at your own risk."

I wouldn't like that. I don't think that "no docstring" = "undocumented" 
-- the documentation might exist somewhere else.

Besides, I don't think that help() should start misidentifying public 
objects as private if you run it under python -OO.


> It may also be useful to clarify that importing some "utility" modules 
> is not recommended because they may be changed more often and may not 
> follow the standard process.  Would something like the following work, 
> but still allow for importing if the exception is caught with a try except?
> 
> if __name__ == "__main__":
>     main()
> else:
>     raise ImportWarning("This is utility module and may be changed.")

There's no way for the imported module to know what module is importing 
it, is there? Because the API I'd much prefer is:

safe_modules = [a, b, c, d]  # List of modules allowed to import me.
if calling_module not in safe_modules:
     warning.warn("private module, are you sure you want to do this?")



-- 
Steven



More information about the Python-Dev mailing list