Claude
Skills
Sign in
Back

python-helper

Included with Lifetime
$97 forever

Python development with modern patterns, type hints, testing, and tooling When user works with .py files, mentions Python, pip, pytest, ruff, uv, or encounters Python errors

General

What this skill does


# Python Helper Agent

## What's New in Python (2023-2026)

- **Python 3.14** (Oct 2025): Template strings `t"Hello {name}"` (PEP 750), deferred annotation evaluation (PEP 649), bracketless `except TimeoutError, OSError:` (PEP 758), `concurrent.interpreters` module (PEP 734), `compression.zstd` module (PEP 784), free-threaded mode officially supported (PEP 779), zero-overhead external debugger (PEP 768), `pathlib.Path.copy()/move()`, remote pdb attach `python -m pdb -p PID`, `python -c` auto-dedent, incremental GC with reduced pause times
- **Python 3.13** (Oct 2024): New interactive REPL with multiline editing and color, experimental free-threaded mode (no GIL, `python3.13t`), experimental JIT compiler (PEP 744), `locals()` defined semantics (PEP 667), type parameter defaults `TypeVar('T', default=int)`, `TypeIs` for type narrowing (PEP 742), `ReadOnly` TypedDict fields (PEP 705), `copy.replace()`, `dbm.sqlite3` default backend, `warnings.deprecated()` decorator (PEP 702), iOS/Android tier 3 support, 19 dead-battery modules removed (cgi, telnetlib, etc.)
- **Python 3.12** (Oct 2023): Type parameter syntax `def max[T](args)` (PEP 695), `type` statement for aliases, f-string lifting (nested f-strings, quote reuse, backslashes, comments) (PEP 701), `@override` decorator (PEP 698), `TypedDict` for `**kwargs` via `Unpack` (PEP 692), per-interpreter GIL (PEP 684), comprehension inlining 2x faster (PEP 709), `sys.monitoring` low-impact API, `pathlib.Path.walk()`, `itertools.batched()`, `distutils` removed
- **Current stable**: Python 3.14.2 (Feb 2026)
- **Supported**: 3.10 (security), 3.11 (security), 3.12 (bugfix), 3.13 (bugfix), 3.14 (active)

## Overview

This skill covers Python development using modern patterns (3.10+ features), type hints, dataclasses, structural pattern matching, async/await, and the modern tooling ecosystem: uv (package/project manager), ruff (linter+formatter), pytest (testing), mypy/pyright (type checking), and pyproject.toml-based project configuration.

## CLI Commands

### Auto-Approved Safe Commands

```bash
# Version and environment info
python --version
python -c "import sys; print(sys.version)"
pip list
pip show <package>

# uv commands (fast pip replacement)
uv version
uv python list
uv pip list
uv pip show <package>
uv tree

# Ruff (linter + formatter)
ruff check .
ruff check --fix .
ruff format --check .
ruff format .

# Pytest
pytest
pytest -v
pytest --co  # collect-only, list tests
pytest -x    # stop on first failure

# Type checking
mypy .
pyright .
```

### Project Management with uv

```bash
# Create new project
uv init my-project
uv init --lib my-library

# Add dependencies
uv add requests httpx
uv add --dev pytest ruff mypy

# Lock and sync
uv lock
uv sync

# Run commands in project env
uv run python script.py
uv run pytest
uv run ruff check .

# Python version management
uv python install 3.14
uv python pin 3.14

# Run tools without installing
uvx ruff check .
uvx black --check .

# Build and publish
uv build
uv publish
```

### Virtual Environments

```bash
# Create venv (stdlib)
python -m venv .venv
source .venv/bin/activate  # macOS/Linux
.venv/Scripts/activate     # Windows

# Create venv (uv, faster)
uv venv
uv venv --python 3.14

# pip in venv
pip install -r requirements.txt
pip install -e ".[dev]"
pip freeze > requirements.txt
```

### Ruff Configuration

```bash
# Lint with specific rules
ruff check --select E,F,I,B,UP .
ruff check --fix --unsafe-fixes .

# Format
ruff format .
ruff format --diff .

# Show rule explanation
ruff rule E501
```

Configure in `pyproject.toml`:

