Awesome-omni-skill modern-python
Modern Python tooling best practices using uv, ruff, ty, and pytest. Mandates the Trail of Bits Python coding standards for project setup, dependency management, linting, type checking, and testing. Based on patterns from trailofbits/cookiecutter-python.
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/modern-python-finimo-solutions" ~/.claude/skills/diegosouzapw-awesome-omni-skill-modern-python && rm -rf "$T"
skills/development/modern-python-finimo-solutions/SKILL.mdModern Python Skill
<!-- Agent: evolution-orchestrator | Task: #2 | Session: 2026-02-21 --> <!-- License: CC-BY-SA-4.0 | Source: Trail of Bits (github.com/trailofbits/skills) --> <!-- Attribution: Adapted from Trail of Bits modern-python skill and trailofbits/cookiecutter-python --> <identity> Modern Python tooling skill adapted from Trail of Bits coding standards. Mandates the use of uv (package management), ruff (linting and formatting), ty (type checking), and pytest (testing) as the standard Python toolchain. Based on patterns from trailofbits/cookiecutter-python for consistent, high-quality Python projects. </identity> <capabilities> - Project initialization with modern Python toolchain (uv + ruff + ty + pytest) - Migration from legacy tools (pip/Poetry/pipenv to uv, black/flake8/isort to ruff, mypy to ty) - pyproject.toml configuration for all tools (single source of truth) - Dependency management with uv (lock files, dependency groups, virtual environments) - Linting and formatting with ruff (replaces flake8, isort, black, pyflakes, pycodestyle) - Type checking with ty (Rust-based, faster than mypy) - Testing with pytest, pytest-cov, and hypothesis - CI/CD configuration with GitHub Actions - Dependabot setup for automated dependency updates - Pre-commit hook configuration </capabilities>Overview
This skill implements Trail of Bits' modern Python coding standards for the agent-studio framework. The core philosophy is: use Rust-based tools for faster feedback loops, especially when working with AI agents. Every tool in this stack (uv, ruff, ty) is written in Rust and provides sub-second execution times, enabling tight iteration cycles.
Source repository:
https://github.com/trailofbits/skills
Template: https://github.com/trailofbits/cookiecutter-python
License: CC-BY-SA-4.0
When to Use
- When creating new Python projects from scratch
- When migrating Python projects from legacy tooling
- When setting up CI/CD pipelines for Python projects
- When standardizing Python tooling across a team
- When writing standalone Python scripts that need proper structure
- When an AI agent needs fast feedback from Python tooling
Iron Law
ALL PYTHON TOOLING CONFIGURED IN pyproject.toml — NO SEPARATE CONFIG FILES
pyproject.toml is the single source of truth for all tool configuration. No setup.cfg, no .flake8, no mypy.ini, no black.toml.
The Modern Python Stack
| Tool | Replaces | Purpose | Speed |
|---|---|---|---|
| uv | pip, Poetry, pipenv, pip-tools | Package & project management | 10-100x faster |
| ruff | flake8, isort, black, pyflakes, pycodestyle, pydocstyle | Linting + formatting | 10-100x faster |
| ty | mypy, pyright, pytype | Type checking | 5-10x faster |
| pytest | unittest | Testing | -- |
| hypothesis | (manual property tests) | Property-based testing | -- |
Project Setup
New Project
# Create new project with uv uv init my-project cd my-project # Add dependency groups uv add --group dev ruff ty uv add --group test pytest pytest-cov hypothesis uv add --group docs sphinx myst-parser # Install all dependencies uv sync --all-groups
pyproject.toml Configuration
[project] name = "my-project" version = "0.1.0" requires-python = ">=3.12" dependencies = [] [dependency-groups] dev = ["ruff", "ty"] test = ["pytest", "pytest-cov", "hypothesis"] docs = ["sphinx", "myst-parser"] # === Ruff Configuration === [tool.ruff] target-version = "py312" line-length = 100 [tool.ruff.lint] select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # pyflakes "I", # isort "N", # pep8-naming "UP", # pyupgrade "B", # flake8-bugbear "A", # flake8-builtins "C4", # flake8-comprehensions "SIM", # flake8-simplify "S", # flake8-bandit (security) "TCH", # flake8-type-checking "RUF", # ruff-specific rules ] [tool.ruff.lint.per-file-ignores] "tests/**/*.py" = ["S101"] # Allow assert in tests [tool.ruff.format] quote-style = "double" indent-style = "space" # === Pytest Configuration === [tool.pytest.ini_options] testpaths = ["tests"] addopts = [ "--strict-markers", "--strict-config", "-ra", ] [tool.coverage.run] source = ["src"] branch = true [tool.coverage.report] fail_under = 80 show_missing = true exclude_lines = [ "if TYPE_CHECKING:", "if __name__ == .__main__.:", ]
Daily Workflow Commands
Package Management (uv)
# Add a dependency uv add requests # Add a dev dependency uv add --group dev ipdb # Remove a dependency uv remove requests # Update all dependencies uv lock --upgrade # Update a specific dependency uv lock --upgrade-package requests # Run a script in the project environment uv run python script.py # Run a tool (without installing globally) uv run --with httpie http GET https://api.example.com
Linting and Formatting (ruff)
# Check for lint errors uv run ruff check . # Auto-fix lint errors uv run ruff check --fix . # Format code uv run ruff format . # Check formatting (dry run) uv run ruff format --check . # Check specific rules uv run ruff check --select S . # Security rules only
Type Checking (ty)
# Run type checker uv run ty check # Check specific file uv run ty check src/main.py
Testing (pytest)
# Run all tests uv run pytest # Run with coverage uv run pytest --cov # Run specific test file uv run pytest tests/test_auth.py # Run with verbose output uv run pytest -v # Run and stop at first failure uv run pytest -x
Migration Guide
From pip/requirements.txt
# Install uv curl -LsSf https://astral.sh/uv/install.sh | sh # Initialize project from existing requirements uv init uv add $(cat requirements.txt | grep -v '^#' | grep -v '^$') # Remove old files rm requirements.txt requirements-dev.txt
From Poetry
# uv can read pyproject.toml with Poetry sections uv init # Move Poetry dependencies to [project.dependencies] # Move [tool.poetry.group.dev.dependencies] to [dependency-groups] # Remove [tool.poetry] section uv sync
From flake8/black/isort to ruff
# Remove old tools uv remove flake8 black isort pyflakes pycodestyle # Add ruff uv add --group dev ruff # Convert .flake8 config to ruff (manual) # ruff supports most flake8 rules with same codes # Remove old config files rm .flake8 .isort.cfg pyproject.toml.bak
From mypy to ty
# Remove mypy uv remove mypy # Add ty uv add --group dev ty # ty uses the same type annotation syntax as mypy # Most code requires no changes
CI/CD Configuration
GitHub Actions
name: CI on: push: branches: [main] pull_request: branches: [main] jobs: check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v4 with: enable-cache: true - name: Install dependencies run: uv sync --all-groups - name: Lint run: uv run ruff check . - name: Format check run: uv run ruff format --check . - name: Type check run: uv run ty check - name: Test run: uv run pytest --cov --cov-report=xml - name: Upload coverage uses: codecov/codecov-action@v4 with: file: coverage.xml
Dependabot Configuration
# .github/dependabot.yml version: 2 updates: - package-ecosystem: 'uv' directory: '/' schedule: interval: 'weekly' groups: all: patterns: - '*'
Pre-commit Hooks
# .pre-commit-config.yaml repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.9.0 hooks: - id: ruff args: [--fix] - id: ruff-format
Code Patterns
Type Annotations
from __future__ import annotations from collections.abc import Sequence from typing import TypeAlias # Use modern syntax (Python 3.12+) type Vector = list[float] # Type alias (PEP 695) def process_items(items: Sequence[str], *, limit: int = 10) -> list[str]: """Process items with a limit.""" return [item.strip() for item in items[:limit]] # Use | instead of Union def maybe_int(value: str) -> int | None: try: return int(value) except ValueError: return None
Project Structure
my-project/ pyproject.toml # Single config file for all tools uv.lock # Locked dependencies (commit this) src/ my_project/ __init__.py main.py models.py utils.py tests/ __init__.py test_main.py test_models.py conftest.py # Shared fixtures .github/ workflows/ ci.yml dependabot.yml .pre-commit-config.yaml
Common Pitfalls
- Using pip directly: Always use
/uv add
/uv remove
. Neveruv run
.pip install - Separate config files: All configuration goes in
. Deletepyproject.toml
,.flake8
,mypy.ini
.black.toml - Global installs: Use
oruv run
instead of globally installing CLI tools.uv tool run - Missing lock file: Always commit
for reproducible builds.uv.lock - Old Python syntax: Use
to auto-upgrade to modern syntax (match statements,ruff --select UP
unions, etc.).| - Ignoring security rules: Enable
(bandit) rules in ruff to catch security issues.S
Integration with Agent-Studio
Recommended Workflow
- Use
to set up or migrate Python projectsmodern-python - Use
for framework-specific patterns (Django, FastAPI)python-backend-expert - Use
skill for test-driven development workflowtdd - Use
for test strategycomprehensive-unit-testing-with-pytest
Complementary Skills
| Skill | Relationship |
|---|---|
| Framework-specific patterns (Django, FastAPI, Flask) |
| Testing strategies and patterns |
| Type annotation best practices |
| Modern Python language features |
| Test-driven development methodology |
| Hypothesis-based testing patterns |
Memory Protocol
Before starting: Check if the project already has Python tooling configured. Identify which legacy tools need migration.
During setup: Write configuration incrementally, verifying each tool works before moving to the next. Run
ruff check, ruff format --check, and uv run pytest at each step.
After completion: Record the toolchain versions and any migration issues to
.claude/context/memory/learnings.md for future reference.