Python Package Layout
This document describes the standard package layout for Python packages in this repository. The goal is to keep the public interface clear while isolating implementation details.
Core Rule
Expose the public interface of a package from its __init__.py.
Place concrete implementations under an internal/ subpackage.
Callers should normally import from the package itself rather than from internal/.
Standard Structure
A typical package should look like this:
my_package/
├── __init__.py
└── internal/
├── __init__.py
├── widget.py
└── helpers.py
The package-level __init__.py defines the supported public API.
The internal/ directory holds the implementation modules.
Public Interface Pattern
The package-level __init__.py should re-export the symbols that form the public API.
For example:
from .internal.widget import Widget
from .internal.helpers import make_widget
__all__ = ["Widget", "make_widget"]
With this pattern, external code writes imports such as:
from my_package import Widget, make_widget
External users should not need to import from my_package.internal during normal use.
Implementation Pattern
Implementation logic should live under internal/.
That includes:
concrete classes,
helper functions,
implementation-specific utilities,
and backend-specific adapters.
Modules inside internal/ may depend on one another as needed.
Code outside the package should avoid importing directly from internal/ unless there is a deliberate testing or development reason.
Rules For __init__.py
The package-level __init__.py should:
re-export the intended public API,
define
__all__when appropriate,and contain only minimal metadata, aliases, constants, and import wiring.
The package-level __init__.py should not:
contain substantial implementation logic,
contain long algorithm implementations,
become a catch-all utility module,
or expose internal helper symbols unless they are intentionally public.
When To Use This Pattern
Use this layout for new Python packages in this repository. Use it when refactoring older packages into a cleaner public interface. Use it unless a task explicitly requires a different structure.
Subpackages should follow the same pattern.
For example, buffalo_wings.airfoil and buffalo_wings.wing should expose their supported public APIs from their own __init__.py files.
Shared public aliases such as FloatArray should live in dedicated public modules such as buffalo_wings.type_aliases.
Migration Guidance
When refactoring an existing package into this layout:
Identify the symbols that should remain public.
Move concrete implementations into
internal/.Re-export the public symbols from the package-level
__init__.py.Add or update tests so public imports are validated through the package-level interface.
Definition Of Success
A package follows this layout successfully when:
external imports go through the package-level
__init__.py,implementation logic lives under
internal/,the public API is easy to identify,
internal reorganization does not require downstream import changes,
and
__init__.pyremains small and focused.