```toml
[tool.ruff]
target-version = "py312"
line-length = 88

[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP", "N", "SIM", "RUF"]
ignore = ["E501"]

[tool.ruff.lint.isort]
known-first-party = ["mypackage"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
```

### Pytest Commands

```bash
# Run all tests
pytest

# Verbose with output capture disabled
pytest -v -s

# Run specific test file/function
pytest tests/test_api.py
pytest tests/test_api.py::test_create_user

# Run by marker
pytest -m "not slow"
pytest -m "integration"

# Parallel execution (pytest-xdist)
pytest -n auto

# Coverage
pytest --cov=src --cov-report=term-missing

# Show local variables on failure
pytest -l

# Re-run failed tests
pytest --lf
pytest --ff  # failed first, then rest
```

### Type Checking

```bash
# mypy
mypy src/
mypy --strict src/
mypy --ignore-missing-imports src/

# pyright (faster, VS Code default)
pyright src/
pyright --pythonversion 3.14
```

## Essential Patterns Quick Reference

### Type Hints (Modern Syntax)

```python
# Union types (3.10+)
def process(value: int | str) -> None: ...

# Optional (3.10+)
def find(name: str) -> User | None: ...

# Generic functions (3.12+)
def first[T](items: list[T]) -> T:
    return items[0]

# Type aliases (3.12+)
type Vector = list[float]
type Result[T] = T | None
type Handler[**P] = Callable[P, Awaitable[None]]
```

### Dataclasses

```python
from dataclasses import dataclass, field

@dataclass(frozen=True, slots=True)
class Point:
    x: float
    y: float
    label: str = "origin"
    tags: list[str] = field(default_factory=list)
```

### Structural Pattern Matching (3.10+)

```python
match command:
    case {"action": "move", "x": x, "y": y}:
        move_to(x, y)
    case {"action": "quit"}:
        quit_game()
    case str() as text if text.startswith("/"):
        handle_command(text)
    case _:
        print("Unknown command")
```

### Async/Await

```python
import asyncio

async def fetch_all(urls: list[str]) -> list[str]:
    async with httpx.AsyncClient() as client:
        tasks = [client.get(url) for url in urls]
        responses = await asyncio.gather(*tasks)
        return [r.text for r in responses]

asyncio.run(fetch_all(["https://example.com"]))
```

### Error Handling

```python
# Exception groups (3.11+)
try:
    async with asyncio.TaskGroup() as tg:
        tg.create_task(risky_op())
except* ValueError as eg:
    for exc in eg.exceptions:
        print(f"ValueError: {exc}")
except* TypeError as eg:
    handle_type_errors(eg)

# Custom exceptions
class AppError(Exception):
    def __init__(self, message: str, code: int = 500):
        super().__init__(message)
        self.code = code
```

## pyproject.toml Quick Reference

```toml
[project]
name = "my-package"
version = "0.1.0"
description = "My Python package"
requires-python = ">=3.12"
dependencies = [
    "httpx>=0.27",
    "pydantic>=2.0",
]

[project.optional-dependencies]
dev = ["pytest>=8.0", "ruff>=0.8", "mypy>=1.13"]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-ra -q"
markers = [
    "slow: marks tests as slow",
    "integration: marks integration tests",
]

[tool.mypy]
python_version = "3.14"
strict = true
warn_return_any = true

[tool.ruff]
target-version = "py312"
line-length = 88

[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP"]
```

## Common Error Patterns and Solutions

### ModuleNotFoundError

```python
# Usually: wrong venv or missing dependency
# Check: which python, pip list
# Fix: uv add <package> or pip install <package>
# If script name shadows stdlib: rename your file (e.g., random.py -> my_random.py)
```

### ImportError with Circular Imports

```python
# Move import inside function, or use TYPE_CHECKING guard
from __future__ import annotations  # Defers all annotation evaluation (pre-3.14)
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from myapp.models import User  # Only imported during type checking

def process(user: User) -> None:  # Works at runtime due to deferred eval
    ...
```

### TypeError: unhashable type

```python
# Mutable types (list, dict, set) can't be dict keys or set members
# Fix: use tuple instead of list, frozenset instead of set
# Or for dataclasses: @dataclass(frozen=True)
```

### asyncio.run() Cannot Be Called from Running Event Loop

```python
# In Jupyter

Related in General