Someone in my firm asked “is it ok to annotate a function like this?”
def foo(var: int or float or str): ...
Of course the answer is no. And without
from __future__ import annotations this is evaluated to
int which is useless.
However, in a
from __future__ import annotations world this might be a viable idea. It parses already and reads very nicely!
I prefer the above example to
from typing import Union def foo(var: Union[int, float, str]): ...
and I even prefer
def foo(x: int or None):
from typing import Optional def foo(x: Optional[int]):
I start to dislike it when the union gets huge:
x: int or float or bool or complex or Decimal
x: Union[int, float, bool, complex, Decimal]
Although again I strongly prefer
x: Union[int, float, bool, complex, Decimal] or None
x: Optional[Union[int, float, bool, complex, Decimal]]
x: Union[int, float, bool, complex, Decimal, None]
I think a few things recommend this:
- It eliminates a common
- Slightly reduces line length until the union is 5 types or more.
- The spacing and reduced amount of surrounding
symbols makes each type more legible, not to mention that many existing syntax highlighters will pick out the
orand the type names in different font colours/styles.
- Sphinx already supports equivalent syntax - see ‘Multiple types in a type field will be linked automatically if separated by the word “or”’.
- It is more natural to read and say out loud.
Using this syntax would present compatibility issues while Python versions with evaluated annotations remain a thing, so maybe it’s a longer range idea, unless linters could help mitigate those issues.