python typing: overload vs TypeVar

Viewed 441

I asked myself if there is a best practice concerning the use of TypeVar and overload in python for functions that return the same type as the input. Consider these examples.

Example 1. using TypeVar:

from typing import TypeVar

StrOrInt = TypeVar("StrOrInt", str, int)

def return_same_type_typevar(x: StrOrInt) -> StrOrInt:
    if isinstance(x, str):
        # process str
        return x
    else:
        # process int
       return x

Example 2, using overload:

from typing import overload

@overload
def return_same_type_overload(x: str) -> str:
    ...

@overload
def return_same_type_overload(x: int) -> int:
    ...

def return_same_type_overload(x):
    if isinstance(x, str):
        # process str
        return x
    else:
        # process int
       return x

Are the two examples actually achieving the same? Is this use of overload discuraged here and should overload only be used when the return type is different from the input type? Or is it fine but overly verbose?

Of course this is a trivial example. The code I am looking at would probably more take a pandas Series or DataFrame as input and not str and int.


edit: updated example to show that there are different code paths for int and str

1 Answers

There is no general "best practice", but when applicable the TypeVar is superior in any case.

  • Using a TypeVar is shorter. Every additional type is one additional argument, versus 2-3 lines for an overload.

  • Using a TypeVar is clearer. It immediately expresses that all variants do work fundamentally the same, whereas overload could have additional parameters.

  • Using a TypeVar is more informative. The runtime function keeps its annotation for introspection, whereas the overload annotation is discarded.

Prefer to restrict overload to cases that significantly differ in their signature, i.e. have additional or restricted parameters in specific variants.

Related