Use this when creating, modifying, debugging, or testing Python code or scripts. Follow the repository's existing Python toolchain and conventions first; only introduce new tooling when the project has no clear setup or the user explicitly asks.
Use this skill whenever the user asks to create, update, refactor, debug, or test Python code.
.env file only for local development when needed.timeout= to subprocess.run(...) in tests and helper scripts that execute commands.shell=True unless shell semantics are required or the existing code already depends on it.Choose commands in this order:
uv.lock, uv docs, or existing uv run ... commands -> use uv.poetry.lock or [tool.poetry] -> use poetry.Pipfile -> use pipenv.requirements.txt, pyproject.toml, tox.ini, noxfile.py, or an existing virtualenv -> follow those.Examples below use bare commands such as pytest. If the repo uses a runner, prefix the command with that runner:
uv run pytest
poetry run pytest
pipenv run pytest
pytest
pathlib.Path instead of string path manipulation.encoding="utf-8" for text files unless the project requires another encoding.logging for diagnostic output in libraries or long-running scripts; use print() for user-facing CLI output.argparse by default unless the repo already uses click, typer, or another CLI framework.main() function that returns an integer exit code.--dry-run when a script mutates files, systems, or remote state.Canonical CLI pattern:
import argparse
import sys
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description="Describe the script clearly")
parser.add_argument(
"--dry-run",
action="store_true",
help="Show actions without changing anything",
)
return parser
def main(argv: list[str] | None = None) -> int:
args = build_parser().parse_args(argv)
try:
if args.dry_run:
print("Would perform work")
return 0
print("Work complete")
return 0
except ValueError as exc:
print(f"Error: {exc}", file=sys.stderr)
return 2
except (OSError, RuntimeError) as exc:
print(f"Error: {exc}", file=sys.stderr)
return 1
if __name__ == "__main__":
raise SystemExit(main())
Common exit code pattern for scripts when the repo does not define one:
0 - success1 - runtime or external system error2 - validation or usage errortmp_path, monkeypatch, and deterministic test data to isolate state.Direct-call tests are usually the best default:
def test_slugify_basic_case() -> None:
assert slugify("Hello, World!") == "hello-world"
Subprocess tests are appropriate when the CLI wrapper itself is part of the behavior under test.
cwd= and env= explicitly when context matters.capture_output=True, text=True, and timeout= for test helpers.check=False when you want to assert on exit codes; use check=True only when failure should raise immediately.sys.executable when invoking Python from the current environment.--fix or formatting.def add(item, items=[]): ...except: clauses== None instead of is Nonereferences/ruff.md - Linting and formatting guidancereferences/pyright.md - Static type checking guidancereferences/pytest.md - Testing guidance