freenode
Languages & Toolchains

PEP 844 proposes public and private builtins for module APIs

Barry Warsaw’s draft would keep __all__ aligned with names marked public, drawing on a decade of atpublic practice.

Barry Warsaw has published PEP 844, proposing two new builtins, public() and private(), that document a module’s public interface by keeping its all list synchronized with the names actually marked public.

The design is drawn from Warsaw’s atpublic library and about ten years of use in the wild. Both helpers work as decorators on definitions; public() can also register names via keyword arguments. The stated problem is ordinary drift: distant all lists fall out of date, third-party helpers add a dependency some projects will not take, and linters catch only part of the mismatch. Builtins would make the pattern available without an import and without new syntax.

Guido van Rossum questioned private() in particular, arguing it is mostly documentation. Warsaw replied that in atpublic it can remove a name from all, but said he would not object if only public() landed in builtins. Van Rossum separately restated support for stronger access-control ideas elsewhere; Warsaw countered that past restriction schemes were unreliable and un-Pythonic, and that he does not want Python to be annoying.

Several reviewers preferred a stdlib module (for example api) over new builtins, calling a one-time import minor friction and a natural home for related API helpers. Warsaw has so far rejected that path to avoid even that import and to avoid a top-level module for a small surface. Soft-keyword and annotation-style alternatives were sketched for dryer call sites, especially beside related export-statement work, but PEP 844 explicitly treats new syntax as too expensive: it cannot be backported, must be taught, and locks the grammar.

The proposal stays at documentation and all bookkeeping. It does not enforce privacy on class attributes, where Warsaw still prefers the leading-underscore convention.