← ClaudeAtlas

py-typeslisted

Python type system advisor. Always use this skill when working with Python type hints, mypy, Protocol, TypedDict, dataclasses, or generics. Use when the user asks "how do I type this in Python", "mypy is complaining", "should I use TypedDict or dataclass", "how do I type a dict", "what's Optional", "how do I make a generic class", "Protocol vs ABC vs TypedDict", "how do I annotate a function that returns X or Y", or "how do I avoid Any". Read this skill before answering any Python type annotation question.
AllThingsSmitty/agent-skills · ★ 1 · Code & Development · score 74
Install: claude install-skill AllThingsSmitty/agent-skills
# Python Types Python's type system is gradual — you can add hints incrementally without breaking anything. But partial typing is a trap: unannotated code is treated as `Any` by mypy, and `Any` propagates silently. The goal is enough coverage that mypy can catch real mistakes. ## Start with `--strict` in mypy The default mypy configuration is lenient. Enable strict mode to get meaningful coverage: ```ini # mypy.ini or pyproject.toml [tool.mypy] strict = true ``` Or per-file to adopt gradually: ```python # mypy: strict ``` Key strict flags: `--disallow-untyped-defs`, `--disallow-any-generics`, `--warn-return-any`. Fix these first — they catch the most real bugs. ## `Any` vs `object` `Any` is a two-way escape hatch: it's compatible with every type and every type is compatible with it. This means errors hide. ```python # Bad: Any propagates — x.anything() won't be caught def process(x: Any) -> Any: return x.value # Better: object is the base type — forces you to narrow before using def process(x: object) -> str: if isinstance(x, MyModel): return x.value raise TypeError(f"Unexpected type: {type(x)}") ``` Use `Any` only at true integration boundaries (untyped third-party libs) and isolate it with a narrow wrapper. ## Nullable types Always annotate `None` explicitly. A missing annotation and `Optional[X]` are not the same — the latter is checked. ```python # Python 3.10+: use the union shorthand def find_user(id: str) -> User | None: ... # Earlier