Enforces strict type safety and testing standards for Python projects.

Install

mkdir -p .claude/skills/python && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/4297" && unzip -o skill.zip -d .claude/skills/python && rm skill.zip

Installs to .claude/skills/python

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Python development with ruff, mypy, pytest - TDD and type safety
64 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Enforce strict type hints on function signatures
  • Separate pure business logic from side effects
  • Configure linting and formatting rules via Ruff
  • Implement unit and integration tests with Pytest
  • Validate data structures using Pydantic models
  • Apply dependency injection for database operations

How it works

The skill establishes a project structure with separated concerns and enforces quality gates through pre-commit hooks, Mypy type checking, and Pytest coverage requirements.

Inputs & outputs

You give it
Python source code files and project configuration
You get back
Validated, linted, and tested Python project structure

When to use python

  • Setting up a new Python project structure
  • Adding strict type hints to existing code
  • Configuring linting and formatting rules
  • Implementing unit tests with Pytest

About this skill

Python Skill


Type Hints

  • Use type hints on all function signatures
  • Use typing module for complex types
  • Run mypy --strict in CI
def process_user(user_id: int, options: dict[str, Any] | None = None) -> User:
    ...

Project Structure

project/
├── src/
│   └── package_name/
│       ├── __init__.py
│       ├── core/           # Pure business logic
│       │   ├── __init__.py
│       │   ├── models.py   # Pydantic models / dataclasses
│       │   └── services.py # Pure functions
│       ├── infra/          # Side effects
│       │   ├── __init__.py
│       │   ├── api.py      # FastAPI routes
│       │   └── db.py       # Database operations
│       └── utils/          # Shared utilities
├── tests/
│   ├── unit/
│   └── integration/
├── pyproject.toml
└── CLAUDE.md

Tooling (Required)

# pyproject.toml
[tool.ruff]
line-length = 100
select = ["E", "F", "I", "N", "W", "UP"]

[tool.mypy]
strict = true

[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "--cov=src --cov-report=term-missing --cov-fail-under=80"

Testing with Pytest

# tests/unit/test_services.py
import pytest
from package_name.core.services import calculate_total

class TestCalculateTotal:
    def test_returns_sum_of_items(self):
        # Arrange
        items = [{"price": 10}, {"price": 20}]
        
        # Act
        result = calculate_total(items)
        
        # Assert
        assert result == 30

    def test_returns_zero_for_empty_list(self):
        assert calculate_total([]) == 0

    def test_raises_on_invalid_item(self):
        with pytest.raises(ValueError):
            calculate_total([{"invalid": "item"}])

GitHub Actions

name: Python Quality Gate

on: [push, pull_request]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          
      - name: Install dependencies
        run: |
          pip install -e ".[dev]"
          
      - name: Lint (Ruff)
        run: ruff check .
        
      - name: Format Check (Ruff)
        run: ruff format --check .
        
      - name: Type Check (mypy)
        run: mypy src/
        
      - name: Test with Coverage
        run: pytest

Pre-Commit Hooks

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.8.0
    hooks:
      - id: ruff
        args: [--fix]
      - id: ruff-format

  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.13.0
    hooks:
      - id: mypy
        additional_dependencies: [pydantic]
        args: [--strict]

  - repo: local
    hooks:
      - id: pytest
        name: pytest
        entry: pytest tests/unit -x --tb=short
        language: system
        pass_filenames: false
        always_run: true

Install and setup:

pip install pre-commit
pre-commit install

Patterns

Pydantic for Data Validation

from pydantic import BaseModel, Field

class CreateUserRequest(BaseModel):
    email: str = Field(..., min_length=5)
    name: str = Field(..., max_length=100)

Dependency Injection

# Don't import dependencies directly in business logic
# Pass them in

# Bad
from .db import database
def get_user(user_id: int) -> User:
    return database.fetch(user_id)

# Good
def get_user(user_id: int, db: Database) -> User:
    return db.fetch(user_id)

Result Pattern (No Exceptions in Core)

from dataclasses import dataclass

@dataclass
class Result[T]:
    value: T | None
    error: str | None
    
    @property
    def is_ok(self) -> bool:
        return self.error is None

Python Anti-Patterns

  • from module import *
  • ❌ Mutable default arguments
  • ❌ Bare except: clauses
  • ❌ Using type: ignore without explanation
  • ❌ Global variables for state
  • ❌ Classes when functions suffice

When not to use it

  • When project requirements prohibit external dependencies
  • When working outside of Python environments

Prerequisites

pippre-commit

Limitations

  • Requires adherence to strict Mypy settings
  • Enforces a minimum 80% test coverage threshold

How it compares

Unlike manual project setup, this approach enforces standardized tooling configurations and architectural patterns through automated quality gates.

Compared to similar skills

python side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
python (this skill)74moReviewIntermediate
python-testing-patterns772moReviewIntermediate
pr-review62moReviewIntermediate
pytest87moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry