From ca234e4be9a8f783131d2324c859114d8ba4c61b Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Mon, 1 Jan 2024 19:08:23 +0100 Subject: [PATCH] Add slicing notation to F expressions --- django-stubs/db/models/expressions.pyi | 17 +++++++++++++++-- django-stubs/db/models/fields/__init__.pyi | 3 ++- scripts/stubtest/allowlist_todo_django51.txt | 7 ------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/django-stubs/db/models/expressions.pyi b/django-stubs/db/models/expressions.pyi index 85191cde4..f76d9ce9f 100644 --- a/django-stubs/db/models/expressions.pyi +++ b/django-stubs/db/models/expressions.pyi @@ -1,7 +1,7 @@ import datetime from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence from decimal import Decimal -from typing import Any, ClassVar, Generic, Literal, TypeVar +from typing import Any, ClassVar, Generic, Literal, NoReturn, TypeVar from django.db.backends.base.base import BaseDatabaseWrapper from django.db.models import Q, fields @@ -132,6 +132,8 @@ class F(_Deconstructible, Combinable): name: str allowed_default: ClassVar[bool] def __init__(self, name: str) -> None: ... + def __getitem__(self, subscript: int | slice) -> Sliced: ... + def __contains__(self, other: Any) -> NoReturn: ... def resolve_expression( self, query: Any | None = None, @@ -154,7 +156,18 @@ class F(_Deconstructible, Combinable): nulls_first: bool | None = ..., nulls_last: bool | None = ..., ) -> OrderBy: ... - def copy(self) -> F: ... + def copy(self) -> Self: ... + +class Sliced(F): + def __init__(self, obj: F, subscript: int | slice) -> None: ... + def resolve_expression( + self, + query: Any | None = None, + allow_joins: bool = True, + reuse: set[str] | None = None, + summarize: bool = False, + for_save: bool = False, + ) -> Func: ... class ResolvedOuterRef(F): contains_aggregate: ClassVar[bool] diff --git a/django-stubs/db/models/fields/__init__.pyi b/django-stubs/db/models/fields/__init__.pyi index 74111ee67..8400a7ba8 100644 --- a/django-stubs/db/models/fields/__init__.pyi +++ b/django-stubs/db/models/fields/__init__.pyi @@ -10,7 +10,7 @@ from django.core import validators # due to weird mypy.stubtest error from django.core.checks import CheckMessage from django.db.backends.base.base import BaseDatabaseWrapper from django.db.models import Model -from django.db.models.expressions import Col, Combinable, Expression +from django.db.models.expressions import Col, Combinable, Expression, Func from django.db.models.fields.reverse_related import ForeignObjectRel from django.db.models.query_utils import Q, RegisterLookupMixin from django.forms import Widget @@ -234,6 +234,7 @@ class Field(RegisterLookupMixin, Generic[_ST, _GT]): def get_attname(self) -> str: ... def get_attname_column(self) -> tuple[str, str]: ... def value_to_string(self, obj: Model) -> str: ... + def slice_expression(self, expression: Expression, start: int, end: int | None) -> Func: ... class IntegerField(Field[_ST, _GT]): _pyi_private_set_type: float | int | str | Combinable diff --git a/scripts/stubtest/allowlist_todo_django51.txt b/scripts/stubtest/allowlist_todo_django51.txt index 8123c6764..84fa424ae 100644 --- a/scripts/stubtest/allowlist_todo_django51.txt +++ b/scripts/stubtest/allowlist_todo_django51.txt @@ -30,8 +30,6 @@ django.contrib.gis.admin.ModelAdmin.log_deletions django.contrib.gis.db.backends.mysql.operations.MySQLOperations.collect django.contrib.gis.db.models.CharField.slice_expression django.contrib.gis.db.models.CheckConstraint.__init__ -django.contrib.gis.db.models.F.__contains__ -django.contrib.gis.db.models.F.__getitem__ django.contrib.gis.db.models.Field.slice_expression django.contrib.gis.db.models.ForeignObjectRel.accessor_name django.contrib.gis.db.models.ForeignObjectRel.cache_name @@ -257,8 +255,6 @@ django.db.migrations.operations.special.SeparateDatabaseAndState.category django.db.migrations.serializer.FUNCTION_TYPES django.db.models.CharField.slice_expression django.db.models.CheckConstraint.__init__ -django.db.models.F.__contains__ -django.db.models.F.__getitem__ django.db.models.Field.slice_expression django.db.models.ForeignObjectRel.accessor_name django.db.models.ForeignObjectRel.cache_name @@ -279,10 +275,7 @@ django.db.models.base.Model.save django.db.models.constraints.CheckConstraint.__init__ django.db.models.expressions.BaseExpression.constraint_validation_compatible django.db.models.expressions.BaseExpression.get_expression_for_validation -django.db.models.expressions.F.__contains__ -django.db.models.expressions.F.__getitem__ django.db.models.expressions.OrderBy.constraint_validation_compatible -django.db.models.expressions.Sliced django.db.models.expressions.WindowFrame.__init__ django.db.models.expressions.WindowFrame.get_exclusion django.db.models.expressions.WindowFrameExclusion