Как сделать typehint пользовательских и переопределенных менеджеров в абстрактном классе с помощью django-stubs?

мы пытаемся добавить typehints в наш проект django (3.2). Мы используем django-stubs (1.12.0).

У нас есть BaseModel с пользовательским менеджером, который мы используем почти для каждой другой модели.

class BaseManager(models.Manager):
    # ...

class AbstractBaseModel(models.Model):
    # ...
    objects = BaseManager()
    # ...

class MyManager(BaseManager):
    # ...

class MyModel(AbstractBaseModel):
    # ...
    objects = MyManager()
    # ...

Когда я запускаю это через mypy (0.982), я получаю эту ошибку на objects присвоении MyModel:

Incompatible types in assignment (expression has type "MyManager[MyModel]", 
base class "AbstractBaseModel" defined the type as 
"AbstractBaseModel_BaseManager2[AbstractBaseModel]")

Как мне добавить подсказки к этому? Спасибо!

Как я уже сказал в своем комментарии выше, я не смог воспроизвести ту же ошибку, которую вы описали. Похоже, что в django-stubs BaseManager определяется как ковариантный общий тип над любым Model (под)классом.

Так что я бы аннотировал предоставленный вами код следующим образом:

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

Это проходит mypy --strict без проблем.

Используемые версии:

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
Вернуться на верх