Rechu
Rechu

Reputation: 727

Incorrect type warning in PyCharm

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?

Minimalistic Example:

- 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)

Update #1

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

Answers (1)

Brian61354270
Brian61354270

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

Related Questions