# Python Code Style Guide > Style rules for Python code under `skills/ppt-master/scripts/` and any Python that ships with the skill. Derived from the de facto patterns in the existing codebase. These rules are pragmatic, not exhaustive. They capture the conventions readers actually encounter — anything PEP 8 hands you for free is assumed. --- ## 1. File Header Every script under `scripts/` starts with: ```python #!/usr/bin/env python3 """ PPT Master - Short Tool Name One-paragraph description of what this script does. Usage: python3 scripts/.py [options] Examples: python3 scripts/.py projects/ -o output_dir Dependencies: None (only uses standard library) <-- or list third-party deps """ ``` | Element | Rule | |---|---| | Shebang | `#!/usr/bin/env python3` (always — even for non-CLI helper modules) | | Module docstring | Tool name + purpose + Usage + Examples + Dependencies | | Internal helper modules | May add an early `--help` short-circuit (see §4) | --- ## 2. Imports ```python # 1. Standard library import os import sys import argparse import re from pathlib import Path from typing import Optional # 2. Third-party import requests # 3. Local — sometimes need sys.path injection first (see §3) from image_sources.provider_common import ( AssetCandidate, ImageSearchRequest, ) ``` | Rule | Note | |---|---| | Group order | std → third-party → local, blank line between groups | | Within a group | Sorted by length when short; alphabetical when ≥ 4 imports | | `from x import` lists | One name per line if ≥ 4 names, with trailing comma | | `from __future__ import annotations` | Add at top when the file uses `X \| Y` union syntax (PEP 604) and may run on Python < 3.10 | --- ## 3. sys.path Injection (Project Convention) `scripts/` is **not a Python package** — it's a flat directory of scripts. Each entry-point script that imports a sibling module injects `scripts/` onto `sys.path` itself: ```python import sys from pathlib import Path _SCRIPTS_DIR = Path(__file__).resolve().parent if str(_SCRIPTS_DIR) not in sys.path: sys.path.insert(0, str(_SCRIPTS_DIR)) from image_backends.backend_common import download_image # noqa: E402 ``` | Rule | Why | |---|---| | Inject only in entry-points | Library modules under `image_sources/` / `image_backends/` import each other normally | | Use `Path(__file__).resolve().parent` | Robust under symlinks and aliasing | | Annotate post-injection imports with `# noqa: E402` | Suppress the lint warning honestly, not via per-file noqa | --- ## 4. CLI Entry Points ```python def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser( description="One-line description.", formatter_class=argparse.RawDescriptionHelpFormatter, ) parser.add_argument("query", help="...") parser.add_argument("-o", "--output", default=".", help="...") return parser def main(argv: Optional[list[str]] = None) -> int: parser = build_parser() args = parser.parse_args(argv) # ... do the thing ... return 0 if __name__ == "__main__": raise SystemExit(main()) ``` | Rule | Note | |---|---| | `main(argv=None) -> int` | Returns exit code; testable by passing `argv` | | `raise SystemExit(main())` | Preferred over `sys.exit(main())` | | `formatter_class=argparse.RawDescriptionHelpFormatter` | Preserves docstring formatting in `--help` | | Internal helpers `--help` | Module-level: `if __name__ == "__main__" and any(arg in {"-h", "--help", "help"} for arg in sys.argv[1:]): print(__doc__); raise SystemExit(0)` | | Output | Progress / status to **stderr**; the script's primary output (if any) to stdout | **Help and argument validation requirements**: - `-h` / `--help` must be handled by `argparse` (preferred) or an explicit early helper guard before any side effect: no directory creation, file writes, network calls, package installs, or long-running servers. - Help flags must never be accepted as positional values. Examples: `init --help` must not create a project named `--help`; `export --help` must not write a file named `--help`. - Scripts with subcommands use `argparse` subparsers. Each subcommand must provide its own help (`