From cbcad7915cbc146562972bb696167deee0945aa1 Mon Sep 17 00:00:00 2001 From: Thibaut Decombe Date: Sun, 8 Oct 2023 17:32:08 +0200 Subject: [PATCH 1/8] Update `BaseExpression.output_field` --- django-stubs/db/models/expressions.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django-stubs/db/models/expressions.pyi b/django-stubs/db/models/expressions.pyi index 4ff89770e..71f3920fe 100644 --- a/django-stubs/db/models/expressions.pyi +++ b/django-stubs/db/models/expressions.pyi @@ -85,7 +85,7 @@ class BaseExpression: def conditional(self) -> bool: ... @property def field(self) -> Field: ... - @property + @cached_property def output_field(self) -> Field: ... @cached_property def convert_value(self) -> Callable: ... From 56ce55ee6bc84b1004bab3694169041ce446db06 Mon Sep 17 00:00:00 2001 From: Thibaut Decombe Date: Sun, 8 Oct 2023 19:47:36 +0200 Subject: [PATCH 2/8] Fix some mypy override --- .../contrib/gis/db/models/functions.pyi | 3 +- .../contrib/postgres/fields/ranges.pyi | 28 +++++-------------- django-stubs/contrib/postgres/search.pyi | 5 ++-- .../db/models/functions/comparison.pyi | 2 +- django-stubs/db/models/functions/datetime.pyi | 8 +++--- django-stubs/db/models/functions/text.pyi | 14 +++++----- django-stubs/db/models/functions/window.pyi | 12 ++++---- django-stubs/db/models/sql/query.pyi | 2 +- 8 files changed, 31 insertions(+), 43 deletions(-) diff --git a/django-stubs/contrib/gis/db/models/functions.pyi b/django-stubs/contrib/gis/db/models/functions.pyi index 508b953e8..af9e8dbe9 100644 --- a/django-stubs/contrib/gis/db/models/functions.pyi +++ b/django-stubs/contrib/gis/db/models/functions.pyi @@ -4,6 +4,7 @@ from django.db.backends.base.base import BaseDatabaseWrapper from django.db.models import Func from django.db.models import Transform as StandardTransform from django.db.models.sql.compiler import SQLCompiler, _AsSqlType +from utils.functional import cached_property NUMERIC_TYPES: Any @@ -77,7 +78,7 @@ class Difference(OracleToleranceMixin, GeomOutputGeoFunc): geom_param_pos: Any class DistanceResultMixin: - @property + @cached_property def output_field(self) -> Any: ... def source_is_geography(self) -> Any: ... diff --git a/django-stubs/contrib/postgres/fields/ranges.pyi b/django-stubs/contrib/postgres/fields/ranges.pyi index 7600d864f..ff6749f47 100644 --- a/django-stubs/contrib/postgres/fields/ranges.pyi +++ b/django-stubs/contrib/postgres/fields/ranges.pyi @@ -73,38 +73,24 @@ class AdjacentToLookup(PostgresOperatorLookup): postgres_operator: str class RangeStartsWith(models.Transform): - lookup_name: str - function: str @property - def output_field(self) -> models.Field: ... + def output_field(self) -> models.Field: ... # type: ignore[override] class RangeEndsWith(models.Transform): - lookup_name: str - function: str @property - def output_field(self) -> models.Field: ... + def output_field(self) -> models.Field: ... # type: ignore[override] class IsEmpty(models.Transform): - lookup_name: str - function: str - output_field: models.BooleanField + output_field: models.BooleanField # type: ignore[assignment] class LowerInclusive(models.Transform): - lookup_name: str - function: str - output_field: models.BooleanField + output_field: models.BooleanField # type: ignore[assignment] class LowerInfinite(models.Transform): - lookup_name: str - function: str - output_field: models.BooleanField + output_field: models.BooleanField # type: ignore[assignment] class UpperInclusive(models.Transform): - lookup_name: str - function: str - output_field: models.BooleanField + output_field: models.BooleanField # type: ignore[assignment] class UpperInfinite(models.Transform): - lookup_name: str - function: str - output_field: models.BooleanField + output_field: models.BooleanField # type: ignore[assignment] diff --git a/django-stubs/contrib/postgres/search.pyi b/django-stubs/contrib/postgres/search.pyi index f3e0dcc5f..88410381c 100644 --- a/django-stubs/contrib/postgres/search.pyi +++ b/django-stubs/contrib/postgres/search.pyi @@ -1,5 +1,6 @@ from typing import Any +from db.models import TextField from django.db.models import Expression, Field from django.db.models.expressions import Combinable, CombinedExpression, Func from django.db.models.lookups import Lookup @@ -24,7 +25,7 @@ class SearchVector(SearchVectorCombinable, Func): config: _Expression | None function: str arg_joiner: str - output_field: Field + output_field: SearchVectorField # type: ignore[assignment] def __init__( self, *expressions: _Expression, config: _Expression | None = ..., weight: Any | None = ... ) -> None: ... @@ -83,7 +84,7 @@ class SearchRank(Func): class SearchHeadline(Func): function: str template: str - output_field: Field + output_field: TextField def __init__( self, expression: _Expression, diff --git a/django-stubs/db/models/functions/comparison.pyi b/django-stubs/db/models/functions/comparison.pyi index fb1a63385..4d79528a3 100644 --- a/django-stubs/db/models/functions/comparison.pyi +++ b/django-stubs/db/models/functions/comparison.pyi @@ -16,7 +16,7 @@ class Greatest(Func): ... class JSONObject(Func): def __init__(self, **fields: Any) -> None: ... - output_field: JSONField + output_field: JSONField # type: ignore[assignment] class Least(Func): ... class NullIf(Func): ... diff --git a/django-stubs/db/models/functions/datetime.pyi b/django-stubs/db/models/functions/datetime.pyi index e5ce958ae..084f6a44e 100644 --- a/django-stubs/db/models/functions/datetime.pyi +++ b/django-stubs/db/models/functions/datetime.pyi @@ -9,7 +9,7 @@ class TimezoneMixin: class Extract(TimezoneMixin, Transform): lookup_name: str - output_field: models.IntegerField + output_field: models.IntegerField # type: ignore[assignment] def __init__( self, expression: Any, lookup_name: str | None = ..., tzinfo: Any | None = ..., **extra: Any ) -> None: ... @@ -27,7 +27,7 @@ class ExtractMinute(Extract): ... class ExtractSecond(Extract): ... class Now(Func): - output_field: models.DateTimeField + output_field: models.DateTimeField # type: ignore[assignment] class TruncBase(TimezoneMixin, Transform): kind: str @@ -41,10 +41,10 @@ class TruncWeek(TruncBase): ... class TruncDay(TruncBase): ... class TruncDate(TruncBase): - output_field: models.DateField + output_field: models.DateField # type: ignore[assignment] class TruncTime(TruncBase): - output_field: models.TimeField + output_field: models.TimeField # type: ignore[assignment] class TruncHour(TruncBase): ... class TruncMinute(TruncBase): ... diff --git a/django-stubs/db/models/functions/text.pyi b/django-stubs/db/models/functions/text.pyi index e71cbf571..9a99f8f0c 100644 --- a/django-stubs/db/models/functions/text.pyi +++ b/django-stubs/db/models/functions/text.pyi @@ -31,20 +31,20 @@ class Concat(Func): def __init__(self, *expressions: Any, **extra: Any) -> None: ... class Left(Func): - output_field: models.CharField + output_field: models.CharField # type: ignore[assignment] def __init__(self, expression: Expression | str, length: Expression | int, **extra: Any) -> None: ... def get_substr(self) -> Substr: ... def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class Length(Transform): - output_field: models.IntegerField + output_field: models.IntegerField # type: ignore[assignment] def as_mysql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class Lower(Transform): ... class LPad(Func): - output_field: models.CharField + output_field: models.CharField # type: ignore[assignment] def __init__( self, expression: Expression | str, length: Expression | int | None, fill_text: Expression = ..., **extra: Any ) -> None: ... @@ -52,12 +52,12 @@ class LPad(Func): class LTrim(Transform): ... class Ord(Transform): - output_field: models.IntegerField + output_field: models.IntegerField # type: ignore[assignment] def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... def as_mysql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class Repeat(Func): - output_field: models.CharField + output_field: models.CharField # type: ignore[assignment] def __init__(self, expression: Expression | str, number: Expression | int | None, **extra: Any) -> None: ... def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... @@ -82,13 +82,13 @@ class SHA384(MySQLSHA2Mixin, OracleHashMixin, PostgreSQLSHAMixin, Transform): .. class SHA512(MySQLSHA2Mixin, OracleHashMixin, PostgreSQLSHAMixin, Transform): ... class StrIndex(Func): - output_field: models.IntegerField + output_field: models.IntegerField # type: ignore[assignment] def as_postgresql( self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any ) -> _AsSqlType: ... class Substr(Func): - output_field: models.CharField + output_field: models.CharField # type: ignore[assignment] def __init__( self, expression: Expression | str, pos: Expression | int, length: Expression | int | None = ..., **extra: Any ) -> None: ... diff --git a/django-stubs/db/models/functions/window.pyi b/django-stubs/db/models/functions/window.pyi index 7de622d19..836c09819 100644 --- a/django-stubs/db/models/functions/window.pyi +++ b/django-stubs/db/models/functions/window.pyi @@ -4,10 +4,10 @@ from django.db import models from django.db.models.expressions import Func class CumeDist(Func): - output_field: models.FloatField + output_field: models.FloatField # type: ignore[assignment] class DenseRank(Func): - output_field: models.IntegerField + output_field: models.IntegerField # type: ignore[assignment] class FirstValue(Func): ... @@ -23,13 +23,13 @@ class NthValue(Func): class Ntile(Func): def __init__(self, num_buckets: int = ..., **extra: Any) -> None: ... - output_field: models.IntegerField + output_field: models.IntegerField # type: ignore[assignment] class PercentRank(Func): - output_field: models.FloatField + output_field: models.FloatField # type: ignore[assignment] class Rank(Func): - output_field: models.IntegerField + output_field: models.IntegerField # type: ignore[assignment] class RowNumber(Func): - output_field: models.IntegerField + output_field: models.IntegerField # type: ignore[assignment] diff --git a/django-stubs/db/models/sql/query.pyi b/django-stubs/db/models/sql/query.pyi index 0b6418c4f..0c42d9a4f 100644 --- a/django-stubs/db/models/sql/query.pyi +++ b/django-stubs/db/models/sql/query.pyi @@ -83,7 +83,7 @@ class Query(BaseExpression): annotations: dict[str, Expression] def __init__(self, model: type[Model] | None, where: type[WhereNode] = ..., alias_cols: bool = ...) -> None: ... @property - def output_field(self) -> Field: ... + def output_field(self) -> Field: ... # type: ignore[override] @property def has_select_fields(self) -> bool: ... @cached_property From f9481861f3c7cde2dc40d2db80c04f3c56e31594 Mon Sep 17 00:00:00 2001 From: Thibaut Decombe Date: Fri, 13 Oct 2023 14:29:42 +0200 Subject: [PATCH 3/8] Remove allowlist entries rm -rf .mypy_cache/ && bash ./scripts/stubtest.sh | rg "note: unused allowlist entry" | cut -d" " -f5 | xargs -I {} sd "{}\n" "" ./scripts/stubtest/allowlist_todo.txt --- django-stubs/db/models/lookups.pyi | 1 + scripts/stubtest/allowlist_todo.txt | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/django-stubs/db/models/lookups.pyi b/django-stubs/db/models/lookups.pyi index c97b3b22b..10f8c5e7e 100644 --- a/django-stubs/db/models/lookups.pyi +++ b/django-stubs/db/models/lookups.pyi @@ -8,6 +8,7 @@ from django.db.models.sql.compiler import SQLCompiler, _AsSqlType, _ParamT from django.utils.datastructures import OrderedSet from django.utils.functional import cached_property from typing_extensions import Self +from utils.functional import cached_property _T = TypeVar("_T") diff --git a/scripts/stubtest/allowlist_todo.txt b/scripts/stubtest/allowlist_todo.txt index 495e88301..bd44a55be 100644 --- a/scripts/stubtest/allowlist_todo.txt +++ b/scripts/stubtest/allowlist_todo.txt @@ -491,7 +491,6 @@ django.contrib.gis.db.models.aggregates.Extent.is_extent django.contrib.gis.db.models.aggregates.Extent3D.is_extent django.contrib.gis.db.models.aggregates.GeoAggregate.as_sql django.contrib.gis.db.models.aggregates.GeoAggregate.function -django.contrib.gis.db.models.aggregates.GeoAggregate.output_field django.contrib.gis.db.models.fields.BaseSpatialField.class_lookups django.contrib.gis.db.models.fields.GeometryField.contribute_to_class django.contrib.gis.db.models.fields.RasterField.contribute_to_class @@ -1169,7 +1168,6 @@ django.db.models.constraints.UniqueConstraint.contains_expressions django.db.models.constraints.UniqueConstraint.validate django.db.models.expressions.BaseExpression.empty_result_set_value django.db.models.expressions.BaseExpression.get_refs -django.db.models.expressions.BaseExpression.output_field django.db.models.expressions.BaseExpression.prefix_references django.db.models.expressions.BaseExpression.replace_expressions django.db.models.expressions.BaseExpression.select_format From 2286794340a257433071724aeef4ed1fed1307a4 Mon Sep 17 00:00:00 2001 From: Thibaut Decombe Date: Fri, 13 Oct 2023 10:37:55 +0200 Subject: [PATCH 4/8] Change to classVar when necessary Found match using `rg "^ output_field = .*Field\(\)"` in django repository --- .../contrib/gis/db/models/functions.pyi | 42 ++++++++++--------- .../contrib/postgres/aggregates/general.pyi | 26 +++++++++--- .../postgres/aggregates/statistics.pyi | 13 ++++-- .../contrib/postgres/fields/hstore.pyi | 14 +++++-- .../contrib/postgres/fields/ranges.pyi | 42 ++++++------------- django-stubs/contrib/postgres/functions.pyi | 11 +++-- django-stubs/contrib/postgres/search.pyi | 13 +++--- django-stubs/db/models/aggregates.pyi | 8 +++- django-stubs/db/models/expressions.pyi | 4 +- django-stubs/db/models/fields/json.pyi | 4 +- .../db/models/functions/comparison.pyi | 4 +- django-stubs/db/models/functions/datetime.pyi | 10 ++--- django-stubs/db/models/functions/text.pyi | 16 +++---- django-stubs/db/models/functions/window.pyi | 14 +++---- 14 files changed, 124 insertions(+), 97 deletions(-) diff --git a/django-stubs/contrib/gis/db/models/functions.pyi b/django-stubs/contrib/gis/db/models/functions.pyi index af9e8dbe9..4aa87c311 100644 --- a/django-stubs/contrib/gis/db/models/functions.pyi +++ b/django-stubs/contrib/gis/db/models/functions.pyi @@ -1,7 +1,9 @@ -from typing import Any +from typing import Any, ClassVar +from django.contrib.gis.db.models.fields import GeometryField +from django.contrib.gis.db.models.sql.conversion import DistanceField from django.db.backends.base.base import BaseDatabaseWrapper -from django.db.models import Func +from django.db.models import BinaryField, BooleanField, FloatField, Func, IntegerField, TextField from django.db.models import Transform as StandardTransform from django.db.models.sql.compiler import SQLCompiler, _AsSqlType from utils.functional import cached_property @@ -33,12 +35,12 @@ class Area(OracleToleranceMixin, GeoFunc): def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class Azimuth(GeoFunc): - output_field: Any + output_field: ClassVar[FloatField] # type: ignore[assignment] arity: int geom_param_pos: Any class AsGeoJSON(GeoFunc): - output_field: Any + output_field: ClassVar[TextField] # type: ignore[assignment] def __init__( self, expression: Any, bbox: bool = ..., crs: bool = ..., precision: int = ..., **extra: Any ) -> None: ... @@ -46,24 +48,24 @@ class AsGeoJSON(GeoFunc): class AsGML(GeoFunc): geom_param_pos: Any - output_field: Any + output_field: ClassVar[TextField] # type: ignore[assignment] def __init__(self, expression: Any, version: int = ..., precision: int = ..., **extra: Any) -> None: ... def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class AsKML(GeoFunc): - output_field: Any + output_field: ClassVar[TextField] # type: ignore[assignment] def __init__(self, expression: Any, precision: int = ..., **extra: Any) -> None: ... class AsSVG(GeoFunc): - output_field: Any + output_field: ClassVar[TextField] # type: ignore[assignment] def __init__(self, expression: Any, relative: bool = ..., precision: int = ..., **extra: Any) -> None: ... class AsWKB(GeoFunc): - output_field: Any + output_field: ClassVar[BinaryField] # type: ignore[assignment] arity: int class AsWKT(GeoFunc): - output_field: Any + output_field: ClassVar[TextField] # type: ignore[assignment] arity: int class BoundingCircle(OracleToleranceMixin, GeomOutputGeoFunc): @@ -79,7 +81,7 @@ class Difference(OracleToleranceMixin, GeomOutputGeoFunc): class DistanceResultMixin: @cached_property - def output_field(self) -> Any: ... + def output_field(self) -> DistanceField: ... def source_is_geography(self) -> Any: ... class Distance(DistanceResultMixin, OracleToleranceMixin, GeoFunc): @@ -98,20 +100,20 @@ class ForcePolygonCW(GeomOutputGeoFunc): arity: int class FromWKB(GeoFunc): - output_field: Any + output_field: ClassVar[GeometryField] # type: ignore[assignment] arity: int class FromWKT(GeoFunc): - output_field: Any + output_field: ClassVar[GeometryField] # type: ignore[assignment] arity: int class GeoHash(GeoFunc): - output_field: Any + output_field: ClassVar[TextField] # type: ignore[assignment] def __init__(self, expression: Any, precision: Any | None = ..., **extra: Any) -> None: ... def as_mysql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class GeometryDistance(GeoFunc): - output_field: Any + output_field: ClassVar[FloatField] # type: ignore[assignment] arity: int function: str arg_joiner: str @@ -123,11 +125,11 @@ class Intersection(OracleToleranceMixin, GeomOutputGeoFunc): class IsEmpty(GeoFuncMixin, StandardTransform): lookup_name: str - output_field: Any + output_field: ClassVar[BooleanField] # type: ignore[assignment] class IsValid(OracleToleranceMixin, GeoFuncMixin, StandardTransform): lookup_name: str - output_field: Any + output_field: ClassVar[BooleanField] # type: ignore[assignment] def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class Length(DistanceResultMixin, OracleToleranceMixin, GeoFunc): @@ -139,22 +141,22 @@ class Length(DistanceResultMixin, OracleToleranceMixin, GeoFunc): def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class LineLocatePoint(GeoFunc): - output_field: Any + output_field: ClassVar[FloatField] # type: ignore[assignment] arity: int geom_param_pos: Any class MakeValid(GeomOutputGeoFunc): ... class MemSize(GeoFunc): - output_field: Any + output_field: ClassVar[IntegerField] # type: ignore[assignment] arity: int class NumGeometries(GeoFunc): - output_field: Any + output_field: ClassVar[IntegerField] # type: ignore[assignment] arity: int class NumPoints(GeoFunc): - output_field: Any + output_field: ClassVar[IntegerField] # type: ignore[assignment] arity: int class Perimeter(DistanceResultMixin, OracleToleranceMixin, GeoFunc): diff --git a/django-stubs/contrib/postgres/aggregates/general.pyi b/django-stubs/contrib/postgres/aggregates/general.pyi index b38f30789..cb79097dd 100644 --- a/django-stubs/contrib/postgres/aggregates/general.pyi +++ b/django-stubs/contrib/postgres/aggregates/general.pyi @@ -1,11 +1,25 @@ -from django.db.models.aggregates import Aggregate +from typing import ClassVar + +from django.contrib.postgres.fields import ArrayField +from django.db.models import Aggregate, BooleanField, JSONField, TextField from .mixins import OrderableAggMixin -class ArrayAgg(OrderableAggMixin, Aggregate): ... +class ArrayAgg(OrderableAggMixin, Aggregate): + @property + def output_field(self) -> ArrayField: ... # type: ignore[override] + class BitAnd(Aggregate): ... class BitOr(Aggregate): ... -class BoolAnd(Aggregate): ... -class BoolOr(Aggregate): ... -class JSONBAgg(OrderableAggMixin, Aggregate): ... -class StringAgg(OrderableAggMixin, Aggregate): ... + +class BoolAnd(Aggregate): + output_field: ClassVar[BooleanField] # type: ignore[assignment] + +class BoolOr(Aggregate): + output_field: ClassVar[BooleanField] # type: ignore[assignment] + +class JSONBAgg(OrderableAggMixin, Aggregate): + output_field: ClassVar[JSONField] # type: ignore[assignment] + +class StringAgg(OrderableAggMixin, Aggregate): + output_field: ClassVar[TextField] # type: ignore[assignment] diff --git a/django-stubs/contrib/postgres/aggregates/statistics.pyi b/django-stubs/contrib/postgres/aggregates/statistics.pyi index 9e7d1380c..509484e48 100644 --- a/django-stubs/contrib/postgres/aggregates/statistics.pyi +++ b/django-stubs/contrib/postgres/aggregates/statistics.pyi @@ -1,11 +1,18 @@ -from django.db.models.aggregates import Aggregate +from typing import ClassVar + +from django.db.models import Aggregate, FloatField, IntegerField + +class StatAggregate(Aggregate): + output_field: ClassVar[FloatField] # type: ignore[assignment] -class StatAggregate(Aggregate): ... class Corr(StatAggregate): ... class CovarPop(StatAggregate): ... class RegrAvgX(StatAggregate): ... class RegrAvgY(StatAggregate): ... -class RegrCount(StatAggregate): ... + +class RegrCount(StatAggregate): + output_field: ClassVar[IntegerField] # type: ignore[assignment] + class RegrIntercept(StatAggregate): ... class RegrR2(StatAggregate): ... class RegrSlope(StatAggregate): ... diff --git a/django-stubs/contrib/postgres/fields/hstore.pyi b/django-stubs/contrib/postgres/fields/hstore.pyi index 207f79037..97967b866 100644 --- a/django-stubs/contrib/postgres/fields/hstore.pyi +++ b/django-stubs/contrib/postgres/fields/hstore.pyi @@ -1,17 +1,23 @@ -from typing import Any +from typing import Any, ClassVar -from django.db.models import Field, Transform +from django.contrib.postgres.fields.array import ArrayField +from django.db.models import Field, TextField, Transform from django.db.models.fields.mixins import CheckFieldDefaultMixin class HStoreField(CheckFieldDefaultMixin, Field): def get_transform(self, name: str) -> Any: ... class KeyTransform(Transform): + output_field: ClassVar[TextField] # type: ignore[assignment] + def __init__(self, key_name: str, *args: Any, **kwargs: Any) -> None: ... class KeyTransformFactory: def __init__(self, key_name: str) -> None: ... def __call__(self, *args: Any, **kwargs: Any) -> KeyTransform: ... -class KeysTransform(Transform): ... -class ValuesTransform(Transform): ... +class KeysTransform(Transform): + output_field: ClassVar[ArrayField] # type: ignore[assignment] + +class ValuesTransform(Transform): + output_field: ClassVar[ArrayField] # type: ignore[assignment] diff --git a/django-stubs/contrib/postgres/fields/ranges.pyi b/django-stubs/contrib/postgres/fields/ranges.pyi index ff6749f47..b9bd7056e 100644 --- a/django-stubs/contrib/postgres/fields/ranges.pyi +++ b/django-stubs/contrib/postgres/fields/ranges.pyi @@ -1,4 +1,4 @@ -from typing import Any, Literal +from typing import Any, ClassVar, Literal from django.db import models from django.db.models.lookups import PostgresOperatorLookup @@ -43,34 +43,16 @@ class DateTimeRangeField(RangeField): class DateRangeField(RangeField): def __get__(self, instance: Any, owner: Any) -> DateRange: ... -class DateTimeRangeContains(PostgresOperatorLookup): - lookup_name: str - postgres_operator: str +class DateTimeRangeContains(PostgresOperatorLookup): ... class RangeContainedBy(PostgresOperatorLookup): - lookup_name: str type_mapping: dict[str, str] - postgres_operator: str -class FullyLessThan(PostgresOperatorLookup): - lookup_name: str - postgres_operator: str - -class FullGreaterThan(PostgresOperatorLookup): - lookup_name: str - postgres_operator: str - -class NotLessThan(PostgresOperatorLookup): - lookup_name: str - postgres_operator: str - -class NotGreaterThan(PostgresOperatorLookup): - lookup_name: str - postgres_operator: str - -class AdjacentToLookup(PostgresOperatorLookup): - lookup_name: str - postgres_operator: str +class FullyLessThan(PostgresOperatorLookup): ... +class FullGreaterThan(PostgresOperatorLookup): ... +class NotLessThan(PostgresOperatorLookup): ... +class NotGreaterThan(PostgresOperatorLookup): ... +class AdjacentToLookup(PostgresOperatorLookup): ... class RangeStartsWith(models.Transform): @property @@ -81,16 +63,16 @@ class RangeEndsWith(models.Transform): def output_field(self) -> models.Field: ... # type: ignore[override] class IsEmpty(models.Transform): - output_field: models.BooleanField # type: ignore[assignment] + output_field: ClassVar[models.BooleanField] # type: ignore[assignment] class LowerInclusive(models.Transform): - output_field: models.BooleanField # type: ignore[assignment] + output_field: ClassVar[models.BooleanField] # type: ignore[assignment] class LowerInfinite(models.Transform): - output_field: models.BooleanField # type: ignore[assignment] + output_field: ClassVar[models.BooleanField] # type: ignore[assignment] class UpperInclusive(models.Transform): - output_field: models.BooleanField # type: ignore[assignment] + output_field: ClassVar[models.BooleanField] # type: ignore[assignment] class UpperInfinite(models.Transform): - output_field: models.BooleanField # type: ignore[assignment] + output_field: ClassVar[models.BooleanField] # type: ignore[assignment] diff --git a/django-stubs/contrib/postgres/functions.pyi b/django-stubs/contrib/postgres/functions.pyi index 414a0998a..566e960ec 100644 --- a/django-stubs/contrib/postgres/functions.pyi +++ b/django-stubs/contrib/postgres/functions.pyi @@ -1,4 +1,9 @@ -from django.db.models import Func +from typing import ClassVar -class RandomUUID(Func): ... -class TransactionNow(Func): ... +from django.db.models import DateTimeField, Func, UUIDField + +class RandomUUID(Func): + output_field: ClassVar[UUIDField] # type: ignore[assignment] + +class TransactionNow(Func): + output_field: ClassVar[DateTimeField] # type: ignore[assignment] diff --git a/django-stubs/contrib/postgres/search.pyi b/django-stubs/contrib/postgres/search.pyi index 88410381c..acc93ad03 100644 --- a/django-stubs/contrib/postgres/search.pyi +++ b/django-stubs/contrib/postgres/search.pyi @@ -1,7 +1,6 @@ -from typing import Any +from typing import Any, ClassVar -from db.models import TextField -from django.db.models import Expression, Field +from django.db.models import Expression, Field, FloatField, TextField from django.db.models.expressions import Combinable, CombinedExpression, Func from django.db.models.lookups import Lookup from typing_extensions import Self, TypeAlias @@ -25,7 +24,7 @@ class SearchVector(SearchVectorCombinable, Func): config: _Expression | None function: str arg_joiner: str - output_field: SearchVectorField # type: ignore[assignment] + output_field: ClassVar[SearchVectorField] # type: ignore[assignment] def __init__( self, *expressions: _Expression, config: _Expression | None = ..., weight: Any | None = ... ) -> None: ... @@ -49,6 +48,7 @@ class SearchQueryCombinable: def __rand__(self, other: SearchQueryCombinable) -> Self: ... class SearchQuery(SearchQueryCombinable, Func): # type: ignore[misc] + output_field: ClassVar[SearchQueryField] # type: ignore[assignment] SEARCH_TYPES: dict[str, str] def __init__( self, @@ -72,6 +72,7 @@ class CombinedSearchQuery(SearchQueryCombinable, CombinedExpression): # type: i ) -> None: ... class SearchRank(Func): + output_field: ClassVar[FloatField] # type: ignore[assignment] def __init__( self, vector: SearchVector | _Expression, @@ -84,7 +85,7 @@ class SearchRank(Func): class SearchHeadline(Func): function: str template: str - output_field: TextField + output_field: ClassVar[TextField] # type: ignore[assignment] def __init__( self, expression: _Expression, @@ -102,9 +103,11 @@ class SearchHeadline(Func): ) -> None: ... class TrigramBase(Func): + output_field: ClassVar[FloatField] # type: ignore[assignment] def __init__(self, expression: _Expression, string: str, **extra: Any) -> None: ... class TrigramWordBase(Func): + output_field: ClassVar[FloatField] # type: ignore[assignment] def __init__(self, string: str, expression: _Expression, **extra: Any) -> None: ... class TrigramSimilarity(TrigramBase): ... diff --git a/django-stubs/db/models/aggregates.pyi b/django-stubs/db/models/aggregates.pyi index e712f937d..f1e0ca6d3 100644 --- a/django-stubs/db/models/aggregates.pyi +++ b/django-stubs/db/models/aggregates.pyi @@ -1,6 +1,7 @@ -from typing import Any +from typing import Any, ClassVar from django.db.models.expressions import Func +from django.db.models.fields import IntegerField from django.db.models.functions.mixins import FixDurationInputMixin, NumericOutputFieldMixin class Aggregate(Func): @@ -10,7 +11,10 @@ class Aggregate(Func): def __init__(self, *expressions: Any, distinct: bool = ..., filter: Any | None = ..., **extra: Any) -> None: ... class Avg(FixDurationInputMixin, NumericOutputFieldMixin, Aggregate): ... -class Count(Aggregate): ... + +class Count(Aggregate): + output_field: ClassVar[IntegerField] # type: ignore[assignment] + class Max(Aggregate): ... class Min(Aggregate): ... class StdDev(NumericOutputFieldMixin, Aggregate): ... diff --git a/django-stubs/db/models/expressions.pyi b/django-stubs/db/models/expressions.pyi index 71f3920fe..bcf3a3fde 100644 --- a/django-stubs/db/models/expressions.pyi +++ b/django-stubs/db/models/expressions.pyi @@ -4,7 +4,7 @@ from decimal import Decimal from typing import Any, ClassVar, Generic, Literal, TypeVar from django.db.backends.base.base import BaseDatabaseWrapper -from django.db.models import Q +from django.db.models import Q, fields from django.db.models.fields import Field from django.db.models.lookups import Lookup, Transform from django.db.models.query import QuerySet @@ -124,6 +124,7 @@ class DurationExpression(CombinedExpression): def compile(self, side: Combinable, compiler: SQLCompiler, connection: BaseDatabaseWrapper) -> _AsSqlType: ... class TemporalSubtraction(CombinedExpression): + output_field: ClassVar[fields.DurationField] # type: ignore[assignment] def __init__(self, lhs: Combinable, rhs: Combinable) -> None: ... class F(_Deconstructible, Combinable): @@ -241,6 +242,7 @@ class Subquery(BaseExpression, Combinable): def __init__(self, queryset: Query | QuerySet, output_field: Field | None = ..., **extra: Any) -> None: ... class Exists(Subquery): + output_field: ClassVar[fields.BooleanField] # type: ignore[assignment] def __init__(self, queryset: Query | QuerySet, **kwargs: Any) -> None: ... class OrderBy(Expression): diff --git a/django-stubs/db/models/fields/json.pyi b/django-stubs/db/models/fields/json.pyi index 4ab220f11..f9ddc2b38 100644 --- a/django-stubs/db/models/fields/json.pyi +++ b/django-stubs/db/models/fields/json.pyi @@ -1,9 +1,10 @@ import json from collections.abc import Callable -from typing import Any +from typing import Any, ClassVar from django.db.backends.base.base import BaseDatabaseWrapper from django.db.models import lookups +from django.db.models.fields import TextField from django.db.models.lookups import PostgresOperatorLookup, Transform from django.db.models.sql.compiler import SQLCompiler from django.utils.functional import _StrOrPromise @@ -57,6 +58,7 @@ class KeyTransform(Transform): class KeyTextTransform(KeyTransform): postgres_operator: str postgres_nested_operator: str + output_field: ClassVar[TextField] # type: ignore[assignment] @classmethod def from_lookup(cls, lookup: str) -> Self: ... diff --git a/django-stubs/db/models/functions/comparison.pyi b/django-stubs/db/models/functions/comparison.pyi index 4d79528a3..e3aceaf24 100644 --- a/django-stubs/db/models/functions/comparison.pyi +++ b/django-stubs/db/models/functions/comparison.pyi @@ -1,4 +1,4 @@ -from typing import Any +from typing import Any, ClassVar from django.db.models import Func from django.db.models.fields import Field @@ -16,7 +16,7 @@ class Greatest(Func): ... class JSONObject(Func): def __init__(self, **fields: Any) -> None: ... - output_field: JSONField # type: ignore[assignment] + output_field: ClassVar[JSONField] # type: ignore[assignment] class Least(Func): ... class NullIf(Func): ... diff --git a/django-stubs/db/models/functions/datetime.pyi b/django-stubs/db/models/functions/datetime.pyi index 084f6a44e..0f389d2a6 100644 --- a/django-stubs/db/models/functions/datetime.pyi +++ b/django-stubs/db/models/functions/datetime.pyi @@ -1,4 +1,4 @@ -from typing import Any +from typing import Any, ClassVar from django.db import models from django.db.models import Func, Transform @@ -9,7 +9,7 @@ class TimezoneMixin: class Extract(TimezoneMixin, Transform): lookup_name: str - output_field: models.IntegerField # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] # type: ignore[assignment] def __init__( self, expression: Any, lookup_name: str | None = ..., tzinfo: Any | None = ..., **extra: Any ) -> None: ... @@ -27,7 +27,7 @@ class ExtractMinute(Extract): ... class ExtractSecond(Extract): ... class Now(Func): - output_field: models.DateTimeField # type: ignore[assignment] + output_field: ClassVar[models.DateTimeField] # type: ignore[assignment] class TruncBase(TimezoneMixin, Transform): kind: str @@ -41,10 +41,10 @@ class TruncWeek(TruncBase): ... class TruncDay(TruncBase): ... class TruncDate(TruncBase): - output_field: models.DateField # type: ignore[assignment] + output_field: ClassVar[models.DateField] # type: ignore[assignment] class TruncTime(TruncBase): - output_field: models.TimeField # type: ignore[assignment] + output_field: ClassVar[models.TimeField] # type: ignore[assignment] class TruncHour(TruncBase): ... class TruncMinute(TruncBase): ... diff --git a/django-stubs/db/models/functions/text.pyi b/django-stubs/db/models/functions/text.pyi index 9a99f8f0c..1fae48cc6 100644 --- a/django-stubs/db/models/functions/text.pyi +++ b/django-stubs/db/models/functions/text.pyi @@ -1,4 +1,4 @@ -from typing import Any +from typing import Any, ClassVar from django.db import models from django.db.backends.base.base import BaseDatabaseWrapper @@ -31,20 +31,20 @@ class Concat(Func): def __init__(self, *expressions: Any, **extra: Any) -> None: ... class Left(Func): - output_field: models.CharField # type: ignore[assignment] + output_field: ClassVar[models.CharField] # type: ignore[assignment] def __init__(self, expression: Expression | str, length: Expression | int, **extra: Any) -> None: ... def get_substr(self) -> Substr: ... def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class Length(Transform): - output_field: models.IntegerField # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] # type: ignore[assignment] def as_mysql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class Lower(Transform): ... class LPad(Func): - output_field: models.CharField # type: ignore[assignment] + output_field: ClassVar[models.CharField] # type: ignore[assignment] def __init__( self, expression: Expression | str, length: Expression | int | None, fill_text: Expression = ..., **extra: Any ) -> None: ... @@ -52,12 +52,12 @@ class LPad(Func): class LTrim(Transform): ... class Ord(Transform): - output_field: models.IntegerField # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] # type: ignore[assignment] def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... def as_mysql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class Repeat(Func): - output_field: models.CharField # type: ignore[assignment] + output_field: ClassVar[models.CharField] # type: ignore[assignment] def __init__(self, expression: Expression | str, number: Expression | int | None, **extra: Any) -> None: ... def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... @@ -82,13 +82,13 @@ class SHA384(MySQLSHA2Mixin, OracleHashMixin, PostgreSQLSHAMixin, Transform): .. class SHA512(MySQLSHA2Mixin, OracleHashMixin, PostgreSQLSHAMixin, Transform): ... class StrIndex(Func): - output_field: models.IntegerField # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] # type: ignore[assignment] def as_postgresql( self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any ) -> _AsSqlType: ... class Substr(Func): - output_field: models.CharField # type: ignore[assignment] + output_field: ClassVar[models.CharField] # type: ignore[assignment] def __init__( self, expression: Expression | str, pos: Expression | int, length: Expression | int | None = ..., **extra: Any ) -> None: ... diff --git a/django-stubs/db/models/functions/window.pyi b/django-stubs/db/models/functions/window.pyi index 836c09819..20a7a884d 100644 --- a/django-stubs/db/models/functions/window.pyi +++ b/django-stubs/db/models/functions/window.pyi @@ -1,13 +1,13 @@ -from typing import Any +from typing import Any, ClassVar from django.db import models from django.db.models.expressions import Func class CumeDist(Func): - output_field: models.FloatField # type: ignore[assignment] + output_field: ClassVar[models.FloatField] # type: ignore[assignment] class DenseRank(Func): - output_field: models.IntegerField # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] # type: ignore[assignment] class FirstValue(Func): ... @@ -23,13 +23,13 @@ class NthValue(Func): class Ntile(Func): def __init__(self, num_buckets: int = ..., **extra: Any) -> None: ... - output_field: models.IntegerField # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] # type: ignore[assignment] class PercentRank(Func): - output_field: models.FloatField # type: ignore[assignment] + output_field: ClassVar[models.FloatField] # type: ignore[assignment] class Rank(Func): - output_field: models.IntegerField # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] # type: ignore[assignment] class RowNumber(Func): - output_field: models.IntegerField # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] # type: ignore[assignment] From 875b5af831c60be488217bf520423caef8f4e034 Mon Sep 17 00:00:00 2001 From: Thibaut Decombe Date: Fri, 13 Oct 2023 14:00:56 +0200 Subject: [PATCH 5/8] Finish `output_field` cleanup --- django-stubs/db/models/lookups.pyi | 3 +++ django-stubs/db/models/sql/where.pyi | 3 +++ scripts/stubtest/allowlist_todo.txt | 4 ---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/django-stubs/db/models/lookups.pyi b/django-stubs/db/models/lookups.pyi index 10f8c5e7e..56a1f0f97 100644 --- a/django-stubs/db/models/lookups.pyi +++ b/django-stubs/db/models/lookups.pyi @@ -1,6 +1,7 @@ from collections.abc import Iterable, Mapping from typing import Any, Generic, Literal, TypeVar +from db.models import BooleanField from django.db.backends.base.base import BaseDatabaseWrapper from django.db.models.expressions import Expression, Func from django.db.models.query_utils import RegisterLookupMixin @@ -38,6 +39,8 @@ class Lookup(Generic[_T]): def as_sql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper) -> _AsSqlType: ... def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper) -> _AsSqlType: ... @cached_property + def output_field(self) -> BooleanField: ... + @cached_property def contains_aggregate(self) -> bool: ... @cached_property def contains_over_clause(self) -> bool: ... diff --git a/django-stubs/db/models/sql/where.pyi b/django-stubs/db/models/sql/where.pyi index 32d00bba9..537133974 100644 --- a/django-stubs/db/models/sql/where.pyi +++ b/django-stubs/db/models/sql/where.pyi @@ -1,6 +1,7 @@ from collections.abc import Sequence from typing import Any +from db.models import BooleanField from django.db.backends.base.base import BaseDatabaseWrapper from django.db.models.expressions import Expression from django.db.models.sql.compiler import SQLCompiler, _AsSqlType @@ -25,6 +26,8 @@ class WhereNode(tree.Node): def relabeled_clone(self, change_map: dict[str | None, str]) -> WhereNode: ... def resolve_expression(self, *args: Any, **kwargs: Any) -> WhereNode: ... @cached_property + def output_field(self) -> BooleanField: ... + @cached_property def contains_aggregate(self) -> bool: ... @cached_property def contains_over_clause(self) -> bool: ... diff --git a/scripts/stubtest/allowlist_todo.txt b/scripts/stubtest/allowlist_todo.txt index bd44a55be..79f4e005f 100644 --- a/scripts/stubtest/allowlist_todo.txt +++ b/scripts/stubtest/allowlist_todo.txt @@ -415,7 +415,6 @@ django.contrib.gis.db.models.JSONField.from_db_value django.contrib.gis.db.models.JSONField.get_transform django.contrib.gis.db.models.Lookup.get_prep_lhs django.contrib.gis.db.models.Lookup.lookup_name -django.contrib.gis.db.models.Lookup.output_field django.contrib.gis.db.models.Lookup.relabeled_clone django.contrib.gis.db.models.Lookup.resolve_expression django.contrib.gis.db.models.Lookup.select_format @@ -1068,7 +1067,6 @@ django.db.models.JSONField.from_db_value django.db.models.JSONField.get_transform django.db.models.Lookup.get_prep_lhs django.db.models.Lookup.lookup_name -django.db.models.Lookup.output_field django.db.models.Lookup.relabeled_clone django.db.models.Lookup.resolve_expression django.db.models.Lookup.select_format @@ -1438,7 +1436,6 @@ django.db.models.lookups.FieldGetDbPrepValueIterableMixin.process_rhs django.db.models.lookups.IExact.process_rhs django.db.models.lookups.Lookup.get_prep_lhs django.db.models.lookups.Lookup.lookup_name -django.db.models.lookups.Lookup.output_field django.db.models.lookups.Lookup.relabeled_clone django.db.models.lookups.Lookup.resolve_expression django.db.models.lookups.Lookup.select_format @@ -1622,7 +1619,6 @@ django.db.models.sql.where.WhereNode.get_lookup django.db.models.sql.where.WhereNode.get_refs django.db.models.sql.where.WhereNode.get_source_expressions django.db.models.sql.where.WhereNode.leaves -django.db.models.sql.where.WhereNode.output_field django.db.models.sql.where.WhereNode.replace_expressions django.db.models.sql.where.WhereNode.select_format django.db.models.sql.where.WhereNode.set_source_expressions From 942ce32497450c5a051aa3c58e6c1b6e73ef1031 Mon Sep 17 00:00:00 2001 From: Thibaut Decombe Date: Fri, 13 Oct 2023 20:19:23 +0200 Subject: [PATCH 6/8] Fix imports of `@cached_property` --- django-stubs/contrib/gis/db/models/functions.pyi | 8 ++++---- django-stubs/db/models/lookups.pyi | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/django-stubs/contrib/gis/db/models/functions.pyi b/django-stubs/contrib/gis/db/models/functions.pyi index 4aa87c311..ffc35484b 100644 --- a/django-stubs/contrib/gis/db/models/functions.pyi +++ b/django-stubs/contrib/gis/db/models/functions.pyi @@ -6,7 +6,7 @@ from django.db.backends.base.base import BaseDatabaseWrapper from django.db.models import BinaryField, BooleanField, FloatField, Func, IntegerField, TextField from django.db.models import Transform as StandardTransform from django.db.models.sql.compiler import SQLCompiler, _AsSqlType -from utils.functional import cached_property +from django.utils.functional import cached_property NUMERIC_TYPES: Any @@ -84,7 +84,7 @@ class DistanceResultMixin: def output_field(self) -> DistanceField: ... def source_is_geography(self) -> Any: ... -class Distance(DistanceResultMixin, OracleToleranceMixin, GeoFunc): +class Distance(DistanceResultMixin, OracleToleranceMixin, GeoFunc): # type: ignore[misc] geom_param_pos: Any spheroid: Any def __init__(self, expr1: Any, expr2: Any, spheroid: Any | None = ..., **extra: Any) -> None: ... @@ -132,7 +132,7 @@ class IsValid(OracleToleranceMixin, GeoFuncMixin, StandardTransform): output_field: ClassVar[BooleanField] # type: ignore[assignment] def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... -class Length(DistanceResultMixin, OracleToleranceMixin, GeoFunc): +class Length(DistanceResultMixin, OracleToleranceMixin, GeoFunc): # type: ignore[misc] spheroid: Any def __init__(self, expr1: Any, spheroid: bool = ..., **extra: Any) -> None: ... def as_postgresql( @@ -159,7 +159,7 @@ class NumPoints(GeoFunc): output_field: ClassVar[IntegerField] # type: ignore[assignment] arity: int -class Perimeter(DistanceResultMixin, OracleToleranceMixin, GeoFunc): +class Perimeter(DistanceResultMixin, OracleToleranceMixin, GeoFunc): # type: ignore[misc] arity: int def as_postgresql( self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any diff --git a/django-stubs/db/models/lookups.pyi b/django-stubs/db/models/lookups.pyi index 56a1f0f97..1ce6dccb4 100644 --- a/django-stubs/db/models/lookups.pyi +++ b/django-stubs/db/models/lookups.pyi @@ -9,7 +9,6 @@ from django.db.models.sql.compiler import SQLCompiler, _AsSqlType, _ParamT from django.utils.datastructures import OrderedSet from django.utils.functional import cached_property from typing_extensions import Self -from utils.functional import cached_property _T = TypeVar("_T") From 58aa39c0f90978ded150638c18f9b690f0801493 Mon Sep 17 00:00:00 2001 From: Thibaut Decombe Date: Wed, 25 Oct 2023 14:01:14 +0200 Subject: [PATCH 7/8] Update allowlist and remove unused ignore --- .../contrib/gis/db/models/functions.pyi | 40 +++++++++---------- .../contrib/postgres/aggregates/general.pyi | 10 ++--- .../postgres/aggregates/statistics.pyi | 2 +- .../contrib/postgres/fields/hstore.pyi | 6 +-- .../contrib/postgres/fields/ranges.pyi | 14 +++---- django-stubs/contrib/postgres/functions.pyi | 4 +- django-stubs/contrib/postgres/search.pyi | 12 +++--- django-stubs/db/models/aggregates.pyi | 2 +- django-stubs/db/models/expressions.pyi | 4 +- django-stubs/db/models/fields/json.pyi | 2 +- .../db/models/functions/comparison.pyi | 2 +- django-stubs/db/models/functions/datetime.pyi | 8 ++-- django-stubs/db/models/functions/text.pyi | 14 +++---- django-stubs/db/models/functions/window.pyi | 12 +++--- django-stubs/db/models/sql/query.pyi | 2 +- scripts/stubtest/allowlist.txt | 3 ++ 16 files changed, 70 insertions(+), 67 deletions(-) diff --git a/django-stubs/contrib/gis/db/models/functions.pyi b/django-stubs/contrib/gis/db/models/functions.pyi index ffc35484b..38b592798 100644 --- a/django-stubs/contrib/gis/db/models/functions.pyi +++ b/django-stubs/contrib/gis/db/models/functions.pyi @@ -35,12 +35,12 @@ class Area(OracleToleranceMixin, GeoFunc): def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class Azimuth(GeoFunc): - output_field: ClassVar[FloatField] # type: ignore[assignment] + output_field: ClassVar[FloatField] arity: int geom_param_pos: Any class AsGeoJSON(GeoFunc): - output_field: ClassVar[TextField] # type: ignore[assignment] + output_field: ClassVar[TextField] def __init__( self, expression: Any, bbox: bool = ..., crs: bool = ..., precision: int = ..., **extra: Any ) -> None: ... @@ -48,24 +48,24 @@ class AsGeoJSON(GeoFunc): class AsGML(GeoFunc): geom_param_pos: Any - output_field: ClassVar[TextField] # type: ignore[assignment] + output_field: ClassVar[TextField] def __init__(self, expression: Any, version: int = ..., precision: int = ..., **extra: Any) -> None: ... def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class AsKML(GeoFunc): - output_field: ClassVar[TextField] # type: ignore[assignment] + output_field: ClassVar[TextField] def __init__(self, expression: Any, precision: int = ..., **extra: Any) -> None: ... class AsSVG(GeoFunc): - output_field: ClassVar[TextField] # type: ignore[assignment] + output_field: ClassVar[TextField] def __init__(self, expression: Any, relative: bool = ..., precision: int = ..., **extra: Any) -> None: ... class AsWKB(GeoFunc): - output_field: ClassVar[BinaryField] # type: ignore[assignment] + output_field: ClassVar[BinaryField] arity: int class AsWKT(GeoFunc): - output_field: ClassVar[TextField] # type: ignore[assignment] + output_field: ClassVar[TextField] arity: int class BoundingCircle(OracleToleranceMixin, GeomOutputGeoFunc): @@ -84,7 +84,7 @@ class DistanceResultMixin: def output_field(self) -> DistanceField: ... def source_is_geography(self) -> Any: ... -class Distance(DistanceResultMixin, OracleToleranceMixin, GeoFunc): # type: ignore[misc] +class Distance(DistanceResultMixin, OracleToleranceMixin, GeoFunc): geom_param_pos: Any spheroid: Any def __init__(self, expr1: Any, expr2: Any, spheroid: Any | None = ..., **extra: Any) -> None: ... @@ -100,20 +100,20 @@ class ForcePolygonCW(GeomOutputGeoFunc): arity: int class FromWKB(GeoFunc): - output_field: ClassVar[GeometryField] # type: ignore[assignment] + output_field: ClassVar[GeometryField] arity: int class FromWKT(GeoFunc): - output_field: ClassVar[GeometryField] # type: ignore[assignment] + output_field: ClassVar[GeometryField] arity: int class GeoHash(GeoFunc): - output_field: ClassVar[TextField] # type: ignore[assignment] + output_field: ClassVar[TextField] def __init__(self, expression: Any, precision: Any | None = ..., **extra: Any) -> None: ... def as_mysql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class GeometryDistance(GeoFunc): - output_field: ClassVar[FloatField] # type: ignore[assignment] + output_field: ClassVar[FloatField] arity: int function: str arg_joiner: str @@ -125,14 +125,14 @@ class Intersection(OracleToleranceMixin, GeomOutputGeoFunc): class IsEmpty(GeoFuncMixin, StandardTransform): lookup_name: str - output_field: ClassVar[BooleanField] # type: ignore[assignment] + output_field: ClassVar[BooleanField] class IsValid(OracleToleranceMixin, GeoFuncMixin, StandardTransform): lookup_name: str - output_field: ClassVar[BooleanField] # type: ignore[assignment] + output_field: ClassVar[BooleanField] def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... -class Length(DistanceResultMixin, OracleToleranceMixin, GeoFunc): # type: ignore[misc] +class Length(DistanceResultMixin, OracleToleranceMixin, GeoFunc): spheroid: Any def __init__(self, expr1: Any, spheroid: bool = ..., **extra: Any) -> None: ... def as_postgresql( @@ -141,25 +141,25 @@ class Length(DistanceResultMixin, OracleToleranceMixin, GeoFunc): # type: ignor def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class LineLocatePoint(GeoFunc): - output_field: ClassVar[FloatField] # type: ignore[assignment] + output_field: ClassVar[FloatField] arity: int geom_param_pos: Any class MakeValid(GeomOutputGeoFunc): ... class MemSize(GeoFunc): - output_field: ClassVar[IntegerField] # type: ignore[assignment] + output_field: ClassVar[IntegerField] arity: int class NumGeometries(GeoFunc): - output_field: ClassVar[IntegerField] # type: ignore[assignment] + output_field: ClassVar[IntegerField] arity: int class NumPoints(GeoFunc): - output_field: ClassVar[IntegerField] # type: ignore[assignment] + output_field: ClassVar[IntegerField] arity: int -class Perimeter(DistanceResultMixin, OracleToleranceMixin, GeoFunc): # type: ignore[misc] +class Perimeter(DistanceResultMixin, OracleToleranceMixin, GeoFunc): arity: int def as_postgresql( self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any diff --git a/django-stubs/contrib/postgres/aggregates/general.pyi b/django-stubs/contrib/postgres/aggregates/general.pyi index cb79097dd..f42e82b8c 100644 --- a/django-stubs/contrib/postgres/aggregates/general.pyi +++ b/django-stubs/contrib/postgres/aggregates/general.pyi @@ -7,19 +7,19 @@ from .mixins import OrderableAggMixin class ArrayAgg(OrderableAggMixin, Aggregate): @property - def output_field(self) -> ArrayField: ... # type: ignore[override] + def output_field(self) -> ArrayField: ... class BitAnd(Aggregate): ... class BitOr(Aggregate): ... class BoolAnd(Aggregate): - output_field: ClassVar[BooleanField] # type: ignore[assignment] + output_field: ClassVar[BooleanField] class BoolOr(Aggregate): - output_field: ClassVar[BooleanField] # type: ignore[assignment] + output_field: ClassVar[BooleanField] class JSONBAgg(OrderableAggMixin, Aggregate): - output_field: ClassVar[JSONField] # type: ignore[assignment] + output_field: ClassVar[JSONField] class StringAgg(OrderableAggMixin, Aggregate): - output_field: ClassVar[TextField] # type: ignore[assignment] + output_field: ClassVar[TextField] diff --git a/django-stubs/contrib/postgres/aggregates/statistics.pyi b/django-stubs/contrib/postgres/aggregates/statistics.pyi index 509484e48..986736af9 100644 --- a/django-stubs/contrib/postgres/aggregates/statistics.pyi +++ b/django-stubs/contrib/postgres/aggregates/statistics.pyi @@ -3,7 +3,7 @@ from typing import ClassVar from django.db.models import Aggregate, FloatField, IntegerField class StatAggregate(Aggregate): - output_field: ClassVar[FloatField] # type: ignore[assignment] + output_field: ClassVar[FloatField] class Corr(StatAggregate): ... class CovarPop(StatAggregate): ... diff --git a/django-stubs/contrib/postgres/fields/hstore.pyi b/django-stubs/contrib/postgres/fields/hstore.pyi index 97967b866..179722afa 100644 --- a/django-stubs/contrib/postgres/fields/hstore.pyi +++ b/django-stubs/contrib/postgres/fields/hstore.pyi @@ -8,7 +8,7 @@ class HStoreField(CheckFieldDefaultMixin, Field): def get_transform(self, name: str) -> Any: ... class KeyTransform(Transform): - output_field: ClassVar[TextField] # type: ignore[assignment] + output_field: ClassVar[TextField] def __init__(self, key_name: str, *args: Any, **kwargs: Any) -> None: ... @@ -17,7 +17,7 @@ class KeyTransformFactory: def __call__(self, *args: Any, **kwargs: Any) -> KeyTransform: ... class KeysTransform(Transform): - output_field: ClassVar[ArrayField] # type: ignore[assignment] + output_field: ClassVar[ArrayField] class ValuesTransform(Transform): - output_field: ClassVar[ArrayField] # type: ignore[assignment] + output_field: ClassVar[ArrayField] diff --git a/django-stubs/contrib/postgres/fields/ranges.pyi b/django-stubs/contrib/postgres/fields/ranges.pyi index b9bd7056e..006695691 100644 --- a/django-stubs/contrib/postgres/fields/ranges.pyi +++ b/django-stubs/contrib/postgres/fields/ranges.pyi @@ -56,23 +56,23 @@ class AdjacentToLookup(PostgresOperatorLookup): ... class RangeStartsWith(models.Transform): @property - def output_field(self) -> models.Field: ... # type: ignore[override] + def output_field(self) -> models.Field: ... class RangeEndsWith(models.Transform): @property - def output_field(self) -> models.Field: ... # type: ignore[override] + def output_field(self) -> models.Field: ... class IsEmpty(models.Transform): - output_field: ClassVar[models.BooleanField] # type: ignore[assignment] + output_field: ClassVar[models.BooleanField] class LowerInclusive(models.Transform): - output_field: ClassVar[models.BooleanField] # type: ignore[assignment] + output_field: ClassVar[models.BooleanField] class LowerInfinite(models.Transform): - output_field: ClassVar[models.BooleanField] # type: ignore[assignment] + output_field: ClassVar[models.BooleanField] class UpperInclusive(models.Transform): - output_field: ClassVar[models.BooleanField] # type: ignore[assignment] + output_field: ClassVar[models.BooleanField] class UpperInfinite(models.Transform): - output_field: ClassVar[models.BooleanField] # type: ignore[assignment] + output_field: ClassVar[models.BooleanField] diff --git a/django-stubs/contrib/postgres/functions.pyi b/django-stubs/contrib/postgres/functions.pyi index 566e960ec..2d957735d 100644 --- a/django-stubs/contrib/postgres/functions.pyi +++ b/django-stubs/contrib/postgres/functions.pyi @@ -3,7 +3,7 @@ from typing import ClassVar from django.db.models import DateTimeField, Func, UUIDField class RandomUUID(Func): - output_field: ClassVar[UUIDField] # type: ignore[assignment] + output_field: ClassVar[UUIDField] class TransactionNow(Func): - output_field: ClassVar[DateTimeField] # type: ignore[assignment] + output_field: ClassVar[DateTimeField] diff --git a/django-stubs/contrib/postgres/search.pyi b/django-stubs/contrib/postgres/search.pyi index acc93ad03..1687a8a09 100644 --- a/django-stubs/contrib/postgres/search.pyi +++ b/django-stubs/contrib/postgres/search.pyi @@ -24,7 +24,7 @@ class SearchVector(SearchVectorCombinable, Func): config: _Expression | None function: str arg_joiner: str - output_field: ClassVar[SearchVectorField] # type: ignore[assignment] + output_field: ClassVar[SearchVectorField] def __init__( self, *expressions: _Expression, config: _Expression | None = ..., weight: Any | None = ... ) -> None: ... @@ -48,7 +48,7 @@ class SearchQueryCombinable: def __rand__(self, other: SearchQueryCombinable) -> Self: ... class SearchQuery(SearchQueryCombinable, Func): # type: ignore[misc] - output_field: ClassVar[SearchQueryField] # type: ignore[assignment] + output_field: ClassVar[SearchQueryField] SEARCH_TYPES: dict[str, str] def __init__( self, @@ -72,7 +72,7 @@ class CombinedSearchQuery(SearchQueryCombinable, CombinedExpression): # type: i ) -> None: ... class SearchRank(Func): - output_field: ClassVar[FloatField] # type: ignore[assignment] + output_field: ClassVar[FloatField] def __init__( self, vector: SearchVector | _Expression, @@ -85,7 +85,7 @@ class SearchRank(Func): class SearchHeadline(Func): function: str template: str - output_field: ClassVar[TextField] # type: ignore[assignment] + output_field: ClassVar[TextField] def __init__( self, expression: _Expression, @@ -103,11 +103,11 @@ class SearchHeadline(Func): ) -> None: ... class TrigramBase(Func): - output_field: ClassVar[FloatField] # type: ignore[assignment] + output_field: ClassVar[FloatField] def __init__(self, expression: _Expression, string: str, **extra: Any) -> None: ... class TrigramWordBase(Func): - output_field: ClassVar[FloatField] # type: ignore[assignment] + output_field: ClassVar[FloatField] def __init__(self, string: str, expression: _Expression, **extra: Any) -> None: ... class TrigramSimilarity(TrigramBase): ... diff --git a/django-stubs/db/models/aggregates.pyi b/django-stubs/db/models/aggregates.pyi index f1e0ca6d3..2e00bca4a 100644 --- a/django-stubs/db/models/aggregates.pyi +++ b/django-stubs/db/models/aggregates.pyi @@ -13,7 +13,7 @@ class Aggregate(Func): class Avg(FixDurationInputMixin, NumericOutputFieldMixin, Aggregate): ... class Count(Aggregate): - output_field: ClassVar[IntegerField] # type: ignore[assignment] + output_field: ClassVar[IntegerField] class Max(Aggregate): ... class Min(Aggregate): ... diff --git a/django-stubs/db/models/expressions.pyi b/django-stubs/db/models/expressions.pyi index bcf3a3fde..cbb55ab98 100644 --- a/django-stubs/db/models/expressions.pyi +++ b/django-stubs/db/models/expressions.pyi @@ -124,7 +124,7 @@ class DurationExpression(CombinedExpression): def compile(self, side: Combinable, compiler: SQLCompiler, connection: BaseDatabaseWrapper) -> _AsSqlType: ... class TemporalSubtraction(CombinedExpression): - output_field: ClassVar[fields.DurationField] # type: ignore[assignment] + output_field: ClassVar[fields.DurationField] def __init__(self, lhs: Combinable, rhs: Combinable) -> None: ... class F(_Deconstructible, Combinable): @@ -242,7 +242,7 @@ class Subquery(BaseExpression, Combinable): def __init__(self, queryset: Query | QuerySet, output_field: Field | None = ..., **extra: Any) -> None: ... class Exists(Subquery): - output_field: ClassVar[fields.BooleanField] # type: ignore[assignment] + output_field: ClassVar[fields.BooleanField] def __init__(self, queryset: Query | QuerySet, **kwargs: Any) -> None: ... class OrderBy(Expression): diff --git a/django-stubs/db/models/fields/json.pyi b/django-stubs/db/models/fields/json.pyi index f9ddc2b38..544fb03ea 100644 --- a/django-stubs/db/models/fields/json.pyi +++ b/django-stubs/db/models/fields/json.pyi @@ -58,7 +58,7 @@ class KeyTransform(Transform): class KeyTextTransform(KeyTransform): postgres_operator: str postgres_nested_operator: str - output_field: ClassVar[TextField] # type: ignore[assignment] + output_field: ClassVar[TextField] @classmethod def from_lookup(cls, lookup: str) -> Self: ... diff --git a/django-stubs/db/models/functions/comparison.pyi b/django-stubs/db/models/functions/comparison.pyi index e3aceaf24..50590a9dc 100644 --- a/django-stubs/db/models/functions/comparison.pyi +++ b/django-stubs/db/models/functions/comparison.pyi @@ -16,7 +16,7 @@ class Greatest(Func): ... class JSONObject(Func): def __init__(self, **fields: Any) -> None: ... - output_field: ClassVar[JSONField] # type: ignore[assignment] + output_field: ClassVar[JSONField] class Least(Func): ... class NullIf(Func): ... diff --git a/django-stubs/db/models/functions/datetime.pyi b/django-stubs/db/models/functions/datetime.pyi index 0f389d2a6..b2469e33e 100644 --- a/django-stubs/db/models/functions/datetime.pyi +++ b/django-stubs/db/models/functions/datetime.pyi @@ -9,7 +9,7 @@ class TimezoneMixin: class Extract(TimezoneMixin, Transform): lookup_name: str - output_field: ClassVar[models.IntegerField] # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] def __init__( self, expression: Any, lookup_name: str | None = ..., tzinfo: Any | None = ..., **extra: Any ) -> None: ... @@ -27,7 +27,7 @@ class ExtractMinute(Extract): ... class ExtractSecond(Extract): ... class Now(Func): - output_field: ClassVar[models.DateTimeField] # type: ignore[assignment] + output_field: ClassVar[models.DateTimeField] class TruncBase(TimezoneMixin, Transform): kind: str @@ -41,10 +41,10 @@ class TruncWeek(TruncBase): ... class TruncDay(TruncBase): ... class TruncDate(TruncBase): - output_field: ClassVar[models.DateField] # type: ignore[assignment] + output_field: ClassVar[models.DateField] class TruncTime(TruncBase): - output_field: ClassVar[models.TimeField] # type: ignore[assignment] + output_field: ClassVar[models.TimeField] class TruncHour(TruncBase): ... class TruncMinute(TruncBase): ... diff --git a/django-stubs/db/models/functions/text.pyi b/django-stubs/db/models/functions/text.pyi index 1fae48cc6..0be24be07 100644 --- a/django-stubs/db/models/functions/text.pyi +++ b/django-stubs/db/models/functions/text.pyi @@ -31,20 +31,20 @@ class Concat(Func): def __init__(self, *expressions: Any, **extra: Any) -> None: ... class Left(Func): - output_field: ClassVar[models.CharField] # type: ignore[assignment] + output_field: ClassVar[models.CharField] def __init__(self, expression: Expression | str, length: Expression | int, **extra: Any) -> None: ... def get_substr(self) -> Substr: ... def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class Length(Transform): - output_field: ClassVar[models.IntegerField] # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] def as_mysql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class Lower(Transform): ... class LPad(Func): - output_field: ClassVar[models.CharField] # type: ignore[assignment] + output_field: ClassVar[models.CharField] def __init__( self, expression: Expression | str, length: Expression | int | None, fill_text: Expression = ..., **extra: Any ) -> None: ... @@ -52,12 +52,12 @@ class LPad(Func): class LTrim(Transform): ... class Ord(Transform): - output_field: ClassVar[models.IntegerField] # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... def as_mysql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class Repeat(Func): - output_field: ClassVar[models.CharField] # type: ignore[assignment] + output_field: ClassVar[models.CharField] def __init__(self, expression: Expression | str, number: Expression | int | None, **extra: Any) -> None: ... def as_oracle(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... @@ -82,13 +82,13 @@ class SHA384(MySQLSHA2Mixin, OracleHashMixin, PostgreSQLSHAMixin, Transform): .. class SHA512(MySQLSHA2Mixin, OracleHashMixin, PostgreSQLSHAMixin, Transform): ... class StrIndex(Func): - output_field: ClassVar[models.IntegerField] # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] def as_postgresql( self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any ) -> _AsSqlType: ... class Substr(Func): - output_field: ClassVar[models.CharField] # type: ignore[assignment] + output_field: ClassVar[models.CharField] def __init__( self, expression: Expression | str, pos: Expression | int, length: Expression | int | None = ..., **extra: Any ) -> None: ... diff --git a/django-stubs/db/models/functions/window.pyi b/django-stubs/db/models/functions/window.pyi index 20a7a884d..59152c395 100644 --- a/django-stubs/db/models/functions/window.pyi +++ b/django-stubs/db/models/functions/window.pyi @@ -4,10 +4,10 @@ from django.db import models from django.db.models.expressions import Func class CumeDist(Func): - output_field: ClassVar[models.FloatField] # type: ignore[assignment] + output_field: ClassVar[models.FloatField] class DenseRank(Func): - output_field: ClassVar[models.IntegerField] # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] class FirstValue(Func): ... @@ -23,13 +23,13 @@ class NthValue(Func): class Ntile(Func): def __init__(self, num_buckets: int = ..., **extra: Any) -> None: ... - output_field: ClassVar[models.IntegerField] # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] class PercentRank(Func): - output_field: ClassVar[models.FloatField] # type: ignore[assignment] + output_field: ClassVar[models.FloatField] class Rank(Func): - output_field: ClassVar[models.IntegerField] # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] class RowNumber(Func): - output_field: ClassVar[models.IntegerField] # type: ignore[assignment] + output_field: ClassVar[models.IntegerField] diff --git a/django-stubs/db/models/sql/query.pyi b/django-stubs/db/models/sql/query.pyi index 0c42d9a4f..0b6418c4f 100644 --- a/django-stubs/db/models/sql/query.pyi +++ b/django-stubs/db/models/sql/query.pyi @@ -83,7 +83,7 @@ class Query(BaseExpression): annotations: dict[str, Expression] def __init__(self, model: type[Model] | None, where: type[WhereNode] = ..., alias_cols: bool = ...) -> None: ... @property - def output_field(self) -> Field: ... # type: ignore[override] + def output_field(self) -> Field: ... @property def has_select_fields(self) -> bool: ... @cached_property diff --git a/scripts/stubtest/allowlist.txt b/scripts/stubtest/allowlist.txt index b6373fdd7..74c035e3a 100644 --- a/scripts/stubtest/allowlist.txt +++ b/scripts/stubtest/allowlist.txt @@ -390,3 +390,6 @@ django.urls.resolvers.URLPattern.lookup_str django.urls.resolvers.URLResolver.url_patterns django.urls.resolvers.URLResolver.urlconf_module django.utils.connection.BaseConnectionHandler.settings +django.contrib.gis.db.models.aggregates.GeoAggregate.output_field +django.contrib.gis.db.models.functions.DistanceResultMixin.output_field +django.db.models.expressions.BaseExpression.output_field From c24b7bee6c1715618f7872a3436038a1a8c34aa3 Mon Sep 17 00:00:00 2001 From: Thibaut Decombe Date: Fri, 10 Nov 2023 11:01:57 +0100 Subject: [PATCH 8/8] Fix last occurences and reorder allowlist --- .../contrib/gis/db/backends/postgis/operations.pyi | 6 ++++-- django-stubs/contrib/gis/db/models/functions.pyi | 10 +++++----- scripts/stubtest/allowlist.txt | 11 +++++++---- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/django-stubs/contrib/gis/db/backends/postgis/operations.pyi b/django-stubs/contrib/gis/db/backends/postgis/operations.pyi index adeb6ca00..eee045678 100644 --- a/django-stubs/contrib/gis/db/backends/postgis/operations.pyi +++ b/django-stubs/contrib/gis/db/backends/postgis/operations.pyi @@ -2,8 +2,10 @@ from typing import Any, Literal from django.contrib.gis.db.backends.base.operations import BaseSpatialOperations from django.contrib.gis.db.backends.utils import SpatialOperator +from django.contrib.gis.db.models.fields import GeometryField from django.db.backends.postgresql.operations import DatabaseOperations from django.db.models import Func +from django.utils.functional import cached_property BILATERAL: Literal["bilateral"] @@ -16,8 +18,8 @@ class PostGISOperator(SpatialOperator): class ST_Polygon(Func): function: str def __init__(self, expr: Any) -> None: ... - @property - def output_field(self) -> Any: ... + @cached_property + def output_field(self) -> GeometryField: ... class PostGISOperations(BaseSpatialOperations, DatabaseOperations): name: str diff --git a/django-stubs/contrib/gis/db/models/functions.pyi b/django-stubs/contrib/gis/db/models/functions.pyi index 38b592798..2a4f380ca 100644 --- a/django-stubs/contrib/gis/db/models/functions.pyi +++ b/django-stubs/contrib/gis/db/models/functions.pyi @@ -1,7 +1,7 @@ from typing import Any, ClassVar from django.contrib.gis.db.models.fields import GeometryField -from django.contrib.gis.db.models.sql.conversion import DistanceField +from django.contrib.gis.db.models.sql.conversion import AreaField, DistanceField from django.db.backends.base.base import BaseDatabaseWrapper from django.db.models import BinaryField, BooleanField, FloatField, Func, IntegerField, TextField from django.db.models import Transform as StandardTransform @@ -18,8 +18,8 @@ class GeoFuncMixin: class GeoFunc(GeoFuncMixin, Func): ... class GeomOutputGeoFunc(GeoFunc): - @property - def output_field(self) -> Any: ... + @cached_property + def output_field(self) -> GeometryField: ... class SQLiteDecimalToFloatMixin: def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... @@ -30,8 +30,8 @@ class OracleToleranceMixin: class Area(OracleToleranceMixin, GeoFunc): arity: int - @property - def output_field(self) -> Any: ... + @cached_property + def output_field(self) -> AreaField: ... def as_sqlite(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper, **extra_context: Any) -> _AsSqlType: ... class Azimuth(GeoFunc): diff --git a/scripts/stubtest/allowlist.txt b/scripts/stubtest/allowlist.txt index 74c035e3a..40376cb50 100644 --- a/scripts/stubtest/allowlist.txt +++ b/scripts/stubtest/allowlist.txt @@ -172,6 +172,7 @@ django.contrib.gis.db.backends.mysql.operations.MySQLOperations.mariadb django.contrib.gis.db.backends.mysql.operations.MySQLOperations.mysql django.contrib.gis.db.backends.mysql.operations.MySQLOperations.select django.contrib.gis.db.backends.mysql.operations.MySQLOperations.unsupported_functions +django.contrib.gis.db.backends.postgis.operations.ST_Polygon.output_field django.contrib.gis.db.backends.spatialite.features.DatabaseFeatures.supports_area_geodetic django.contrib.gis.db.backends.spatialite.operations.SpatiaLiteOperations.unsupported_functions django.contrib.gis.db.models.DecimalField.validators @@ -191,6 +192,10 @@ django.contrib.gis.db.models.ForeignObjectRel.related_model django.contrib.gis.db.models.IntegerField.validators django.contrib.gis.db.models.Lookup.contains_aggregate django.contrib.gis.db.models.Lookup.contains_over_clause +django.contrib.gis.db.models.aggregates.GeoAggregate.output_field +django.contrib.gis.db.models.functions.Area.output_field +django.contrib.gis.db.models.functions.DistanceResultMixin.output_field +django.contrib.gis.db.models.functions.GeomOutputGeoFunc.output_field django.contrib.gis.forms.BaseForm.changed_data django.contrib.gis.forms.BaseFormSet.forms django.contrib.gis.forms.BaseFormSet.management_form @@ -305,9 +310,10 @@ django.db.models.Lookup.contains_aggregate django.db.models.Lookup.contains_over_clause django.db.models.expressions.BaseExpression.contains_aggregate django.db.models.expressions.BaseExpression.contains_column_references -django.db.models.expressions.BaseExpression.contains_subquery django.db.models.expressions.BaseExpression.contains_over_clause +django.db.models.expressions.BaseExpression.contains_subquery django.db.models.expressions.BaseExpression.convert_value +django.db.models.expressions.BaseExpression.output_field django.db.models.fields.DecimalField.validators django.db.models.fields.Field.cached_col django.db.models.fields.Field.validators @@ -390,6 +396,3 @@ django.urls.resolvers.URLPattern.lookup_str django.urls.resolvers.URLResolver.url_patterns django.urls.resolvers.URLResolver.urlconf_module django.utils.connection.BaseConnectionHandler.settings -django.contrib.gis.db.models.aggregates.GeoAggregate.output_field -django.contrib.gis.db.models.functions.DistanceResultMixin.output_field -django.db.models.expressions.BaseExpression.output_field