Files

6.4 KiB

Python Development Guidelines

Document Version: v8

Note on Versioning:

  • This document version is independent — reused across projects
  • Project version source of truth: pyproject.toml
  • Version propagates: pyproject.tomlconstants.py → code
  • CHANGELOG.md uses project version from pyproject.toml
  • README.md — Project overview, tool descriptions, build instructions
  • AGENTS.md — Rules for AI assistants
  • PROJECT.md — Project goals and current state
  • CHANGELOG.md — Version history

Documentation Organization

All detailed documentation of features and systems belongs in the docs/ folder, not in the project root.

The root directory contains only the core documents: DESIGN_DOCUMENT.md, AGENTS.md, PROJECT.md, CHANGELOG.md.


1. Code Style

  • PEP8 with 150-character lines (Ruff)
  • 4 spaces indentation
  • snake_case functions/variables, PascalCase classes, SCREAMING_SNAKE_CASE constants
  • Type hints required on all functions
  • Import order: stdlib → third-party → local

2. SOLID Principles

  • SRP — One class = one responsibility
  • OCP — Open for extension, closed for modification
  • LSP — Subclasses substitutable for parents
  • ISP — Small interfaces over large ones
  • DIP — Depend on abstractions

3. Dependency Injection

Pass dependencies via constructor. Never instantiate dependencies inside a class.


4. Protocols Over Inheritance

Prefer typing.Protocol and composition over class inheritance.


5. Data Classes

Use @dataclass for internal data structures, pydantic.BaseModel for data that requires validation.


6. Logging and Console Output

Logging — loguru

Use loguru for all internal logging. Never log secrets, passwords, tokens, or API keys.

Log sinks

Sink Level Format
File logs/{AppName}_{time}.log DEBUG full (timestamp + level + message)
stdout INFO full

File sink retains max 10 log files (retention=10). No rotation by size — each run creates a new file via {time} in the filename.

The DEBUG sink is only active when constants.DEBUG is True (controlled by ENV_DEBUG=true in .env).

Additional sinks (e.g. GUI log panels) may be added per project as needed.

Log levels

Level When to use
DEBUG Per-item detail: individual file reads/writes, cache hits, per-row operations
INFO User-visible milestones: file loaded, process started/finished, file saved
WARNING Recoverable issues: fallback used, unexpected but non-fatal state
ERROR Failures the user must know about: missing file, failed save, missing config — operation cannot continue

Console output — print()

print() is allowed for direct user-facing console communication: input prompts, progress lines, and result summaries. This applies to console tools that interact with the user through stdin/stdout.

print() is not a substitute for loguru. It must not be used for debugging or internal event tracking.


7. Environment and Secrets

  • Secrets in .env file; controlled by ENV_DEBUG=true/false
  • Load via python-dotenv and os.getenv()
  • Never commit .env

8. Error Handling

Define specific exception types. Use a fail-fast approach — surface errors early rather than silently continuing.


9. Testing

  • pytest only — no unittest, no TestCase classes, no self.assert*
  • Arrange-Act-Assert pattern
  • Test naming: test_<action>_<context>

10. Tooling

Tool Purpose
Ruff Formatting and linting
mypy Static type checking
pytest Testing

Run before every commit:

poetry run ruff check
poetry run mypy

11. Poetry

poetry install                    # Install all dependencies
poetry add <pkg>                  # Add runtime dependency
poetry add --group dev <pkg>      # Add dev dependency
poetry remove <pkg>               # Remove dependency
poetry run <cmd>                  # Run command in virtualenv

Never edit pyproject.toml directly to add or remove dependencies.


12. Project Structure

project/
├── entry_point.py      # Entry point(s) — named by purpose or tool name
├── src/                # All application modules
├── tests/              # Tests
├── docs/               # Detailed documentation
├── .venv/              # Virtual environment (managed by Poetry)
└── pyproject.toml      # Project config and dependencies

A project may have multiple entry points (e.g. cli.py, gui.py, or per-tool scripts).


13. Distribution and Deployment

When a project is distributed as a standalone executable (no Python required on target machine):

  • Use PyInstaller to compile each entry point into a single .exe
  • Each tool has its own .spec file in the project root
  • All console tools must use console=True in the .spec — tools rely on input() and print() for user interaction
  • Compiled executables are stored in dist/ and committed to the repository — the repository serves as the distribution channel for internal teams
  • .gitignore must not exclude dist/ in projects that use this deployment model

Build command:

poetry run pyinstaller ToolName.spec

This section applies only to projects that produce standalone executables. Skip for libraries or web services.


14. Versioning

  • Follow semantic versioning: MAJOR.MINOR.PATCH
  • Version is defined in pyproject.toml under [project]
  • Always ask before bumping the version — never increment automatically
  • Update CHANGELOG.md before bumping the version

15. Documentation and Task Management

  • Keep PROJECT.md and CHANGELOG.md up to date when making changes
  • Document architectural changes in this file or in docs/

Task notation

Tasks are written as single-line comments directly in code, or in PROJECT.md for cross-cutting concerns:

# TODO: one-liner description of a task to be done
# FIXME: one-liner description of a known bug to be fixed

No other task format is used — no checkboxes, no numbered lists in documentation.

If a # TODO: comment already exists at a specific location in code, do not repeat it in PROJECT.md.