Revisiting types in Django / DEP-14

To add to what @jacobtylerwalls said I think that very minimal typing around the introduction of two typing.Protocol could go a long way in making the ORM more approachable

from __future__ import annotations

from typing import Protocol

from django.db.models import fields
from django.db.models.sql import compiler, query


class Compilable(Protocol):
    """
    Object that can be compiled to a PEP 249 compliant tuple comprised of
    a SQL string and its associated parameters sequence.

    It can optionally have `as_vendor` methods defined to specialize the
    compilation on different backends (e.g. `as_postgres`).
    """

    def get_source_expressions(self) -> list[Compilable | None]: ...

    def as_sql(
        self, compiler: compiler.SQLCompiler, connection
    ) -> tuple[str, tuple]: ...


class Resolvable(Protocol):
    """
    Object that can resolve any field and transform reference it has in
    the context of a query and return an object ready to be compiled for
    execution.
    """

    output_field: fields.Field

    def get_source_expressions(self) -> list[Resolvable | None]: ...

    def resolve_expression(
        self,
        query: query.Query,
        allow_joins: bool = True,
        reuse: set[str] | None = None,
        summarize: bool = False,
        for_save: bool = False,
    ) -> Compilable: ...
5 Likes