Python
SkillAI & modelsUse when writing, reviewing, or modernizing Python 3.11+ code. Produces fully type-annotated modules, async I/O, dataclasses and protocols, pytest suites, and a lint/type gate built on ruff and mypy --strict.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Python skill
What this skill tells your AI
The instructions your AI receives, as published by nimadorostkar/claude-skills-collection in skills/languages/python/SKILL.md and read by ahel’s review.
Purpose
Write production Python that is type-safe, async-first, and testable. This skill sets a single quality bar — annotated, linted, tested — and applies it consistently to new code and to code being modernized.
When to Use
- Writing new Python modules, packages, or services.
- Adding type coverage to an untyped or partially typed codebase.
- Converting blocking I/O to
asyncio, or debugging async behavior. - Standing up a pytest suite, fixtures, or parametrized tests.
- Modernizing Python 2-era or pre-3.10 idioms.
Capabilities
- Full type annotation, including generics,
Protocol,TypedDict, andParamSpec. - Async design: task groups, timeouts, cancellation, structured concurrency.
- Data modeling with
dataclasses,enum, and Pydantic when validation is needed. - Test authoring: fixtures, factories, mocking, property-based tests via Hypothesis.
- Tooling configuration:
pyproject.toml, ruff, mypy, uv or Poetry. - Profiling and hot-path optimization.
Inputs
- Source files or a package path.
- Target Python version (default: 3.12).
- Existing tooling config, if any.
- Runtime constraints: sync vs async, framework, deployment target.
Outputs
- Type-annotated source that passes
mypy --strict. - A pytest suite with meaningful assertions, not coverage padding.
- A
pyproject.tomlsection configuring ruff and mypy. - A short summary of behavioral changes when refactoring.
Workflow
- Survey — Read the module and its imports. Identify the runtime model (sync, async, threaded) and existing conventions. Do not fight established conventions without a reason.
- Model the data — Define dataclasses, enums, and protocols before writing logic. Type the boundaries first.
- Implement — Write the smallest correct version. Prefer standard library over dependencies.
- Test — Cover the contract and the failure modes, not the implementation details.
- Gate — Run
ruff check --fix,ruff format,mypy --strict,pytest. Fix each failure and re-run until all four are clean.
Best Practices
- Use
X | None, notOptional[X]. Uselist[str], notList[str]. - Never use a bare
except:. Catch the narrowest exception that can actually be raised. - Raise domain-specific exceptions; do not signal failure with
Nonereturn values. - Use
pathlib.Pathfor every filesystem path. - Never mutate a default argument. Use
field(default_factory=...). - Guard async code with explicit timeouts; an un-timed
awaiton a network call is a latency bug waiting to happen. - Log with the
loggingmodule and structured extras — neverprintin library code.
Examples
Typed, async, cancellation-safe fetch:
import asyncio
from dataclasses import dataclass
import httpx
@dataclass(frozen=True, slots=True)
class Quote:
symbol: str
price: float
class QuoteUnavailable(Exception):
"""Raised when the upstream cannot serve a quote."""
async def fetch_quotes(symbols: list[str], *, timeout: float = 5.0) -> list[Quote]:
async with httpx.AsyncClient(timeout=timeout) as client:
async with asyncio.TaskGroup() as tg:
tasks = {s: tg.create_task(client.get(f"/quote/{s}")) for s in symbols}
quotes: list[Quote] = []
for symbol, task in tasks.items():
response = task.result()
if response.status_code != 200:
raise QuoteUnavailable(symbol)
quotes.append(Quote(symbol=symbol, price=response.json()["price"]))
return quotes
Test that covers the contract and the failure:
import pytest
@pytest.mark.asyncio
async def test_fetch_quotes_raises_on_upstream_error(mock_client):
mock_client.get.return_value.status_code = 503
with pytest.raises(QuoteUnavailable, match="AAPL"):
await fetch_quotes(["AAPL"])
Notes
TaskGrouprequires Python 3.11+. On 3.10, useasyncio.gather(..., return_exceptions=True)and re-raise explicitly.mypy --stricton a large legacy codebase is a project, not a task. Enable it per-module withdisallow_untyped_defsand expand the surface gradually.- Prefer
uvfor new projects; it is materially faster than Poetry and pip for resolution and installs.
Signals
- GitHub stars
- 26
- Forks
- 3
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
python-nimadorostkar- Source
- github.com/nimadorostkar/claude-skills-collection