Reputation: 2033
we are trying to add typehints to our django (3.2) project. We are using django-stubs (1.12.0).
We have an AbstractBaseModel
with a custom BaseManager
that we use for almost every other model. In some cases we also extend the custom Manager.
Example:
class BaseManager(models.Manager):
# ...
class AbstractBaseModel(models.Model):
# ...
objects = BaseManager()
# ...
class MyManager(BaseManager):
# ...
class MyModel(AbstractBaseModel):
# ...
objects = MyManager()
# ...
When I run this through mypy (0.982), I get this error on the objects
assignment of MyModel
:
Incompatible types in assignment (expression has type "MyManager[MyModel]",
base class "AbstractBaseModel" defined the type as
"AbstractBaseModel_BaseManager2[AbstractBaseModel]")
How would I add typehints to this? Thank you!
Upvotes: 1
Views: 1371
Reputation: 18663
As I said in my comment above, I could not reproduce that same error you described. It seems that in the django-stubs
the BaseManager
is defined as a covariant generic type over any Model
(sub-)class.
So I would annotate the code you provided as follows:
from __future__ import annotations
from typing import TypeVar
from django.db import models
M = TypeVar("M", bound=models.Model, covariant=True)
class BaseManager(models.Manager[M]):
pass
class AbstractBaseModel(models.Model):
objects: BaseManager[AbstractBaseModel] = BaseManager()
class MyManager(BaseManager[M]):
pass
class MyModel(AbstractBaseModel):
objects: BaseManager[MyModel] = MyManager()
This passes mypy --strict
without issues.
Versions used:
Python==3.10.7
Django==3.2
django-stubs==1.12.0
django-stubs-ext==0.5.0
mypy==0.982
mypy-extensions==0.4.3
Upvotes: 2