py-typeslisted
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