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.

Answer from Pavlo Kvas on Stack Overflow
🌐
Python
typing.python.org › en › latest › spec › generics.html
Generics — typing documentation
With the new Python 3.12 syntax for generics (introduced by PEP 695), this can be enforced at compile time:
Discussions

Support for Python v3.13's New Generic Syntax
The New Generic Syntax Python version 3.13 introduces support for a new generic syntax: #New generic syntax def demo_func_new[T](argv: T) -> T: """!Demo function using the new gen... More on github.com
🌐 github.com
3
January 14, 2026
Let's talk about python 3.12's new Type Parameter Syntax.
There was probably much discussion on this placement, and there is not point discussing it now because it won't change. If you want to learn more about this, I recommend reading PEP 695 and additionally the following: https://jellezijlstra.github.io/pep695 https://github.com/python/peps/pull/3122 More on reddit.com
🌐 r/Python
43
0
January 26, 2024
Generics/templates in python? - Stack Overflow
How does python handle generic/template type scenarios? Say I want to create an external file "BinaryTree.py" and have it handle binary trees, but for any data type. So I could pass it the type... More on stackoverflow.com
🌐 stackoverflow.com
Generics: Making Go more Pythonic?

No. Typing is not the same as generic. The point is not converting a typed language to one without type, but allowing functions to be generic, eg accepting and returning a set of type. E.g. a sort function than can sort arrays of str and arrays of int. You're not mixing types, you are just postponing the type selection. Type checking will still happen at compile time.

More on reddit.com
🌐 r/golang
17
0
November 6, 2020
🌐
Mypy
mypy.readthedocs.io › en › stable › generics.html
Generics - mypy 1.19.1 documentation
Here is the same example using the old syntax (required for Python 3.11 and earlier, but also supported on newer Python versions): from typing import TypeVar, Generic T = TypeVar('T') # Define type variable "T" class Stack(Generic[T]): def __init__(self) -> None: # Create an empty list with items of type T self.items: list[T] = [] def push(self, item: T) -> None: self.items.append(item) def pop(self) -> T: return self.items.pop() def empty(self) -> bool: return not self.items
🌐
ArjanCodes
arjancodes.com › blog › python-generics-syntax
Python 3.12 Generics: Cleaner, Easier Type-Hinting | ArjanCodes
June 6, 2024 - With the new syntax, T, *Ts, and **P replace TypeVar, TypeVarTuple, and ParamSpec, respectively, and any class that has generic annotations is considered a Generic type. This approach uses a more familiar and less cluttered syntax, akin to other ...
🌐
Medium
medium.com › @r_bilan › generics-in-python-3-12-whats-new-in-the-syntax-and-how-to-use-it-now-1024fcdf02f8
Generics in Python 3.12: What’s New in the Syntax and How to Use It Now | by Rostyslav Bilan | Medium
October 2, 2024 - With Python 3.12, it has become even easier to work with generics thanks to the new syntax. There’s no need to import Generic and TypeVar anymore, as this is now handled directly by the syntax.
🌐
Python
peps.python.org › pep-0695
PEP 695 – Type Parameter Syntax | peps.python.org
Here is an example of a generic function today. from typing import TypeVar _T = TypeVar("_T") def func(a: _T, b: _T) -> _T: ... And the new syntax.
🌐
Real Python
realpython.com › python312-typing
Python 3.12 Preview: Static Typing Improvements – Real Python
October 21, 2023 - In this tutorial, you'll preview the new static typing features in Python 3.12. You'll learn about the new syntax for type variables, making generics simpler to define. You'll also see how @override lets you model inheritance and how you use typed dictionaries to annotate variable keyword arguments.
Find elsewhere
🌐
GitHub
github.com › doxygen › doxygen › issues › 11948
Support for Python v3.13's New Generic Syntax · Issue #11948 · doxygen/doxygen
January 14, 2026 - The New Generic Syntax Python version 3.13 introduces support for a new generic syntax: #New generic syntax def demo_func_new[T](argv: T) -> T: """!Demo function using the new generic syntax @tparam T The type of both the parameter and t...
Author   Immortal-Sty
🌐
Python documentation
docs.python.org › 3 › library › typing.html
typing — Support for type hints
3 weeks ago - Parameter specification variables created with covariant=True or contravariant=True can be used to declare covariant or contravariant generic types. The bound argument is also accepted, similar to TypeVar. However the actual semantics of these keywords are yet to be decided. Added in version 3.10. Changed in version 3.12: Parameter specifications can now be declared using the type parameter syntax introduced by PEP 695.
🌐
mypy
mypy.readthedocs.io › en › latest › generics.html
Generics - mypy 1.20.0+dev.69a0925bbf08cad3858c1b4abf06fe6f497fdb24 documentation
August 24, 2021 - Here is the same example using the old syntax (required for Python 3.11 and earlier, but also supported on newer Python versions): from typing import TypeVar, Generic T = TypeVar('T') # Define type variable "T" class Stack(Generic[T]): def __init__(self) -> None: # Create an empty list with items of type T self.items: list[T] = [] def push(self, item: T) -> None: self.items.append(item) def pop(self) -> T: return self.items.pop() def empty(self) -> bool: return not self.items
🌐
Tutorialspoint
tutorialspoint.com › python › python_generics.htm
Python - Generics
The type variable 'T' represents the generic type, which will be replaced with a specific type when the function is used.
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-generics
Python Generics - GeeksforGeeks
October 29, 2025 - Below, are examples of Python Generics in Python. In this example, the below code defines a generic function element that retrieves the first element from a list of any type. It employs Python's TypeVar to denote the placeholder type T.
🌐
GitHub
github.com › python › mypy › blob › master › docs › source › generics.rst
mypy/docs/source/generics.rst at master · python/mypy
September 7, 2022 - Here is the same example using the old syntax (required for Python 3.11 and earlier, but also supported on newer Python versions): from typing import TypeVar, Generic T = TypeVar('T') # Define type variable "T" class Stack(Generic[T]): def __init__(self) -> None: # Create an empty list with items of type T self.items: list[T] = [] def push(self, item: T) -> None: self.items.append(item) def pop(self) -> T: return self.items.pop() def empty(self) -> bool: return not self.items
Author   python
🌐
Python documentation
docs.python.org › 3 › whatsnew › 3.12.html
What's New In Python 3.12 — Python 3.14.3 documentation
3 weeks ago - Generic classes and functions under PEP 484 were declared using a verbose syntax that left the scope of type parameters unclear and required explicit declarations of variance. PEP 695 introduces a new, more compact and explicit way to create generic classes and functions:
Top answer
1 of 10
205

