# Tool and Library Registry

> Comprehensive catalog of development tools, testing frameworks, CLI libraries, data processing utilities, and MCP tools for modern Python 3.11+ development.

- Skill: `tools-only/tool-and-library-registry-2` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tools-only/tool-and-library-registry-2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tools-only/tool-and-library-registry-2/raw
- Safety review: pending (external: skill-scanner WARNING, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tools-only (https://skillmd.com/u/tools-only)
- Updated: 2026-09-29
- Page: https://skillmd.com/skills/tools-only/tool-and-library-registry-2

---


# Tool and Library Registry

Comprehensive catalog of development tools, testing frameworks, CLI libraries, data processing utilities, and MCP tools for modern Python 3.11+ development.

**Coverage**: 50+ tools across 10 categories **Sources**: Pattern extraction analysis, taxonomy organization, 13 agent discovery reports **User Requirements**: datasette, arrow, fabric, shiv, httpx, prefect, boltons, blinker, paho-mqtt, robotframework, copier, pytest, prospector, pre-commit, mypy, bandit, ruff, uv, hatchling

---

## 1. Tool Categories Overview

### Category Matrix

| Category          | Tool Count | Mandatory Tools                 | Optional Tools                     | Use Cases                                     |
| ----------------- | ---------- | ------------------------------- | ---------------------------------- | --------------------------------------------- |
| Development Tools | 8          | uv, ruff, mypy, pyright         | prospector, bandit                 | Package management, linting, type checking    |
| Testing Tools     | 9          | pytest, pytest-mock, pytest-cov | hypothesis, mutmut, robotframework | Unit tests, BDD, mutation testing             |
| CLI Frameworks    | 4          | typer, argparse                 | textual, click                     | Human-facing CLIs, portable scripts, TUIs     |
| Data Libraries    | 5          | -                               | datasette, arrow, httpx, requests  | Data exploration, time handling, HTTP clients |
| Workflow Tools    | 4          | -                               | prefect, fabric, copier, invoke    | Orchestration, automation, templating         |
| IoT/Messaging     | 2          | -                               | paho-mqtt, blinker                 | MQTT messaging, signals/events                |
| Build Tools       | 4          | uv                              | hatchling, shiv, pip-tools         | Package building, executable creation         |
| Quality Tools     | 4          | pre-commit, ruff                | prospector, bandit                 | Code quality gates, security scanning         |
| Utility Libraries | 3          | -                               | boltons, pydantic, structlog       | General utilities, validation, logging        |
| MCP Tools         | 8          | -                               | context7, ref, exa, github         | Documentation lookup, code search, reasoning  |

---

## 2. Development Tools

### 2.1 uv (Package Manager & Script Executor)

```yaml
tool_name: uv
category: development
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "curl -LsSf https://astral.sh/uv/install.sh | sh"
purpose: "Modern Python package manager and PEP 723 script executor"
mandatory: true
scenarios:
  - All Python development
  - PEP 723 script execution
  - Package installation
  - Virtual environment management
alternatives:
  - pip + pip-tools + virtualenv (legacy, NOT recommended)
  - poetry (different approach, heavier)
  - pdm (alternative modern tool)
```

**When to Use**:

- MANDATORY for PEP 723 scripts (shebang requirement)
- Primary package manager for all projects
- Replaces pip, pip-tools, virtualenv, pipx

**Basic Usage**:

```bash
# Install packages
uv add requests pydantic

# Add development dependencies
uv add --dev pytest mypy ruff

# Run PEP 723 script
uv run --script script.py

# Create virtual environment
uv venv

# Sync dependencies from pyproject.toml
uv sync
```

**Integration with Other Tools**:

- Works with pyproject.toml for dependency management
- Executes PEP 723 scripts via shebang
- Compatible with pre-commit hooks
- Faster than pip for all operations

**Configuration**:

```toml
# pyproject.toml - Minimal dependency declaration example
# NOTE: Replace ALL {{template_variables}} with actual values before creating file
[project]
name = "{{project_name_from_directory_or_git_remote}}"
version = "{{version_from_git_tag_or_default_0_1_0}}"
dependencies = [
    "typer>=0.19.2",
    "pydantic>=2.0.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=8.0.0",
    "mypy>=1.11.0",
    "ruff>=0.6.0",
]

[tool.hatchling.build.targets.wheel]
packages = ["packages/{{package_name_from_project_name}}"]
```

**Related Standards**:

- PEP 723 (inline script metadata)
- PEP 621 (project metadata)
- Pattern: All Python agents require uv

**Source**: pattern-extraction.md Section 3.1, all discovery reports

---

### 2.2 ruff (Linting & Formatting)

```yaml
tool_name: ruff
category: development
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "uv add --dev ruff"
purpose: "Extremely fast Python linter and formatter replacing flake8, black, isort"
mandatory: true
scenarios:
  - All Python code validation
  - Pre-commit hooks
  - CI/CD pipelines
  - Linting error investigation
alternatives:
  - flake8 + black + isort (legacy, slower)
  - pylint (comprehensive but slower)
  - prospector (multi-tool wrapper)
```

**When to Use**:

- MANDATORY for all Python code before delivery
- Layer 2 of validation pipeline
- Pre-commit hook integration
- CI/CD quality gates

**Basic Usage**:

```bash
# Check code
uv run ruff check .

# Fix auto-fixable issues
uv run ruff check --fix .

# Format code
uv run ruff format .

# Get rule documentation
ruff rule ANN201

# Check specific files (rare - usually run on .)
uv run ruff check path/to/file.py
```

**Integration with Other Tools**:

- Pre-commit: Automatic linting on git commits
- Linting-root-cause-resolver: Uses `ruff rule {CODE}` for investigation
- Mypy/Pyright: Complementary type checking
- pytest: Can check test code

**Configuration**:

```toml
# pyproject.toml
[tool.ruff]
target-version = "py311"
fix = true
unsafe-fixes = true
src = ["packages", "scripts", "tests", "typings", ".gitlab", ".github"]

[tool.ruff.format]
docstring-code-format = true
quote-style = "double"
line-ending = "lf"
skip-magic-trailing-comma = true
preview = true

[tool.ruff.lint]
preview = true
extend-select = [
    "A",     # see: https://docs.astral.sh/ruff/rules/#flake8-builtins-a
    "ANN",   # see: https://docs.astral.sh/ruff/rules/#flake8-annotations-ann
    "ASYNC", # see: https://docs.astral.sh/ruff/rules/#flake8-async-async
    "B",     # see: https://docs.astral.sh/ruff/rules/#flake8-bugbear-b
    "BLE",   # see: https://docs.astral.sh/ruff/rules/#flake8-blind-except-ble
    "C4",    # see: https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4
    "C90",   # see: https://docs.astral.sh/ruff/rules/#mccabe-c90
    "D",     # see: https://docs.astral.sh/ruff/rules/#pydocstyle-d
    "DOC",   # see: https://docs.astral.sh/ruff/rules/#pydoclint-doc
    "E",     # see: https://docs.astral.sh/ruff/rules/#error-e
    "EXE",   # see: https://docs.astral.sh/ruff/rules/#flake8-executable-exe
    "F",     # see: https://docs.astral.sh/ruff/rules/#pyflakes-f
    "FA",    # see: https://docs.astral.sh/ruff/rules/#flake8-annotations-fa
    "FAST",  # see: https://docs.astral.sh/ruff/rules/#fastapi-fast
    "FLY",   # see: https://docs.astral.sh/ruff/rules/#flynt-fly
    "FURB",  # see: https://docs.astral.sh/ruff/rules/#refurb-furb
    "G201",  # see: https://docs.astral.sh/ruff/rules/logging-exc-info/
    "G202",  # see: https://docs.astral.sh/ruff/rules/logging-redundant-exc-info/
    "I",     # see: https://docs.astral.sh/ruff/rules/#isort-i
    "N",     # see: https://docs.astral.sh/ruff/rules/#flake8-quotes-n
    "PERF",  # see: https://docs.astral.sh/ruff/rules/#perflint-perf
    "PGH",   # see: https://docs.astral.sh/ruff/rules/#pygrep-hooks-pgh
    "PIE",   # see: https://docs.astral.sh/ruff/rules/#flake8-pie-pie
    "PL",    # see: https://docs.astral.sh/ruff/rules/#pyflakes-f
    "PT",    # see: https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt
    "PTH",   # see: https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth
    "PYI",   # see: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi
    "Q",     # see: https://docs.astral.sh/ruff/rules/#flake8-quotes-q
    "RET",   # see: https://docs.astral.sh/ruff/rules/#flake8-return-ret
    "RSE",   # see: https://docs.astral.sh/ruff/rules/#flake8-raise-rse
    "RUF",   # see: https://docs.astral.sh/ruff/rules/#ruff-ruf
    "S",     # see: https://docs.astral.sh/ruff/rules/#flake8-bandit-s
    "SIM",   # see: https://docs.astral.sh/ruff/rules/#flake8-simplify-sim
    "SLF",   # see: https://docs.astral.sh/ruff/rules/#flake8-self-slf
    "SLOT",  # see: https://docs.astral.sh/ruff/rules/#flake8-slots-slot
    "T10",   # see: https://docs.astral.sh/ruff/rules/#flake8-debugger-t10
    "T20",   # see: https://docs.astral.sh/ruff/rules/#flake8-typing-t20
    "TC",    # see: https://docs.astral.sh/ruff/rules/#flake8-type-checking-tc
    "TRY",   # see: https://docs.astral.sh/ruff/rules/#tryceratops-try
    "UP",    # see: https://docs.astral.sh/ruff/rules/#pyupgrade-up
    "W",     # see: https://docs.astral.sh/ruff/rules/#warning-w
    "YTT",   # see: https://docs.astral.sh/ruff/rules/#flake8-2020-ytt
]
ignore = [
    "DOC501", # Raised exception {id} missing from docstring
    "DOC502", # Raised exception is not explicitly raised
    "E501",   # Line too long ({width} > {limit})
    "EXE003", # Shebang should contain python, pytest, or uv run (doesn't handle global arguments)
    "S404",   # subprocess possibly insecure - still need to use subprocess though
    "S603",   # subprocess without shell=True
    "TRY003", # Long error messages are fine
]
unfixable = ["F401"]

[tool.ruff.lint.per-file-ignores]
"tests/**" = ["S", "D", "E501"]
"typings/**" = ["N", "ANN", "A"]
".gitlab/scripts/**" = [
    "T201", # print() statements are intentional for CI output visibility
]

[tool.ruff.lint.pycodestyle]
max-line-length = 120

[tool.ruff.lint.isort]
combine-as-imports = true
split-on-trailing-comma = false
force-single-line = false
force-wrap-aliases = false

[tool.ruff.lint.flake8-quotes]
docstring-quotes = "double"

[tool.ruff.lint.pydocstyle]
convention = "google"

[tool.ruff.lint.mccabe]
max-complexity = 12
```

**Common Patterns**:

```python
# REQUIRED: No legacy typing imports
# ruff will flag: from typing import List, Dict, Optional

# REQUIRED: Use native generics
def process(items: list[str]) -> dict[str, int]:  # ✓
    pass

# FORBIDDEN: Legacy typing
from typing import List, Dict
def process(items: List[str]) -> Dict[str, int]:  # ✗
    pass
```

**Related Standards**:

- NEVER suppress with # noqa comments
- Use linting-root-cause-resolver for root cause fixes
- ANN\* rules enforce type annotations
- PYI\* rules for stub files

**Source**: pattern-extraction.md Section 3.1, linting-root-cause-resolver-analysis.md

---

### 2.3 mypy (Static Type Checker)

```yaml
tool_name: mypy
category: development
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "uv add --dev mypy"
purpose: "Static type checker for Python with strict mode enforcement"
mandatory: true
scenarios:
  - All Python code type validation
  - Layer 3 of validation pipeline
  - CI/CD type safety gates
  - Pre-commit hooks
alternatives:
  - pyright (Microsoft, also recommended)
  - pyre (Facebook, less common)
```

**When to Use**:

- MANDATORY for all Python code
- Layer 3 of validation pipeline (after ruff)
- Use `--strict` mode exclusively
- Run before pyright for additional checks

**Basic Usage**:

```bash
# Check with strict mode
uv run mypy --strict .

# Generate HTML report
uv run mypy --html-report mypy-report .
```

**Integration with Other Tools**:

- Ruff: Complementary linting
- Pyright: Run both for comprehensive checking
- pytest: Type-check test code
- Pre-commit: Automatic type checking

**Configuration**:

```toml
# pyproject.toml
[tool.mypy]
python_version = "3.11"
strict = true
extra_checks = true
warn_unused_configs = true
warn_redundant_casts = true
warn_unused_ignores = true
ignore_missing_imports = true
show_error_codes = true
pretty = true
disable_error_code = ["call-arg", "misc"]
mypy_path = ["packages", "scripts", "."]

[[tool.mypy.overrides]]
module = ["test.*", "tests.*"]
disable_error_code = ["attr-defined", "call-arg", "var-annotated"]
```

**Common Patterns**:

```python
# REQUIRED: Complete type annotations
def authenticate_user(username: str, password: str) -> AuthResult:
    """Authenticate user credentials."""
    pass

# REQUIRED: Generator fixtures with full typing
from typing import Generator
from pytest import fixture

@fixture
def database_connection() -> Generator[Connection, None, None]:
    """Provide database connection."""
    conn = connect_to_db()
    yield conn
    conn.close()

# REQUIRED: Modern union syntax
def get_user(user_id: int) -> User | None:  # ✓
    pass

# FORBIDDEN: Legacy Optional
from typing import Optional
def get_user(user_id: int) -> Optional[User]:  # ✗
    pass
```

**Related Standards**:

- Python 3.11+ native generics required
- Strict mode is MANDATORY
- All functions must have return type annotations
- Pattern: Run mypy before pyright

**Source**: pattern-extraction.md Section 1.2, taxonomy.md Section 6.1

---

### 2.4 pyright (Static Type Checker)

```yaml
tool_name: pyright
category: development
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "uv add --dev pyright"
purpose: "Microsoft's static type checker with strict mode"
mandatory: true
scenarios:
  - All Python code type validation
  - Layer 3 of validation pipeline (with mypy)
  - VS Code integration
  - CI/CD type safety gates
alternatives:
  - mypy (also recommended, run both)
```

**When to Use**:

- MANDATORY for all Python code
- Run after mypy for comprehensive coverage
- Use strict mode exclusively
- Complements mypy with different checks

**Basic Usage**:

```bash
# Check with strict mode (prefer basedpyright for CI native reports)
uv run basedpyright .

# Or standard pyright
uv run pyright .
```

**Integration with Other Tools**:

- VS Code: Built-in Pylance extension uses pyright
- basedpyright: Fork with native CI output formats (GitLab, GitHub)
- Mypy: Run both for best coverage
- Ruff: Complementary linting
- Pre-commit: Automatic type checking

**Configuration** (pyproject.toml - basedpyright):

```toml
# pyproject.toml
[tool.basedpyright]
pythonVersion = "3.11"
typeCheckingMode = "basic"
reportMissingImports = false
reportMissingTypeStubs = false
reportUnnecessaryTypeIgnoreComment = "error"
reportPrivateImportUsage = false
include = ["packages", "scripts"]
extraPaths = ["packages", "scripts", "tests"]
ignore = ["**/typings", "**/tests"]
venvPath = "."
venv = ".venv"
```

**Related Standards**:

- Use strict mode only
- Complements mypy checks
- Pattern: mypy then pyright in validation pipeline

**Source**: pattern-extraction.md Section 1.2, taxonomy.md Section 6.4

---

### 2.5 pre-commit (Git Hooks)

```yaml
tool_name: pre-commit
category: development
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "uv add --dev pre-commit"
purpose: "Git hook framework for running quality checks before commits"
mandatory: true
scenarios:
  - All Python projects
  - Layer 6 integration validation
  - CI/CD pre-flight checks
  - Team quality enforcement
alternatives:
  - Manual script execution (NOT recommended)
  - Custom git hooks (harder to maintain)
```

**When to Use**:

- MANDATORY for all Python projects
- Layer 6 of validation pipeline
- Install hooks: `pre-commit install`
- Run before commits: `pre-commit run --files <files>`

**Basic Usage**:

```bash
# Install hooks
uv run pre-commit install

# Run on staged files (preferred - scoped operation)
uv run pre-commit run

# Run on specific files (scoped operation)
uv run pre-commit run --files path/to/file.py

# Update hook versions
uv run pre-commit autoupdate
```

**Important**: Always scope operations to changed files using `pre-commit run` (staged files) or `--files <paths>`. Avoid `--all-files` unless explicitly requested by user, as it formats unrelated code causing diff pollution and merge conflicts.

**Integration with Other Tools**:

- Ruff: Automatic linting and formatting
- Mypy: Type checking before commit
- Pyright: Additional type checks
- pytest: Run tests before commit

**Configuration**:

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

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

  - repo: local
    hooks:
      - id: basedpyright
        name: basedpyright
        entry: uv run basedpyright
        language: system
        types: [python]
        pass_filenames: false

      - id: pytest-check
        name: pytest
        entry: uv run pytest
        language: system
        pass_filenames: false
        always_run: true
```

**Common Patterns**:

```bash
# Standard workflow
git add file.py
uv run pre-commit run --files file.py  # Run checks
git commit -m "Add feature"  # Auto-runs hooks

# Fix issues on specific files
uv run pre-commit run --files file.py other.py
```

**Note**: Hooks run automatically on staged files during commit. Manual invocation is typically only needed for verification before staging. Avoid `--all-files` to prevent formatting code outside your current branch.

**Related Standards**:

- MUST pass all hooks before commit
- NEVER skip hooks without justification
- Pattern: Automated quality enforcement

**Source**: pattern-extraction.md Section 3.5, taxonomy.md Section 6.4

---

### 2.6 prospector (Multi-Tool Linter)

```yaml
tool_name: prospector
category: development
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "uv add --dev prospector[with_everything]"
purpose: "Multi-tool wrapper combining pylint, pep8, pyflakes, mccabe, and more"
mandatory: false
scenarios:
  - Comprehensive code analysis
  - Legacy codebase auditing
  - Security scanning
  - Complexity analysis
alternatives:
  - ruff + mypy + bandit (recommended modern stack)
  - Individual tools separately
```

**When to Use**:

- Optional for comprehensive analysis
- Legacy code evaluation
- NOT recommended as primary linter (use ruff)
- Useful for one-off deep analysis

**Basic Usage**:

```bash
# Run all checks
prospector

# With specific tools
prospector --with-tool bandit --with-tool mccabe

# Output to file
prospector --output-format json > report.json

# Strictness levels
prospector --strictness high
```

**Integration with Other Tools**:

- Combines: pylint, pep8, pyflakes, mccabe, dodgy, pep257, vulture
- Can run bandit for security
- Ruff replaces most prospector functionality

**Configuration**:

```yaml
# .prospector.yaml
strictness: high
test-warnings: true
doc-warnings: true

pylint:
  run: true
  disable:
    - too-few-public-methods

pep8:
  run: true
  max-line-length: 100

mccabe:
  run: true
  max-complexity: 10

bandit:
  run: true
```

**Comparison with ruff**:

- Ruff: Faster, modern, single tool
- Prospector: Comprehensive, slower, multiple tools
- Recommendation: Use ruff + mypy + bandit instead

**Source**: User requirements list

---

### 2.7 bandit (Security Scanner)

```yaml
tool_name: bandit
category: development
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "uv add --dev bandit"
purpose: "Security-focused static analysis tool for Python"
mandatory: false
scenarios:
  - Security-critical code
  - Compliance requirements (HIPAA, PCI-DSS, GDPR)
  - Pre-production security audits
  - CI/CD security gates
alternatives:
  - ruff (has some security rules via flake8-bandit)
  - semgrep (broader security scanning)
```

**When to Use**:

- MANDATORY for security-critical code
- Recommended for all production code
- CI/CD security scanning
- Compliance requirement validation

**Basic Usage**:

```bash
# Scan directory
bandit -r packages/

# Skip specific tests
bandit -r packages/ -s B101,B601

# Output formats
bandit -r packages/ -f json -o report.json
bandit -r packages/ -f html -o report.html

# Severity levels
bandit -r packages/ -ll  # Low confidence + Low severity
```

**Integration with Other Tools**:

- Ruff: Some overlap with flake8-bandit rules
- Pre-commit: Security scanning before commit
- CI/CD: Fail pipeline on high-severity issues

**Configuration**:

```yaml
# .bandit
tests:
  - B201 # flask_debug_true
  - B301 # pickle
  - B302 # marshal
  - B303 # md5
  - B304 # ciphers
  - B305 # cipher_modes
  - B306 # mktemp_q
  - B307 # eval
  - B308 # mark_safe
  - B309 # httpsconnection
  - B310 # urllib_urlopen
  - B311 # random
  - B312 # telnetlib
  - B313 # xml_bad_cElementTree
  - B314 # xml_bad_ElementTree
  - B315 # xml_bad_expatreader
  - B316 # xml_bad_expatbuilder
  - B317 # xml_bad_sax
  - B318 # xml_bad_minidom
  - B319 # xml_bad_pulldom
  - B320 # xml_bad_etree
  - B321 # ftplib
  - B323 # unverified_context
  - B324 # hashlib_new_insecure_functions
  - B325 # tempnam
  - B401 # import_telnetlib
  - B402 # import_ftplib
  - B403 # import_pickle
  - B404 # import_subprocess
  - B405 # import_xml_etree
  - B406 # import_xml_sax
  - B407 # import_xml_expat
  - B408 # import_xml_minidom
  - B409 # import_xml_pulldom
  - B410 # import_lxml
  - B411 # import_xmlrpclib
  - B412 # import_httpoxy
  - B501 # request_with_no_cert_validation
  - B502 # ssl_with_bad_version
  - B503 # ssl_with_bad_defaults
  - B504 # ssl_with_no_version
  - B505 # weak_cryptographic_key
  - B506 # yaml_load
  - B507 # ssh_no_host_key_verification
  - B601 # paramiko_calls
  - B602 # shell_true
  - B603 # subprocess_without_shell_equals_true
  - B604 # any_other_function_with_shell_equals_true
  - B605 # start_process_with_a_shell
  - B606 # start_process_with_no_shell
  - B607 # start_process_with_partial_path
  - B608 # hardcoded_sql_expressions
  - B609 # wildcard_injection

exclude_dirs:
  - /tests/
  - /venv/
```

**Common Patterns**:

```python
# AVOID: Hardcoded passwords
password = "secret123"  # B105

# PREFER: Environment variables
import os
password = os.getenv("DB_PASSWORD")

# AVOID: Shell injection
subprocess.run(f"ls {user_input}", shell=True)  # B602

# PREFER: Parameterized commands
subprocess.run(["ls", user_input], shell=False)

# AVOID: Insecure random
import random
token = random.randint(0, 1000000)  # B311

# PREFER: Cryptographically secure random
import secrets
token = secrets.token_hex(16)
```

**Related Standards**:

- MANDATORY for payment processing
- MANDATORY for authentication code
- MANDATORY for data validation
- Pattern: Security-first development

**Source**: User requirements list, pattern-extraction.md Section 4

---

## 3. Testing Tools

### 3.1 pytest (Test Framework)

```yaml
tool_name: pytest
category: testing
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "uv add --dev pytest"
purpose: "Modern Python testing framework with fixtures and plugins"
mandatory: true
scenarios:
  - All Python testing
  - Unit tests
  - Integration tests
  - E2E tests
  - API testing
alternatives:
  - unittest (stdlib, NOT recommended)
  - nose2 (deprecated)
```

**When to Use**:

- MANDATORY for all Python testing
- NEVER use unittest
- Layer 4 of validation pipeline
- Minimum 80% code coverage required

**Basic Usage**:

```bash
# Run all tests (coverage via pyproject.toml config)
uv run pytest

# Verbose output
uv run pytest -v

# Run specific test file
uv run pytest tests/test_auth.py

# Run specific test function
uv run pytest tests/test_auth.py::test_login

# Run tests matching pattern
uv run pytest -k "auth"

# Show print statements
uv run pytest -s

# Stop on first failure
uv run pytest -x

# Show local variables on failure
uv run pytest -l

# Run last failed tests
uv run pytest --lf

# Run failed tests first
uv run pytest --ff
```

**Integration with Other Tools**:

- pytest-cov: Coverage reporting
- pytest-mock: Mocking (MANDATORY)
- pytest-asyncio: Async test support
- pytest-bdd: BDD/Gherkin tests
- hypothesis: Property-based testing
- mutmut: Mutation testing

**Configuration**:

```toml
# pyproject.toml
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
    "-v",
    "--strict-markers",
    "--strict-config",
    "--cov=packages",
    "--cov-report=term-missing",
    "--cov-report=html",
    "--cov-fail-under=80",
]
markers = [
    "slow: marks tests as slow (deselect with '-m \"not slow\"')",
    "integration: marks tests as integration tests",
    "unit: marks tests as unit tests",
]
```

**Common Patterns**:

```python
# REQUIRED: AAA pattern (Arrange-Act-Assert)
def test_user_authentication() -> None:
    """Test user authentication with valid credentials.

    Tests: Authentication system
    How: Create user, attempt login, verify token
    Why: Core security validation
    """
    # Arrange
    user = create_test_user("test@example.com", "Pass123!")

    # Act
    response = authenticate(user.email, "Pass123!")

    # Assert
    assert response.success
    assert response.token is not None
    assert response.expires_at > datetime.now()

# REQUIRED: Type annotations
def test_data_processing(tmp_path: Path) -> None:
    """Test data processing with temporary files."""
    pass

# REQUIRED: Comprehensive docstrings
def test_edge_case_handling() -> None:
    """Test handling of empty input data.

    Tests: Data validation module
    How: Pass empty list, verify graceful handling
    Why: Prevent runtime errors on edge cases
    """
    result = process_data([])
    assert result.success is False
    assert "empty" in result.error.lower()
```

**Related Standards**:

- MANDATORY 80% coverage minimum
- AAA pattern required
- Type hints on all test functions
- Comprehensive docstrings
- Pattern: pytest-architect creates tests

**Source**: pattern-extraction.md Section 1.3, pytest-architect-analysis.md

---

### 3.2 pytest-mock (Mocking Framework)

```yaml
tool_name: pytest-mock
category: testing
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "uv add --dev pytest-mock"
purpose: "Thin wrapper around unittest.mock providing pytest fixtures"
mandatory: true
scenarios:
  - All mocking in tests
  - External service mocking
  - Database mocking
  - API client mocking
alternatives:
  - unittest.mock (FORBIDDEN - never use directly)
```

**When to Use**:

- MANDATORY for all mocking
- NEVER use unittest.mock directly
- Use `mocker: MockerFixture` parameter
- Replaces @patch decorators

**Basic Usage**:

```python
from pytest_mock import MockerFixture

def test_external_api(mocker: MockerFixture) -> None:
    """Test external API integration with mock."""
    # Mock external service
    mock_response = mocker.Mock()
    mock_response.status_code = 200
    mock_response.json.return_value = {"status": "ok"}

    mock_get = mocker.patch("requests.get", return_value=mock_response)

    # Test code that uses requests.get
    result = fetch_data("https://api.example.com")

    # Verify
    assert result["status"] == "ok"
    mock_get.assert_called_once_with("https://api.example.com")

def test_database_operations(mocker: MockerFixture) -> None:
    """Test database operations with mocked connection."""
    # Mock database connection
    mock_conn = mocker.Mock()
    mock_cursor = mocker.Mock()
    mock_conn.cursor.return_value = mock_cursor
    mock_cursor.fetchall.return_value = [("user1",), ("user2",)]

    mocker.patch("psycopg2.connect", return_value=mock_conn)

    # Test
    users = get_all_users()

    # Verify
    assert users == ["user1", "user2"]
    mock_conn.cursor.assert_called_once()
```

**Integration with Other Tools**:

- pytest: Provides MockerFixture
- Type checkers: Full type hint support
- Fixtures: Can be used in fixture composition

**Common Patterns**:

```python
# REQUIRED: Use mocker parameter
def test_with_mock(mocker: MockerFixture) -> None:  # ✓
    mock = mocker.patch("module.function")

# FORBIDDEN: Direct unittest.mock import
from unittest.mock import patch  # ✗
@patch("module.function")
def test_with_patch(mock):
    pass

# REQUIRED: mocker.Mock() not Mock()
def test_mock_object(mocker: MockerFixture) -> None:
    mock_obj = mocker.Mock()  # ✓
    mock_obj.method.return_value = 42

# REQUIRED: mocker.spy() for partial mocking
def test_spy_on_method(mocker: MockerFixture) -> None:
    obj = MyClass()
    spy = mocker.spy(obj, "method")
    obj.method("arg")
    spy.assert_called_once_with("arg")
```

**Related Standards**:

- NEVER import from unittest.mock
- ALWAYS use mocker parameter
- Type hint as MockerFixture
- Pattern: pytest-architect enforces this

**Source**: pattern-extraction.md Section 2.2, pytest-architect-analysis.md

---

### 3.3 pytest-cov (Coverage Reporting)

```yaml
tool_name: pytest-cov
category: testing
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "uv add --dev pytest-cov"
purpose: "Coverage.py plugin for pytest with comprehensive reporting"
mandatory: true
scenarios:
  - All Python testing
  - Coverage measurement
  - CI/CD quality gates
  - Coverage-driven development
alternatives:
  - coverage.py (pytest-cov wraps this)
```

**When to Use**:

- MANDATORY for all Python projects
- Minimum 80% coverage required
- Critical code: 95%+ coverage required
- Layer 4 validation with pytest

**Basic Usage**:

Coverage is configured in `pyproject.toml` - no CLI flags needed:

```bash
# Run tests with coverage (config-driven)
uv run pytest
```

**Integration with Other Tools**:

- pytest: Native plugin integration
- CI/CD: Generate reports for pipeline
- Coverage.py: Underlying engine
- Mutation testing: Complements mutmut

**Configuration** (MANDATORY - coverage in config, not CLI):

```toml
# pyproject.toml
[tool.pytest.ini_options]
addopts = [
    "--cov=packages",
    "--cov-report=term-missing",
    "--cov-report=html:htmlcov",
    "--cov-fail-under=80",
]

[tool.coverage.run]
source = ["packages"]
omit = [
    "*/tests/*",
    "*/test_*.py",
    "*/__init__.py",
]
branch = true

[tool.coverage.report]
fail_under = 80
show_missing = true
skip_covered = false
exclude_lines = [
    "pragma: no cover",
    "def __repr__",
    "raise AssertionError",
    "raise NotImplementedError",
    "if __name__ == .__main__.:",
    "if TYPE_CHECKING:",
    "@abstractmethod",
    "@overload",
]

[tool.coverage.html]
directory = "htmlcov"
```

**Coverage Standards**:

```python
# General code: 80% minimum
# Critical code: 95%+ required

# Coverage excludes
def __repr__(self) -> str:  # pragma: no cover
    """String representation."""
    return f"User({self.name})"

# Type checking blocks
if TYPE_CHECKING:  # pragma: no cover
    from .models import User

# Abstract methods
@abstractmethod
def process(self) -> None:  # pragma: no cover
    """Process data."""
```

**Related Standards**:

- MANDATORY 80% general code
- MANDATORY 95%+ critical code
- Pattern: Testing pyramid distribution
- Source: Coverage gates in validation pipeline

**Source**: pattern-extraction.md Section 1.3, taxonomy.md Section 6.2

---

### 3.4 hypothesis (Property-Based Testing)

```yaml
tool_name: hypothesis
category: testing
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "uv add --dev hypothesis"
purpose: "Property-based testing framework for generating test cases"
mandatory: false
scenarios:
  - Data validation testing
  - Algorithm correctness
  - Edge case discovery
  - Fuzzing inputs
alternatives:
  - Manual parametrization (less comprehensive)
```

**When to Use**:

- RECOMMENDED for all projects
- ESPECIALLY emphasized in pytest-architect
- Data validation and sanitization
- Complex algorithm testing
- Discovering edge cases

**Basic Usage**:

```python
from hypothesis import given, strategies as st

@given(st.integers())
def test_absolute_value_always_positive(n: int) -> None:
    """Test that absolute value is always positive."""
    assert abs(n) >= 0

@given(st.lists(st.integers()))
def test_reverse_twice_is_identity(lst: list[int]) -> None:
    """Test that reversing twice returns original list."""
    assert list(reversed(list(reversed(lst)))) == lst

@given(st.text(min_size=1, max_size=100))
def test_email_validation(email_input: str) -> None:
    """Test email validation with various inputs."""
    result = validate_email(email_input)
    # Property: valid emails have @ symbol
    if result.is_valid:
        assert "@" in email_input
```

**Integration with Other Tools**:

- pytest: Native integration
- pytest-cov: Coverage of generated cases
- Type hints: Strategy inference

**Advanced Patterns**:

```python
from hypothesis import given, strategies as st, assume
from datetime import date, timedelta

# Custom strategies
email_strategy = st.builds(
    lambda name, domain: f"{name}@{domain}",
    name=st.text(min_size=1, max_size=20, alphabet=st.characters(whitelist_categories=("Ll", "Nd"))),
    domain=st.sampled_from(["example.com", "test.org", "demo.net"])
)

@given(email_strategy)
def test_email_domain_validation(email: str) -> None:
    """Test email domain validation."""
    result = validate_email_domain(email)
    assert result.domain in ["example.com", "test.org", "demo.net"]

# Composite strategies
@st.composite
def date_range(draw):
    """Generate valid date range."""
    start = draw(st.dates())
    days = draw(st.integers(min_value=1, max_value=365))
    end = start + timedelta(days=days)
    return (start, end)

@given(date_range())
def test_date_range_processing(dates: tuple[date, date]) -> None:
    """Test date range processing."""
    start, end = dates
    assert start <= end
```

**Configuration**:

```toml
# pyproject.toml
[tool.pytest.ini_options]
markers = [
    "hypothesis: property-based tests using hypothesis",
]

# Add hypothesis profile
[tool.hypothesis]
max_examples = 100
derandomize = true
```

**Related Standards**:

- Emphasized in pytest-architect
- Recommended for data validation
- Pattern: Property-based testing

**Source**: pytest-architect-analysis.md Section 4.1

---

### 3.5 mutmut (Mutation Testing)

```yaml
tool_name: mutmut
category: testing
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "uv add --dev mutmut"
purpose: "Mutation testing tool to verify test suite quality"
mandatory: false
scenarios:
  - Critical business logic
  - Payment processing
  - Authentication/authorization
  - Security-critical code
  - Compliance code (HIPAA, PCI-DSS, GDPR)
alternatives:
  - cosmic-ray (alternative mutation tester)
```

**When to Use**:

- MANDATORY for critical code:
  - Payment processing
  - Authentication/authorization
  - Security-critical code
  - Data validation and sanitization
  - Regulatory compliance code
  - Complex algorithms
  - Core libraries
- Target: 100% mutation score (kill all mutants)

**Basic Usage**:

```bash
# Run mutation testing
mutmut run

# Show results
mutmut results

# Show specific mutant
mutmut show 1

# Apply specific mutant (for debugging)
mutmut apply 1

# Run tests after applying mutant
pytest

# Revert mutant
mutmut apply --revert

# Run on specific paths
mutmut run --paths-to-mutate=packages/auth/
```

**Integration with Other Tools**:

- pytest: Uses pytest to run tests
- Coverage: Complements code coverage
- CI/CD: Critical code quality gate

**Configuration**:

```toml
# setup.cfg or pyproject.toml
[mutmut]
paths_to_mutate = packages/
backup = false
runner = pytest
tests_dir = tests/
```

**Common Patterns**:

```python
# Example: Payment processing (MANDATORY mutation testing)
def calculate_total(items: list[Item], tax_rate: float) -> Decimal:
    """Calculate order total with tax.

    CRITICAL: Payment processing - mutation tested.
    """
    subtotal = sum(item.price * item.quantity for item in items)
    tax = subtotal * Decimal(str(tax_rate))
    total = subtotal + tax
    return total.quantize(Decimal("0.01"))

# Tests MUST kill all mutants:
# - Operator changes (+ to -, * to /)
# - Number changes (tax_rate to 0, to 1)
# - Decimal precision changes
# - Boundary conditions

def test_calculate_total_normal() -> None:
    """Test normal calculation."""
    items = [Item(price=Decimal("10.00"), quantity=2)]
    total = calculate_total(items, 0.08)
    assert total == Decimal("21.60")  # 20.00 + 1.60 tax

def test_calculate_total_zero_tax() -> None:
    """Test with zero tax rate."""
    items = [Item(price=Decimal("10.00"), quantity=1)]
    total = calculate_total(items, 0.0)
    assert total == Decimal("10.00")

def test_calculate_total_precision() -> None:
    """Test decimal precision handling."""
    items = [Item(price=Decimal("10.99"), quantity=1)]
    total = calculate_total(items, 0.08)
    assert total == Decimal("11.87")  # Rounds correctly
```

**Mutation Score Interpretation**:

- 100%: All mutants killed (perfect)
- 90-99%: Excellent test coverage
- 80-89%: Good, some gaps
- <80%: Insufficient testing for critical code

**Related Standards**:

- MANDATORY for critical code
- Target: 100% mutation score
- Pattern: Complements code coverage

**Source**: pattern-extraction.md Section 2.7, pytest-architect-analysis.md

---

### 3.6 robotframework (Acceptance Testing)

```yaml
tool_name: robotframework
category: testing
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "uv add --dev robotframework"
purpose: "Keyword-driven acceptance testing framework"
mandatory: false
scenarios:
  - BDD acceptance tests
  - E2E testing
  - Non-technical stakeholder tests
  - Keyword-driven testing
alternatives:
  - pytest-bdd (Python-native BDD)
  - behave (Gherkin-based BDD)
```

**When to Use**:

- Optional for acceptance testing
- E2E test scenarios
- Non-technical stakeholder involvement
- Keyword-driven test approach

**Basic Usage**:

```bash
# Run tests
robot tests/

# Run specific test file
robot tests/login.robot

# Run with tags
robot --include smoke tests/

# Generate reports
robot --outputdir reports tests/
```

**Example Test**:

```robotframework
*** Settings ***
Library           SeleniumLibrary

*** Variables ***
${URL}            https://example.com
${BROWSER}        Chrome

*** Test Cases ***
User Can Login With Valid Credentials
    [Documentation]    Test successful login flow
    [Tags]    smoke    login
    Open Browser    ${URL}    ${BROWSER}
    Input Text      id:username    testuser
    Input Text      id:password    TestPass123!
    Click Button    id:login
    Page Should Contain    Welcome, testuser
    [Teardown]    Close Browser
```

**Integration with Other Tools**:

- pytest: Can run alongside pytest
- Selenium: Web automation
- CI/CD: Generate XML reports

**Related Standards**:

- Alternative to pytest-bdd
- Pattern: Acceptance testing layer

**Source**: User requirements list

---

### 3.7 pytest-asyncio (Async Testing)

```yaml
tool_name: pytest-asyncio
category: testing
python_versions: [3.11, 3.12, 3.13, 3.14]
installation: "uv add --dev pytest-asyncio"
purpose: "Pytest support for testing async code"
mandatory: false
scenarios:
  - FastAPI testing
  - Async function testing
  - Concurrent operation testing
  - AsyncIO-based applications
alternatives:
  - pytest-trio (Trio async framework)
```

**When to Use**:

- Required for async/await code testing
- FastAPI endpoint testing
- Async database operations
- Concurrent task testing

**Basic Usage**:

```python
import pytest
from httpx import AsyncClient
from app import app

@pytest.mark.asyncio
async def test_async_endpoint() -> None:
    """Test async API endpoint."""
    async with AsyncClient(app=app, base_url="http://test") as client:
        response = await client.get("/users/1")
        assert response.status_code == 200
        assert response.json()["id"] == 1

@pytest.mark.asyncio
async def test_concurrent_operations() -> None:
    """Test concurrent async operations."""
    import asyncio

    async def fetch_user(user_id: int) -> dict:
        # Simulate async operation
        await asyncio.sleep(0.1)
        return {"id": user_id}

    # Test concurrent execution
    results = await asyncio.gather(
        fetch_user(1),
        fetch_user(2),
        fetch_user(3),
    )

    assert len(resul

…(truncated)
