atpublic

7.0.0 · active · verified Thu Apr 09

atpublic is a Python library that offers simple decorators and a utility function to synchronize a module's `__all__` variable, explicitly defining its public API. This helps prevent `__all__` from becoming outdated, which is a common issue when functions or classes are added, renamed, or removed. The library is currently in version 7.0.0 and maintains an active development cadence with regular updates.

Warnings

Install

Imports

Quickstart

This example demonstrates how to use the `@public` and `@private` decorators, along with `populate_all()`, to define and synchronize your module's public API. After running `populate_all()`, the `__all__` list will contain the names marked `@public`, including those renamed via the decorator. This ensures `from module import *` only exposes intended symbols.

import inspect
from public import public, private, populate_all

@public
def my_public_function():
    """This function is part of the public API."""
    return "Hello from public"

@private
def _my_private_function():
    """This function is explicitly private."""
    return "Shhh, private"

@public(name="renamed_public_function")
def _internal_name_function():
    """This function is public under a different name."""
    return "Hello from renamed public"

class PublicClass:
    @public
    def public_method(self):
        return "Public method call"


# Populate __all__ based on decorators
populate_all(inspect.currentframe().f_globals)

# Verify the __all__ list
if __name__ == '__main__':
    print(f"Module __all__: {__all__}")
    # Expected: ['my_public_function', 'renamed_public_function', 'PublicClass']

    # Test public access
    try:
        print(my_public_function())
        print(_internal_name_function())
        instance = PublicClass()
        print(instance.public_method())
    except NameError as e:
        print(f"Error accessing public member: {e}")

    # Test private access (should be NameError if 'from module import *' was used)
    try:
        _my_private_function()
        print("Accessed private function (this shouldn't happen with import *)")
    except NameError:
        print("Cannot access private function directly (as expected with import * semantics)")

view raw JSON →