- We can't naively union a callable type with another type:
union_of_callables: (int) -> str | (bool) -> str # Syntax error!
# Needs extra parens; Not intuitive or user-friendly.
union_of_callable2: ((int) -> str) | ((bool) -> str)
# Simpler and can be easily split into multiple lines, as Никита mentioned.
union_of_callables3: Union[(int) -> str, (bool) -> str, (list[int]) -> str]
Likewise, int | (str) -> bool
is a syntax error.
- Another huge gotcha is with Optional callables if we naively use
<new-syntax> | None
:
old: Optional[Callable[[int], str]]
# This works fine
with_pipe: Callable[[int], str] | None
# Incorrect! This specifies a non-optional function with return type `str | None`
naive_translation_to_new_syntax: (int) -> str | None
# Trying to use order of types to fix a precedence issue won't work
naive_attempt_to_fix_above_error: None | (int) -> str # Syntax error!
# The solution requires parentheses if we're using `<type> | None`
intended: ((int) -> str) | None
# Expressing it with Optional (If we don't deprecate optional!) is clean:
unambiguous_and_simple: Optional[(int) -> str]