Type hints for bool vs int overload

Here’s a general purpose solution:

from __future__ import annotations

from typing import Protocol, overload, override

class A: pass
class B: pass

class Just[T](Protocol):
    @property
    @override
    def __class__(self, /) -> type[T]: ...  # pyright: ignore[reportIncompatibleMethodOverride]
    @__class__.setter
    @override
    def __class__(self, t: type[T], /) -> None: ...

@overload
def func(arg: bool) -> A: ...
@overload
def func(arg: Just[int]) -> B: ...
def func(arg: bool | Just[int]) -> A | B:
    if isinstance(arg, bool):
        return A()
    else:
        return B()

playground links:

This Just type, and several (runtime-checkable) aliases like JustInt and JustObject (useful for sentinels), are implemented (and tested) in the upcoming optype v0.9 release (docs), which I’ll release today or tomorrow.
I’ve been using this trick quite a lot in scipy-stubs, and I’ve had no problems with it so far.

2 Likes