### Syntax Example for datetime Module Source: https://github.com/python/typing/blob/main/docs/guides/writing_stubs.md Illustrates the expected syntax for type annotations and method signatures in stub files, using the datetime module as an example. ```default MAXYEAR: int MINYEAR: int class date: def __new__(cls, year: SupportsIndex, month: SupportsIndex, day: SupportsIndex) -> Self: ... @classmethod def fromtimestamp(cls, timestamp: float, /) -> Self: ... @classmethod def today(cls) -> Self: ... @classmethod def fromordinal(cls, n: int, /) -> Self: ... @property def year(self) -> int: ... def replace(self, year: SupportsIndex = ..., month: SupportsIndex = ..., day: SupportsIndex = ...) -> Self: ... def ctime(self) -> str: ... def weekday(self) -> int: ... ``` -------------------------------- ### Install Stub Package Source: https://github.com/python/typing/blob/main/docs/tutorials/external_libraries.md Install a stub package for a library to enable type checking. This is useful for libraries that do not include their own type hints. ```default pip install requests types-requests ``` -------------------------------- ### Install New Lockfile and Rerun Conformance Source: https://github.com/python/typing/blob/main/conformance/README.md After bumping type checkers, install the new lockfile and rerun the conformance tests. This step is crucial for verifying the impact of type checker updates. ```bash uv sync --python 3.12 --frozen ``` ```bash uv run --python 3.12 --frozen python src/main.py ``` -------------------------------- ### Class Example with Dataclass Transform Source: https://github.com/python/typing/blob/main/docs/spec/dataclasses.md Shows how to use `@typing.dataclass_transform` on a base class to set default behaviors for its subclasses. This example configures `ModelBase` to default to synthesizing comparison methods. ```python # Indicate that classes that derive from this class default to # synthesizing comparison methods. @typing.dataclass_transform(eq_default=True, order_default=True) class ModelBase: def __init_subclass__( cls, *, init: bool = True, frozen: bool = False, eq: bool = True, order: bool = True, ): ... # Example of how this class would be used by code that imports # from this library: class CustomerModel( ModelBase, init=False, frozen=True, eq=False, order=False, ): id: int name: str ``` -------------------------------- ### Dataclass Instantiation Examples Source: https://github.com/python/typing/blob/main/docs/spec/dataclasses.md Demonstrates valid and invalid ways to instantiate a dataclass-like class. Static type checkers should flag invalid instantiations. ```python # Using positional arguments c1 = CustomerModel(327, "John Smith") # Using keyword arguments c2 = CustomerModel(id=327, name="John Smith") # These calls will generate runtime errors and should be flagged as # errors by a static type checker. c3 = CustomerModel() c4 = CustomerModel(327, first_name="John") c5 = CustomerModel(327, "John Smith", 0) ``` -------------------------------- ### Annotated Syntax and Usage Source: https://github.com/python/typing/blob/main/docs/spec/qualifiers.md Demonstrates the basic syntax of Annotated, including how to define it with a base expression and metadata, and provides examples of its application. ```APIDOC ## Annotated Type Hinting ### Description The `Annotated` type hint allows associating metadata with a base type expression. This metadata can be used for static analysis, runtime checks, or other tool-specific purposes. ### Syntax `Annotated` is parameterized with a *base expression* and at least one Python value representing associated *metadata*: ```python from typing import Annotated Annotated[BaseExpr, Metadata1, Metadata2, ...] ``` ### Key Syntax Rules: * **Base Expression**: The first argument must be a valid type or annotation expression in the given context. * **Multiple Metadata**: `Annotated` supports multiple metadata arguments. ```python Annotated[int, ValueRange(3, 10), ctype("char")] ``` * **Minimum Metadata**: At least one metadata element is required (`Annotated[int]` is invalid). * **Metadata Order**: The order of metadata elements is preserved and affects equality checks. ```python Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[ int, ctype("char"), ValueRange(3, 10) ] ``` * **Nested Flattening**: Nested `Annotated` types are flattened, preserving the order of metadata. ```python Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[ int, ValueRange(3, 10), ctype("char") ] ``` * **Duplicate Metadata**: Duplicate metadata elements are not removed. ```python Annotated[int, ValueRange(3, 10)] != Annotated[ int, ValueRange(3, 10), ValueRange(3, 10) ] ``` * **Generic Aliases**: `Annotated` can be used in generic aliases if it wraps a type expression. ```python type Vec[T] = Annotated[list[tuple[T, T]], MaxLen(10)] type V = Vec[int] # Equivalent to Annotated[list[tuple[int, int]], MaxLen(10)] ``` * **Type Assignment**: `Annotated` is generally not assignable to `type` or `type[T]`. ```python v1: type[int] = Annotated[int, ""] # Type error ``` * **Calling Annotated**: Calling `Annotated` (parameterized or not) is a type error. ```python Annotated() # Type error Annotated[int, ""](0) # Type error ``` ### Meaning of Metadata The metadata can be used for static or runtime analysis. Libraries or tools encountering `Annotated[T, x]` should ignore unknown metadata `x` and treat the expression as equivalent to `T`. Type checkers may recognize specific metadata elements for extensions to the type system. ### Consuming Metadata Tools and libraries are responsible for interpreting metadata. They can scan metadata (e.g., using `isinstance()`). * **Unknown Metadata**: Ignored; the annotation is treated as the base expression. * **Namespacing**: Not needed, as the class of the metadata object acts as a namespace. * **Multiple Elements**: Consumers decide how to handle multiple metadata elements, including duplicates. Nested annotations are flattened before consumption. ``` -------------------------------- ### TypeGuard vs TypeIs Example Source: https://github.com/python/typing/blob/main/docs/guides/type_narrowing.md Demonstrates the distinct type narrowing behaviors of TypeGuard and TypeIs when used in conditional checks with custom predicate functions. ```python from typing import TypeGuard, TypeIs, reveal_type, final class Base: ... class Child(Base): ... @final class Unrelated: ... def is_base_typeguard(x: object) -> TypeGuard[Base]: return isinstance(x, Base) def is_base_typeis(x: object) -> TypeIs[Base]: return isinstance(x, Base) def use_typeguard(x: Child | Unrelated) -> None: if is_base_typeguard(x): reveal_type(x) # Base else: reveal_type(x) # Child | Unrelated def use_typeis(x: Child | Unrelated) -> None: if is_base_typeis(x): reveal_type(x) # Child else: reveal_type(x) # Unrelated ``` -------------------------------- ### TypedDict Inheritance Example Source: https://github.com/python/typing/blob/main/docs/spec/typeddict.md Demonstrates a TypedDict subclass inheriting fields from a parent TypedDict. ```python class BookBasedMovie(Movie): based_on: str ``` ```python class BookBasedMovie(TypedDict): name: str year: int based_on: str ``` -------------------------------- ### Demonstrate covariance Source: https://github.com/python/typing/blob/main/docs/spec/special-types.md Example showing that type[Derived] is a subtype of type[Base]. ```python def new_pro_user(pro_user_class: type[ProUser]): user = new_user(pro_user_class) # OK ... ``` -------------------------------- ### Companion Type Stub Package Configuration Source: https://github.com/python/typing/blob/main/docs/guides/libraries.md Example `pyproject.toml` configuration for a companion type stub package, specifying its name, version, and build system requirements. ```toml [project] name = "my-great-package-stubs" version = "0.1.0" requires-python = ">=3.10" [build-system] requires = ["uv_build>=0.9.18,<0.10.0"] build-backend = "uv_build" ``` -------------------------------- ### Metaclass Example with Dataclass Transform Source: https://github.com/python/typing/blob/main/docs/spec/dataclasses.md Illustrates using `@typing.dataclass_transform` on a metaclass to define default behaviors for classes that use it. This example sets up `ModelMeta` to default to synthesizing comparison methods for its classes. ```python # Indicate that classes that use this metaclass default to # synthesizing comparison methods. @typing.dataclass_transform(eq_default=True, order_default=True) class ModelMeta(type): def __new__( cls, name, bases, namespace, *, init: bool = True, frozen: bool = False, eq: bool = True, order: bool = True, ): ... class ModelBase(metaclass=ModelMeta): ... # Example of how this class would be used by code that imports # from this library: class CustomerModel( ModelBase, init=False, frozen=True, eq=False, order=False, ): id: int name: str ``` -------------------------------- ### Inconsistent Overload Implementation Example Source: https://github.com/python/typing/blob/main/docs/spec/overload.md This example demonstrates an implementation that is inconsistent with its overloads. The implementation fails to accept a keyword argument 'x' as required by the second overload, and its return type 'str' is not assignable to the overload's return type 'int'. ```python @overload def func(x: str, /) -> str: ... @overload def func(x: int) -> int: ... # This implementation is inconsistent with the second overload # because it does not accept a keyword argument ``x`` and the # the overload's return type ``int`` is not assignable to the # implementation's return type ``str``. def func(x: int | str, /) -> str: return str(x) ``` -------------------------------- ### Define subclasses of generic classes Source: https://github.com/python/typing/blob/main/docs/reference/generics.md Examples of creating generic and non-generic subclasses from existing generic base classes. ```python from typing import Generic, TypeVar, Mapping, Iterator KT = TypeVar('KT') VT = TypeVar('VT') # This is a generic subclass of Mapping class MyMap(Mapping[KT, VT]): def __getitem__(self, k: KT) -> VT: ... def __iter__(self) -> Iterator[KT]: ... def __len__(self) -> int: ... items: MyMap[str, int] # OK # This is a non-generic subclass of dict class StrDict(dict[str, str]): def __str__(self) -> str: return f'StrDict({super().__str__()})' data: StrDict[int, int] # error: "StrDict" expects no type arguments, but 2 given data2: StrDict # OK # This is a user-defined generic class class Receiver(Generic[T]): def accept(self, value: T) -> None: ... # This is a generic subclass of Receiver class AdvancedReceiver(Receiver[T]): ... ``` -------------------------------- ### Function Type Annotations Source: https://github.com/python/typing/blob/main/docs/guides/libraries.md Shows examples of functions with known types, partially unknown types due to missing parameter or return annotations, and the impact of untyped decorators. ```python # Function with known type def func(a: int | None, b: dict[str, float] = {}) -> None: pass # Function with partially unknown type (because type annotations # are missing for input parameters and return type) def func(a, b): pass # Function with partially unknown type (because of missing # type args on Dict) def func(a: int, b: Dict) -> None: pass # Function with partially unknown type (because return type # annotation is missing) def func(a: int, b: dict[str, float]): pass ``` ```python # Decorator with partially unknown type (because type annotations # are missing for input parameters and return type) def my_decorator(func): return func # Function with partially unknown type (because type is obscured # by untyped decorator) @my_decorator def func(a: int) -> str: pass ``` -------------------------------- ### Companion Type Stub Package Structure Source: https://github.com/python/typing/blob/main/docs/guides/libraries.md Example directory structure for a companion type stub package, which provides type information for a separate runtime package. This structure uses `.pyi` files and does not require a `py.typed` marker. ```text pyproject.toml my_great_package-stubs/ __init__.pyi stuff.pyi ``` -------------------------------- ### Example of 'Any Trick' Usage Source: https://github.com/python/typing/blob/main/docs/guides/writing_stubs.md Illustrates how `MaybeNone` (an alias for `Any`) can be used to indicate a return type that might be None, simplifying user code and allowing type checkers to catch errors. ```default match = re.fullmatch(r"\d+(.*)", some_string) assert match is not None name_group = match.group(1) # The user knows that this will never be None name_group.uper() # This typo will be flagged by the type checker ``` -------------------------------- ### Avoiding Type Comments and Forward Reference Quotes Source: https://github.com/python/typing/blob/main/docs/guides/writing_stubs.md This example demonstrates the older, less preferred syntax for type hints using type comments and quoted forward references, which should be avoided in stubs. ```default class Py35Class: x = 0 # type: int forward_reference: 'OtherClass' class OtherClass: ... ``` -------------------------------- ### Function-based Syntax for NamedTuple and TypedDict (Avoid) Source: https://github.com/python/typing/blob/main/docs/guides/writing_stubs.md This example shows the older, function-based syntax for NamedTuple and TypedDict, which is discouraged in favor of the class-based syntax. ```default from typing import NamedTuple, TypedDict Point = NamedTuple("Point", [('x', float), ('y', float)]) Thing = TypedDict("Thing", {'stuff': str, 'index': int}) ``` -------------------------------- ### Defining and Using Disjoint Base Classes Source: https://github.com/python/typing/blob/main/docs/spec/directives.md Demonstrates how to use the @disjoint_base decorator to define disjoint base classes and how type checkers evaluate inheritance hierarchies to determine a class's valid disjoint base. Includes examples of valid and invalid configurations. ```python from typing import disjoint_base, assert_never @disjoint_base class Disjoint1: pass @disjoint_base class Disjoint2: pass @disjoint_base class DisjointChild(Disjoint1): pass class C1: # disjoint base is `object` pass # OK: candidate disjoint bases are `Disjoint1` and `object`, and `Disjoint1` is a subclass of `object`. class C2(Disjoint1, C1): # disjoint base is `Disjoint1` pass # OK: candidate disjoint bases are `DisjointChild` and `Disjoint1`, and `DisjointChild` is a subclass of `Disjoint1`. class C3(DisjointChild, Disjoint1): # disjoint base is `DisjointChild` pass # error: candidate disjoint bases are `Disjoint1` and `Disjoint2`, but neither is a subclass of the other class C4(Disjoint1, Disjoint2): pass def narrower(obj: Disjoint1) -> None: if isinstance(obj, Disjoint2): assert_never(obj) # OK: child class of `Disjoint1` and `Disjoint2` cannot exist if isinstance(obj, C1): reveal_type(obj) # Shows a non-empty type, e.g. `Disjoint1 & C1` ``` -------------------------------- ### TypeVar Subtype Promotion Example Source: https://github.com/python/typing/blob/main/docs/reference/generics.md Demonstrates how a subtype of a constrained TypeVar is promoted to the base type. When a subclass of str is used, the return type is inferred as str, not the subclass. ```python class S(str): pass ss = concat(S('foo'), S('bar')) reveal_type(ss) # Revealed type is "builtins.str" ``` -------------------------------- ### Define a Protocol with `typing.Protocol` Source: https://github.com/python/typing/blob/main/docs/spec/protocol.md Define a protocol by including `typing.Protocol` in the base classes. This example defines a `SupportsClose` protocol requiring a `close` method. ```python from typing import Protocol class SupportsClose(Protocol): def close(self) -> None: ... ``` -------------------------------- ### TypedDict Subtyping with Mapping Source: https://github.com/python/typing/blob/main/docs/spec/typeddict.md Demonstrates how TypedDict types are subtypes of Mapping[str, VT] when their value types are subtypes of VT. Shows examples with extra_items of str and int. ```python class MovieExtraStr(TypedDict, extra_items=str): name: str extra_str: MovieExtraStr = {"name": "Blade Runner", "summary": ""} str_mapping: Mapping[str, str] = extra_str # OK class MovieExtraInt(TypedDict, extra_items=int): name: str extra_int: MovieExtraInt = {"name": "Blade Runner", "year": 1982} int_mapping: Mapping[str, int] = extra_int # Not OK. 'int | str' is not assignable with 'int' int_str_mapping: Mapping[str, int | str] = extra_int # OK ``` -------------------------------- ### Class Type Annotations Source: https://github.com/python/typing/blob/main/docs/guides/libraries.md Provides examples of classes with complete type annotations and those with partially unknown types due to missing annotations for class variables, instance variables, or methods. ```python # Class with known type class MyClass: height: float = 2.0 def __init__(self, name: str, age: int): self.age: int = age @property def name(self) -> str: ... # Class with partially unknown type class MyClass: # Missing type annotation for class variable height = 2.0 # Missing input parameter annotations def __init__(self, name, age): # Missing type annotation for instance variable self.age = age # Missing return type annotation @property def name(self): ... ``` ```python # Class with partially unknown type class BaseClass: # Missing type annotation height = 2.0 # Missing type annotation def get_stuff(self): ... # Class with known type (because it overrides all symbols # exposed by BaseClass that have incomplete types) class DerivedClass(BaseClass): height: float def get_stuff(self) -> str: ... ``` ```python # Class with partially unknown type because base class # (dict) is generic, and type arguments are not specified. class DictSubclass(dict): pass ``` -------------------------------- ### Validating __new__ and __init__ Signature Consistency Source: https://github.com/python/typing/blob/main/docs/spec/constructors.md Shows an example where a type checker flags an error due to inconsistent signatures between the class constructor and initializer. ```python class MyClass: def __new__(cls) -> Self: return super().__new__(cls) # Type error: __new__ and __init__ have inconsistent signatures def __init__(self, x: str) -> None: pass ``` -------------------------------- ### Partial Module and Class Stubs Source: https://github.com/python/typing/blob/main/docs/guides/writing_stubs.md For partial modules or classes, include `__getattr__` marked with `_typeshed.Incomplete`. This example shows a partial module with a partial class `Foo` and a partially annotated function `bar`. ```python from _typeshed import Incomplete def __getattr__(name: str) -> Incomplete: ... class Foo: def __getattr__(self, name: str) -> Incomplete: ... x: int y: str def bar(x: str, y, *, z=...): ... ``` -------------------------------- ### TypedDict Subtyping with dict Source: https://github.com/python/typing/blob/main/docs/spec/typeddict.md Illustrates when a TypedDict with extra items can be a subtype of dict[str, VT]. Shows examples where mutable extra items and non-required items meet the conditions. ```python class IntDict(TypedDict, extra_items=int): pass class IntDictWithNum(IntDict): num: NotRequired[int] def f(x: IntDict) -> None: v: dict[str, int] = x # OK v.clear() # OK not_required_num_dict: IntDictWithNum = {"num": 1, "bar": 2} regular_dict: dict[str, int] = not_required_num_dict # OK f(not_required_num_dict) # OK ``` -------------------------------- ### Parametrized test case with `pytest-mypy-plugins` Source: https://github.com/python/typing/blob/main/docs/reference/quality.md Example of a parametrized test using `pytest-mypy-plugins`, where test cases are defined in YAML. This setup supports per-test `mypy` configuration and complex typing arrangements. ```yaml - case: with_params parametrized: - val: 1 rt: builtins.int - val: 1.0 rt: builtins.float main: | reveal_type({[ val }}) # N: Revealed type is '{{ rt }}' ``` -------------------------------- ### Create Virtual Environment Source: https://github.com/python/typing/blob/main/docs/README.rst Initializes a virtual environment with the necessary tools for building documentation. ```bash make venv ``` -------------------------------- ### LiteralString Type Inference Examples Source: https://github.com/python/typing/blob/main/docs/spec/literal.md Provides examples of how `LiteralString` is inferred in Python, including assignments, addition, joining, and formatting. ```python literal_string: LiteralString s: str = literal_string # OK literal_string: LiteralString = s # Error: Expected LiteralString, got str. literal_string: LiteralString = "hello" # OK ``` ```python def expect_literal_string(s: LiteralString) -> None: ... expect_literal_string("foo" + "bar") # OK expect_literal_string(literal_string + "bar") # OK literal_string2: LiteralString expect_literal_string(literal_string + literal_string2) # OK plain_string: str expect_literal_string(literal_string + plain_string) # Not OK. ``` ```python expect_literal_string(",".join(["foo", "bar"])) # OK expect_literal_string(literal_string.join(["foo", "bar"])) # OK expect_literal_string(literal_string.join([literal_string, literal_string2])) # OK xs: List[LiteralString] expect_literal_string(literal_string.join(xs)) # OK expect_literal_string(plain_string.join([literal_string, literal_string2])) # Not OK because the separator has type 'str'. ``` ```python literal_string += "foo" # OK literal_string += literal_string2 # OK literal_string += plain_string # Not OK ``` ```python literal_name: LiteralString expect_literal_string(f"hello {literal_name}") # OK because it is composed from literal strings. expect_literal_string("hello {}".format(literal_name)) # OK expect_literal_string(f"hello") # OK username: str expect_literal_string(f"hello {username}") # NOT OK. The format-string is constructed from 'username', ``` -------------------------------- ### Instantiate Generic Collections Source: https://github.com/python/typing/blob/main/docs/spec/generics.md Demonstrates instantiation of concrete generic collections and the recommended use of type aliases for readability. ```python data = DefaultDict[int, bytes]() ``` ```python data: DefaultDict[int, bytes] = collections.defaultdict() ``` -------------------------------- ### Build HTML Documentation Source: https://github.com/python/typing/blob/main/docs/README.rst Generates standalone HTML files from the source documentation. ```bash make html ``` -------------------------------- ### Concrete Generic Instantiation Source: https://github.com/python/typing/blob/main/docs/spec/generics.md Shows how to instantiate specific concrete types and the resulting errors for mismatched types. ```python # (continued from previous example) p = Node[int]() q = Node[str]() r = Node[int]('') # Error s = Node[str](0) # Error ``` -------------------------------- ### Decorator Function Example Source: https://github.com/python/typing/blob/main/docs/spec/dataclasses.md Demonstrates using `@typing.dataclass_transform` on a function to indicate default behaviors for synthesized methods. This example shows how a library function might use it to enforce keyword-only parameters and always synthesize order methods. ```python # Indicate that the ``create_model`` function assumes keyword-only # parameters for the synthesized ``__init__`` method unless it is # invoked with ``kw_only=False``. It always synthesizes order-related # methods and provides no way to override this behavior. @typing.dataclass_transform(kw_only_default=True, order_default=True) def create_model( *, frozen: bool = False, kw_only: bool = True, ) -> Callable[[Type[_T]], Type[_T]]: ... # Example of how this decorator would be used by code that imports # from this library: @create_model(frozen=True, kw_only=False) class CustomerModel: id: int name: str ``` -------------------------------- ### Use a generic stack class Source: https://github.com/python/typing/blob/main/docs/reference/generics.md Shows how to instantiate and interact with a generic class, including type checking behavior. ```python # Construct an empty Stack[int] instance stack = Stack[int]() stack.push(2) stack.pop() + 1 stack.push('x') # error: Argument 1 to "push" of "Stack" has incompatible type "str"; expected "int" ``` -------------------------------- ### Call factory function Source: https://github.com/python/typing/blob/main/docs/spec/special-types.md Example of type inference when calling the factory function. ```python joe = new_user(BasicUser) # Inferred type is BasicUser ``` -------------------------------- ### Generate Stubs with pyright Source: https://github.com/python/typing/blob/main/docs/guides/writing_stubs.md Utilize pyright's command-line tool to generate initial stub files for a package. Similar to stubgen, these are foundational stubs. ```console pyright --createstub my_great_package ``` -------------------------------- ### Invalid TypeIs assignment Source: https://github.com/python/typing/blob/main/docs/spec/narrowing.md Example of a type checker error when the narrowed type is not assignable to the input type. ```python from typing import TypeIs def is_str(x: int) -> TypeIs[str]: # Type checker error ... ``` -------------------------------- ### Nominal subtyping error example Source: https://github.com/python/typing/blob/main/docs/reference/protocols.md Demonstrates a type error when attempting to use nominal subtyping with a Protocol. ```python x: NotAProtocol = Concrete() # Error! ``` -------------------------------- ### Define Protocol Methods Source: https://github.com/python/typing/blob/main/docs/spec/protocol.md Shows how to define protocol members with and without default implementations using abstractmethod. ```python from typing import Protocol from abc import abstractmethod class Example(Protocol): def first(self) -> int: # This is a protocol member return 42 @abstractmethod def second(self) -> int: # Method without a default implementation raise NotImplementedError ``` -------------------------------- ### Invalid generic protocol definitions Source: https://github.com/python/typing/blob/main/docs/spec/protocol.md Examples of incorrect syntax when combining protocol definitions with generic type parameters. ```python class Iterable(Protocol[T], Generic[T]): # INVALID ... class Iterable[T](Protocol[T]): # INVALID ... ``` -------------------------------- ### Annotate variadic parameters Source: https://github.com/python/typing/blob/main/docs/spec/callables.md Demonstrates how to annotate *args and **kwargs to specify the types of their contained elements. ```python def func(*args: str, **kwargs: int): ... ``` ```python func('a', 'b', 'c') func(x=1, y=2) func('', z=0) ``` -------------------------------- ### Tuple Consistency and Subtyping Source: https://github.com/python/typing/blob/main/docs/spec/tuples.md Demonstrates how tuple types interact with Any and how different tuple lengths and types relate to one another. ```default def func(t1: tuple[int], t2: tuple[int, ...], t3: tuple[Any, ...]): v1: tuple[int, ...] = t1 # OK v2: tuple[Any, ...] = t1 # OK v3: tuple[int] = t2 # Type error v4: tuple[Any, ...] = t2 # OK v5: tuple[float, float] = t3 # OK v6: tuple[int, *tuple[str, ...]] = t3 # OK ``` -------------------------------- ### Define Generic Classes with Base Classes Source: https://github.com/python/typing/blob/main/docs/spec/generics.md Examples of defining generic classes that inherit from Iterable, Container, or Mapping. ```python from typing import TypeVar from collections.abc import Iterable, Container T = TypeVar('T') class LinkedList(Iterable[T], Container[T]): ... ``` ```python from typing import TypeVar from collections.abc import Mapping T = TypeVar('T') class MyDict(Mapping[str, T]): ... ``` -------------------------------- ### Handling non-literal mode arguments Source: https://github.com/python/typing/blob/main/docs/spec/literal.md Example of code that would break if a fallback overload is not provided for non-literal arguments. ```default mode: str = pick_file_mode(...) with open(path, mode) as f: # f should continue to be of type IO[Any] here ``` -------------------------------- ### Assignability with **kwargs parameters Source: https://github.com/python/typing/blob/main/docs/spec/callables.md Demonstrates how callables with **kwargs are compared for assignability based on their parameter types. ```python class NoKwargs(Protocol): def __call__(self) -> None: ... class IntKwargs(Protocol): def __call__(self, **kwargs: int) -> None: ... class FloatKwargs(Protocol): def __call__(self, **kwargs: float) -> None: ... def func(no_kwargs: NoKwargs, int_kwargs: IntKwargs, float_kwargs: FloatKwargs): f1: NoKwargs = int_kwargs # OK f2: NoKwargs = float_kwargs # OK f3: IntKwargs = no_kwargs # Error: missing **kwargs parameter f4: IntKwargs = float_kwargs # OK f5: FloatKwargs = no_kwargs # Error: missing **kwargs parameter f6: FloatKwargs = int_kwargs # Error: float is not assignable to int ``` -------------------------------- ### Misplaced Type Comment Example Source: https://github.com/python/typing/blob/main/docs/spec/historical.md Illustrates a misplaced type comment that would be flagged as an error by a type checker. ```default def f(): """Docstring""" # type: () -> None # Error! ``` -------------------------------- ### Importing and Using Generic Type Aliases Source: https://github.com/python/typing/blob/main/docs/reference/generics.md This example shows how to import and use generic type aliases from other modules. It also demonstrates creating a new generic class `NewVec` that inherits from an imported generic alias `Vec` and defining an optional generic type alias `OIntVec`. ```python from typing import TypeVar, Generic, Optional from example1 import AliasType from example2 import Vec # AliasType and Vec are type aliases (Vec as defined above) def fun() -> AliasType: ... T = TypeVar('T') class NewVec(Vec[T]): ... for i, j in NewVec[int](): ... OIntVec = Optional[Vec[int]] ``` -------------------------------- ### Function Default Values and Annotations Source: https://github.com/python/typing/blob/main/docs/guides/writing_stubs.md Shows the recommended way to handle default values for function parameters, using simple literals or ellipsis, and explicit `X | None` for None defaults. ```default def foo(x: int = 0) -> None: ... def bar(y: str | None = None) -> None: ... ``` ```default def foo(x: X = X()) -> None: ... def bar(y: str = None) -> None: ... ``` -------------------------------- ### Modifying Openness in Subclasses Source: https://github.com/python/typing/blob/main/docs/spec/typeddict.md Shows how subclasses can explicitly change openness using `closed` and `extra_items`, with examples of valid configurations. ```python class ExtraItemsRO(TypedDict, extra_items=ReadOnly[int | str]): name: str class ClosedChild(ExtraItemsRO, closed=True): # OK pass # OK, str is assignable to int | str, and mutable extra items can override read-only ones class NarrowerChild(ExtraItemsRO, extra_items=str): pass ``` -------------------------------- ### TypeIs for TypedDict Source: https://github.com/python/typing/blob/main/docs/guides/type_narrowing.md Example of a correct `TypeIs` function for a `TypedDict`. This function checks if an object conforms to the `Point` TypedDict structure. ```python from typing import TypedDict, TypeIs class Point(TypedDict): x: int y: int def is_point(obj: object) -> TypeIs[Point]: return ( isinstance(obj, dict) and all(isinstance(key, str) for key in obj) and isinstance(obj.get("x"), int) and isinstance(obj.get("y"), int) ) ``` -------------------------------- ### Using __future__ annotations for forward references Source: https://github.com/python/typing/blob/main/docs/guides/modernizing.md Demonstrates how to use from __future__ import annotations to handle forward references in type hints while still requiring quotes for type aliases. ```python from __future__ import annotations from typing_extensions import TypeAlias def f(x: Foo) -> Foo: ... # the future import is sufficient Alias: TypeAlias = "Foo" # this forward reference requires quoting class Foo: pass ``` -------------------------------- ### Define User classes Source: https://github.com/python/typing/blob/main/docs/spec/special-types.md Base and derived classes for demonstrating type annotations. ```python class User: ... # Abstract base for User classes class BasicUser(User): ... class ProUser(User): ... class TeamUser(User): ... ``` -------------------------------- ### Define a generic class for variance inference Source: https://github.com/python/typing/blob/main/docs/spec/generics.md Example of a generic class structure used to demonstrate the variance inference algorithm. ```default class ClassA[T1, T2, T3](list[T1]): def method1(self, a: T2) -> None: ... def method2(self) -> T3: ... ``` -------------------------------- ### Invalid TypeForm Expressions Source: https://github.com/python/typing/blob/main/docs/spec/type-forms.md Examples of expressions that violate syntactic or contextual rules for TypeForm, resulting in static analysis errors. ```python from typing import ClassVar, Final, Literal, Optional, Self, TypeVarTuple, Unpack from typing_extensions import TypeForm Ts = TypeVarTuple("Ts") var = 1 bad1: TypeForm = tuple() # Error: call expression not allowed in type expression bad2: TypeForm = (1, 2) # Error: tuple expression not allowed in type expression bad3: TypeForm = 1 # Error: non-class object not allowed in type expression bad4: TypeForm = Self # Error: Self not allowed outside of a class bad5: TypeForm = Literal[var] # Error: variable not allowed in type expression bad6: TypeForm = Literal[f""] # Error: f-strings not allowed in type expression bad7: TypeForm = ClassVar[int] # Error: ClassVar not allowed in type expression bad8: TypeForm = Final[int] # Error: Final not allowed in type expression bad9: TypeForm = Unpack[Ts] # Error: Unpack not allowed in this context bad10: TypeForm = Optional # Error: invalid use of Optional special form bad11: TypeForm = "int + str" # Error: invalid quoted type expression ``` -------------------------------- ### LiteralString Assignment and Error Examples Source: https://github.com/python/typing/blob/main/docs/spec/literal.md Demonstrates that non-literal types like int or specific Literal integers are not compatible with LiteralString. ```python some_int: int expect_literal_string(some_int) # Error: Expected LiteralString, got int. literal_one: Literal[1] = 1 expect_literal_string(literal_one) # Error: Expected LiteralString, got Literal[1]. ``` -------------------------------- ### Function and Method Body Syntax Source: https://github.com/python/typing/blob/main/docs/guides/writing_stubs.md Illustrates the required syntax for function and method bodies in stub files, which should consist solely of the ellipsis literal `...`. ```default def to_int1(x: str) -> int: ... def to_int2( x: str, ) -> int: ... ``` ```default def to_int1(x: str) -> int: return int(x) def to_int2(x: str) -> int: ... def to_int3(x: str) -> int: pass ``` -------------------------------- ### Define generic functions Source: https://github.com/python/typing/blob/main/docs/reference/generics.md Initial setup for defining functions that use type variables to relate argument and return types. ```python from typing import TypeVar, Sequence T = TypeVar('T') ``` -------------------------------- ### Blank Lines in Stub Files Source: https://github.com/python/typing/blob/main/docs/guides/writing_stubs.md Demonstrates correct usage of blank lines for grouping functions, methods, and classes in stub files to improve readability. ```default def time_func() -> None: ... def date_func() -> None: ... def ip_func() -> None: ... class Foo: x: int y: int def __init__(self) -> None: ... class MyError(Exception): ... class AnotherError(Exception): ... ``` ```default def time_func() -> None: ... def date_func() -> None: ... # do not leave unnecessary empty lines def ip_func() -> None: ... class Foo: # leave only one empty line above x: int class MyError(Exception): ... # leave an empty line between the classes ``` -------------------------------- ### Instance Attributes and Class Variables Source: https://github.com/python/typing/blob/main/docs/guides/writing_stubs.md Illustrates the correct way to declare instance attributes and class variables within classes, distinguishing between type annotations and assignments. ```default class Foo: c: ClassVar[str] x: int class Color(Enum): # An assignment with no type annotation is a convention used to indicate # an enum member. RED = 1 ``` ```default class Foo: c: ClassVar[str] = "" d: ClassVar[int] = ... x = 4 y: int = ... ``` -------------------------------- ### Rejected Self Annotations Source: https://github.com/python/typing/blob/main/docs/spec/generics.md Examples of invalid Self usage, including global scope, type aliases, static methods, and metaclasses. ```python def foo(bar: Self) -> Self: ... # Rejected (not within a class) bar: Self # Rejected (not within a class) class Foo: # Rejected (Self is treated as unknown). def has_existing_self_annotation(self: T) -> Self: ... class Foo: def return_concrete_type(self) -> Self: return Foo() # Rejected (see FooChild below for rationale) class FooChild(Foo): child_value: int = 42 def child_method(self) -> None: # At runtime, this would be Foo, not FooChild. y = self.return_concrete_type() y.child_value # Runtime error: Foo has no attribute child_value class Bar(Generic[T]): def bar(self) -> T: ... class Baz(Bar[Self]): ... # Rejected ``` ```python TupleSelf = Tuple[Self, Self] # Rejected class Alias: def return_tuple(self) -> TupleSelf: # Rejected return (self, self) ``` ```python class Base: @staticmethod def make() -> Self: # Rejected ... @staticmethod def return_parameter(foo: Self) -> Self: # Rejected ... ``` ```python class MyMetaclass(type): def __new__(cls, *args: Any) -> Self: # Rejected return super().__new__(cls, *args) def __mul__(cls, count: int) -> list[Self]: # Rejected return [cls()] * count class Foo(metaclass=MyMetaclass): ... ``` -------------------------------- ### Accepted Self Annotations in Classes Source: https://github.com/python/typing/blob/main/docs/spec/generics.md Examples of valid Self usage within class methods, class methods, and nested structures. ```python class ReturnsSelf: def foo(self) -> Self: ... # Accepted @classmethod def bar(cls) -> Self: # Accepted return cls() def __new__(cls, value: int) -> Self: ... # Accepted def explicitly_use_self(self: Self) -> Self: ... # Accepted # Accepted (Self can be nested within other types) def returns_list(self) -> list[Self]: ... # Accepted (Self can be nested within other types) @classmethod def return_cls(cls) -> type[Self]: return cls class Child(ReturnsSelf): # Accepted (we can override a method that uses Self annotations) def foo(self) -> Self: ... class TakesSelf: def foo(self, other: Self) -> bool: ... # Accepted class Recursive: # Accepted (treated as an @property returning ``Self | None``) next: Self | None class CallableAttribute: def foo(self) -> int: ... # Accepted (treated as an @property returning the Callable type) bar: Callable[[Self], int] = foo class HasNestedFunction: x: int = 42 def foo(self) -> None: # Accepted (Self is bound to HasNestedFunction). def nested(z: int, inner_self: Self) -> Self: print(z) print(inner_self.x) return inner_self nested(42, self) # OK class Outer: class Inner: def foo(self) -> Self: ... # Accepted (Self is bound to Inner) ``` -------------------------------- ### Intelligent indexing with getattr Source: https://github.com/python/typing/blob/main/docs/spec/literal.md Demonstrates using Literal strings to index class attributes and methods via getattr. ```default class Test: def __init__(self, param: int) -> None: self.myfield = param def mymethod(self, val: int) -> str: ... a: Literal["myfield"] = "myfield" b: Literal["mymethod"] = "mymethod" c: Literal["blah"] = "blah" t = Test() reveal_type(getattr(t, a)) # Revealed type is 'int' reveal_type(getattr(t, b)) # Revealed type is 'Callable[[int], str]' getattr(t, c) # Error: No attribute named 'blah' in Test ``` -------------------------------- ### TypeVarTuple with Defaulted TypeVar Error Source: https://github.com/python/typing/blob/main/docs/spec/generics.md A TypeVar immediately following a TypeVarTuple cannot have a default, as it leads to ambiguity. This example shows an invalid declaration. ```python class Foo[*Ts, T = bool]: ... # Type checker error # Could be reasonably interpreted as either Ts = (int, str, float), T = bool # or Ts = (int, str), T = float Foo[int, str, float] ``` -------------------------------- ### Validate default argument types Source: https://github.com/python/typing/blob/main/docs/spec/callables.md Examples of type checking for default argument values, where the default must be assignable to the parameter type. ```python def func(x: int = 0): ... # OK def func(x: int | None = None): ... # OK def func(x: int = 0.0): ... # Error def func(x: int = None): ... # Error ``` -------------------------------- ### Define a function with various parameter types Source: https://github.com/python/typing/blob/main/docs/spec/callables.md Illustrates the syntax for positional-only, standard, keyword-only, and variadic parameters in a single function signature. ```python def func(a: str, /, b, *args, c=0, **kwargs) -> None: ... ``` -------------------------------- ### Named Tuple Field Restrictions Source: https://github.com/python/typing/blob/main/docs/spec/namedtuples.md Field names in Named Tuples cannot start with an underscore. Methods and unannotated attributes are not considered fields. ```python class MyTuple(NamedTuple): x1 = 1 # Not a field def x2() -> None: pass # Not a field _x3: int # Type error: illegal field name ``` -------------------------------- ### Define and use a callback protocol Source: https://github.com/python/typing/blob/main/docs/reference/protocols.md Use a Protocol with a __call__ method to define complex callback signatures. Argument names in the protocol must match the implementation unless a double underscore prefix is used. ```python from typing import Optional, Iterable, Protocol class Combiner(Protocol): def __call__(self, *vals: bytes, maxlen: Optional[int] = None) -> list[bytes]: ... def batch_proc(data: Iterable[bytes], cb_results: Combiner) -> bytes: for item in data: ... def good_cb(*vals: bytes, maxlen: Optional[int] = None) -> list[bytes]: ... def bad_cb(*vals: bytes, maxitems: Optional[int]) -> list[bytes]: ... batch_proc([], good_cb) # OK batch_proc([], bad_cb) # Error! Argument 2 has incompatible type because of # different name and kind in the callback ``` ```python from typing import Callable, TypeVar, Protocol T = TypeVar('T') class Copy(Protocol): def __call__(self, __origin: T) -> T: ... copy_a: Callable[[T], T] copy_b: Copy copy_a = copy_b # OK copy_b = copy_a # Also OK ``` -------------------------------- ### Define Positional-Only Parameters Source: https://github.com/python/typing/blob/main/docs/spec/historical.md Parameters starting with double underscores are treated as positional-only for backward compatibility with Python versions prior to 3.8. ```default def f(__x: int, __y__: int = 0) -> None: ... f(3, __y__=1) # This call is fine. f(__x=3) # This call is an error. ``` -------------------------------- ### Subclassing with Generic Defaults Source: https://github.com/python/typing/blob/main/docs/spec/generics.md Shows how subclasses inherit and substitute defaults from generic base classes. ```python class SubclassMe(Generic[T, DefaultStrT]): x: DefaultStrT class Bar(SubclassMe[int, DefaultStrT]): ... reveal_type(Bar) # type is type[Bar[DefaultStrT = str]] reveal_type(Bar()) # type is Bar[str] reveal_type(Bar[bool]()) # type is Bar[bool] class Foo(SubclassMe[float]): ... reveal_type(Foo().x) # type is str Foo[str] # Invalid: Foo cannot be further subscripted class Baz(Generic[DefaultIntT, DefaultStrT]): ... class Spam(Baz): ... reveal_type(Spam()) # type is ``` -------------------------------- ### Annotated Type with Value Range Metadata Source: https://github.com/python/typing/blob/main/docs/spec/qualifiers.md Example of using Annotated with metadata for value range analysis, showing nested and merged metadata. ```python T1 = Annotated[int, ValueRange(-10, 5)] T2 = Annotated[T1, ValueRange(-20, 3)] # Flattening nested annotations, this translates to: T2 = Annotated[int, ValueRange(-10, 5), ValueRange(-20, 3)] ``` -------------------------------- ### Simplified open() function signature with Literal modes Source: https://github.com/python/typing/blob/main/docs/spec/literal.md Illustrates how Literal types can define specific string values for function parameters, simplifying complex type signatures for functions like `open()`. ```python # Note: this is a simplification of the true type signature. _PathType = str | bytes | int @overload def open(path: _PathType, mode: Literal["r", "w", "a", "x", "r+", "w+", "a+", "x+"], ) -> IO[str]: ... @overload def open(path: _PathType, mode: Literal["rb", "wb", "ab", "xb", "r+b", "w+b", "a+b", "x+b"], ) -> IO[bytes]: ... # Fallback overload for when the user isn't using literal types @overload def open(path: _PathType, mode: str) -> IO[Any]: ... ``` -------------------------------- ### Verify Protocol Implementation Source: https://github.com/python/typing/blob/main/docs/spec/protocol.md Demonstrates how explicit subclassing allows type checkers to verify that a class correctly implements the protocol requirements. ```python class RGB(Protocol): rgb: tuple[int, int, int] @abstractmethod def intensity(self) -> int: return 0 class Point(RGB): def __init__(self, red: int, green: int, blue: str) -> None: self.rgb = red, green, blue # Error, 'blue' must be 'int' # Type checker might warn that 'intensity' is not defined ```