just-init
Use __init__.py files as the single source of truth for understanding and
documenting Python packages.
Navigation Rule
Before opening any file in a Python package, read its __init__.py first.
Use the docstring to understand the package's purpose and decide which files
to explore next. Apply this recursively — when entering a sub-package, read
its __init__.py before going deeper.
When exploring an unfamiliar codebase, start from the top-level package
__init__.py and drill down based on what each docstring describes.
Docstring Format
Every __init__.py must start with a triple-quoted docstring containing:
- •A one-line description of the package's purpose.
- •A file tree listing
.pyfiles and subdirectories (not non-Python files). - •A
# commentafter each entry describing its purpose.
""" One-line description of what this package does. package_name/ ├── __init__.py # Package init and public exports. ├── module_a.py # Brief description of module_a. ├── module_b.py # Brief description of module_b. └── subpackage/ # Brief description of subpackage. """
Rules:
- •Use
├──for all entries except the last, which uses└──. - •List
.pyfiles first, then subdirectories, both in alphabetical order. - •Subdirectories end with
/and are not expanded — their own__init__.pydocuments their contents. - •Descriptions are concise: aim for under 10 words per entry.
- •The package name in the tree matches the directory name.
Auto-Update Rule
After any of these changes, immediately update the affected __init__.py:
- •File added — Add the new entry to the tree with a description.
- •File removed — Remove the entry from the tree.
- •File renamed — Update the entry name and description if needed.
- •Subdirectory added — Add the directory entry (with trailing
/) and create a new__init__.pyinside it. - •Subdirectory removed — Remove the directory entry from the parent tree.
When a change affects a nested package, update both the sub-package's own
__init__.py and the parent's __init__.py if the sub-package entry changed.
Do not wait for the user to ask — update __init__.py as part of every file
operation within a Python package.
New Package Rule
When creating a new Python package:
- •Create the directory.
- •Create
__init__.pyas the first file. - •Write the docstring with the package description and initial file tree.
- •Then create the other files.
- •Update the tree in
__init__.pyafter all files are in place.
Edge Cases
- •Empty package — The docstring contains only the description and a tree
with just
__init__.py. - •Non-Python directories (data, fixtures, configs) — List them in the tree
with a trailing
/and a description, but do not expand their contents and do not create an__init__.pyinside them. - •No existing docstring — When encountering an
__init__.pywithout a docstring, add one based on the current directory contents before proceeding. - •Conflicting docstring — If the docstring is outdated (doesn't match actual files), update it to reflect reality before continuing.
Examples
See references/examples.md for concrete patterns: simple flat packages, nested packages, packages with non-Python directories, and before/after update scenarios.