Description
Sometimes a function or method can return one of several types, depending on the passed in arguments or external factors. Best example is probably open()
, but there are other examples in the standard library, like shutil.copy()
[1]. In many of those cases, the caller knows what return type to expect.
Currently there are several options, but none of them is really satisfactory:
- Use
@overload
. This is the best solution if it can be used. But that is often not the case, like in the examples above. - Use a mypy plugin. This solution does not scale to outside the standard library (and arguably not even inside it) and is mypy-specific.
- Use
Union
as the return type. This is usually not recommended, since it means that the caller needs to useisinstance()
to use the return type. - Use
Any
as the return type. This is currently best practice in those cases, but of course provides no type safety at all.
Therefore, I propose to add another type, for example AnyOf[...]
that acts like Union
, but can be used everywhere any of its type arguments could be used.
from datetime import date
x: AnyOf[str, date] = ...
s: str = x # ok
dt: date = x # ok
i: int = x # type error
u: Union[str, bytes] = x # ok
x = u # type error (although the type checker could do something smart here and infer that u can only be str here)
I also think that the documentation should make it clear that using AnyOf
is a code smell.
[1] Currently the type behaviour in shutil
is broken in my opinion, but that does not change the fact that currently it is as it is.