0

The easiest way to ask this question is to show what I am trying to accomplish

from typing import Generic, TypeVar

ID_T = TypeVar("ID_T", int, str)


class BaseModel(Generic[ID_T]):
    def __init__(self, id: ID_T) -> None:
        self._id: ID_T = id

    @property
    def id(self) -> ID_T:
        return self._id


MODEL_T = TypeVar("MODEL_T", bound=BaseModel[ID_T])


class BaseModelRepository(Generic[MODEL_T, ID_T]):
    def __init__(self) -> None:
        self._db: dict[ID_T, MODEL_T] = {}

    def add(self, model: MODEL_T) -> None:
        self._db[model.id] = model

    def get(self, id: ID_T) -> MODEL_T | None:
        return self._db.get(id, None)


class MyStrModel(BaseModel[str]):
    @property
    def foo(self) -> str:
        return "foo"


class MyStrModelRepository(BaseModelRepository[MyStrModel, str]):
    pass


my_str_model_repo = MyStrModelRepository()
my_str_model = MyStrModel("id")
my_str_model_repo.add(my_str_model)

my_other_str_model = my_str_model_repo.get("id")
print(my_str_model.foo)

Basically, I am having a hard time figuring out the correct way to type the BaseModelRepository so that the id parameters and model return types are all correct and pass mypy without issues.

I'm probably missing something really obvious, and will no doubt hang my head in shame once I see the solution.

niltz
  • 1,014
  • 11
  • 28
  • See comments [here](https://stackoverflow.com/questions/76344074/python-and-mypy-typevar-bound-by-protocol-with-another-bouned-typevar). What you intend is not possible; can't close as dupe, because that question has no answer. Maybe there are older duplicates. – STerliakov Jun 01 '23 at 16:14
  • Oh, yes, there are dupes. See the suggested one. – STerliakov Jun 01 '23 at 16:14

0 Answers0