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.