Python Conventions
pytest
- Register helper fixtures using
pytest_plugins = ["<module_path>"]. - Name fixture functions with
fixture_ prefix and pass public name via @pytest.fixture(name="foo").
CLI & Arguments
- Use direct attribute access (e.g.
args.foo) on argparse.Namespace with well-defined shapes. Avoid defensive getattr().
Interface & ABC Docstrings
- In abstract base class / interface methods, always document
Args:, Returns:, and all custom exceptions raised under Raises:.
Exception Handling
- Inherit custom exceptions from
Exception, not RuntimeError.
Subprocess
- Demarcate captured stdout/stderr in exceptions with 20
= characters: ==================== STDOUT BEGIN ==================== / ==================== STDOUT END ==================== (same for STDERR).
TypedDict
- External Objects: When defining a
TypedDict for an external object, link to its definition in the docstring.
Type Checking & Annotations
- Version differences: Guard version-specific arguments or APIs with runtime checks (e.g.
if sys.version_info >= (3, 13):) instead of # pyrefly: ignore[...] comments. importlib.metadata PackagePath: f.locate() is typed as PathLike. Wrap with pathlib.Path(f.locate()) to call .exists(), .is_file(), etc.- In-file disables vs target skipping: Prefer
# pyrefly: ignore[<error-code>] (e.g. [missing-import]) over tags = ["no-pyrefly"]. - No blanket ignores: NEVER use bare
# type: ignore or literal # type: ignore[...]. Use error-specific ignores instead. - Ignore comments: When adding
# pyrefly: ignore[...] or type suppressions, add an explanatory comment indicating why it is suppressed. - Type assertions: When adding assertions for type narrowing, add an end-of-line comment:
assert foo is not None # type assert. - Consent for
Any: Require user consent before changing type annotations to Any. - Union syntax (
X | None): Use X | None instead of typing.Optional[X]. Add from __future__ import annotations if necessary. - Collections generics: Use
collections.abc (e.g., Sequence, Iterable, Iterator, Callable, Mapping) and builtin generics (list, dict, tuple, set) instead of typing.XXX collection types.
Runfiles
- Fail-fast creation: Prefer
runfiles.CreateOrRaise() over runfiles.Create() + assert. - Path navigation: Prefer
rf.root() / "<repo>/<path>" over Rlocation(); use .glob() on runfiles.Path instead of multi-root fallback loops.
Delegating Functions
- Module-level functions delegating to class methods should have a docstring referring to the class method (e.g.
"""Refer to \Class.method`."""`).