Modules and Packaging
Module layout, imports, and packaging entrypoints for libraries and apps. Results appear in the same fence: same-line # when short, multiline # blocks below the sample when not.
Search across all documentation pages
Module layout, imports, and packaging entrypoints for libraries and apps. Results appear in the same fence: same-line # when short, multiline # blocks below the sample when not.
Prefer absolute imports; alias long names with as.
import json
from pathlib import Path
import math as m
json.dumps({"a": 1}) # '{"a": 1}'
Path("a").suffix # ''
m.pi # 3.141592653589793Re-export public API from __init__.py carefully.
# mypkg/__init__.py conceptually:
# from .service import Service
# __all__ = ["Service"]
__all__ = ["Service"]
"Service" in __all__ # TrueUse relative imports inside packages when they clarify package boundaries.
# inside mypkg/api.py (illustrative names only):
# from .models import User
# from ..utils import retry
rel = [".models", "..utils"]
rel[0].startswith(".") # TrueGuard script execution so importing the module does not run CLI side effects.
def main() -> str:
return "hi"
if __name__ == "__main__":
main()
main() # 'hi'Declare console entry points in pyproject.toml.
# [project.scripts]
# mytool = "mypkg.cli:main"
entry = "mypkg.cli:main"
entry.split(":") # ['mypkg.cli', 'main']Implicit namespace packages omit __init__.py for split distributions - use deliberately.
# company/plugin_a and company/plugin_b without company/__init__.py
ns = "company.plugin_a"
ns.count(".") # 1Load package data files portably with importlib.resources.
from importlib.resources import files
# text = files("mypkg.data").joinpath("schema.json").read_text()
# Prefer files() over legacy path hacks
hasattr(files, "__call__") # TrueAvoid mutating sys.path in library code - fix packaging/install instead.
import sys
isinstance(sys.path, list) # True
# Prefer: uv pip install -e .
# Avoid: sys.path.append("..")Import heavy optional deps inside functions to speed module import.
def use_json():
import json
return json.dumps([1])
use_json() # '[1]'Run tools in managed environments with uv without global installs.
# shell (not Python):
# uv run ruff check .
# uv run pytest
cmds = ["uv run ruff check .", "uv run pytest"]
cmds[0].startswith("uv run") # TrueEditable installs keep source linked for local development.
# shell:
# uv pip install -e .
# or: pip install -e .
flag = "-e"
flag in "uv pip install -e ." # TrueExpose package version for support logs.
__version__ = "1.2.3"
tuple(int(p) for p in __version__.split(".")) # (1, 2, 3)Break cycles with local imports or by splitting modules.
def fn():
# from . import other # local import breaks cycle
other = type("M", (), {"help": staticmethod(lambda: "ok")})
return other.help()
fn() # 'ok'UPPER_SNAKE constants document module-wide config.
DEFAULT_TIMEOUT = 5.0
MAX_RETRIES = 3
DEFAULT_TIMEOUT * MAX_RETRIES # 15.0Define __all__ to document star-import public surface.
__all__ = ["Client", "Error"]
len(__all__) # 2
"Client" in __all__ # TrueStack versions: Python 3.14.0 (stable 3.14, maintenance 3.13) · uv 0.6+ · ruff 0.9+
Reviewed by Chris St. John·Last updated Jul 31, 2026