| name | python-modern |
| description | Modern Python project workflow. Uses uv, pyproject.toml, ruff, mypy, src layout, and pytest. Use when this capability is needed. |
| metadata | {"author":"fricklers"} |
When this skill is active, follow this 7-step discipline for Python projects:
1. Project Structure
Use the src layout with pyproject.toml as the single config file:
src/<package>/ for source code, tests/ at the root
pyproject.toml for all metadata, dependencies, and tool config — no setup.py, setup.cfg, or requirements.txt
py.typed marker in the package root for PEP 561 type stub discovery
.python-version file pinning the minimum supported version
2. Dependency Management with uv
Use uv for fast, reproducible dependency management:
uv init for new projects, uv add <pkg> for dependencies
uv add --dev pytest ruff mypy for dev dependencies
uv lock to generate a lockfile, uv sync to install from it
- Pin Python version:
uv python pin 3.12
3. Type Everything
Set up the project for strict typing from day one:
- Add
from __future__ import annotations to every new file via a project template or snippet
- Run
uv run mypy src/ --strict after adding each module to catch gaps immediately
- Audit untyped boundaries: any function accepting or returning
dict or Any needs a typed replacement
- Generate stubs for untyped dependencies:
uv run stubgen -p <package> or add [[tool.mypy.overrides]]
4. Configure Ruff
Set up ruff in pyproject.toml for linting and formatting:
[tool.ruff]
target-version = "py312"
line-length = 88
[tool.ruff.lint]
select = ["E", "F", "I", "N", "UP", "B", "SIM", "TCH", "RUF"]
- Run
uv run ruff check --fix . before every commit
- Run
uv run ruff format . for consistent formatting
- Fix all violations — no
# noqa unless the rule is genuinely inapplicable
5. Configure Mypy
Set up mypy for strict type checking in pyproject.toml:
[tool.mypy]
strict = true
warn_return_any = true
warn_unreachable = true
- Run
uv run mypy src/ — zero errors required
- For third-party packages without stubs, add specific
[[tool.mypy.overrides]] instead of blanket ignores
- Never use bare
# type: ignore — always include a specific error code: # type: ignore[override]
6. Write Tests with pytest
Structure tests to mirror the source layout:
tests/test_<module>.py for each source module
- Use
pytest fixtures for setup/teardown, conftest.py for shared fixtures
- Use
pytest.mark.parametrize for multiple input cases
- Run with
uv run pytest -x --tb=short — stop on first failure during development
7. Verify the Full Pipeline
Before marking work complete, run the full verification chain:
uv run ruff check . — zero lint errors
uv run ruff format --check . — formatting matches
uv run mypy src/ — zero type errors
uv run pytest — all tests pass
- If any step fails, fix and re-run the entire chain
Converted and distributed by TomeVault — claim your Tome and manage your conversions.