python-type-hints
Complete Python type hints system. PROACTIVELY activate for: (1) Built-in generics (list[str], dict[str, int]), (2) Union types (str | None), (3) Type parameter syntax 3.12+, (4) Protocol for structural typing, (5) TypedDict for dict schemas, (6) Literal and Final types, (7) TypeGuard and TypeIs, (8) ParamSpec for decorators, (9) Mypy/Pyright configuration. Provides: Type syntax, Protocol patterns, TypedDict, mypy config. Ensures static type safety with gradual typing strategy.
What this skill does
## Quick Reference
| Type | Syntax (3.9+) | Example |
|------|---------------|---------|
| List | `list[str]` | `names: list[str] = []` |
| Dict | `dict[str, int]` | `ages: dict[str, int] = {}` |
| Optional | `str \| None` | `name: str \| None = None` |
| Union | `int \| str` | `value: int \| str` |
| Callable | `Callable[[int], str]` | `func: Callable[[int], str]` |
| Feature | Version | Syntax |
|---------|---------|--------|
| Type params | 3.12+ | `def first[T](items: list[T]) -> T:` |
| type alias | 3.12+ | `type Point = tuple[float, float]` |
| Self | 3.11+ | `def copy(self) -> Self:` |
| TypeIs | 3.13+ | `def is_str(x) -> TypeIs[str]:` |
| Construct | Use Case |
|-----------|----------|
| `Protocol` | Structural subtyping (duck typing) |
| `TypedDict` | Dict with specific keys |
| `Literal["a", "b"]` | Specific values only |
| `Final[str]` | Cannot be reassigned |
## When to Use This Skill
Use for **static type checking**:
- Adding type hints to functions and classes
- Creating typed dictionaries with TypedDict
- Defining protocols for duck typing
- Configuring mypy or pyright
- Writing generic functions and classes
**Related skills:**
- For Python fundamentals: see `python-fundamentals-313`
- For testing: see `python-testing`
- For FastAPI schemas: see `python-fastapi`
---
# Python Type Hints Complete Guide
## Overview
Type hints enable static type checking, better IDE support, and self-documenting code. Python's typing system is gradual - you can add types incrementally.
## Modern Type Hints (Python 3.9+)
### Built-in Generic Types
```python
# Python 3.9+ - Use built-in types directly
# No need for typing.List, typing.Dict, etc.
def process_items(items: list[str]) -> dict[str, int]:
return {item: len(item) for item in items}
# Collections
names: list[str] = ["Alice", "Bob"]
ages: dict[str, int] = {"Alice": 30, "Bob": 25}
coordinates: tuple[float, float] = (1.0, 2.0)
unique_ids: set[int] = {1, 2, 3}
frozen_data: frozenset[str] = frozenset(["a", "b"])
# Nested generics
matrix: list[list[int]] = [[1, 2], [3, 4]]
config: dict[str, list[str]] = {"servers": ["a", "b"]}
```
### Union Types (Python 3.10+)
```python
# Old way (still works)
from typing import Union, Optional
def old_style(value: Union[int, str]) -> Optional[str]:
return str(value) if value else None
# New way (Python 3.10+)
def new_style(value: int | str) -> str | None:
return str(value) if value else None
# Optional is just Union with None
# Optional[str] == str | None
```
### Type Aliases
```python
# Simple type alias
UserId = int
Username = str
def get_user(user_id: UserId) -> Username:
return "user_" + str(user_id)
# Complex type alias
from typing import TypeAlias
JsonValue: TypeAlias = str | int | float | bool | None | list["JsonValue"] | dict[str, "JsonValue"]
# Python 3.12+ type statement
type Point = tuple[float, float]
type Vector[T] = list[T]
type JsonDict = dict[str, "JsonValue"]
```
### Type Parameters (Python 3.12+)
```python
# Old way with TypeVar
from typing import TypeVar
T = TypeVar("T")
def first_old(items: list[T]) -> T:
return items[0]
# New way (Python 3.12+)
def first[T](items: list[T]) -> T:
return items[0]
# Generic classes
class Stack[T]:
def __init__(self) -> None:
self._items: list[T] = []
def push(self, item: T) -> None:
self._items.append(item)
def pop(self) -> T:
return self._items.pop()
# Multiple type parameters
def merge[K, V](d1: dict[K, V], d2: dict[K, V]) -> dict[K, V]:
return {**d1, **d2}
# Bounded type parameters
from typing import SupportsLessThan
def minimum[T: SupportsLessThan](a: T, b: T) -> T:
return a if a < b else b
# Default type parameters (Python 3.13+)
class Container[T = int]:
def __init__(self, value: T) -> None:
self.value = value
```
## Function Signatures
### Basic Functions
```python
from typing import Callable, Iterable, Iterator
# Simple function
def greet(name: str) -> str:
return f"Hello, {name}!"
# Multiple parameters
def create_user(name: str, age: int, email: str | None = None) -> dict:
return {"name": name, "age": age, "email": email}
# *args and **kwargs
def log(*args: str, **kwargs: int) -> None:
for arg in args:
print(arg)
for key, value in kwargs.items():
print(f"{key}={value}")
# Callable type
def apply_func(func: Callable[[int, int], int], a: int, b: int) -> int:
return func(a, b)
# Higher-order functions
def make_multiplier(n: int) -> Callable[[int], int]:
def multiplier(x: int) -> int:
return x * n
return multiplier
```
### Overloads
```python
from typing import overload, Literal
@overload
def process(data: str) -> str: ...
@overload
def process(data: bytes) -> bytes: ...
@overload
def process(data: int) -> int: ...
def process(data: str | bytes | int) -> str | bytes | int:
if isinstance(data, str):
return data.upper()
elif isinstance(data, bytes):
return data.upper()
else:
return data * 2
# Overload with Literal
@overload
def fetch(url: str, format: Literal["json"]) -> dict: ...
@overload
def fetch(url: str, format: Literal["text"]) -> str: ...
@overload
def fetch(url: str, format: Literal["bytes"]) -> bytes: ...
def fetch(url: str, format: str) -> dict | str | bytes:
# Implementation
...
```
### ParamSpec for Decorators
```python
from typing import ParamSpec, TypeVar, Callable
from functools import wraps
P = ParamSpec("P")
R = TypeVar("R")
def log_calls(func: Callable[P, R]) -> Callable[P, R]:
@wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
print(f"Calling {func.__name__}")
return func(*args, **kwargs)
return wrapper
@log_calls
def add(a: int, b: int) -> int:
return a + b
# Python 3.12+ syntax
def log_calls_new[**P, R](func: Callable[P, R]) -> Callable[P, R]:
@wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
print(f"Calling {func.__name__}")
return func(*args, **kwargs)
return wrapper
```
## Classes and Protocols
### Class Typing
```python
from typing import ClassVar, Self
class User:
# Class variable
count: ClassVar[int] = 0
def __init__(self, name: str, age: int) -> None:
self.name = name
self.age = age
User.count += 1
# Self type for method chaining
def with_name(self, name: str) -> Self:
self.name = name
return self
def with_age(self, age: int) -> Self:
self.age = age
return self
# Usage
user = User("Alice", 30).with_name("Bob").with_age(25)
```
### Protocols (Structural Subtyping)
```python
from typing import Protocol, runtime_checkable
# Define a protocol (interface)
class Drawable(Protocol):
def draw(self) -> None: ...
class Resizable(Protocol):
def resize(self, width: int, height: int) -> None: ...
# Combining protocols
class DrawableAndResizable(Drawable, Resizable, Protocol):
pass
# Implementation (no explicit inheritance needed!)
class Circle:
def draw(self) -> None:
print("Drawing circle")
class Rectangle:
def draw(self) -> None:
print("Drawing rectangle")
def resize(self, width: int, height: int) -> None:
print(f"Resizing to {width}x{height}")
# Works because Circle has draw() method
def render(shape: Drawable) -> None:
shape.draw()
render(Circle()) # OK - Circle satisfies Drawable protocol
# Runtime checkable protocol
@runtime_checkable
class Closeable(Protocol):
def close(self) -> None: ...
# Can use isinstance
if isinstance(file, Closeable):
file.close()
```
### TypedDict
```python
from typing import TypedDict, Required, NotRequired
# Basic TypedDict
class Movie(TypedDict):
title: str
year: int
director: str
movie: Movie = {"title": "Inception", "year": 2010, "director": "Nolan"}
# With optional keys
class UserProfile(TypedDict, total=False):
name: str # Optional
email: str # Optional
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.