Files
ruff/crates/red_knot_python_semantic/resources/mdtest/generics/pep695.md
Douglas Creager ebd172e732 [red-knot] Several failing tests for generics (#16509)
To kick off the work of supporting generics, this adds many new
(currently failing) tests, showing the behavior we plan to support.

This is still missing a lot!  Not included:

- typevar tuples
- param specs
- variance
- `Self`

But it's a good start! We can add more failing tests for those once we
tackle these.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2025-03-05 17:21:19 -05:00

1.4 KiB

PEP 695 Generics

PEP 695 and Python 3.12 introduced new, more ergonomic syntax for type variables.

Type variables

Defining PEP 695 type variables

PEP 695 introduces a new syntax for defining type variables. The resulting type variables are instances of typing.TypeVar, just like legacy type variables.

def f[T]():
    reveal_type(type(T))  # revealed: Literal[TypeVar]
    reveal_type(T)  # revealed: T
    reveal_type(T.__name__)  # revealed: Literal["T"]

Cannot have only one constraint

TypeVar supports constraining parametric types to a fixed set of possible types...There should be at least two constraints, if any; specifying a single constraint is disallowed.

# error: [invalid-type-variable-constraints] "TypeVar must have at least two constrained types"
def f[T: (int,)]():
    pass

Invalid uses

Note that many of the invalid uses of legacy typevars do not apply to PEP 695 typevars, since the PEP 695 syntax is only allowed places where typevars are allowed.

Displaying typevars

We use a suffix when displaying the typevars of a generic function or class. This helps distinguish different uses of the same typevar.

def f[T](x: T, y: T) -> None:
    # TODO: revealed: T@f
    reveal_type(x)  # revealed: T

class C[T]:
    def m(self, x: T) -> None:
        # TODO: revealed: T@c
        reveal_type(x)  # revealed: T