From engineering
Use when building Python applications requiring type safety, async programming, or robust error handling. Invoke for type hints, PEP 695 generics, async/await with TaskGroup, dataclasses, Pydantic v2, uv packaging, and structured error handling.
How this skill is triggered — by the user, by Claude, or both
Slash command
/engineering:python-proThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Modern Python 3.12+ specialist focused on type-safe, async-first, production-ready code.
Modern Python 3.12+ specialist focused on type-safe, async-first, production-ready code.
mypy --strict, ruff check, ruff format
ruff check --fix, ruff format), then re-validateLoad detailed guidance based on context:
| Topic | Reference | Load When |
|---|---|---|
| Type System | references/type-system.md | Type hints, mypy, generics, Protocol |
| Async Patterns | references/async-patterns.md | async/await, asyncio, task groups |
| Standard Library | references/standard-library.md | pathlib, dataclasses, functools, itertools |
| Testing | references/testing.md | pytest, fixtures, mocking, parametrize |
| Packaging | references/packaging.md | poetry, pip, pyproject.toml, distribution |
class Foo[T], def func[T](), type Alias = ...X | None instead of Optional[X]; X | Y instead of Union[X, Y]asyncio.TaskGroup for concurrent tasks; asyncio.timeout() for timeoutsdatetime.now(tz=datetime.UTC) — never datetime.utcnow() (deprecated)@override on methods that intentionally override a parent methodasyncio.run(main()) as the sole async entry pointruff format; linting via ruff checkasyncio_mode = "auto")pathlib.Path over os.pathTypeVar + Generic for new generic classes/functions (use PEP 695 syntax)typing.Optional, typing.Union, typing.List, typing.Dict (use builtins + |)TypeAlias (use type statement)asyncio.gather() for structured concurrency (use TaskGroup)asyncio.wait_for() (use asyncio.timeout())asyncio.get_event_loop() or event loop policies (deprecated, removal 3.16)asyncio.iscoroutinefunction() (use inspect.iscoroutinefunction())datetime.utcnow() (deprecated — use datetime.now(tz=datetime.UTC))cgi, aifc, crypt, telnetlib, etc.from __future__ import annotations with Pydantic v2 (breaks runtime introspection)from pathlib import Path
def read_config(path: Path) -> dict[str, str]:
"""Read configuration from a file.
Args:
path: Path to the configuration file.
Returns:
Parsed key-value configuration entries.
Raises:
FileNotFoundError: If the config file does not exist.
ValueError: If a line cannot be parsed.
"""
config: dict[str, str] = {}
with path.open() as f:
for line in f:
key, _, value = line.partition("=")
if not key.strip():
raise ValueError(f"Invalid config line: {line!r}")
config[key.strip()] = value.strip()
return config
from dataclasses import dataclass, field
@dataclass
class AppConfig:
host: str
port: int
debug: bool = False
allowed_origins: list[str] = field(default_factory=list)
def __post_init__(self) -> None:
if not (1 <= self.port <= 65535):
raise ValueError(f"Invalid port: {self.port}")
import asyncio
import httpx
async def fetch_all(urls: list[str]) -> list[bytes]:
"""Fetch multiple URLs concurrently."""
async with httpx.AsyncClient() as client:
tasks = [client.get(url) for url in urls]
responses = await asyncio.gather(*tasks)
return [r.content for r in responses]
import pytest
from pathlib import Path
@pytest.fixture
def config_file(tmp_path: Path) -> Path:
cfg = tmp_path / "config.txt"
cfg.write_text("host=localhost\nport=8080\n")
return cfg
@pytest.mark.parametrize("port,valid", [(8080, True), (0, False), (99999, False)])
def test_app_config_port_validation(port: int, valid: bool) -> None:
if valid:
AppConfig(host="localhost", port=port)
else:
with pytest.raises(ValueError):
AppConfig(host="localhost", port=port)
# Generic function — no TypeVar import needed
def first[T](items: list[T]) -> T | None:
return items[0] if items else None
# Generic class
class Cache[K, V]:
def __init__(self) -> None:
self._data: dict[K, V] = {}
def get(self, key: K) -> V | None:
return self._data.get(key)
# Type alias
type JsonDict = dict[str, object]
[tool.mypy]
python_version = "3.12"
strict = true
[tool.ruff]
line-length = 88
target-version = "py312"
[tool.ruff.lint]
select = ["E", "W", "F", "I", "UP", "B", "C4", "SIM", "TC", "PTH", "RUF"]
ignore = ["E501"]
Clean mypy --strict output looks like:
Success: no issues found in 12 source files
Any reported error must be resolved before the implementation is considered complete.
When implementing Python features, provide:
Python 3.12+, PEP 695 generics, mypy strict, pytest asyncio_mode=auto, ruff (lint+format), uv, dataclasses, Pydantic v2, asyncio.TaskGroup, asyncio.timeout, pathlib, functools, itertools, contextlib, collections.abc, Protocol, TypeIs, TypedDict, copy.replace
npx claudepluginhub corticalstack/engineering --plugin engineeringProvides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.