Python type hint conventions for this codebase. Apply when writing or reviewing Python code that needs type annotations on functions, classes, or variables.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
Python type hint conventions for this codebase. Apply when writing or reviewing Python code that needs type annotations on functions, classes, or variables.
user-invocable
false
Type Hints
Type annotations are REQUIRED on all functions and classes.
Quick Reference
Element
Convention
Example
Optional values
X | None
user: User | None
Input collections
Sequence, Mapping, Iterable
items: Sequence[str]
Return collections
list, dict
-> list[str]
Generic containers
Lowercase builtins
list[str], dict[str, int]
Type variables
Inline [T] syntax (PEP 695)
def first[T](...)
Type aliases
type statement (PEP 695)
type UserId = int
Constants
Final[type]
MAX_RETRIES: Final[int] = 3
Constrained strings
Literal
Status = Literal["active", "pending"]
Dict structures
TypedDict
For API responses and configs
Fluent methods
Self
For builder patterns
Interfaces
Protocol
For duck typing with type safety
Modern Syntax (Python 3.10+)
Union Types
# CORRECT - modern union syntaxdefget_user(user_id: int) -> User | None:
...
defprocess(value: str | int | float) -> str:
...
# INCORRECT - deprecated Optionalfrom typing importOptional, Uniondefget_user(user_id: int) -> Optional[User]: # Don't use
...
defprocess(value: Union[str, int, float]) -> str: # Don't use
...
Use collections.abc for parameters when you only need iteration or read access:
from collections.abc importSequence, Mapping, Callable, Iterator, Iterable
# CORRECT - accept abstract, return concretedeftransform(items: Sequence[str]) -> list[str]:
return [item.upper() for item in items]
deflookup(data: Mapping[str, int], key: str) -> int | None:
return data.get(key)
defapply(fn: Callable[[int], str], values: Iterable[int]) -> Iterator[str]:
return (fn(v) for v in values)
# INCORRECT - overly restrictive parameter typesdeftransform(items: list[str]) -> list[str]: # Rejects tuples, other sequences
...
Generic Types (PEP 695, Python 3.12+)
Use inline [T] type parameter syntax instead of explicit TypeVar declarations:
from collections.abc importSequence# CORRECT - PEP 695 inline syntaxdeffirst[T](items: Sequence[T]) -> T | None:
"""Return the first item or None if empty."""return items[0] if items elseNonedefmerge_dicts[K, V](a: dict[K, V], b: dict[K, V]) -> dict[K, V]:
"""Merge two dictionaries, with b taking precedence."""return {**a, **b}
classStack[T]:
"""Generic stack with proper typing."""def__init__(self) -> None:
self._items: list[T] = []
defpush(self, item: T) -> None:
self._items.append(item)
defpop(self) -> T:
returnself._items.pop()
# Bounded type parametersdefprocess[T: (str, bytes)](data: T) -> T: ...
# ParamSpecfrom collections.abc importCallabledefdecorator[**P, R](fn: Callable[P, R]) -> Callable[P, R]: ...
# TypeVarTupledefzip_args[*Ts](*args: *Ts) -> tuple[*Ts]: ...
# INCORRECT - old-style TypeVar declarationsfrom typing import TypeVar
T = TypeVar("T")
deffirst(items: Sequence[T]) -> T | None: # Don't use
...
Self Type (Python 3.11+)
Use Self for methods that return the instance (fluent/builder patterns):
from typing import Self
classBuilder:
"""Fluent builder pattern with proper typing."""defwith_name(self, name: str) -> Self:
self.name = name
returnselfdefwith_value(self, value: int) -> Self:
self.value = value
returnself
Protocol for Structural Subtyping
Use Protocol to define interfaces based on behavior (duck typing with type safety):
from typing import Protocol
classReadable(Protocol):
"""Any object that can be read."""defread(self) -> str: ...
classCloseable(Protocol):
"""Any object that can be closed."""defclose(self) -> None: ...
# Intersection of protocolsdefprocess_stream(stream: Readable & Closeable) -> str:
"""Process any readable, closeable stream."""try:
return stream.read()
finally:
stream.close()
Type Aliases (PEP 695, Python 3.12+)
Use the type statement instead of TypeAlias:
# CORRECT - PEP 695 type statementtype UserId = inttype Embedding = list[float]
type BatchEmbeddings = list[Embedding]
# Generic type aliasestype Matrix[T] = list[list[T]]
# Recursive aliases (no forward references needed with type statement)type JsonValue = str | int | float | bool | None | list[JsonValue] | dict[str, JsonValue]
defencode(texts: list[str]) -> BatchEmbeddings:
...
# INCORRECT - old-style TypeAliasfrom typing import TypeAlias
UserId: TypeAlias = int# Don't use
Always annotate module-level constants with Final[type], including the explicit type parameter:
from typing import Final
# CORRECT - Final[type] with explicit type parameter
MAX_RETRIES: Final[int] = 3
API_BASE_URL: Final[str] = "https://api.example.com"
DEFAULT_TIMEOUT: Final[float] = 30.0
SUPPORTED_FORMATS: Final[frozenset[str]] = frozenset({"json", "csv", "parquet"})
ENABLE_DEBUG: Final[bool] = False# INCORRECT - bare Final without type parameter
MAX_RETRIES: Final = 3# Missing type parameter# INCORRECT - no Final annotation at all
MAX_RETRIES: int = 3# Mutable, not marked as constant
MAX_RETRIES = 3# No type info, not marked as constant
Validation
Run type checking via the validate-code skill:
uv run .claude/scripts/validate_code.py --type <path>