Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A bound TypeVar is a generic type variable that restricts its permissible types to a specific base type and its subtypes. By defining an upper bound, the static type checker guarantees that any type assigned to the variable conforms to the interface of the bounding type, while strictly preserving the specific subclass type through the generic operation.

Syntax

Legacy Syntax (Python 3.11 and older): Using the typing module, the bound keyword argument accepts a single type (a class, a Union, or another type construct).
from typing import TypeVar

class BaseType:
    pass


# T is restricted to BaseType or any of its subclasses
T = TypeVar('T', bound=BaseType)
Modern Syntax (Python 3.12+ / PEP 695): Python 3.12 introduced native generic syntax using type parameter lists. A bound is denoted using a colon (:) after the type variable name.
class BaseType:
    pass


# T is bound to BaseType
def process_item[T: BaseType](item: T) -> T:
    return item

Type Resolution Mechanics

When a type checker evaluates a bound TypeVar, it performs two primary operations:
  1. Validation: It verifies that the concrete type provided at the call site is a subtype of the bound (e.g., issubclass(ConcreteType, BaseType)). If it is not, a type error is emitted.
  2. Type Preservation: Unlike a standard type hint (which upcasts the type to the base class), a bound TypeVar binds to the exact subclass provided.
from typing import TypeVar

class Animal: pass
class Dog(Animal): pass

T = TypeVar('T', bound=Animal)

def generic_identity(obj: T) -> T:
    return obj

def standard_identity(obj: Animal) -> Animal:
    return obj


# Type Resolution:
dog_instance = Dog()


# generic_identity returns type 'Dog'. The specific subtype is preserved.
result_a = generic_identity(dog_instance) 


# standard_identity returns type 'Animal'. The specific subtype is lost (upcasted).
result_b = standard_identity(dog_instance) 


# Type Checker Error: 'str' is not a subtype of 'Animal'
result_c = generic_identity("invalid") 

Bound vs. Constrained TypeVars

It is critical to distinguish a bound TypeVar from a constrained TypeVar.
  • Bound (bound=BaseType): Establishes an upper limit in the inheritance tree. It accepts the base type and an infinite number of potential subclasses. The type checker resolves T to whatever specific subclass is passed.
  • Constrained (TypeVar('T', TypeA, TypeB)): Restricts the variable to an exact, finite list of types. Subclasses of TypeA or TypeB are evaluated strictly as TypeA or TypeB.
from typing import TypeVar

class Base: pass
class ChildA(Base): pass
class ChildB(Base): pass
class GrandChild(ChildA): pass


# Bound: Accepts Base, ChildA, ChildB, GrandChild, etc.
T_Bound = TypeVar('T_Bound', bound=Base)


# Constrained: Accepts ONLY ChildA or ChildB. 

# Passing GrandChild will result in the type checker evaluating it as ChildA.
T_Constrained = TypeVar('T_Constrained', ChildA, ChildB)

Forward References in Bounds

If the bounding type is not yet defined when the TypeVar is declared, the bound argument accepts a string literal representing the forward reference. To be valid and provide type-checking utility, the type variable must establish a relationship by appearing at least twice in a signature (e.g., linking an argument type to a return type) or be used to define a Generic class.
from typing import TypeVar


# Using a string literal for a class defined later in the module
T_Node = TypeVar('T_Node', bound='Node')

class Node:
    # T_Node appears twice, establishing a relationship that guarantees 
    # the return type matches the exact subclass of the instance.
    def clone(self: T_Node) -> T_Node:
        pass
Master Python with Deep Grasping Methodology!Learn More