From d0e5df2ae7323937db69361ced9a4ba212f18ddb Mon Sep 17 00:00:00 2001 From: Petter Friberg Date: Sun, 5 Nov 2023 21:25:27 +0100 Subject: [PATCH] Simulate `@deconstructible` as a mixin class (#1818) `@desconstructible` inserts its own `__new__` method and adds a `deconstruct` method to decorated classes. We can simulate that behaviour with a class definition, which decorated classes inherits. --- django-stubs/contrib/auth/validators.pyi | 10 +---- django-stubs/contrib/gis/geos/geometry.pyi | 5 +-- django-stubs/contrib/postgres/validators.pyi | 6 +-- .../core/files/storage/filesystem.pyi | 7 +-- django-stubs/core/files/storage/memory.pyi | 7 +-- django-stubs/core/validators.pyi | 33 +++++--------- django-stubs/db/models/expressions.pyi | 13 ++---- django-stubs/utils/deconstruct.pyi | 9 +++- scripts/stubtest/allowlist_todo.txt | 45 ------------------- 9 files changed, 32 insertions(+), 103 deletions(-) diff --git a/django-stubs/contrib/auth/validators.pyi b/django-stubs/contrib/auth/validators.pyi index 783948669..bb7c913de 100644 --- a/django-stubs/contrib/auth/validators.pyi +++ b/django-stubs/contrib/auth/validators.pyi @@ -1,10 +1,4 @@ -from collections.abc import Sequence -from typing import Any - from django.core.validators import RegexValidator -class ASCIIUsernameValidator(RegexValidator): - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... - -class UnicodeUsernameValidator(RegexValidator): - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... +class ASCIIUsernameValidator(RegexValidator): ... +class UnicodeUsernameValidator(RegexValidator): ... diff --git a/django-stubs/contrib/gis/geos/geometry.pyi b/django-stubs/contrib/gis/geos/geometry.pyi index 147a17e44..8b11a3c4e 100644 --- a/django-stubs/contrib/gis/geos/geometry.pyi +++ b/django-stubs/contrib/gis/geos/geometry.pyi @@ -1,4 +1,3 @@ -from collections.abc import Sequence from typing import Any from django.contrib.gis.gdal import CoordTransform, SpatialReference @@ -8,6 +7,7 @@ from django.contrib.gis.geos.coordseq import GEOSCoordSeq from django.contrib.gis.geos.mutable_list import ListMixin from django.contrib.gis.geos.point import Point from django.contrib.gis.geos.prepared import PreparedGeometry +from django.utils.deconstruct import _Deconstructible from typing_extensions import Self class GEOSGeometryBase(GEOSBase): @@ -142,6 +142,5 @@ class LinearGeometryMixin: @property def closed(self) -> bool: ... -class GEOSGeometry(GEOSGeometryBase, ListMixin): +class GEOSGeometry(_Deconstructible, GEOSGeometryBase, ListMixin): def __init__(self, geo_input: Any, srid: int | None = ...) -> None: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... diff --git a/django-stubs/contrib/postgres/validators.pyi b/django-stubs/contrib/postgres/validators.pyi index a764d3a24..2c95a9096 100644 --- a/django-stubs/contrib/postgres/validators.pyi +++ b/django-stubs/contrib/postgres/validators.pyi @@ -1,17 +1,17 @@ -from collections.abc import Iterable, Mapping, Sequence +from collections.abc import Iterable, Mapping from typing import Any from django.core.validators import MaxLengthValidator, MaxValueValidator, MinLengthValidator, MinValueValidator +from django.utils.deconstruct import _Deconstructible class ArrayMaxLengthValidator(MaxLengthValidator): ... class ArrayMinLengthValidator(MinLengthValidator): ... -class KeysValidator: +class KeysValidator(_Deconstructible): messages: dict[str, str] strict: bool def __init__(self, keys: Iterable[str], strict: bool = ..., messages: Mapping[str, str] | None = ...) -> None: ... def __call__(self, value: Any) -> None: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... # fake class RangeMaxValueValidator(MaxValueValidator): ... class RangeMinValueValidator(MinValueValidator): ... diff --git a/django-stubs/core/files/storage/filesystem.pyi b/django-stubs/core/files/storage/filesystem.pyi index b8f0e7b2c..e9d0c132c 100644 --- a/django-stubs/core/files/storage/filesystem.pyi +++ b/django-stubs/core/files/storage/filesystem.pyi @@ -1,13 +1,11 @@ -from collections.abc import Sequence -from typing import Any - from django.utils._os import _PathCompatible +from django.utils.deconstruct import _Deconstructible from django.utils.functional import cached_property from .base import Storage from .mixins import StorageSettingsMixin -class FileSystemStorage(Storage, StorageSettingsMixin): +class FileSystemStorage(_Deconstructible, Storage, StorageSettingsMixin): OS_OPEN_FLAGS: int def __init__( @@ -27,4 +25,3 @@ class FileSystemStorage(Storage, StorageSettingsMixin): def file_permissions_mode(self) -> int | None: ... @cached_property def directory_permissions_mode(self) -> int | None: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... # fake diff --git a/django-stubs/core/files/storage/memory.pyi b/django-stubs/core/files/storage/memory.pyi index 039268fda..32ab895d7 100644 --- a/django-stubs/core/files/storage/memory.pyi +++ b/django-stubs/core/files/storage/memory.pyi @@ -1,13 +1,11 @@ -from collections.abc import Sequence -from typing import Any - from django.utils._os import _PathCompatible +from django.utils.deconstruct import _Deconstructible from django.utils.functional import cached_property from .base import Storage from .mixins import StorageSettingsMixin -class InMemoryStorage(Storage, StorageSettingsMixin): +class InMemoryStorage(_Deconstructible, Storage, StorageSettingsMixin): def __init__( self, location: _PathCompatible | None = ..., @@ -25,4 +23,3 @@ class InMemoryStorage(Storage, StorageSettingsMixin): def file_permissions_mode(self) -> int | None: ... @cached_property def directory_permissions_mode(self) -> int | None: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... # fake diff --git a/django-stubs/core/validators.pyi b/django-stubs/core/validators.pyi index 0bd337833..2a0665a30 100644 --- a/django-stubs/core/validators.pyi +++ b/django-stubs/core/validators.pyi @@ -4,6 +4,7 @@ from re import Pattern, RegexFlag from typing import Any from django.core.files.base import File +from django.utils.deconstruct import _Deconstructible from django.utils.functional import _StrOrPromise from typing_extensions import TypeAlias @@ -13,7 +14,7 @@ _Regex: TypeAlias = str | Pattern[str] _ValidatorCallable: TypeAlias = Callable[[Any], None] # noqa: PYI047 -class RegexValidator: +class RegexValidator(_Deconstructible): regex: _Regex # Pattern[str] on instance, but may be str on class definition message: _StrOrPromise code: str @@ -28,7 +29,6 @@ class RegexValidator: flags: RegexFlag | None = ..., ) -> None: ... def __call__(self, value: Any) -> None: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... class URLValidator(RegexValidator): ul: str @@ -43,13 +43,12 @@ class URLValidator(RegexValidator): max_length: int def __init__(self, schemes: Sequence[str] | None = ..., **kwargs: Any) -> None: ... def __call__(self, value: str) -> None: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... integer_validator: RegexValidator def validate_integer(value: float | str | None) -> None: ... -class EmailValidator: +class EmailValidator(_Deconstructible): message: _StrOrPromise code: str user_regex: Pattern[str] @@ -65,7 +64,6 @@ class EmailValidator: def __call__(self, value: str | None) -> None: ... def validate_domain_part(self, domain_part: str) -> bool: ... def __eq__(self, other: object) -> bool: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... validate_email: EmailValidator slug_re: Pattern[str] @@ -87,7 +85,7 @@ def int_list_validator( validate_comma_separated_integer_list: RegexValidator -class BaseValidator: +class BaseValidator(_Deconstructible): message: _StrOrPromise code: str limit_value: Any @@ -96,35 +94,26 @@ class BaseValidator: def compare(self, a: Any, b: Any) -> bool: ... def clean(self, x: Any) -> Any: ... def __eq__(self, other: object) -> bool: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... -class MaxValueValidator(BaseValidator): - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... - -class MinValueValidator(BaseValidator): - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... - -class StepValueValidator(BaseValidator): - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... +class MaxValueValidator(BaseValidator): ... +class MinValueValidator(BaseValidator): ... +class StepValueValidator(BaseValidator): ... class MinLengthValidator(BaseValidator): def clean(self, x: Sized) -> int: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... class MaxLengthValidator(BaseValidator): def clean(self, x: Sized) -> int: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... -class DecimalValidator: +class DecimalValidator(_Deconstructible): messages: dict[str, str] max_digits: int | None decimal_places: int | None def __init__(self, max_digits: int | None, decimal_places: int | None) -> None: ... def __call__(self, value: Decimal) -> None: ... def __eq__(self, other: object) -> bool: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... -class FileExtensionValidator: +class FileExtensionValidator(_Deconstructible): message: _StrOrPromise code: str allowed_extensions: Collection[str] | None @@ -135,14 +124,12 @@ class FileExtensionValidator: code: str | None = ..., ) -> None: ... def __call__(self, value: File) -> None: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... def get_available_image_extensions() -> Sequence[str]: ... def validate_image_file_extension(value: File) -> None: ... -class ProhibitNullCharactersValidator: +class ProhibitNullCharactersValidator(_Deconstructible): message: _StrOrPromise code: str def __init__(self, message: _StrOrPromise | None = ..., code: str | None = ...) -> None: ... def __call__(self, value: Any) -> None: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... diff --git a/django-stubs/db/models/expressions.pyi b/django-stubs/db/models/expressions.pyi index eb65ca4aa..a69e6c0c0 100644 --- a/django-stubs/db/models/expressions.pyi +++ b/django-stubs/db/models/expressions.pyi @@ -10,6 +10,7 @@ from django.db.models.lookups import Lookup, Transform from django.db.models.query import QuerySet from django.db.models.sql.compiler import SQLCompiler, _AsSqlType from django.db.models.sql.query import Query +from django.utils.deconstruct import _Deconstructible from typing_extensions import Self, TypeAlias class SQLiteNumericMixin: @@ -108,8 +109,7 @@ class BaseExpression: def flatten(self) -> Iterator[BaseExpression]: ... def as_sql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper) -> _AsSqlType: ... -class Expression(BaseExpression, Combinable): - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... +class Expression(_Deconstructible, BaseExpression, Combinable): ... class CombinedExpression(SQLiteNumericMixin, Expression): connector: str @@ -123,7 +123,7 @@ class DurationExpression(CombinedExpression): class TemporalSubtraction(CombinedExpression): def __init__(self, lhs: Combinable, rhs: Combinable) -> None: ... -class F(Combinable): +class F(_Deconstructible, Combinable): name: str def __init__(self, name: str) -> None: ... def resolve_expression( @@ -149,7 +149,6 @@ class F(Combinable): nulls_last: bool | None = ..., ) -> OrderBy: ... def copy(self) -> F: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... class ResolvedOuterRef(F): contains_aggregate: ClassVar[bool] @@ -179,12 +178,10 @@ class Func(SQLiteNumericMixin, Expression): arg_joiner: str | None = ..., **extra_context: Any, ) -> _AsSqlType: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... class Value(Expression): value: Any def __init__(self, value: Any, output_field: Field | None = ...) -> None: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... class RawSQL(Expression): params: list[Any] @@ -213,7 +210,6 @@ _E = TypeVar("_E", bound=Q | Combinable) class ExpressionWrapper(Expression, Generic[_E]): def __init__(self, expression: _E, output_field: Field) -> None: ... expression: _E - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... class NegatedExpression(ExpressionWrapper[_E]): def __init__(self, expression: _E) -> None: ... @@ -224,7 +220,6 @@ class When(Expression): condition: Any result: Any def __init__(self, condition: Any = ..., then: Any = ..., **lookups: Any) -> None: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... class Case(Expression): template: str @@ -235,7 +230,6 @@ class Case(Expression): def __init__( self, *cases: Any, default: Any | None = ..., output_field: Field | None = ..., **extra: Any ) -> None: ... - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... class Subquery(BaseExpression, Combinable): template: str @@ -261,7 +255,6 @@ class OrderBy(Expression): ) -> None: ... def asc(self) -> None: ... # type: ignore[override] def desc(self) -> None: ... # type: ignore[override] - def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... class Window(SQLiteNumericMixin, Expression): template: str diff --git a/django-stubs/utils/deconstruct.pyi b/django-stubs/utils/deconstruct.pyi index 067112efc..dd1baf0d5 100644 --- a/django-stubs/utils/deconstruct.pyi +++ b/django-stubs/utils/deconstruct.pyi @@ -1,6 +1,13 @@ -from collections.abc import Callable +from collections.abc import Callable, Sequence from typing import Any, TypeVar, overload +from typing_extensions import Self + +# Contains additions from a class being decorated with '@deconstructible' +class _Deconstructible: + def __new__(cls, *args: Any, **kwargs: Any) -> Self: ... + def deconstruct(obj) -> tuple[str, Sequence[Any], dict[str, Any]]: ... + _T = TypeVar("_T") _TCallable = TypeVar("_TCallable", bound=Callable[..., Any]) diff --git a/scripts/stubtest/allowlist_todo.txt b/scripts/stubtest/allowlist_todo.txt index 9e8f5b39f..d1423cda6 100644 --- a/scripts/stubtest/allowlist_todo.txt +++ b/scripts/stubtest/allowlist_todo.txt @@ -202,8 +202,6 @@ django.contrib.auth.password_validation.PasswordValidator django.contrib.auth.password_validation.exceeds_maximum_length_ratio django.contrib.auth.tokens.PasswordResetTokenGenerator._make_token_with_timestamp django.contrib.auth.tokens.PasswordResetTokenGenerator.algorithm -django.contrib.auth.validators.ASCIIUsernameValidator.__new__ -django.contrib.auth.validators.UnicodeUsernameValidator.__new__ django.contrib.auth.views.INTERNAL_RESET_URL_TOKEN django.contrib.auth.views.LoginView.form_class django.contrib.auth.views.LogoutView.get_next_page @@ -321,7 +319,6 @@ django.contrib.gis.db.models.BigAutoField.rel_db_type django.contrib.gis.db.models.BigIntegerField.formfield django.contrib.gis.db.models.BinaryField.get_placeholder django.contrib.gis.db.models.BooleanField.formfield -django.contrib.gis.db.models.Case.__new__ django.contrib.gis.db.models.Case.as_sql django.contrib.gis.db.models.CharField.cast_db_type django.contrib.gis.db.models.CharField.description @@ -348,12 +345,9 @@ django.contrib.gis.db.models.EmailField.formfield django.contrib.gis.db.models.Empty django.contrib.gis.db.models.Exists.empty_result_set_value django.contrib.gis.db.models.Exists.select_format -django.contrib.gis.db.models.Expression.__new__ django.contrib.gis.db.models.Expression.identity -django.contrib.gis.db.models.ExpressionWrapper.__new__ django.contrib.gis.db.models.Extent.is_extent django.contrib.gis.db.models.Extent3D.is_extent -django.contrib.gis.db.models.F.__new__ django.contrib.gis.db.models.Field.__copy__ django.contrib.gis.db.models.Field.__deepcopy__ django.contrib.gis.db.models.Field.__ge__ @@ -433,7 +427,6 @@ django.contrib.gis.db.models.ForeignObjectRel.one_to_many django.contrib.gis.db.models.ForeignObjectRel.one_to_one django.contrib.gis.db.models.ForeignObjectRel.path_infos django.contrib.gis.db.models.ForeignObjectRel.related_model -django.contrib.gis.db.models.Func.__new__ django.contrib.gis.db.models.Func.function django.contrib.gis.db.models.GenericIPAddressField.formfield django.contrib.gis.db.models.GeoAggregate @@ -482,7 +475,6 @@ django.contrib.gis.db.models.OneToOneField.formfield django.contrib.gis.db.models.OneToOneField.forward_related_accessor_class django.contrib.gis.db.models.OneToOneField.related_accessor_class django.contrib.gis.db.models.OneToOneRel.__init__ -django.contrib.gis.db.models.OrderBy.__new__ django.contrib.gis.db.models.OrderBy.as_oracle django.contrib.gis.db.models.OrderBy.as_sql django.contrib.gis.db.models.PositiveBigIntegerField.formfield @@ -530,11 +522,9 @@ django.contrib.gis.db.models.UUIDField.formfield django.contrib.gis.db.models.UniqueConstraint.__init__ django.contrib.gis.db.models.UniqueConstraint.contains_expressions django.contrib.gis.db.models.UniqueConstraint.validate -django.contrib.gis.db.models.Value.__new__ django.contrib.gis.db.models.Value.empty_result_set_value django.contrib.gis.db.models.Value.for_save django.contrib.gis.db.models.Variance.__init__ -django.contrib.gis.db.models.When.__new__ django.contrib.gis.db.models.When.as_sql django.contrib.gis.db.models.Window.as_sql django.contrib.gis.db.models.Window.as_sqlite @@ -627,9 +617,7 @@ django.contrib.gis.gdal.srs.SpatialReference.xml django.contrib.gis.geoip2.GeoIP2 django.contrib.gis.geoip2.GeoIP2Exception django.contrib.gis.geoip2.base -django.contrib.gis.geos.GEOSGeometry.__new__ django.contrib.gis.geos.Point.tuple -django.contrib.gis.geos.geometry.GEOSGeometry.__new__ django.contrib.gis.geos.geometry.GEOSGeometryBase.geojson django.contrib.gis.geos.geometry.GEOSGeometryBase.make_valid django.contrib.gis.geos.geometry.GEOSGeometryBase.normalize @@ -761,7 +749,6 @@ django.contrib.postgres.search.SearchVectorExact.as_sql django.contrib.postgres.search.SearchVectorExact.process_rhs django.contrib.postgres.search.SearchVectorField.class_lookups django.contrib.postgres.signals.get_type_oids -django.contrib.postgres.validators.KeysValidator.__new__ django.contrib.redirects.admin.RedirectAdmin django.contrib.redirects.models.Redirect.id django.contrib.redirects.models.Redirect.new_path @@ -811,10 +798,6 @@ django.core.files.base.File.__next__ django.core.files.locks.OVERLAPPED django.core.files.locks.PVOID django.core.files.locks.ULONG_PTR -django.core.files.storage.FileSystemStorage.__new__ -django.core.files.storage.InMemoryStorage.__new__ -django.core.files.storage.filesystem.FileSystemStorage.__new__ -django.core.files.storage.memory.InMemoryStorage.__new__ django.core.files.uploadedfile.InMemoryUploadedFile.__init__ django.core.files.uploadedfile.UploadedFile.size django.core.files.utils.FileProxyMixin.encoding @@ -905,18 +888,6 @@ django.core.signing.Signer.signature django.core.signing.b62_decode django.core.signing.b62_encode django.core.signing.loads -django.core.validators.BaseValidator.__new__ -django.core.validators.DecimalValidator.__new__ -django.core.validators.EmailValidator.__new__ -django.core.validators.FileExtensionValidator.__new__ -django.core.validators.MaxLengthValidator.__new__ -django.core.validators.MaxValueValidator.__new__ -django.core.validators.MinLengthValidator.__new__ -django.core.validators.MinValueValidator.__new__ -django.core.validators.ProhibitNullCharactersValidator.__new__ -django.core.validators.RegexValidator.__new__ -django.core.validators.StepValueValidator.__new__ -django.core.validators.URLValidator.__new__ django.db.backends.base.base.BaseDatabaseWrapper.timezone django.db.backends.base.base.BaseDatabaseWrapper.timezone_name django.db.backends.base.features.BaseDatabaseFeatures.supports_explaining_query_execution @@ -1065,7 +1036,6 @@ django.db.models.BigAutoField.rel_db_type django.db.models.BigIntegerField.formfield django.db.models.BinaryField.get_placeholder django.db.models.BooleanField.formfield -django.db.models.Case.__new__ django.db.models.Case.as_sql django.db.models.CharField.cast_db_type django.db.models.CharField.description @@ -1092,10 +1062,7 @@ django.db.models.EmailField.formfield django.db.models.Empty django.db.models.Exists.empty_result_set_value django.db.models.Exists.select_format -django.db.models.Expression.__new__ django.db.models.Expression.identity -django.db.models.ExpressionWrapper.__new__ -django.db.models.F.__new__ django.db.models.Field.__copy__ django.db.models.Field.__deepcopy__ django.db.models.Field.__ge__ @@ -1175,7 +1142,6 @@ django.db.models.ForeignObjectRel.one_to_many django.db.models.ForeignObjectRel.one_to_one django.db.models.ForeignObjectRel.path_infos django.db.models.ForeignObjectRel.related_model -django.db.models.Func.__new__ django.db.models.Func.function django.db.models.GenericIPAddressField.formfield django.db.models.ImageField.__get__ @@ -1222,7 +1188,6 @@ django.db.models.OneToOneField.formfield django.db.models.OneToOneField.forward_related_accessor_class django.db.models.OneToOneField.related_accessor_class django.db.models.OneToOneRel.__init__ -django.db.models.OrderBy.__new__ django.db.models.OrderBy.as_oracle django.db.models.OrderBy.as_sql django.db.models.PositiveBigIntegerField.formfield @@ -1269,11 +1234,9 @@ django.db.models.UUIDField.formfield django.db.models.UniqueConstraint.__init__ django.db.models.UniqueConstraint.contains_expressions django.db.models.UniqueConstraint.validate -django.db.models.Value.__new__ django.db.models.Value.empty_result_set_value django.db.models.Value.for_save django.db.models.Variance.__init__ -django.db.models.When.__new__ django.db.models.When.as_sql django.db.models.Window.as_sql django.db.models.Window.as_sqlite @@ -1323,19 +1286,13 @@ 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 -django.db.models.expressions.Case.__new__ django.db.models.expressions.Case.as_sql django.db.models.expressions.Col.relabeled_clone django.db.models.expressions.Exists.empty_result_set_value django.db.models.expressions.Exists.select_format -django.db.models.expressions.Expression.__new__ django.db.models.expressions.Expression.identity -django.db.models.expressions.ExpressionWrapper.__new__ -django.db.models.expressions.F.__new__ -django.db.models.expressions.Func.__new__ django.db.models.expressions.Func.function django.db.models.expressions.NegatedExpression.select_format -django.db.models.expressions.OrderBy.__new__ django.db.models.expressions.OrderBy.as_oracle django.db.models.expressions.OrderBy.as_sql django.db.models.expressions.Ref.get_refs @@ -1348,10 +1305,8 @@ django.db.models.expressions.Subquery.empty_result_set_value django.db.models.expressions.Subquery.external_aliases django.db.models.expressions.Subquery.get_external_cols django.db.models.expressions.Subquery.subquery -django.db.models.expressions.Value.__new__ django.db.models.expressions.Value.empty_result_set_value django.db.models.expressions.Value.for_save -django.db.models.expressions.When.__new__ django.db.models.expressions.When.as_sql django.db.models.expressions.Window.as_sql django.db.models.expressions.Window.as_sqlite