The other answers are totally fine:

  • One does not need a special syntax to support generics in Python
  • Python uses duck typing as pointed out by André.

However, if you still want a typed variant, there is a built-in solution since Python 3.5.

A full list of available type annotations is available in the Python documentation.


Generic classes:

from typing import TypeVar, Generic, List

T = TypeVar('T')

class Stack(Generic[T]):
    def __init__(self) -> None:
        # Create an empty list with items of type T
        self.items: List[T] = []

    def push(self, item: T) -> None:
        self.items.append(item)

    def pop(self) -> T:
        return self.items.pop()

    def empty(self) -> bool:
        return not self.items
# Construct an empty Stack[int] instance
stack = Stack[int]()
stack.push(2)
stack.pop()
stack.push('x')        # Type error

Generic functions:

from typing import TypeVar, Sequence

T = TypeVar('T')      # Declare type variable

def first(seq: Sequence[T]) -> T:
    return seq[0]

def last(seq: Sequence[T]) -> T:
    return seq[-1]


n = first([1, 2, 3])  # n has type int.

Static type checking:

You must use a static type checker such as mypy or Pyre (developed by Meta/FB) to analyze your source code.

Install mypy:

python3 -m pip install mypy

Analyze your source code, for example a certain file:

mypy foo.py

or directory:

mypy some_directory

mypy will detect and print type errors. A concrete output for the Stack example provided above:

foo.py:23: error: Argument 1 to "push" of "Stack" has incompatible type "str"; expected "int"

References: mypy documentation about generics and running mypy

2 of 10
116

Python uses duck typing, so it doesn't need special syntax to handle multiple types.

If you're from a C++ background, you'll remember that, as long as the operations used in the template function/class are defined on some type T (at the syntax level), you can use that type T in the template.

So, basically, it works the same way:

  1. define a contract for the type of items you want to insert in the binary tree.
  2. document this contract (i.e. in the class documentation)
  3. implement the binary tree using only operations specified in the contract
  4. enjoy

You'll note however, that unless you write explicit type checking (which is usually discouraged), you won't be able to enforce that a binary tree contains only elements of the chosen type.

🌐
Runebook.dev
runebook.dev › en › docs › python › library › typing › typing.TypeAliasType.__type_params__
New-Style Generic Type Aliases in Python 3.12: Common Issues
October 30, 2024 - Explanation While PEP 695 introduced the new bracket syntax for generic classes (class Mapping[K, V]:), the class object itself still primarily uses the traditional mechanisms for generics, though they are more consistent now.
🌐
Medium
medium.com › pythoneers › understanding-typevar-in-python-f78e5108471d
Understanding TypeVar in Python. A Quick Guide to Generics, Best… | by Harshit Singh | The Pythoneers | Medium
January 8, 2025 - Python 3.13 allows you to define them inline: ... Improved Error Messages: Type checking tools like mypy and Pyright now provide clearer and more actionable error messages. Performance Enhancements: The typing module has received optimizations, making type hinting faster and less memory-intensive. Better Support for Variadic Generics: Python now handles more complex generics, like tuples of variable lengths, more effectively.
🌐
Python
peps.python.org › pep-0646
PEP 646 – Variadic Generics - Python Enhancement Proposals
February 1, 2025 - We rarely deal with arrays of truly ... with a syntax such as Array[Batch, Time, ...]. We therefore made the decision to have variadic generics other than Tuple behave differently, in order to give the user more flexibility in how much of their code they wish to annotate, and to enable compatibility between old unannotated code and new versions of ...