python Python PEPs ·

PEP 842 Proposes Module Exports for Explicit Python API Control

engineer
announcement

Python's PEP 842 introduces a draft proposal for a new `__export__` variable, allowing modules to explicitly define their public API. This mechanism aims to limit the visibility and access of internal variables and imported modules from outside, addressing common issues with name disambiguation and unintended reliance on private components. It prevents users from accidentally using internal `_`-prefixed names or implicitly public imported modules. The proposal, targeting Python 3.16, seeks to improve module maintainability and clarity for both developers and consumers.

  • Introduce `__export__` for explicit module APIs
  • Address private name disambiguation and import visibility
  • Define `__export__` behavior and requirements
  • Impacts on `__dir__` and `__all__` behavior
Notes (4)
  • Introduce `__export__` for explicit module APIs

    PEP 842 proposes the `__export__` variable that modules can define to precisely limit which variables and imported names are visible and accessible from outside the module. If a name is not in `__export__`, attempts to access it will raise an `ImportError`.

  • Address private name disambiguation and import visibility

    The proposal motivates `__export__` by solving issues like the ambiguity of non-prefixed private names, the verbosity and maintainability burden of `_`-prefixed names, and the problem of internal imports appearing as public attributes. It aims to prevent users from relying on internal implementation details.

  • Define `__export__` behavior and requirements

    `__export__` must be an object implementing `__contains__()` or `__iter__()` that can check for string containment, typically a list or tuple of strings. It applies to module attribute access, but dunder names (e.g., `__dict__`, `__file__`) always remain accessible.

  • Impacts on `__dir__` and `__all__` behavior

    When `__export__` is present, a module's `dir()` output will exclude unexported names, though user-defined `__dir__` takes precedence. If `__export__` is defined but `__all__` is not, `__all__` will implicitly be set to the value of `__export__`, affecting wildcard imports.

Read the original announcement →

https://peps.python.org/pep-0842/

Related releases