atpublic
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
- gotcha The PyPI package name is `atpublic`, but the Python module you import from is `public`. Importing `from atpublic import ...` will fail. Always use `from public import ...`.
- breaking Version 7.0.0 and subsequent releases require Python 3.10 or newer. Older Python versions are not supported.
- gotcha If `__all__` is manually defined in your module *before* calling `populate_all()`, `populate_all()` will overwrite it with the list of names decorated as public. This is the intended behavior for synchronizing `__all__`.
Install
-
pip install atpublic
Imports
- public
from public import public
- private
from public import private
- populate_all
from public import populate_all
Quickstart
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)")