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.toml→constants.py→ codeCHANGELOG.mduses project version frompyproject.toml
Related Documents
- 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
.envfile; controlled byENV_DEBUG=true/false - Load via
python-dotenvandos.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, noTestCaseclasses, noself.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
.specfile in the project root - All console tools must use
console=Truein the.spec— tools rely oninput()andprint()for user interaction - Compiled executables are stored in
dist/and committed to the repository — the repository serves as the distribution channel for internal teams .gitignoremust not excludedist/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.tomlunder[project] - Always ask before bumping the version — never increment automatically
- Update
CHANGELOG.mdbefore bumping the version
15. Documentation and Task Management
- Keep
PROJECT.mdandCHANGELOG.mdup 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.