Usage
To make use of this plugin in code means using the annotation classes that are provided.
The following examples assume there is an abstract model AbstractModel
with the concrete models Concrete1
, Concrete2
and Concrete3
and
Concrete2
has a custom queryset class called Concrete2QS
.
Concrete
To create a union of the concrete models, use the Concrete
annotation:
from extended_mypy_django_plugin import Concrete
instance: Concrete[AbstractModel]
# --------------
# Equivalent to
# --------------
instance: Concrete1 | Concrete2 | Concrete3
This also works for types:
from extended_mypy_django_plugin import Concrete
cls: Concrete[type[AbstractModel]]
# --------------
# Equivalent to
# --------------
cls: type[Concrete1 | Concrete2 | Concrete3]
Concrete.type_var
To create a type var representing any one of the concrete models of an abstract
model, create a TypeVar
object using Concrete.type_var
:
from extended_mypy_django_plugin import Concrete
T_Concrete = Concrete.type_var("T_Concrete", AbstractModel)
def create_row(cls: type[T_Concrete]) -> T_Concrete:
return cls.objects.create()
# --------------
# Equivalent to
# --------------
from typing import TypeVar
T_Concrete = TypeVar("T_Concrete", Concrete1, Concrete2, Concrete3)
def create_row(cls: type[T_Concrete]) -> T_Concrete:
return cls.objects.create()
ConcreteQuerySet
To create a union of the default querysets for the concrete models of an
abstract class, use the ConcreteQuerySet
annotation:
from extended_mypy_django_plugin import ConcreteQuerySet
from django.db import models
qs: ConcreteQuerySet[AbstractModel]
# --------------
# Equivalent to
# --------------
qs: models.QuerySet[Concrete1] | Concrete2QuerySet | models.QuerySet[Concrete3]
DefaultQuerySet
This is similar to ConcreteQuerySet
but works on the concrete models themselves:
from extended_mypy_django_plugin import DefaultQuerySet
qs1: DefaultQuerySet[Concrete1]
qs2: DefaultQuerySet[Concrete2]
# --------------
# Equivalent to
# --------------
from django.db import models
qs1: models.QuerySet[Concrete1]
qs2: Concrete2QuerySet
It also works on the TypeVar
objects returned by Concrete.type_var
:
from extended_mypy_django_plugin import Concrete, DefaultQuerySet
T_Concrete = Concrete.type_var("T_Concrete", AbstractModel)
def get_qs(cls: type[T_Concrete]) -> DefaultQuerySet[T_Concrete]:
return cls.objects.all()
# --------------
# Essentially equivalent to
# --------------
from typing import TypeVar, overload
T_Concrete = TypeVar("T_Concrete", Concrete1, Concrete2, Concrete3)
@overload
def create_row(cls: Concrete1) -> models.QuerySet[Concrete1]: ...
@overload
def create_row(cls: Concrete2) -> Concrete2QuerySet: ...
@overload
def create_row(cls: Concrete3) -> models.QuerySet[Concrete3]: ...
def create_row(
cls: type[Concrete1 | Concrete2 | Concrete3],
) -> models.QuerySet[Concrete1] | Concrete2QuerySet | models.QuerySet[Concrete3]:
return cls.objects.create()