TypeVars and the new 3.12 syntax: what happend to co-/contravariances?

(Disclaimer: I actually don’t know what “variance” means. I’m writing this post because I’m curious)

With the new Python 3.12 we have got a new syntax for TypeVars, so instead of:

T = TypeVar("T")
def a_fn(arg: T) -> list[T]: ...

we can write:

def a_fn[T](arg: T) -> list[T]: ...

However with the old way we could also specify variance:

T = TypeVar("T", covariant=False, contravariant=True)

I wonder: why the new syntax doesn’t include variance? Is it because variance can be inferred? If so, how?

You are referring to type parameter syntax, which was described in PEP 695.
You will find in the document a “variance inference” section, which answers your question:

This PEP eliminates the need for variance to be specified for type parameters. Instead, type checkers will infer the variance of type parameters based on their usage within a class. Type parameters are inferred to be invariant, covariant, or contravariant depending on how they are used.

1 Like

Thanks, it shed a light to me a bit for the topic :slight_smile: