Skip to content

Instantly share code, notes, and snippets.

@mypy-play
Created July 22, 2024 10:48
Show Gist options
  • Save mypy-play/33959d9b602de632ca50760c806934e0 to your computer and use it in GitHub Desktop.
Save mypy-play/33959d9b602de632ca50760c806934e0 to your computer and use it in GitHub Desktop.
Shared via mypy Playground
import typing as tp
if not tp.TYPE_CHECKING:
reveal_type = lambda var: var
class Foo: # Only supports "*Foo*".
def __init__(self, value: int) -> None:
self.value = value
def __add__(self, other: tp.Union["Foo", "FooBar"]) -> "Foo":
if not isinstance(other, (Foo, FooBar)):
return NotImplemented
self.value += other.value
return self
def __repr__(self) -> str:
return "Foo({})".format(self.value)
class FooBar: # Supports all three.
def __init__(self, value: int) -> None:
self.value = value
def __add__(self, other: tp.Union["FooBar", Foo, "Bar"]) -> "FooBar":
if not isinstance(other, (FooBar, Foo, Bar)):
return NotImplemented
self.value += other.value
return self
def __repr__(self) -> str:
return "FooBar({})".format(self.value)
class Bar: # Only supports "*Bar*".
def __init__(self, value: int) -> None:
self.value = value
def __add__(self, other: tp.Union["Bar", FooBar]) -> "Bar":
if not isinstance(other, (Bar, FooBar)):
return NotImplemented
self.value += other.value
return self
def __repr__(self) -> str:
return "Bar({})".format(self.value)
Fooable = tp.Union[FooBar, Foo]
Barable = tp.Union[Bar, FooBar]
T1 = tp.TypeVar("T1", Fooable, Barable)
def add_foo_bar(a: T1, b: T1, c: T1) -> T1:
return a + b + c
if __name__ == "__main__":
# Should resolve to 'Fooable' because arguments don't contain 'Bar'.
print(reveal_type(add_foo_bar(FooBar(1), Foo(2), FooBar(3))))
print(reveal_type(add_foo_bar(FooBar(1), Bar(3), FooBar(-2)))) # Should resolve to 'Barable'.
print(reveal_type(add_foo_bar(Bar(1), Foo(2), Foo(3)))) # Should emit type-check & runtime error.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment