name: python-modern description: Modern Python project workflow. Uses uv, pyproject.toml, ruff, mypy, src layout, and pytest.
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 rootpyproject.tomlfor all metadata, dependencies, and tool config — nosetup.py,setup.cfg, orrequirements.txtpy.typedmarker in the package root for PEP 561 type stub discovery.python-versionfile pinning the minimum supported version
2. Dependency Management with uv
Use uv for fast, reproducible dependency management:
uv initfor new projects,uv add <pkg>for dependenciesuv add --dev pytest ruff mypyfor dev dependenciesuv lockto generate a lockfile,uv syncto 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 annotationsto every new file via a project template or snippet - Run
uv run mypy src/ --strictafter adding each module to catch gaps immediately - Audit untyped boundaries: any function accepting or returning
dictorAnyneeds 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
# noqaunless 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>.pyfor each source module- Use
pytestfixtures for setup/teardown,conftest.pyfor shared fixtures - Use
pytest.mark.parametrizefor 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 errorsuv run ruff format --check .— formatting matchesuv run mypy src/— zero type errorsuv run pytest— all tests pass- If any step fails, fix and re-run the entire chain