[Python] Type narrowing an element of tuple based on type of other element

Discussão em 'Python' iniciado por Stack, Maio 16, 2025.

  1. Stack

    Stack Membro Participativo

    I am looking for a way to type hint a function that returns a tuple containing a success flag and, in the case of success, None, or, in the case of failure, an Exception instance. Declaring the function as returning tuple[bool, Union[Exception, None]] obviously doesn't work -- there is no way for the type checker to know whether the second element of the tuple is an Exception or None, so when I write, e.g., raise result[1], pyright complains that None does not inherit from BaseException.

    I have tried overloading the return value, i.e.


    @overload
    def validate(value: MyClass) -> tuple[Literal[True], None]: ...

    @overload
    def validate(value: MyClass) -> tuple[Literal[False], Exception]: ...

    def validate(value: MyClass) -> tuple[bool, Union[Exception, None]]:
    try:
    value.validate()
    except Exception as e:
    return False, e

    return True, None

    def do_something(value: MyClass):
    success, error = validate(value)

    if not success:
    raise error

    value.do_something()


    But because the arguments are identical in both overloads, pyright seems to think I am always calling the first overload, and that the return value is always Literal[True], None.

    A simpler example also demonstrates the issue:

    from typing import Literal, reveal_type

    type T = tuple[Literal[True], None] | tuple[Literal[False], Exception]

    def test(t: T):
    a, b = t
    reveal_type(a) # bool
    reveal_type(b) # Exception | None
    if not a:
    reveal_type(a) # Literal[False]
    reveal_type(b) # Exception | None
    raise b # <-- Invalid exception class or object; "None" does not derive from BaseException (PylancereportGeneralTypeIssues)



    This seems like a fairly common use-case, but I can't find a way to do it.

    This also doesn't work with mypy.

    Continue reading...

Compartilhe esta Página