Agent skill
python3-typing
Selects and applies the strongest valid Python typing strategy for the current project. Use when designing models, validating external data, addressing type checker failures, reducing Any usage, defining boundaries, or choosing between stdlib typing, Pydantic, and Hypothesis-based boundary testing.
Stars
33
Forks
4
Install this agent skill to your Project
npx add-skill https://github.com/Jamie-BitFlight/claude_skills/tree/main/plugins/python-engineering/skills/python3-typing
SKILL.md
Python Typing
Choose the strongest valid lane automatically. Do not ask the user to pick a typing philosophy.
Consult references/typing-policy.md for the full policy document.
Required Policy
- Forbid
Any, broadobject, and uncheckedcast()in normal internal code - Allow them only at explicit boundaries where unknown-shape data enters
- Isolate boundary code in dedicated validator, parser, adapter, or boundary modules
- Validate immediately and return strongly typed internal objects
- Do not let raw payloads cross into the typed core
- Allow narrow lint exceptions for
Anyonly in approved boundary modules
Lane Selection
1. Python 3.10 Constrained or stdlib-only
- Use only compatibility-safe stdlib typing features
- Prefer
dataclasses,TypedDict,Protocol,Literal,TypeGuard,NewType - Validate with explicit runtime checks in dedicated boundary wrappers
- No third-party type assumptions
2. Python 3.11+ stdlib-only
- Use modern stdlib typing features supported by the interpreter
- Use
Self,assert_type, andreveal_typewhere useful during refactoring TypedDictwithNotRequired
3. Python 3.11+ with Pydantic
- Use Pydantic models for ingress contracts
- Prefer strict mode where coercion would hide upstream errors
- Use
TypeAdapterfor annotated types that do not need full models - See
references/pydantic-boundaries.md
4. Python 3.11+ with Hypothesis
- Property-test boundaries, validators, parsers, and invariants
- Prefer
from_type()where practical - See
references/hypothesis-boundaries.md
5. Python 3.12+
- Use
typestatement for explicit type aliases:type JSONValue = str | int | ... - Use PEP 695 generic parameter syntax for new generic helpers
6. Python 3.13+
- Use
TypeIsfor clearer custom narrowing helpers (replacesTypeGuardwhere bidirectional narrowing needed) - Use
ReadOnlyinTypedDictfields that must not mutate after validation
7. Python 3.14+
- Keep annotation-reading infrastructure compatible with deferred evaluation (PEP 649)
- Use
annotationlib.get_annotations()in infrastructure that inspects annotations at runtime
Boundary Implementation Standard
Use dedicated wrappers named like:
parse_*validate_*decode_*coerce_**_from_raw
Boundary modules should return typed objects only.
Example: stdlib-only boundary
python
from typing import TypedDict, NotRequired
from dataclasses import dataclass
class _RawIncoming(TypedDict):
user_id: int
email: str
metadata: NotRequired[dict[str, str]]
@dataclass(frozen=True, slots=True)
class IncomingPayload:
user_id: int
email: str
metadata: dict[str, str]
def parse_incoming(data: _RawIncoming) -> IncomingPayload:
return IncomingPayload(
user_id=data["user_id"],
email=data["email"],
metadata=data.get("metadata", {}),
)
Example: Pydantic boundary
python
from pydantic import BaseModel, TypeAdapter
class IncomingPayload(BaseModel):
user_id: int
email: str
metadata: dict[str, str] = {}
model_config = {"strict": True}
def parse_incoming(data: dict[str, object]) -> IncomingPayload:
return IncomingPayload.model_validate(data)
References
references/typing-policy.md— full boundary validation policyreferences/pydantic-boundaries.md— Pydantic model and TypeAdapter patternsreferences/hypothesis-boundaries.md— property-based testing for validators
Didn't find tool you were looking for?