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):
to
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
vs
x: Union[int, float, bool, complex, Decimal]
Although again I strongly prefer
x: Union[int, float, bool, complex, Decimal] or None
to
x: Optional[Union[int, float, bool, complex, Decimal]]
or worse
x: Union[int, float, bool, complex, Decimal, None]
I think a few things recommend this:
- It eliminates a common
typing
import. - 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 theor
and 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.