Skip to content

Instantly share code, notes, and snippets.

@mypy-play
Created April 25, 2024 08:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mypy-play/7f887563bba2a89b77864b8c0a24d594 to your computer and use it in GitHub Desktop.
Save mypy-play/7f887563bba2a89b77864b8c0a24d594 to your computer and use it in GitHub Desktop.
Shared via mypy Playground
from typing import TypeVar, Generic, Any, cast, overload
from abc import abstractmethod, ABC
_TP = TypeVar("_TP", bound=tuple[Any, ...])
class Select(Generic[_TP]):
pass
class Base:
pass
class Other(Base):
pass
ModelType = TypeVar("ModelType", bound=Base)
class DBRepository(ABC, Generic[ModelType]):
T = TypeVar("T", Select[tuple[ModelType]], Select[tuple[int]])
@overload
def func(self, arg: Select[tuple[ModelType]]) -> Select[tuple[ModelType]]:
...
@overload
def func(self, arg: Select[tuple[int]]) -> Select[tuple[int]]:
...
@abstractmethod
def func(self, arg):
...
class SubDBRepository(DBRepository[Other]):
@overload
def func(self, arg: Select[tuple[Other]]) -> Select[tuple[Other]]:
...
@overload
def func(self, arg: Select[tuple[int]]) -> Select[tuple[int]]:
...
def func(self, arg):
# here we are runtime, runtime cannot distinguish
# between tuple[ModelType]() and tuple[int](); can
# only see a difference if the arg is a non-empty tuple
if len(arg):
match arg[0]:
case Other():
# need to come up with a Select[tuple[Other]] but for now:
return arg
case int():
# need to come up with a Select[tuple[int]] but for now:
return arg
else:
return Select()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment