Reputation: 727
I've created BaseRepository
class from which I inherit in my specific repositories.
When invoking an update
method of the RecipeRepository
I get some strange warning.
Warning: Expected type 'SpecificModel' (matched generic type 'T'), got 'SpecificModel' instead
What am I doing wrong?
- Models
from typing import Type, TypeVar, Generic
class BaseModel:
def update(self, *args, **kwargs):
return self
class SpecificModel(BaseModel):
name: str
- Repositories
T = TypeVar('T', bound=BaseModel)
class BaseRepository(Generic[T]):
def __init__(self, model: T):
self._model = model
def update(self, record: T, *args, **kwargs):
return record.update(*args, **kwargs)
class SpecificRepository(BaseRepository[SpecificModel]):
def __init__(self):
super().__init__(SpecificModel)
- Services
class SpecificService:
def __init__(self, repository: SpecificRepository):
self._repository = repository
def update_name(self, record: SpecificModel, name: str):
# When hovering over `record` I get the warning
self._repository.update(record, name)
I've changed my code from:
T = TypeVar('T', bound=Type[BaseModel])
to
T = TypeVar('T', bound=BaseModel)
.
Now I have some type warnings in the constructor of SpeficRepository
.
Expected type 'Union[BaseModel, Any]' (matched generic type 'T'), got 'Type[SpecificModel]' instead
Upvotes: 0
Views: 1352
Reputation: 14423
The issue is in the definition of T
. Instead of
T = TypeVar('T', bound=Type[BaseModel])
you want
T = TypeVar('T', bound=BaseModel)
Ultimately, you want T
to stand for BaseModel
and its subclasess, not type(BaseModel)
(i.e., type
) and its subclasses.
To diagnosis this issue and others like it, you can use a more complete static type checker like mypy. In this case, mypy gives a much more informative error at the definition SpecificRepository
:
error: Type argument "module.SpecificModel" of "BaseRepository" must be a subtype of "Type[module.BaseModel]"
which immediately tells you what the problem is.
Upvotes: 2