Unfortunately, you cannot reuse type variables defined with PEP 695 syntax.
The type variable must have the correct bound to parametrize the superclass (in other words, bounds and constraints can't be inferred or magically "pushed down" from the superclass, that has soundness problems if you consider multiple inheritance). So, you need some way to spell "reuse type variable with these {constraints,bound,default}"... And as you noted in you question, typing.TypeVar is doing exactly that.
Please note that typing.TypeVar is not deprecated (only typing.TypeAlias is) - new generics syntax is just another way, not a replacement. It will likely stay alive for a very long time if not indefinitely: Eric Traut's comment on that
It’s also important to note that this PEP doesn’t deprecate the current mechanisms for defining TypeVars or generic classes, functions, and type aliases. Those mechanisms can live side by side with the new syntax. If you find that those mechanisms are more flexible for exploring extensions to the type system, PEP 695 does not prevent you from leveraging these existing mechanisms.
There are other problems with PEP 695 typevars like inability to specify variance explicitly, so some corner cases would become impossible to express if typing.TypeVar was ever deprecated.
I'm not aware of any recent proposals or discussions that would enable reusing PEP 695 type variables, and for the reasons mentioned above I doubt that will ever be possible.
Answer from STerliakov on Stack OverflowSubclassing a generic class with constrained type variable in Python 3.12+ without repeating the constraints - Stack Overflow
Generic[T] classmethod implicit type retrieval in Python 3.12 - Stack Overflow
Let's talk about python 3.12's new Type Parameter Syntax.
Recursive Generic Type Hints (python 3.12)
Unfortunately, you cannot reuse type variables defined with PEP 695 syntax.
The type variable must have the correct bound to parametrize the superclass (in other words, bounds and constraints can't be inferred or magically "pushed down" from the superclass, that has soundness problems if you consider multiple inheritance). So, you need some way to spell "reuse type variable with these {constraints,bound,default}"... And as you noted in you question, typing.TypeVar is doing exactly that.
Please note that typing.TypeVar is not deprecated (only typing.TypeAlias is) - new generics syntax is just another way, not a replacement. It will likely stay alive for a very long time if not indefinitely: Eric Traut's comment on that
It’s also important to note that this PEP doesn’t deprecate the current mechanisms for defining TypeVars or generic classes, functions, and type aliases. Those mechanisms can live side by side with the new syntax. If you find that those mechanisms are more flexible for exploring extensions to the type system, PEP 695 does not prevent you from leveraging these existing mechanisms.
There are other problems with PEP 695 typevars like inability to specify variance explicitly, so some corner cases would become impossible to express if typing.TypeVar was ever deprecated.
I'm not aware of any recent proposals or discussions that would enable reusing PEP 695 type variables, and for the reasons mentioned above I doubt that will ever be possible.
It caused by PEP 695 with the new syntax introduced with it. So there is no way to not specify T: (int, float) in Subclass
def Point[T](x: T, y: T):
...this looks great but, would this look better?
def [T] Point(x: T, y: T):
...Imagine cluttering this new syntax
def Point[T, E, S, L, A](x: T, y: T):
...doesn't this look messy?
Imagine doing it this way
def [T, E, S, L, A] Point(x: T, y: T):
...TIL from this video typing a recursive flatten (by YT channel anthonywritescode) that you can now type hint recursive data & functions with generic type parameter!
# new syntax
# recursive type for nested list having elems of same type (eg. int)
type _RList[U] = list[U | _RList[U]]
def flatten[T](lst: _RList[T]) -> _RList[T]:
""" Flatten nested list.""""
return [
flatten(x) if isinstance(x, list) else x
for x in lst
]NOTE: Latest mypy type checks this new syntax, but editor / IDE may not recognize it yet.
Did you all know about this? Have you found more such cool type hinting syntax in Python?
The runtime outcome is effectively identical. The difference is that Python 3.12 introduces a way to declare type parameters right in the class definition instead of requiring manual TypeVar declarations.
The examples you have,
3.12+
class MyClass[T]: pass3.11
import typing as t T = t.TypeVar('T') class MyClass2(t.Generic[T]): pass
are not quite the same. From the Python docs on typing.TypeVar:
The variance of type variables is inferred by type checkers when they are created through the type parameter syntax or when
infer_variance=Trueis passed.
Therefore, the equivalent runtime behaviour in Python 3.11 and below is expressed as
import typing_extensions as t
T = t.TypeVar('T', infer_variance=True)
class MyClass2(t.Generic[T]): pass
This won't show up in any string representation of the class.