Modern 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…

)\n\n# Remove old files\nrm requirements.txt requirements-dev.txt\n```\n\n### From Poetry\n\n```bash\n# uv can read pyproject.toml with Poetry sections\nuv init\n\n# Move Poetry dependencies to [project.dependencies]\n# Move [tool.poetry.group.dev.dependencies] to [dependency-groups]\n# Remove [tool.poetry] section\n\nuv sync\n```\n\n### From flake8/black/isort to ruff\n\n```bash\n# Remove old tools\nuv remove flake8 black isort pyflakes pycodestyle\n\n# Add ruff\nuv add --group dev ruff\n\n# Convert .flake8 config to ruff (manual)\n# ruff supports most flake8 rules with same codes\n\n# Remove old config files\nrm .flake8 .isort.cfg pyproject.toml.bak\n```\n\n### From mypy to ty\n\n```bash\n# Remove mypy\nuv remove mypy\n\n# Add ty\nuv add --group dev ty\n\n# ty uses the same type annotation syntax as mypy\n# Most code requires no changes\n```\n\n## CI/CD Configuration\n\n### GitHub Actions\n\n```yaml\nname: CI\n\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\n\njobs:\n check:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - uses: astral-sh/setup-uv@v4\n with:\n enable-cache: true\n\n - name: Install dependencies\n run: uv sync --all-groups\n\n - name: Lint\n run: uv run ruff check .\n\n - name: Format check\n run: uv run ruff format --check .\n\n - name: Type check\n run: uv run ty check\n\n - name: Test\n run: uv run pytest --cov --cov-report=xml\n\n - name: Upload coverage\n uses: codecov/codecov-action@v4\n with:\n file: coverage.xml\n```\n\n### Dependabot Configuration\n\n```yaml\n# .github/dependabot.yml\nversion: 2\nupdates:\n - package-ecosystem: 'uv'\n directory: '/'\n schedule:\n interval: 'weekly'\n groups:\n all:\n patterns:\n - '*'\n```\n\n## Pre-commit Hooks\n\n```yaml\n# .pre-commit-config.yaml\nrepos:\n - repo: https://github.com/astral-sh/ruff-pre-commit\n rev: v0.9.0\n hooks:\n - id: ruff\n args: [--fix]\n - id: ruff-format\n```\n\n## Code Patterns\n\n### Type Annotations\n\n```python\nfrom __future__ import annotations\n\nfrom collections.abc import Sequence\nfrom typing import TypeAlias\n\n# Use modern syntax (Python 3.12+)\ntype Vector = list[float] # Type alias (PEP 695)\n\ndef process_items(items: Sequence[str], *, limit: int = 10) -> list[str]:\n \"\"\"Process items with a limit.\"\"\"\n return [item.strip() for item in items[:limit]]\n\n# Use | instead of Union\ndef maybe_int(value: str) -> int | None:\n try:\n return int(value)\n except ValueError:\n return None\n```\n\n### Project Structure\n\n```\nmy-project/\n pyproject.toml # Single config file for all tools\n uv.lock # Locked dependencies (commit this)\n src/\n my_project/\n __init__.py\n main.py\n models.py\n utils.py\n tests/\n __init__.py\n test_main.py\n test_models.py\n conftest.py # Shared fixtures\n .github/\n workflows/\n ci.yml\n dependabot.yml\n .pre-commit-config.yaml\n```\n\n## Common Pitfalls\n\n1. **Using pip directly**: Always use `uv add` / `uv remove` / `uv run`. Never `pip install`.\n2. **Separate config files**: All configuration goes in `pyproject.toml`. Delete `.flake8`, `mypy.ini`, `black.toml`.\n3. **Global installs**: Use `uv run` or `uv tool run` instead of globally installing CLI tools.\n4. **Missing lock file**: Always commit `uv.lock` for reproducible builds.\n5. **Old Python syntax**: Use `ruff --select UP` to auto-upgrade to modern syntax (match statements, `|` unions, etc.).\n6. **Ignoring security rules**: Enable `S` (bandit) rules in ruff to catch security issues.\n\n## Integration with Agent-Studio\n\n### Recommended Workflow\n\n1. Use `modern-python` to set up or migrate Python projects\n2. Use `python-backend-expert` for framework-specific patterns (Django, FastAPI)\n3. Use `tdd` skill for test-driven development workflow\n4. Use `comprehensive-unit-testing-with-pytest` for test strategy\n\n### Complementary Skills\n\n| Skill | Relationship |\n| ---------------------------------------- | ---------------------------------------------------- |\n| `python-backend-expert` | Framework-specific patterns (Django, FastAPI, Flask) |\n| `comprehensive-unit-testing-with-pytest` | Testing strategies and patterns |\n| `comprehensive-type-annotations` | Type annotation best practices |\n| `prioritize-python-3-10-features` | Modern Python language features |\n| `tdd` | Test-driven development methodology |\n| `property-based-testing` | Hypothesis-based testing patterns |\n\n## Memory Protocol\n\n**Before starting**: Check if the project already has Python tooling configured. Identify which legacy tools need migration.\n\n**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.\n\n**After completion**: Record the toolchain versions and any migration issues to `.claude/context/memory/learnings.md` for future reference.\n---","attachment_filenames":["commands/modern-python.md","references/research-requirements.md","rules/modern-python.md","schemas/input.schema.json","schemas/output.schema.json","templates/implementation-template.md"],"attachments":[{"filename":"commands/modern-python.md","content":"---\ndisable-model-invocation: true\n---\n\nInvoke the modern-python skill and follow it exactly as presented to you\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":113,"content_sha256":"d031cb239257cbaf27d9567fcf94fa4aa47fb06a43b5500f8dba4c57d2c9bf38"},{"filename":"references/research-requirements.md","content":"# modern-python Research Requirements\n\nGenerated: 2026-02-28\n\n## Skill Description\n\nModern 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.\n\n## Research Areas\n\n- Current best practices for modern-python\n- Industry standards and tooling\n- Integration patterns\n\n## Source References\n\n- To be populated by skill-updater research phase\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":531,"content_sha256":"f085a4615cdcb40584827a4211348d02953ca8883c7699afbaf0fd0c4ecb5a76"},{"filename":"rules/modern-python.md","content":"# modern-python Rules\n\n## Purpose\n\nModern 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.\n\n## Best Practices\n\n- Always use uv for dependency management instead of pip/Poetry/pipenv\n- Use ruff for both linting and formatting instead of separate tools\n- Use ty for type checking instead of mypy (faster, Rust-based)\n- Structure tests with pytest and use hypothesis for property-based testing\n- Configure all tools in pyproject.toml, never in separate config files\n\n## Integration Points\n\nSee SKILL.md for complete documentation.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":727,"content_sha256":"4dc83f32fd3af87f75dbc4f45c9bbf7cd7db5582e0adbd6c115844a53e2d5bec"},{"filename":"schemas/input.schema.json","content":"{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"title\": \"modern-pythonInput\",\n \"description\": \"Input schema for 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.\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"properties\": {\n \"target\": {\n \"type\": \"string\",\n \"description\": \"Target file or path for the skill to operate on\"\n },\n \"options\": {\n \"type\": \"object\",\n \"description\": \"Additional options for skill execution\",\n \"additionalProperties\": true\n }\n }\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":722,"content_sha256":"6c1c564f23d8551201522ac038ba2d67ed27434a54a40de860761d4a6f15c500"},{"filename":"schemas/output.schema.json","content":"{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"title\": \"modern-pythonOutput\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"properties\": {\n \"ok\": {\n \"type\": \"boolean\"\n },\n \"summary\": {\n \"type\": \"string\"\n }\n }\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":257,"content_sha256":"4dd76b6a556f760c06f497557a6922c37cfe45ce6b3ffacec43ad6b2aaa4d1ff"},{"filename":"templates/implementation-template.md","content":"# modern-python Implementation Template\n\n## Goal\n\n- Define target outcome and acceptance criteria.\n\n## TDD\n\n1. Red\n2. Green\n3. Refactor\n\n## Verification\n\n- lint\n- format\n- targeted tests\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":187,"content_sha256":"cc891c08a35aca6d54c2873a0ee8f9e524feb57a52900f630425ad4c8bf0d51b"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Modern Python Skill","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003c!-- Agent: evolution-orchestrator | Task: #2 | Session: 2026-02-21 --> \u003c!-- License: CC-BY-SA-4.0 | Source: Trail of Bits (github.com/trailofbits/skills) --> \u003c!-- Attribution: Adapted from Trail of Bits modern-python skill and trailofbits/cookiecutter-python -->","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003cidentity> 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. \u003c/identity>","type":"text"}]},{"type":"paragraph","content":[{"text":"\u003ccapabilities>","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Project initialization with modern Python toolchain (uv + ruff + ty + pytest)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Migration from legacy tools (pip/Poetry/pipenv to uv, black/flake8/isort to ruff, mypy to ty)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"pyproject.toml configuration for all tools (single source of truth)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Dependency management with uv (lock files, dependency groups, virtual environments)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Linting and formatting with ruff (replaces flake8, isort, black, pyflakes, pycodestyle)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Type checking with ty (Rust-based, faster than mypy)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Testing with pytest, pytest-cov, and hypothesis","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CI/CD configuration with GitHub Actions","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Dependabot setup for automated dependency updates","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Pre-commit hook configuration \u003c/capabilities>","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Overview","type":"text"}]},{"type":"paragraph","content":[{"text":"This skill implements Trail of Bits' modern Python coding standards for the agent-studio framework. The core philosophy is: ","type":"text"},{"text":"use Rust-based tools for faster feedback loops, especially when working with AI agents","type":"text","marks":[{"type":"strong"}]},{"text":". Every tool in this stack (uv, ruff, ty) is written in Rust and provides sub-second execution times, enabling tight iteration cycles.","type":"text"}]},{"type":"paragraph","content":[{"text":"Source repository","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"https://github.com/trailofbits/skills","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"Template","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"https://github.com/trailofbits/cookiecutter-python","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"License","type":"text","marks":[{"type":"strong"}]},{"text":": CC-BY-SA-4.0","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Use","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When creating new Python projects from scratch","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When migrating Python projects from legacy tooling","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When setting up CI/CD pipelines for Python projects","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When standardizing Python tooling across a team","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When writing standalone Python scripts that need proper structure","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"When an AI agent needs fast feedback from Python tooling","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Iron Laws","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ALWAYS","type":"text","marks":[{"type":"strong"}]},{"text":" configure all Python tooling in ","type":"text"},{"text":"pyproject.toml","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- no separate config files (","type":"text"},{"text":"setup.cfg","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":".flake8","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"mypy.ini","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"black.toml","type":"text","marks":[{"type":"code_inline"}]},{"text":") are permitted.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ALWAYS","type":"text","marks":[{"type":"strong"}]},{"text":" use ","type":"text"},{"text":"uv add","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"uv remove","type":"text","marks":[{"type":"code_inline"}]},{"text":" for dependency management -- never use bare ","type":"text"},{"text":"pip install","type":"text","marks":[{"type":"code_inline"}]},{"text":" in projects managed by uv.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER","type":"text","marks":[{"type":"strong"}]},{"text":" commit ","type":"text"},{"text":"venv/","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":".venv/","type":"text","marks":[{"type":"code_inline"}]},{"text":", or pip-generated ","type":"text"},{"text":"requirements.txt","type":"text","marks":[{"type":"code_inline"}]},{"text":" -- commit ","type":"text"},{"text":"uv.lock","type":"text","marks":[{"type":"code_inline"}]},{"text":" for reproducible builds.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ALWAYS","type":"text","marks":[{"type":"strong"}]},{"text":" use ","type":"text"},{"text":"uv run","type":"text","marks":[{"type":"code_inline"}]},{"text":" to execute tools and scripts -- this ensures the correct virtual environment and dependency resolution.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"NEVER","type":"text","marks":[{"type":"strong"}]},{"text":" use legacy linting/formatting tools (flake8, black, isort, mypy) when ruff and ty are available -- consolidate to the Rust-based stack for speed and consistency.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Anti-Patterns","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Anti-Pattern","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Why It Fails","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Correct Approach","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Using ","type":"text"},{"text":"pip install","type":"text","marks":[{"type":"code_inline"}]},{"text":" directly in a uv-managed project","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Bypasses lockfile and dependency resolution; creates reproducibility drift","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"uv add \u003cpkg>","type":"text","marks":[{"type":"code_inline"}]},{"text":" to add dependencies and ","type":"text"},{"text":"uv sync","type":"text","marks":[{"type":"code_inline"}]},{"text":" to install","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Maintaining ","type":"text"},{"text":".flake8","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"mypy.ini","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":"black.toml","type":"text","marks":[{"type":"code_inline"}]},{"text":" config files","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fragments configuration across multiple files; hard to maintain and audit","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Consolidate all tool config into ","type":"text"},{"text":"pyproject.toml","type":"text","marks":[{"type":"code_inline"}]},{"text":" under ","type":"text"},{"text":"[tool.ruff]","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"[tool.ty]","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Running ","type":"text"},{"text":"python script.py","type":"text","marks":[{"type":"code_inline"}]},{"text":" instead of ","type":"text"},{"text":"uv run python script.py","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Uses system Python instead of project venv; dependency mismatches","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Always use ","type":"text"},{"text":"uv run","type":"text","marks":[{"type":"code_inline"}]},{"text":" to execute within the managed environment","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Globally installing CLI tools with ","type":"text"},{"text":"pip install --user","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pollutes global environment; version conflicts across projects","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"uv tool run \u003ctool>","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"uvx \u003ctool>","type":"text","marks":[{"type":"code_inline"}]},{"text":" for one-off tool execution","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Ignoring ruff security rules (","type":"text"},{"text":"S","type":"text","marks":[{"type":"code_inline"}]},{"text":" select)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Misses bandit-equivalent security checks like hardcoded passwords and SQL injection","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Enable ","type":"text"},{"text":"select = [\"S\"]","type":"text","marks":[{"type":"code_inline"}]},{"text":" in ","type":"text"},{"text":"[tool.ruff.lint]","type":"text","marks":[{"type":"code_inline"}]},{"text":" for security linting","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"The Modern Python Stack","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tool","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Replaces","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Purpose","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Speed","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"uv","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pip, Poetry, pipenv, pip-tools","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Package & project management","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"10-100x faster","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ruff","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"flake8, isort, black, pyflakes, pycodestyle, pydocstyle","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Linting + formatting","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"10-100x faster","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ty","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"mypy, pyright, pytype","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Type checking","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"5-10x faster","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pytest","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"unittest","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Testing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"hypothesis","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"(manual property tests)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Property-based testing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Project Setup","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"New Project","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Create new project with uv\nuv init my-project\ncd my-project\n\n# Add dependency groups\nuv add --group dev ruff ty\nuv add --group test pytest pytest-cov hypothesis\nuv add --group docs sphinx myst-parser\n\n# Install all dependencies\nuv sync --all-groups","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"pyproject.toml Configuration","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"toml"},"content":[{"text":"[project]\nname = \"my-project\"\nversion = \"0.1.0\"\nrequires-python = \">=3.12\"\ndependencies = []\n\n[dependency-groups]\ndev = [\"ruff\", \"ty\"]\ntest = [\"pytest\", \"pytest-cov\", \"hypothesis\"]\ndocs = [\"sphinx\", \"myst-parser\"]\n\n# === Ruff Configuration ===\n[tool.ruff]\ntarget-version = \"py312\"\nline-length = 100\n\n[tool.ruff.lint]\nselect = [\n \"E\", # pycodestyle errors\n \"W\", # pycodestyle warnings\n \"F\", # pyflakes\n \"I\", # isort\n \"N\", # pep8-naming\n \"UP\", # pyupgrade\n \"B\", # flake8-bugbear\n \"A\", # flake8-builtins\n \"C4\", # flake8-comprehensions\n \"SIM\", # flake8-simplify\n \"S\", # flake8-bandit (security)\n \"TCH\", # flake8-type-checking\n \"RUF\", # ruff-specific rules\n]\n\n[tool.ruff.lint.per-file-ignores]\n\"tests/**/*.py\" = [\"S101\"] # Allow assert in tests\n\n[tool.ruff.format]\nquote-style = \"double\"\nindent-style = \"space\"\n\n# === Pytest Configuration ===\n[tool.pytest.ini_options]\ntestpaths = [\"tests\"]\naddopts = [\n \"--strict-markers\",\n \"--strict-config\",\n \"-ra\",\n]\n\n[tool.coverage.run]\nsource = [\"src\"]\nbranch = true\n\n[tool.coverage.report]\nfail_under = 80\nshow_missing = true\nexclude_lines = [\n \"if TYPE_CHECKING:\",\n \"if __name__ == .__main__.:\",\n]","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Daily Workflow Commands","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Package Management (uv)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Add a dependency\nuv add requests\n\n# Add a dev dependency\nuv add --group dev ipdb\n\n# Remove a dependency\nuv remove requests\n\n# Update all dependencies\nuv lock --upgrade\n\n# Update a specific dependency\nuv lock --upgrade-package requests\n\n# Run a script in the project environment\nuv run python script.py\n\n# Run a tool (without installing globally)\nuv run --with httpie http GET https://api.example.com","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Linting and Formatting (ruff)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Check for lint errors\nuv run ruff check .\n\n# Auto-fix lint errors\nuv run ruff check --fix .\n\n# Format code\nuv run ruff format .\n\n# Check formatting (dry run)\nuv run ruff format --check .\n\n# Check specific rules\nuv run ruff check --select S . # Security rules only","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Type Checking (ty)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Run type checker\nuv run ty check\n\n# Check specific file\nuv run ty check src/main.py","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Testing (pytest)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Run all tests\nuv run pytest\n\n# Run with coverage\nuv run pytest --cov\n\n# Run specific test file\nuv run pytest tests/test_auth.py\n\n# Run with verbose output\nuv run pytest -v\n\n# Run and stop at first failure\nuv run pytest -x","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Migration Guide","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"From pip/requirements.txt","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Install uv\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Initialize project from existing requirements\nuv init\nuv add $(cat requirements.txt | grep -v '^#' | grep -v '^

Modern 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…

)\n\n# Remove old files\nrm requirements.txt requirements-dev.txt","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"From Poetry","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# uv can read pyproject.toml with Poetry sections\nuv init\n\n# Move Poetry dependencies to [project.dependencies]\n# Move [tool.poetry.group.dev.dependencies] to [dependency-groups]\n# Remove [tool.poetry] section\n\nuv sync","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"From flake8/black/isort to ruff","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Remove old tools\nuv remove flake8 black isort pyflakes pycodestyle\n\n# Add ruff\nuv add --group dev ruff\n\n# Convert .flake8 config to ruff (manual)\n# ruff supports most flake8 rules with same codes\n\n# Remove old config files\nrm .flake8 .isort.cfg pyproject.toml.bak","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"From mypy to ty","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Remove mypy\nuv remove mypy\n\n# Add ty\nuv add --group dev ty\n\n# ty uses the same type annotation syntax as mypy\n# Most code requires no changes","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"CI/CD Configuration","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"GitHub Actions","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"yaml"},"content":[{"text":"name: CI\n\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\n\njobs:\n check:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - uses: astral-sh/setup-uv@v4\n with:\n enable-cache: true\n\n - name: Install dependencies\n run: uv sync --all-groups\n\n - name: Lint\n run: uv run ruff check .\n\n - name: Format check\n run: uv run ruff format --check .\n\n - name: Type check\n run: uv run ty check\n\n - name: Test\n run: uv run pytest --cov --cov-report=xml\n\n - name: Upload coverage\n uses: codecov/codecov-action@v4\n with:\n file: coverage.xml","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Dependabot Configuration","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"yaml"},"content":[{"text":"# .github/dependabot.yml\nversion: 2\nupdates:\n - package-ecosystem: 'uv'\n directory: '/'\n schedule:\n interval: 'weekly'\n groups:\n all:\n patterns:\n - '*'","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Pre-commit Hooks","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"yaml"},"content":[{"text":"# .pre-commit-config.yaml\nrepos:\n - repo: https://github.com/astral-sh/ruff-pre-commit\n rev: v0.9.0\n hooks:\n - id: ruff\n args: [--fix]\n - id: ruff-format","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Code Patterns","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Type Annotations","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"from __future__ import annotations\n\nfrom collections.abc import Sequence\nfrom typing import TypeAlias\n\n# Use modern syntax (Python 3.12+)\ntype Vector = list[float] # Type alias (PEP 695)\n\ndef process_items(items: Sequence[str], *, limit: int = 10) -> list[str]:\n \"\"\"Process items with a limit.\"\"\"\n return [item.strip() for item in items[:limit]]\n\n# Use | instead of Union\ndef maybe_int(value: str) -> int | None:\n try:\n return int(value)\n except ValueError:\n return None","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Project Structure","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"my-project/\n pyproject.toml # Single config file for all tools\n uv.lock # Locked dependencies (commit this)\n src/\n my_project/\n __init__.py\n main.py\n models.py\n utils.py\n tests/\n __init__.py\n test_main.py\n test_models.py\n conftest.py # Shared fixtures\n .github/\n workflows/\n ci.yml\n dependabot.yml\n .pre-commit-config.yaml","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Common Pitfalls","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Using pip directly","type":"text","marks":[{"type":"strong"}]},{"text":": Always use ","type":"text"},{"text":"uv add","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"uv remove","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"uv run","type":"text","marks":[{"type":"code_inline"}]},{"text":". Never ","type":"text"},{"text":"pip install","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Separate config files","type":"text","marks":[{"type":"strong"}]},{"text":": All configuration goes in ","type":"text"},{"text":"pyproject.toml","type":"text","marks":[{"type":"code_inline"}]},{"text":". Delete ","type":"text"},{"text":".flake8","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"mypy.ini","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"black.toml","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Global installs","type":"text","marks":[{"type":"strong"}]},{"text":": Use ","type":"text"},{"text":"uv run","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"uv tool run","type":"text","marks":[{"type":"code_inline"}]},{"text":" instead of globally installing CLI tools.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Missing lock file","type":"text","marks":[{"type":"strong"}]},{"text":": Always commit ","type":"text"},{"text":"uv.lock","type":"text","marks":[{"type":"code_inline"}]},{"text":" for reproducible builds.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Old Python syntax","type":"text","marks":[{"type":"strong"}]},{"text":": Use ","type":"text"},{"text":"ruff --select UP","type":"text","marks":[{"type":"code_inline"}]},{"text":" to auto-upgrade to modern syntax (match statements, ","type":"text"},{"text":"|","type":"text","marks":[{"type":"code_inline"}]},{"text":" unions, etc.).","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Ignoring security rules","type":"text","marks":[{"type":"strong"}]},{"text":": Enable ","type":"text"},{"text":"S","type":"text","marks":[{"type":"code_inline"}]},{"text":" (bandit) rules in ruff to catch security issues.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Integration with Agent-Studio","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Recommended Workflow","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"modern-python","type":"text","marks":[{"type":"code_inline"}]},{"text":" to set up or migrate Python projects","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"python-backend-expert","type":"text","marks":[{"type":"code_inline"}]},{"text":" for framework-specific patterns (Django, FastAPI)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"tdd","type":"text","marks":[{"type":"code_inline"}]},{"text":" skill for test-driven development workflow","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"comprehensive-unit-testing-with-pytest","type":"text","marks":[{"type":"code_inline"}]},{"text":" for test strategy","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Complementary Skills","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Skill","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Relationship","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"python-backend-expert","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Framework-specific patterns (Django, FastAPI, Flask)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"comprehensive-unit-testing-with-pytest","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Testing strategies and patterns","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"comprehensive-type-annotations","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Type annotation best practices","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"prioritize-python-3-10-features","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Modern Python language features","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"tdd","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Test-driven development methodology","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"property-based-testing","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Hypothesis-based testing patterns","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Memory Protocol","type":"text"}]},{"type":"paragraph","content":[{"text":"Before starting","type":"text","marks":[{"type":"strong"}]},{"text":": Check if the project already has Python tooling configured. Identify which legacy tools need migration.","type":"text"}]},{"type":"paragraph","content":[{"text":"During setup","type":"text","marks":[{"type":"strong"}]},{"text":": Write configuration incrementally, verifying each tool works before moving to the next. Run ","type":"text"},{"text":"ruff check","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"ruff format --check","type":"text","marks":[{"type":"code_inline"}]},{"text":", and ","type":"text"},{"text":"uv run pytest","type":"text","marks":[{"type":"code_inline"}]},{"text":" at each step.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"After completion","type":"text","marks":[{"type":"strong"}]},{"text":": Record the toolchain versions and any migration issues to ","type":"text"},{"text":".claude/context/memory/learnings.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for future reference.","type":"text"}]}]},"metadata":{"args":"[--init] [--migrate] [--check] [--fix]","date":"2026-06-05","name":"modern-python","tags":["python","uv","ruff","ty","pytest","tooling","linting","formatting","type-checking","dependency-management"],"model":"sonnet","tools":["Read","Write","Bash","Glob","Grep"],"agents":["python-pro","developer","fastapi-pro"],"author":"@skillopedia","source":{"stars":29,"repo_name":"agent-studio","origin_url":"https://github.com/oimiragieo/agent-studio/blob/HEAD/.claude/skills/modern-python/SKILL.md","repo_owner":"oimiragieo","body_sha256":"10eedf921dcc023207d33414fe4daad3f70693c109989930899318171dc15f70","cluster_key":"c0188fa689aa834fc9a062d6977e3f43e896ef00c28e65476950404e1599bd6e","clean_bundle":{"format":"clean-skill-bundle-v1","source":"oimiragieo/agent-studio/.claude/skills/modern-python/SKILL.md","attachments":[{"id":"df5e2e59-e172-5e34-bc92-bcff2e79ec38","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/df5e2e59-e172-5e34-bc92-bcff2e79ec38/attachment.md","path":"commands/modern-python.md","size":113,"sha256":"d031cb239257cbaf27d9567fcf94fa4aa47fb06a43b5500f8dba4c57d2c9bf38","contentType":"text/markdown; charset=utf-8"},{"id":"2e0cdfad-d574-5571-b211-a7f590665160","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/2e0cdfad-d574-5571-b211-a7f590665160/attachment.cjs","path":"hooks/post-execute.cjs","size":304,"sha256":"5400780405de3918c9872a4d8f779cf9ba7679ed206b631a12e7f64b14ffb014","contentType":"text/plain; charset=utf-8"},{"id":"1a4f893e-967d-5527-9171-de762e4cd376","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/1a4f893e-967d-5527-9171-de762e4cd376/attachment.cjs","path":"hooks/pre-execute.cjs","size":421,"sha256":"ae766c905f47a2d29a6fae4f77f1cf6739140b16a36bc2c86b312821ccb95cfb","contentType":"text/plain; charset=utf-8"},{"id":"4e55c999-2aa1-59eb-9cf2-e3c4bdad077d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/4e55c999-2aa1-59eb-9cf2-e3c4bdad077d/attachment.md","path":"references/research-requirements.md","size":531,"sha256":"f085a4615cdcb40584827a4211348d02953ca8883c7699afbaf0fd0c4ecb5a76","contentType":"text/markdown; charset=utf-8"},{"id":"5059a95f-96f4-5df9-a570-2debd22370a7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/5059a95f-96f4-5df9-a570-2debd22370a7/attachment.md","path":"rules/modern-python.md","size":727,"sha256":"4dc83f32fd3af87f75dbc4f45c9bbf7cd7db5582e0adbd6c115844a53e2d5bec","contentType":"text/markdown; charset=utf-8"},{"id":"8d1b0bce-65a6-509b-85fd-355da783b60d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/8d1b0bce-65a6-509b-85fd-355da783b60d/attachment.json","path":"schemas/input.schema.json","size":722,"sha256":"6c1c564f23d8551201522ac038ba2d67ed27434a54a40de860761d4a6f15c500","contentType":"application/json; charset=utf-8"},{"id":"8a6e0dfc-1e10-504e-808a-1bd3d9a86062","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/8a6e0dfc-1e10-504e-808a-1bd3d9a86062/attachment.json","path":"schemas/output.schema.json","size":257,"sha256":"4dd76b6a556f760c06f497557a6922c37cfe45ce6b3ffacec43ad6b2aaa4d1ff","contentType":"application/json; charset=utf-8"},{"id":"d7d73be4-8bdb-5d2e-84b8-26657a493631","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d7d73be4-8bdb-5d2e-84b8-26657a493631/attachment.cjs","path":"scripts/main.cjs","size":1253,"sha256":"2ad673bad0d54de64fb9014dac9c56d0f759b1352592a83ca93354d7ef73e053","contentType":"text/plain; charset=utf-8"},{"id":"111ebcfa-89e6-562f-82eb-f5d2d0b6aaae","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/111ebcfa-89e6-562f-82eb-f5d2d0b6aaae/attachment.md","path":"templates/implementation-template.md","size":187,"sha256":"cc891c08a35aca6d54c2873a0ee8f9e524feb57a52900f630425ad4c8bf0d51b","contentType":"text/markdown; charset=utf-8"}],"bundle_sha256":"52e488b4a1e7e172f6fdc7344959a03e13dd654858c7302bcfecf8bddd2302d2","attachment_count":9,"text_attachments":9,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":".claude/skills/modern-python/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"testing-qa","category_label":"Testing"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"testing-qa","verified":true,"streaming":"supported","import_tag":"clean-skills-v1","invoked_by":"both","description":"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.","trust_score":100,"best_practices":["Always use uv for dependency management instead of pip/Poetry/pipenv","Use ruff for both linting and formatting instead of separate tools","Use ty for type checking instead of mypy (faster, Rust-based)","Structure tests with pytest and use hypothesis for property-based testing","Configure all tools in pyproject.toml, never in separate config files"],"error_handling":"graceful","lastVerifiedAt":"2026-03-01","provenance_sha":"8b510b7ff762a6a6","user_invocable":true}},"renderedAt":1782979232308}

Modern 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…