How to properly overload on bool for 3 different cases?

75 Views Asked by At

I am writing my own run function. How to write 3rd overload on dynamic value bool for text, so that it doesn't conflict with overload for Literal[False] and Literal[True]?

from __future__ import annotations
from typing import TypeVar, overload, Optional, Literal, Union

T = TypeVar('T', str, bytes)

# If text is empty or false, input has to be bytes, we are returning bytes.
@overload
def run(text: Literal[False] = False, input: Optional[bytes] = ...) -> bytes: ...
# If text is true, input is str, returning str
@overload
def run(text: Literal[True], input: Optional[str] = ...) -> str: ...
# When we do not know what is text, it can be anything, but has to be the same.
#@overload
#def run(text: bool, input: Optional[Union[str, bytes]] = ...) -> Union[str, bytes]: ...
#def run(text: bool, input: Optional[T] = ...) -> T: ...


def run(text: bool = False, input: Optional[Union[str, bytes]] = None) -> Union[str, bytes]: return ""

run(input="")  # error
run(input=b"")  # ok
run(False, "")  # error
run(False, b"")  # ok
run(True, "")  # ok
run(True, b"")  # error
def test() -> bool: ...
run(test(), "")  # ok
run(test(), b"")  # ok

pyright playground .

When the 3rd overload is uncommented, all forms are valid. Is it possible for the 3rd form not to be "catch it all"?

0

There are 0 best solutions below