Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simulate @deconstructible as a mixin class #1818

Merged
merged 1 commit into from
Nov 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions django-stubs/contrib/auth/validators.pyi
Original file line number Diff line number Diff line change
@@ -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): ...
5 changes: 2 additions & 3 deletions django-stubs/contrib/gis/geos/geometry.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from collections.abc import Sequence
from typing import Any

from django.contrib.gis.gdal import CoordTransform, SpatialReference
Expand All @@ -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):
Expand Down Expand Up @@ -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]]: ...
6 changes: 3 additions & 3 deletions django-stubs/contrib/postgres/validators.pyi
Original file line number Diff line number Diff line change
@@ -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): ...
7 changes: 2 additions & 5 deletions django-stubs/core/files/storage/filesystem.pyi
Original file line number Diff line number Diff line change
@@ -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__(
Expand All @@ -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
7 changes: 2 additions & 5 deletions django-stubs/core/files/storage/memory.pyi
Original file line number Diff line number Diff line change
@@ -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 = ...,
Expand All @@ -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
33 changes: 10 additions & 23 deletions django-stubs/core/validators.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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]]: ...
13 changes: 3 additions & 10 deletions django-stubs/db/models/expressions.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand All @@ -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(
Expand All @@ -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]
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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: ...
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
9 changes: 8 additions & 1 deletion django-stubs/utils/deconstruct.pyi
Original file line number Diff line number Diff line change
@@ -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])

Expand Down
Loading