### Example usage of NamedTuple Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/classes.md Demonstrates creating a NamedTuple instance and accessing its fields and dictionary representation. ```python from typing_extensions import NamedTuple class Movie(NamedTuple): title: str year: int director: str = "Unknown" m = Movie("Inception", 2010) m.title # "Inception" m._asdict() # OrderedDict([('title', 'Inception'), ('year', 2010), ('director', 'Unknown')]) ``` -------------------------------- ### ParamSpecArgs and ParamSpecKwargs Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Demonstrates how ParamSpecArgs and ParamSpecKwargs can be used within a decorator to preserve the original function's signature. ```python P = ParamSpec('P') def decorator(f: Callable[P, int]) -> Callable[P, int]: def wrapper(*args: P.args, **kwargs: P.kwargs) -> int: # args: ParamSpecArgs # kwargs: ParamSpecKwargs return f(*args, **kwargs) return wrapper ``` -------------------------------- ### Generic Protocol Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Illustrates a generic Protocol for a container that can get and put items of a specific type T. A concrete implementation `ListContainer` is also shown. ```python from typing import TypeVar, Generic from typing_extensions import Protocol T = TypeVar('T') class Container(Protocol[T], Generic[T]): def get(self) -> T: ... def put(self, item: T) -> None: ... class ListContainer(Generic[T]): def __init__(self): self.items: list[T] = [] def get(self) -> T: return self.items[0] def put(self, item: T) -> None: self.items.append(item) def process(container: Container[int]) -> int: return container.get() ``` -------------------------------- ### Get Protocol Members Example Source: https://github.com/python/typing_extensions/blob/main/doc/index.md Demonstrates how to retrieve members of a Protocol using get_protocol_members. This function works with protocols defined using either typing.Protocol or typing_extensions.Protocol. It raises TypeError for non-Protocol arguments. ```python >>> from typing_extensions import Protocol, get_protocol_members >>> class P(Protocol): ... def a(self) -> str: ... ... b: int >>> get_protocol_members(P) frozenset({'a', 'b'}) ``` -------------------------------- ### Run Linters with uv Source: https://github.com/python/typing_extensions/blob/main/CONTRIBUTING.md Use uvx to run pre-commit linters in an isolated environment. This prevents conflicts with locally installed versions of typing_extensions. ```shell uvx pre-commit run -a ``` -------------------------------- ### TypedDict Inheritance Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/typeddict.md Demonstrates how TypedDicts can inherit from other TypedDicts to reuse and extend definitions. The 'User' TypedDict inherits from 'BaseRecord'. ```python from typing_extensions import TypedDict, Required class BaseRecord(TypedDict): id: int created: str class User(BaseRecord): name: str email: str user: User = { "id": 1, "created": "2024-01-01", "name": "Alice", "email": "alice@example.com" } ``` -------------------------------- ### Timing Decorator with ParamSpec Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md A practical example of a decorator using ParamSpec to time function execution and print the elapsed time. ```python from typing import ParamSpec P = ParamSpec('P') def timing_decorator(f: Callable[P, int]) -> Callable[P, int]: def wrapper(*args: P.args, **kwargs: P.kwargs) -> int: import time start = time.time() result = f(*args, **kwargs) elapsed = time.time() - start print(f"Took {elapsed:.2f}s") return result return wrapper ``` -------------------------------- ### Protocol (Structural Typing) Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/protocols.md Illustrates structural typing where a class implicitly satisfies a protocol by having the required methods, without explicit inheritance. ```python from typing_extensions import Protocol class Drawable(Protocol): def draw(self) -> None: ... class Circle: def draw(self) -> None: pass # Works without declaring Circle(Drawable) ``` -------------------------------- ### Get Annotations for a Function Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/functions.md Compute the annotations dictionary for a function. Use format=Format.STRING to get string representations of annotations. ```python from typing_extensions import get_annotations, Format def foo(x: int, y: str) -> bool: pass get_annotations(foo) # {'x': int, 'y': str, 'return': bool} get_annotations(foo, format=Format.STRING) # String representations ``` -------------------------------- ### Unconstrained TypeVar Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Demonstrates using an unconstrained TypeVar 'T' to create a generic Box class that can hold any type. ```python T = TypeVar('T') class Box(Generic[T]): def __init__(self, value: T) -> None: self.value = value def get(self) -> T: return self.value box_int: Box[int] = Box(42) box_str: Box[str] = Box("hello") ``` -------------------------------- ### Generic TypedDict Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/classes.md Demonstrates how to create a generic TypedDict that can hold values of a specified type parameter T. This feature is available in Python 3.11+. ```python from typing import TypeVar, Generic from typing_extensions import TypedDict T = TypeVar('T') class Container(TypedDict, Generic[T]): value: T c: Container[int] = {"value": 42} ``` -------------------------------- ### Run Linters with pipx Source: https://github.com/python/typing_extensions/blob/main/CONTRIBUTING.md Use pipx to run pre-commit linters in an isolated environment. This ensures that pre-commit and its dependencies are installed separately. ```shell pipx run pre-commit run -a ``` -------------------------------- ### Constrained TypeVar Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Illustrates a Constrained TypeVar 'Number' that restricts a function to accept only integers or floats. ```python Number = TypeVar('Number', int, float) def add(x: Number, y: Number) -> Number: return x + y # Type: Number add(1, 2) # OK, returns int add(1.5, 2.5) # OK, returns float add(1, "2") # Type error - str not in constraints ``` -------------------------------- ### TypeVarTuple Basic Usage Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Demonstrates the basic usage of `TypeVarTuple` to create a generic `Tuple` class that can hold a variable number of typed elements. ```python from typing_extensions import TypeVarTuple, Unpack from typing import Generic Ts = TypeVarTuple('Ts') class Tuple[*Ts]: def __init__(self, *args: *Ts) -> None: self.values = args # Usage t: Tuple[int, str, float] = Tuple(1, "hello", 3.14) ``` -------------------------------- ### Logging Wrapper with Concatenate Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md A practical example of a decorator using `Concatenate` to add a logging label before the original function's arguments. ```python from typing import ParamSpec, Callable from typing_extensions import Concatenate P = ParamSpec('P') def logging_wrapper( f: Callable[P, None] ) -> Callable[Concatenate[str, P], None]: def wrapper(label: str, *args: P.args, **kwargs: P.kwargs) -> None: print(f"[{label}]", end=" ") return f(*args, **kwargs) return wrapper @logging_wrapper def greet(name: str, greeting: str = "Hello") -> None: print(f"{greeting}, {name}") greet("Alice") # [Alice] Hello, Alice greet("Alice", greeting="Hi") # [Alice] Hi, Alice ``` -------------------------------- ### Abstract Base Class (Nominal Typing) Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/protocols.md Demonstrates nominal typing where a class must explicitly inherit from an ABC to satisfy its contract. Includes the use of `@abstractmethod`. ```python from abc import ABC, abstractmethod class Drawable(ABC): @abstractmethod def draw(self) -> None: ... class Circle(Drawable): # Must inherit def draw(self) -> None: pass ``` -------------------------------- ### Create and Use Sentinel Objects Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/classes.md Example of creating unique sentinel objects using the sentinel class. Sentinels are useful as distinct marker values, especially when None is a valid option. Supports custom representations and union types. ```python from typing_extensions import sentinel _MISSING = sentinel("_MISSING") _UNSET = sentinel("_UNSET", repr="") def get_value(default=_MISSING): if default is _MISSING: # Use some default pass print(_MISSING) # _MISSING print(_UNSET) # ``` -------------------------------- ### TypedDict Type Safety Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/typeddict.md Demonstrates the type safety benefits of TypedDict compared to a generic `dict[str, Any]`. TypedDict provides structure information, type-safe access, and better IDE support. ```python from typing_extensions import TypedDict class Movie(TypedDict): title: str year: int movie: Movie = {"title": "Inception", "year": 2010} movie["title"] # Type: str movie["unknown"] # Type error - key doesn't exist ``` ```python movie: dict[str, Any] = {"title": "Inception", "year": 2010} movie["title"] # Type: Any movie["unknown"] # Type: Any - no error ``` -------------------------------- ### Bounded TypeVar Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Shows a Bounded TypeVar 'T_abs' that constrains a type to be a subtype of SupportsAbs, ensuring it supports the abs() function. ```python from typing import SupportsAbs T_abs = TypeVar('T_abs', bound=SupportsAbs) def get_absolute(x: T_abs) -> T_abs: return abs(x) get_absolute(42) # OK get_absolute(-3.14) # OK get_absolute("str") # Type error - str doesn't support __abs__ ``` -------------------------------- ### TypeVar with Default Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Demonstrates a TypeVar 'T_default' with a default type of 'int' for a generic Stack class, allowing default type inference. ```python from typing_extensions import NoDefault T_default = TypeVar('T_default', default=int) class Stack(Generic[T_default]): ... Stack() # Type: Stack[int] (uses default) Stack[str] # Type: Stack[str] (override default) ``` -------------------------------- ### TypedDict with total=True (Default) Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/typeddict.md When total is True (the default), all keys defined in the TypedDict are required. This example shows a type error for a missing key. ```python from typing_extensions import TypedDict class Movie(TypedDict): # total=True is default title: str year: int m: Movie = {"title": "Inception"} # Type error - missing 'year' m = {"title": "Inception", "year": 2010} # OK ``` -------------------------------- ### Example Usage of Typing Name Introspection Source: https://github.com/python/typing_extensions/blob/main/doc/index.md Demonstrates how to use the `is_typing_name` function with `functools.partial` to check for specific typing constructs like `Literal` and `Final`. It also shows how to use `get_origin` for introspection. ```python >>> import typing, typing_extensions >>> from functools import partial >>> from typing_extensions import get_origin >>> is_literal = partial(is_typing_name, name="Literal") >>> is_literal(typing.Literal) True >>> is_literal(typing_extensions.Literal) True >>> is_literal(typing.Any) False >>> is_literal(get_origin(typing.Literal[42])) True >>> is_literal(get_origin(typing_extensions.Final[int])) False ``` -------------------------------- ### Closed TypedDict Example (NoExtraItems) Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/typeddict.md Illustrates how to define a TypedDict that strictly prohibits extra keys using `extra_items=NoExtraItems`. A standard TypedDict without this parameter allows extra keys. ```python from typing_extensions import TypedDict, NoExtraItems class Strict(TypedDict, extra_items=NoExtraItems): x: int y: int # TypedDict without extra_items allows extra keys class Flexible(TypedDict): x: int y: int s: Strict = {"x": 1, "y": 2} # OK s = {"x": 1, "y": 2, "z": 3} # Type checker error - extra key ``` -------------------------------- ### Get annotations with different formats Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/classes.md Use get_annotations with the Format enum to retrieve function annotations in various formats. Format.VALUE returns annotations as-is, while Format.STRING returns them as strings. ```python from typing_extensions import get_annotations, Format def foo(x: int, y: str) -> bool: pass # Different formats hints_value = get_annotations(foo, format=Format.VALUE) hints_string = get_annotations(foo, format=Format.STRING) ``` -------------------------------- ### Generic TypedDict Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Define a generic TypedDict that can hold values of any type T, along with a string label. This allows creating type-safe dictionaries with varying value types. ```python from typing import TypeVar, Generic from typing_extensions import TypedDict T = TypeVar('T') class Container(TypedDict, Generic[T]): value: T label: str int_container: Container[int] = {"value": 42, "label": "count"} str_container: Container[str] = {"value": "hi", "label": "greeting"} ``` -------------------------------- ### Covariant Generic Type Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Demonstrates a covariant generic `Producer` class where the type parameter T_co only appears in return positions. This allows `Producer[int]` to be a subtype of `Producer[object]`. ```python T_co = TypeVar('T_co', covariant=True) class Producer(Generic[T_co]): def produce(self) -> T_co: ... # Producer[int] IS a subtype of Producer[object] producer_int: Producer[int] = ... producer_obj: Producer[object] = producer_int # OK ``` -------------------------------- ### Contravariant Generic Type Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Illustrates a contravariant generic `Consumer` class where the type parameter T_contra only appears in argument positions. This allows `Consumer[object]` to be a subtype of `Consumer[int]`. ```python T_contra = TypeVar('T_contra', contravariant=True) class Consumer(Generic[T_contra]): def consume(self, item: T_contra) -> None: ... # Consumer[object] IS a subtype of Consumer[int] consumer_obj: Consumer[object] = ... consumer_int: Consumer[int] = consumer_obj # OK ``` -------------------------------- ### I/O Type Hints (TextIO, BinaryIO) Source: https://github.com/python/typing_extensions/blob/main/_autodocs/types.md Shows how to use TextIO and BinaryIO for type hinting file-like objects that handle text or binary data, respectively. ```python from typing_extensions import TextIO, BinaryIO def read_text(f: TextIO) -> str: return f.read() def read_binary(f: BinaryIO) -> bytes: return f.read() ``` -------------------------------- ### Define and Use Sentinel Objects Source: https://github.com/python/typing_extensions/blob/main/doc/index.md Demonstrates how to define and use sentinel objects for default arguments and type checking. Requires importing sentinel and assert_type from typing_extensions. ```python >>> from typing_extensions import sentinel, assert_type >>> MISSING = sentinel('MISSING') >>> def func(arg: int | MISSING = MISSING) -> None: ... if arg is MISSING: ... assert_type(arg, MISSING) ... else: ... assert_type(arg, int) ... >>> func(MISSING) ``` -------------------------------- ### File Organization Structure Source: https://github.com/python/typing_extensions/blob/main/_autodocs/README.md Illustrates the directory structure of the typing_extensions project, showing the location of the README and other documentation files. ```text output/ ├── README.md (this file) ├── overview.md ├── types.md └── api-reference/ ├── functions.md ├── special-forms.md ├── classes.md ├── protocols.md ├── typeddict.md └── generics.md ``` -------------------------------- ### Annotate type hints with documentation using Doc Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/special-forms.md Shows how to use the Doc construct with Annotated to attach a documentation string to a type hint. ```python Doc("Documentation string") ``` ```python from typing_extensions import Annotated, Doc def process( value: Annotated[int, Doc("The value to process")], name: Annotated[str, Doc("The name of the value")] ) -> None: pass ``` -------------------------------- ### Protocol Types for I/O Streams (Reader, Writer) Source: https://github.com/python/typing_extensions/blob/main/_autodocs/types.md Demonstrates the Reader and Writer protocol types for abstracting I/O stream operations, allowing for flexible stream handling. ```python from typing_extensions import Reader, Writer def copy_stream(src: Reader, dst: Writer) -> None: dst.write(src.read()) ``` -------------------------------- ### Importing from typing_extensions Source: https://github.com/python/typing_extensions/blob/main/_autodocs/README.md Demonstrates the standard import pattern for accessing symbols from the typing_extensions library. All public symbols are available at the top level. ```python from typing_extensions import ( ParamSpec, TypeVar, Protocol, TypedDict, # ... etc ) ``` -------------------------------- ### Run Tests Locally Source: https://github.com/python/typing_extensions/blob/main/CONTRIBUTING.md Execute the tests for typing_extensions using the python interpreter. Ensure you are in the 'src/' directory to use the local file. ```shell cd src/ python test_typing_extensions.py ``` -------------------------------- ### Run Tests with Unittest Source: https://github.com/python/typing_extensions/blob/main/CONTRIBUTING.md Alternatively, invoke the unittest module explicitly to run the tests for typing_extensions. This also ensures the local file is used. ```shell python -m unittest test_typing_extensions.py ``` -------------------------------- ### Use NoExtraItems with TypedDict Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/special-forms.md Demonstrates how to use the NoExtraItems singleton with a TypedDict to disallow any keys beyond those explicitly defined. ```python from typing_extensions import TypedDict, NoExtraItems class StrictMovie(TypedDict, extra_items=NoExtraItems): title: str year: int ``` -------------------------------- ### Abstract Base Class Imports (Sequence, Mapping, etc.) Source: https://github.com/python/typing_extensions/blob/main/_autodocs/types.md Demonstrates importing and using abstract base classes from typing_extensions for common collection types like Sequence, Mapping, Iterable, Iterator, and Callable. ```python from typing_extensions import Sequence, Mapping, Iterable, Iterator, Callable def process(seq: Sequence[int]) -> Iterator[int]: return iter(seq) def apply(f: Callable[[int], str], x: int) -> str: return f(x) ``` -------------------------------- ### Generic NamedTuples Source: https://github.com/python/typing_extensions/blob/main/_autodocs/overview.md Create generic NamedTuples that can hold values of any type. This example defines a Box that can contain a value of a type specified by a TypeVar. ```python from typing import TypeVar, Generic from typing_extensions import NamedTuple T = TypeVar('T') class Box(NamedTuple, Generic[T]): value: T ``` -------------------------------- ### Usage of SupportsInt Protocol Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/protocols.md Shows how the `SupportsInt` protocol from `typing_extensions` can be used to type-hint functions that accept any object convertible to an integer. ```python from typing_extensions import SupportsInt def to_integer(obj: SupportsInt) -> int: return int(obj) to_integer(42) # int to_integer(3.14) # float (has __int__) to_integer("123") # str (has __int__) ``` -------------------------------- ### Get Registered Overloads for a Function Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/functions.md Retrieves all registered overloads for a given function. This is useful for introspection and understanding how a function handles different argument types. ```python from typing import overload from typing_extensions import get_overloads @overload def process(x: int) -> str: ... @overload def process(x: str) -> int: ... def process(x): return x overloads = get_overloads(process) # Returns the list of @overload decorated versions ``` -------------------------------- ### Get Protocol Members Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/protocols.md Use get_protocol_members() to retrieve a frozenset of member names defined within a Protocol. This function raises a TypeError if the input is not a Protocol. ```python from typing_extensions import Protocol, get_protocol_members class Drawable(Protocol): def draw(self) -> None: ... def fill(self) -> None: ... width: int color: str members = get_protocol_members(Drawable) # frozenset({'draw', 'fill', 'width', 'color'}) # Non-protocol raises TypeError get_protocol_members(int) # TypeError: 'int' is not a Protocol ``` -------------------------------- ### Type-Safe Configuration with TypedDict Source: https://github.com/python/typing_extensions/blob/main/_autodocs/overview.md Define structured dictionaries with type hints using TypedDict. Use Required and NotRequired to specify the optionality of keys. ```python from typing_extensions import TypedDict, Required, NotRequired class Config(TypedDict): debug: Required[bool] log_level: NotRequired[str] timeout: int ``` -------------------------------- ### Running Tests with tox Source: https://github.com/python/typing_extensions/blob/main/_autodocs/overview.md Execute the test suite for the typing_extensions project using the tox automation tool. This command ensures compatibility across different Python environments. ```bash tox ``` -------------------------------- ### Type-Safe Decorators with ParamSpec Source: https://github.com/python/typing_extensions/blob/main/_autodocs/overview.md Use ParamSpec to create type-safe decorators that preserve the signature of the decorated function. This example demonstrates adding logging functionality. ```python from typing import Callable, ParamSpec from typing_extensions import Concatenate P = ParamSpec('P') T = TypeVar('T') def add_logging(f: Callable[P, T]) -> Callable[P, T]: def wrapper(*args: P.args, **kwargs: P.kwargs) -> T: print(f"Calling {f.__name__}") return f(*args, **kwargs) return wrapper ``` -------------------------------- ### Get Protocol Members Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/functions.md Retrieves the set of members defined within a Protocol class. Raises a TypeError if the provided argument is not a Protocol. This is useful for analyzing the structure of a protocol. ```python from typing_extensions import Protocol, get_protocol_members class P(Protocol): def a(self) -> str: ... b: int get_protocol_members(P) # frozenset({'a', 'b'}) ``` -------------------------------- ### Get Type Arguments with Substitutions Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/functions.md Retrieves type arguments from a generic alias, performing substitutions and basic simplifications for unions. Returns an empty tuple if the type has no arguments. ```python from typing_extensions import get_args get_args(Dict[str, int]) # (str, int) get_args(int) # () get_args(Union[int, Union[T, int], str][int]) # (int, str) get_args(Callable[[], T][int]) # ([], int) ``` -------------------------------- ### TypedDict with ReadOnly, Required, and NotRequired Modifiers Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/classes.md Example demonstrating the use of ReadOnly for immutable fields, Required for mandatory fields, and NotRequired for optional fields within a TypedDict. ```python from typing_extensions import TypedDict, Required, NotRequired, ReadOnly class Employee(TypedDict): name: ReadOnly[str] # Cannot modify id: Required[int] # Must be present email: NotRequired[str] # May be absent salary: NotRequired[float] emp: Employee = { "name": "John", "id": 123, } from typing_extensions import is_typeddict is_typeddict(Employee) # True ``` -------------------------------- ### Define ParamSpec and access args/kwargs Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/special-forms.md Shows how to define a ParamSpec and access its argument and keyword argument components using .args and .kwargs. ```python P = ParamSpec('P') P.args # ParamSpecArgs P.kwargs # ParamSpecKwargs ``` ```python from typing import ParamSpec P = ParamSpec('P') def decorator(f: Callable[P, T]) -> Callable[P, T]: def inner(*args: P.args, **kwargs: P.kwargs) -> T: # Access to original function's args/kwargs return f(*args, **kwargs) return inner ``` -------------------------------- ### get_args Source: https://github.com/python/typing_extensions/blob/main/doc/index.md Retrieves the arguments of a generic type. ```APIDOC ## get_args(tp) ### Description See `typing.get_args()`. This function backports fixes for handling `Annotated` and `ParamSpec` correctly in older Python versions. ### Parameters #### Path Parameters - **tp** (type) - Required - The type to get arguments from. ``` -------------------------------- ### Protocol with Class Variable Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/protocols.md Defines a protocol that includes a ClassVar for versioning. Demonstrates how a class can implement this protocol by providing the class variable and a method to access it. ```python from typing_extensions import Protocol, ClassVar class HasVersion(Protocol): version: ClassVar[str] def get_version(self) -> str: ... class MyClass: version: ClassVar[str] = "1.0" def get_version(self) -> str: return self.version obj: HasVersion = MyClass() print(obj.get_version()) # "1.0" ``` -------------------------------- ### Literal Types and Type Guard for Narrowing Source: https://github.com/python/typing_extensions/blob/main/_autodocs/overview.md Use Literal to specify exact values a variable can hold and TypeGuard for type narrowing. This example checks if a status is 'active'. ```python from typing_extensions import Literal, TypeGuard Status = Literal["pending", "active", "archived"] def is_active(status: str) -> TypeGuard[Literal["active"]]: return status == "active" ``` -------------------------------- ### Use NoDefault singleton for TypeVar Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/special-forms.md Illustrates the use of the NoDefault singleton to explicitly indicate that a TypeVar has no default value. ```python NoDefault ``` ```python from typing import TypeVar from typing_extensions import NoDefault T = TypeVar('T', default=NoDefault) # No default U = TypeVar('U', default=int) # Has default ``` -------------------------------- ### Get Original Class Bases Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/functions.md Returns a class's original base classes before any modifications by `__mro_entries__`. Raises a TypeError if the argument is not a type. Useful for understanding class inheritance hierarchies. ```python from typing import TypeVar, Generic from typing_extensions import get_original_bases T = TypeVar("T") class Foo(Generic[T]): ... class Bar(Foo[int], float): ... get_original_bases(Bar) # (Foo[int], float) get_original_bases(int) # (object,) ``` -------------------------------- ### Protocol Types for Special Methods (SupportsInt, SupportsFloat) Source: https://github.com/python/typing_extensions/blob/main/_autodocs/types.md Illustrates the use of protocol types like SupportsInt and SupportsFloat, which represent objects implementing specific special methods (e.g., __int__, __float__). ```python from typing_extensions import SupportsInt, SupportsFloat def process_number(x: SupportsInt) -> int: return int(x) ``` -------------------------------- ### Get Unsubscripted Type Origin Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/functions.md Retrieves the original, unsubscripted version of a type. Returns None for types without a clear origin. Supports a wide range of generic and special types. ```python from typing_extensions import get_origin get_origin(Literal[42]) # Literal get_origin(int) # None get_origin(ClassVar[int]) # ClassVar get_origin(Union[T, int]) # Union get_origin(List[Tuple[T, T]][int]) # list ``` -------------------------------- ### Generic Function Definition and Usage Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Demonstrates defining and using a generic function `identity` with `typing.TypeVar`, showing how it can accept and return values of any type while preserving the type. ```python T = TypeVar('T') def identity(x: T) -> T: return x identity(42) # Type: int identity("hello") # Type: str ``` -------------------------------- ### Doc Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/special-forms.md Used with Annotated to attach a documentation string directly to a type hint, providing runtime access to the documentation. ```APIDOC ## Doc Declared at: `src/typing_extensions.py:3943` ```python Doc("Documentation string") ``` Use with Annotated to attach documentation to a type hint. | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | documentation | `str` | Yes | — | Documentation string | **Example**: ```python from typing_extensions import Annotated, Doc def process( value: Annotated[int, Doc("The value to process")], name: Annotated[str, Doc("The name of the value")] ) -> None: pass ``` **Notes**: Available at runtime as `documentation` attribute on the Doc object. Complements docstrings. ``` -------------------------------- ### Invariant Generic Type Example Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Shows an invariant generic `Box` class where the type parameter T is not a subtype of another type parameter. This prevents assigning a `Box[int]` to a `Box[object]`. ```python from typing import TypeVar, Generic T = TypeVar('T') class Box(Generic[T]): def __init__(self, value: T) -> None: self.value = value def set(self, value: T) -> None: self.value = value # Box[int] is NOT a subtype of Box[object] box_int: Box[int] = Box(42) box_obj: Box[object] = box_int # Type error - invariant ``` -------------------------------- ### Using Required and NotRequired for Key Specificity Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/typeddict.md Explicitly declare keys as required or optional using Required and NotRequired, overriding the global 'total' parameter. ```python from typing_extensions import TypedDict, Required, NotRequired class Config(TypedDict, total=False): debug: Required[bool] # Must be present log_file: str # Optional (total=False) timeout: NotRequired[int] # Explicitly optional cfg: Config = {"debug": True} # OK cfg = {} # Type error - missing required 'debug' ``` ```python from typing_extensions import TypedDict, NotRequired class User(TypedDict): name: str # Required (total=True) age: NotRequired[int] # Optional user: User = {"name": "Alice"} # OK user = {"name": "Bob", "age": 30} # OK ``` -------------------------------- ### Importing Multiple Types from typing_extensions Source: https://github.com/python/typing_extensions/blob/main/_autodocs/overview.md Shows the standard import pattern for accessing various typing features from the top-level typing_extensions module. All public symbols are available for direct import. ```python from typing_extensions import ( TypeGuard, ParamSpec, TypeVar, Literal, # ... etc ) ``` -------------------------------- ### Linting with ruff Source: https://github.com/python/typing_extensions/blob/main/_autodocs/overview.md Apply linting rules to the typing_extensions source code using the ruff linter. This command checks for code style and potential errors. ```bash ruff check src/ ``` -------------------------------- ### Get Type Hints with Forward References and Extras Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/functions.md The get_type_hints function retrieves type hints from an object, resolving forward references and optionally including extra type information like Annotated metadata. ```python from typing_extensions import get_type_hints, Required, NotRequired, Annotated, Doc from typing import TypedDict class Movie(TypedDict): title: Required[str] year: NotRequired[int] description: Annotated[str, Doc("Film description")] hints = get_type_hints(Movie) # Returns: {'title': str, 'year': int, 'description': str} hints_with_extras = get_type_hints(Movie, include_extras=True) # Includes Required, NotRequired, Annotated wrappers ``` -------------------------------- ### Configuration Object Pattern with TypedDict Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/typeddict.md Defines a TypedDict for application configuration, using `ReadOnly` for immutable fields and `NotRequired` for optional settings. This promotes type-safe configuration management. ```python from typing_extensions import TypedDict, NotRequired, ReadOnly class AppConfig(TypedDict): name: ReadOnly[str] version: ReadOnly[str] debug: bool log_level: NotRequired[str] workers: NotRequired[int] timeout: int def create_app(config: AppConfig) -> None: print(f"App: {config['name']} v{config['version']}") if "log_level" in config: print(f"Log level: {config['log_level']}") ``` -------------------------------- ### TypedDict Inheritance with Total=False Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/typeddict.md Shows how to create a TypedDict that inherits from another and makes some of its fields optional using `total=False`. Fields from the base TypedDict remain required unless explicitly overridden. ```python class Required(TypedDict): name: str class Optional(Required, total=False): age: int email: str # 'name' is required (from Required) # 'age' and 'email' are optional (total=False) obj: Optional = {"name": "Bob"} # OK ``` -------------------------------- ### TypeVarTuple with Unpack for Function Signatures Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Shows how `TypeVarTuple` and `Unpack` can be used in function signatures to handle variadic types, such as in `transpose` and `flatten` functions. ```python from typing_extensions import TypeVarTuple, Unpack Ts = TypeVarTuple('Ts') def transpose(array: Tuple[*Ts]) -> Tuple[*Ts]: return array def flatten(*args: Unpack[Ts]) -> Tuple[*Ts]: return args ``` -------------------------------- ### Format Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/classes.md Enumeration for annotation format options used in `get_annotations()`. ```APIDOC ## Format ### Description Enumeration for annotation format options in `get_annotations()`. ### Members - **`VALUE`** (`int`) - 1 - Return annotations as-is (default) - **`VALUE_WITH_FAKE_GLOBALS`** (`int`) - 2 - For internal use only - **`FORWARDREF`** (`int`) - 3 - Use ForwardRef for undefined names - **`STRING`** (`int`) - 4 - Return annotations as strings ### Example ```python from typing_extensions import get_annotations, Format def foo(x: int, y: str) -> bool: pass # Different formats hints_value = get_annotations(foo, format=Format.VALUE) hints_string = get_annotations(foo, format=Format.STRING) ``` ``` -------------------------------- ### API Response Pattern with TypedDict Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/typeddict.md Shows how to model an API response structure using TypedDicts, including nested structures and optional fields. This enhances type safety when handling API data. ```python from typing_extensions import TypedDict, NotRequired class User(TypedDict): id: int username: str email: str profile_picture: NotRequired[str] class ApiResponse(TypedDict): success: bool data: NotRequired[User] error: NotRequired[str] def handle_response(response: ApiResponse) -> None: if response["success"] and "data" in response: user = response["data"] print(f"User: {user['username']}") else: print(f"Error: {response.get('error')}") ``` -------------------------------- ### Define TypeVar with different options Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/special-forms.md Demonstrates the declaration of TypeVar with various configurations like unconstrained, constrained to specific types, bounded by another type, and with a default value. ```python T = TypeVar('T') T_co = TypeVar('T', covariant=True) T_contra = TypeVar('T', contravariant=True) T_with_default = TypeVar('T', default=int) ``` ```python from typing import TypeVar # Unconstrained T = TypeVar('T') # Constrained to specific types Number = TypeVar('Number', int, float) # Bounded TypeVar T_ordered = TypeVar('T_ordered', bound=Comparable) # With default T_default = TypeVar('T_default', default=int) class Box(Generic[T]): def __init__(self, value: T) -> None: self.value = value ``` -------------------------------- ### get_type_hints Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/functions.md Returns type hints for an object as a dictionary, resolving forward references and applying qualifiers. Handles inherited annotations and optional defaults. ```APIDOC ## get_type_hints ### Description Return type hints for an object as a dictionary, resolving forward references and applying qualifiers. Handles inherited annotations and optional defaults. ### Parameters #### Path Parameters - obj (Module, Class, Method, or Function) - Required - The object to get hints from - globalns (dict | None) - Optional - Global namespace for resolving references (defaults to auto-detected) - localns (dict | None) - Optional - Local namespace for resolving references (defaults to auto-detected) - include_extras (bool) - Optional - Whether to keep `Annotated`, `Required`, `NotRequired`, `ReadOnly` (defaults to False) ### Return Type dict[str, Any] ### Raises TypeError if argument is not annotatable ### Example ```python from typing_extensions import get_type_hints, Required, NotRequired, Annotated, Doc class Movie(TypedDict): title: Required[str] year: NotRequired[int] description: Annotated[str, Doc("Film description")] hints = get_type_hints(Movie) # Returns: {'title': str, 'year': int, 'description': str} hints_with_extras = get_type_hints(Movie, include_extras=True) # Includes Required, NotRequired, Annotated wrappers ``` ### Notes Handles inherited annotations in classes. Resolves forward references and Optional defaults. By default strips Annotated metadata. ``` -------------------------------- ### Annotated Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/special-forms.md Adds arbitrary metadata to a type hint. The first argument is the type, and remaining arguments are metadata that can be inspected at runtime. ```APIDOC ## Annotated ### Description Adds arbitrary metadata to a type hint. The first argument is the type, remaining arguments are metadata that can be inspected at runtime. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **type** (type) - Required - The underlying type - **metadata** (Any) - No - One or more metadata objects ### Request Example ```python from typing_extensions import Annotated, Doc # With custom metadata UserId = Annotated[int, "user id", "positive"] # With documentation def greet(name: Annotated[str, Doc("User's display name")]) -> None: pass # Runtime inspection from typing import get_args args = get_args(Annotated[int, "positive"]) # args = (int, "positive") ``` ### Response #### Success Response (200) None #### Response Example None ### Notes Metadata is preserved at runtime. Can be used for validation, documentation, serialization hints, etc. ``` -------------------------------- ### Doc Class Source: https://github.com/python/typing_extensions/blob/main/doc/index.md Define documentation for a type annotation using Annotated. ```APIDOC ## class Doc(documentation) ### Description Define the documentation of a type annotation using [`Annotated`](#typing_extensions.Annotated), to be used in class attributes, function and method parameters, return values, and variables. The value should be a positional-only string literal. ### Parameters #### Positional Arguments - **documentation** (str) - Required - The documentation string. ### Example ```python from typing_extensions import Annotated, Doc def hi(to: Annotated[str, Doc("Who to say hi to")]) -> None: print(f"Hi, {to}") ``` ``` -------------------------------- ### Unpack tuple[T, ...] for Function Arguments Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Illustrates using `Unpack` with a standard `tuple[T, ...]` type hint to define a function that accepts a variable number of arguments of a specific type. ```python from typing_extensions import Unpack def flatten(*items: Unpack[tuple[int, ...]]) -> int: return sum(items) flatten(1, 2, 3) # OK ``` -------------------------------- ### Type Checker Behavior with Protocols Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/protocols.md Demonstrates how type checkers handle protocols, including static type checking and structural assignments without explicit inheritance. ```python # Without @runtime_checkable, type checking works statically obj: Drawable = Circle() # OK obj.draw() # Subclasses must explicitly satisfy the protocol class Square(Drawable): # Type error if draw() not defined def draw(self) -> None: ... # Structural assignments work without inheritance def process(drawable: Drawable) -> None: drawable.draw() class Triangle: def draw(self) -> None: print("Triangle") process(Triangle()) # OK - Triangle has draw() method ``` -------------------------------- ### Generic Class with Multiple Type Variables Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Demonstrates a generic `Converter` class and a `Pipeline` class that chains two converters, using multiple type variables (T, U, V) to define input and output types for each step. ```python from typing import TypeVar, Generic T = TypeVar('T') U = TypeVar('U') V = TypeVar('V') class Converter(Generic[T, U]): def convert(self, value: T) -> U: ... class Pipeline(Generic[T, U, V]): def __init__(self, step1: Converter[T, U], step2: Converter[U, V]): self.step1 = step1 self.step2 = step2 def execute(self, value: T) -> V: intermediate = self.step1.convert(value) return self.step2.convert(intermediate) ``` -------------------------------- ### Custom Generic Protocol Definition and Usage Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/protocols.md Defines a generic Serializable protocol with `to_dict` and `from_dict` methods. Demonstrates runtime checking and usage with a concrete User class. ```python from typing import TypeVar, Generic from typing_extensions import Protocol, runtime_checkable T = TypeVar('T') @runtime_checkable class Serializable(Protocol[T]): def to_dict(self) -> dict: ... def from_dict(self, data: dict) -> T: ... class User: def __init__(self, name: str): self.name = name def to_dict(self) -> dict: return {"name": self.name} def from_dict(self, data: dict) -> "User": return User(data["name"]) def serialize(obj: Serializable[User]) -> dict: return obj.to_dict() user = User("Alice") serialize(user) # Type checker accepts isinstance(user, Serializable) # True ``` -------------------------------- ### NoDefault Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/special-forms.md A singleton object indicating that a type parameter has no default value, used in conjunction with PEP 696 default values for TypeVars. ```APIDOC ## NoDefault Declared at: `src/typing_extensions.py:1075` ```python NoDefault ``` Singleton indicating that a type parameter has no default value. Used with PEP 696 default values. **Example**: ```python from typing import TypeVar from typing_extensions import NoDefault T = TypeVar('T', default=NoDefault) # No default U = TypeVar('U', default=int) # Has default ``` **Notes**: Type parameters without defaults must come before those with defaults. Singleton object, not a type. ``` -------------------------------- ### Type Checking with Decorated Function Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Illustrates how type checking works with a function decorated by `timing_decorator`, ensuring correct argument passing. ```python @timing_decorator def compute(x: int, y: int, verbose: bool = False) -> int: return x + y # Signature is preserved: compute(1, 2) # OK compute(1, 2, verbose=True) # OK compute(1) # Type error - missing required argument ``` -------------------------------- ### Unpack TypeVarTuple for Function Arguments Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/generics.md Demonstrates using `Unpack` with `TypeVarTuple` to define a function that accepts arguments corresponding to the unpacked types of a `TypeVarTuple`. ```python from typing_extensions import TypeVarTuple, Unpack Ts = TypeVarTuple('Ts') def process(*args: Unpack[Ts]) -> None: pass ``` -------------------------------- ### get_args Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/functions.md Retrieves the type arguments of a generic alias, performing substitutions and simplifications. It returns an empty tuple if the type has no arguments or is unsupported. ```APIDOC ## get_args ### Description Get type arguments with all substitutions performed. For unions, applies basic simplifications. ### Signature ```python def get_args(tp) -> tuple ``` ### Parameters #### Path Parameters - **tp** (Any) - Required - A type or generic alias ### Return Type `tuple` (empty tuple if tp has no args) ### Example ```python from typing_extensions import get_args get_args(Dict[str, int]) # (str, int) get_args(int) # () get_args(Union[int, Union[T, int], str][int]) # (int, str) get_args(Callable[[], T][int]) # ([], int) ``` ### Notes Returns `()` for unsupported types. Special handling for Callable types (converts arg list to list form). ``` -------------------------------- ### Handle NewType subclassing error Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/classes.md Demonstrates the error raised when attempting to subclass an instance of NewType. ```python from typing_extensions import NewType UserId = NewType('UserId', int) class MyId(UserId): pass # TypeError: Cannot subclass an instance of NewType ``` -------------------------------- ### runtime_checkable Decorator Source: https://github.com/python/typing_extensions/blob/main/doc/index.md Enables runtime checking of protocol conformance. Backports performance improvements. ```APIDOC ## @runtime_checkable ### Description Enables runtime checking of protocol conformance. Backports performance improvements. ``` -------------------------------- ### Alias for Runtime Checkable Protocol Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/functions.md Marks a Protocol as runtime-checkable using isinstance(). This allows you to check if an object conforms to the protocol at runtime. ```python from typing_extensions import Protocol, runtime @runtime class Drawable(Protocol): def draw(self) -> None: ... ``` -------------------------------- ### Deprecated Container Types (Dict, List, Set, Tuple) Source: https://github.com/python/typing_extensions/blob/main/_autodocs/types.md Illustrates the older, deprecated generic forms of container types like Dict and List. It also shows the preferred modern syntax using lowercase built-in types. ```python from typing_extensions import Dict, List, Set, Tuple # Old style (still supported) x: Dict[str, int] = {} y: List[int] = [] # New style (Python 3.9+) x: dict[str, int] = {} y: list[int] = [] ``` -------------------------------- ### Nested TypedDicts Pattern Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/typeddict.md Demonstrates how to create nested TypedDict structures, representing complex data relationships like a person with an address. This improves type safety for hierarchical data. ```python from typing_extensions import TypedDict class Address(TypedDict): street: str city: str zip_code: str class Person(TypedDict): name: str age: int address: Address person: Person = { "name": "Alice", "age": 30, "address": { "street": "123 Main St", "city": "Springfield", "zip_code": "12345" } } ``` -------------------------------- ### Protocol Composition for Specific Types Source: https://github.com/python/typing_extensions/blob/main/_autodocs/api-reference/protocols.md Composes multiple protocols (Drawable, Resizable) into a single Shape protocol. Shows how a class implementing all composed protocols satisfies the composite type. ```python from typing_extensions import Protocol class Drawable(Protocol): def draw(self) -> None: ... class Resizable(Protocol): def resize(self, width: int, height: int) -> None: ... class Shape(Drawable, Resizable, Protocol): """Composite protocol.""" pass class Rectangle: def draw(self) -> None: print("rect") def resize(self, width: int, height: int) -> None: pass def process_shape(shape: Shape) -> None: shape.draw() shape.resize(10, 20) process_shape(Rectangle()) # OK ```