Can the Python walrus operator be used for type hinting generic functions?

94 views Asked by At

Suppose I want to type hint a generic function in Python before 3.12, when the new parameter syntax was introduced:

def max[T](args: Iterable[T]) -> T:
    ...

Then I have the option of using string type hints:

def max(args: Iterable["T"]) -> "T":
    ...

Or typing variables:

T = TypeVar("T")

def max(args: Iterable[T]) -> T:
    ...

I like the latter approach more, but introducing an extra global variable is definitely a drawback. I decided to combine generic type hinting with the walrus operator, like this:

def max(args: Iterable[T := TypeVar("T")]) -> T:
    ...

Or

def max(args: Iterable[T := int | float]) -> T:
    ...

Code like this runs without errors, but some typing libraries don't recognise this syntax. What are the drawbacks to writing code like this?

2

There are 2 answers

0
STerliakov On BEST ANSWER

Apparently it did not get into documentation for some reason, but your question is addressed in PEP484:

A TypeVar() expression must always directly be assigned to a variable (it should not be used as part of a larger expression). The argument to TypeVar() must be a string equal to the variable name to which it is assigned. Type variables must not be redefined.

So, typecheckers should reject your suggested snippet. mypy does, Pyright also does, and Pyre does as well.

So, the main drawback to writing code like this is the fact that such code is non-conformant and is not interpreted by typecheckers correctly.

0
xtofl On
  • As long as the type system is evolving (for the best!) the way it is
  • When you don't control the environment your code is run/checked in (e.g. a distributed team)

I would opt for compatibility with established tools: this will save your coworkers a lot of surprises. So: no walrus in the type hints :).