diff --git a/django-stubs/contrib/admin/forms.pyi b/django-stubs/contrib/admin/forms.pyi index f09ae0d..02de4b7 100644 --- a/django-stubs/contrib/admin/forms.pyi +++ b/django-stubs/contrib/admin/forms.pyi @@ -1,4 +1,4 @@ -from typing import Any +from typing import Any, Dict from django.contrib.auth.forms import AuthenticationForm, PasswordChangeForm from django.contrib.auth.models import User @@ -7,8 +7,8 @@ class AdminAuthenticationForm(AuthenticationForm): auto_id: str data: Dict[str, str] empty_permitted: bool - error_class: Type[django.forms.utils.ErrorList] - fields: collections.OrderedDict + error_class: type + fields: Dict[Any, Any] files: Dict[Any, Any] initial: Dict[Any, Any] is_bound: bool @@ -23,11 +23,11 @@ class AdminPasswordChangeForm(PasswordChangeForm): auto_id: str data: Dict[Any, Any] empty_permitted: bool - error_class: Type[django.forms.utils.ErrorList] - fields: collections.OrderedDict + error_class: type + fields: Dict[Any, Any] files: Dict[Any, Any] initial: Dict[Any, Any] is_bound: bool label_suffix: str - user: django.utils.functional.SimpleLazyObject + user: Any required_css_class: str = ... diff --git a/django-stubs/contrib/auth/base_user.pyi b/django-stubs/contrib/auth/base_user.pyi index e744ac7..287d93b 100644 --- a/django-stubs/contrib/auth/base_user.pyi +++ b/django-stubs/contrib/auth/base_user.pyi @@ -1,21 +1,18 @@ -from typing import Any, Optional, Tuple, Union +from typing import Any, Optional, Tuple, List from django.db import models class BaseUserManager(models.Manager): - creation_counter: int - model: None - name: None @classmethod def normalize_email(cls, email: Optional[str]) -> str: ... def make_random_password(self, length: int = ..., allowed_chars: str = ...) -> str: ... def get_by_natural_key(self, username: Optional[str]) -> AbstractBaseUser: ... class AbstractBaseUser(models.Model): - password: str = ... - last_login: None = ... + password: models.CharField = ... + last_login: Optional[models.DateTimeField] = ... is_active: bool = ... - REQUIRED_FIELDS: Any = ... + REQUIRED_FIELDS: List[str] = ... class Meta: abstract: bool = ... def get_username(self) -> str: ... @@ -34,4 +31,4 @@ class AbstractBaseUser(models.Model): @classmethod def get_email_field_name(cls) -> str: ... @classmethod - def normalize_username(cls, username: Union[int, str]) -> Union[int, str]: ... + def normalize_username(cls, username: str) -> str: ... diff --git a/django-stubs/contrib/auth/models.pyi b/django-stubs/contrib/auth/models.pyi index b9c8583..41e421a 100644 --- a/django-stubs/contrib/auth/models.pyi +++ b/django-stubs/contrib/auth/models.pyi @@ -1,10 +1,10 @@ +import datetime from typing import Any, List, Optional, Set, Tuple, Type, Union -from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager -from django.db import models +from django.contrib.auth.base_user import AbstractBaseUser as AbstractBaseUser, BaseUserManager as BaseUserManager from django.db.models.manager import EmptyManager -from .validators import UnicodeUsernameValidator +from django.db import models def update_last_login(sender: Type[AbstractBaseUser], user: AbstractBaseUser, **kwargs: Any) -> None: ... @@ -72,20 +72,16 @@ class PermissionsMixin(models.Model): class AbstractUser(AbstractBaseUser, PermissionsMixin): is_superuser: bool - last_login: None - password: str username_validator: Any = ... username: str = ... first_name: str = ... last_name: str = ... email: str = ... is_staff: bool = ... - is_active: bool = ... date_joined: datetime.datetime = ... objects: Any = ... EMAIL_FIELD: str = ... USERNAME_FIELD: str = ... - REQUIRED_FIELDS: Any = ... class Meta: verbose_name: Any = ... verbose_name_plural: Any = ... @@ -96,17 +92,6 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin): def email_user(self, subject: str, message: str, from_email: str = ..., **kwargs: Any) -> None: ... class User(AbstractUser): - date_joined: datetime.datetime - email: str - first_name: str - id: None - is_active: bool - is_staff: bool - is_superuser: bool - last_login: None - last_name: str - password: str - username: str class Meta(AbstractUser.Meta): swappable: str = ... diff --git a/django-stubs/core/exceptions.pyi b/django-stubs/core/exceptions.pyi index dab34dc..891307a 100644 --- a/django-stubs/core/exceptions.pyi +++ b/django-stubs/core/exceptions.pyi @@ -33,14 +33,7 @@ class ValidationError(Exception): params: Any = ... def __init__( self, - message: Union[ - Dict[str, List[ValidationError]], - Dict[str, ErrorList], - List[Union[ValidationError, str]], - ValidationError, - ErrorList, - str, - ], + message: Any, code: Optional[str] = ..., params: Optional[ Union[Dict[str, Union[Tuple[str], Type[Model], Model, str]], Dict[str, Union[int, str]]] diff --git a/django-stubs/core/validators.pyi b/django-stubs/core/validators.pyi index 9f55869..078faeb 100644 --- a/django-stubs/core/validators.pyi +++ b/django-stubs/core/validators.pyi @@ -9,24 +9,25 @@ from django.utils.functional import SimpleLazyObject EMPTY_VALUES: Any -def _lazy_re_compile(regex: Union[str, Pattern], flags: int = ...): ... +_Regex = Union[str, Pattern[str]] + +def _lazy_re_compile(regex: _Regex, flags: int = ...): ... class RegexValidator: - regex: SimpleLazyObject = ... + regex: _Regex = ... message: Any = ... code: str = ... inverse_match: bool = ... flags: int = ... def __init__( self, - regex: Optional[str] = ..., + regex: Optional[_Regex] = ..., message: Optional[str] = ..., code: Optional[str] = ..., inverse_match: Optional[bool] = ..., flags: Optional[RegexFlag] = ..., ) -> None: ... def __call__(self, value: Optional[Union[float, str]]) -> None: ... - def __eq__(self, other: Union[ProhibitNullCharactersValidator, RegexValidator]) -> bool: ... class URLValidator(RegexValidator): ul: str = ... @@ -36,8 +37,6 @@ class URLValidator(RegexValidator): domain_re: Any = ... tld_re: Any = ... host_re: Any = ... - regex: SimpleLazyObject = ... - message: Any = ... schemes: Any = ... def __init__(self, schemes: Optional[List[str]] = ..., **kwargs: Any) -> None: ... def __call__(self, value: str) -> None: ... @@ -58,7 +57,6 @@ class EmailValidator: ) -> None: ... def __call__(self, value: Optional[str]) -> None: ... def validate_domain_part(self, domain_part: str) -> bool: ... - def __eq__(self, other: EmailValidator) -> bool: ... validate_email: Any slug_re: Any @@ -83,13 +81,10 @@ class BaseValidator: message: Any = ... code: str = ... limit_value: bool = ... - def __init__( - self, limit_value: Optional[Union[datetime, Decimal, float, str]], message: Optional[str] = ... - ) -> None: ... - def __call__(self, value: Union[bytes, datetime, Decimal, float, str]) -> None: ... - def __eq__(self, other: BaseValidator) -> bool: ... + def __init__(self, limit_value: Any, message: Optional[str] = ...) -> None: ... + def __call__(self, value: Any) -> None: ... def compare(self, a: bool, b: bool) -> bool: ... - def clean(self, x: Union[datetime, Decimal, float]) -> Union[datetime, Decimal, float]: ... + def clean(self, x: Any) -> Any: ... class MaxValueValidator(BaseValidator): limit_value: Decimal @@ -123,7 +118,6 @@ class DecimalValidator: decimal_places: int = ... def __init__(self, max_digits: Optional[Union[int, str]], decimal_places: Optional[Union[int, str]]) -> None: ... def __call__(self, value: Decimal) -> None: ... - def __eq__(self, other: Union[DecimalValidator, MinValueValidator]) -> bool: ... class FileExtensionValidator: message: Any = ... @@ -133,7 +127,6 @@ class FileExtensionValidator: self, allowed_extensions: Optional[List[str]] = ..., message: Optional[str] = ..., code: Optional[str] = ... ) -> None: ... def __call__(self, value: File) -> None: ... - def __eq__(self, other: FileExtensionValidator) -> bool: ... def get_available_image_extensions() -> List[str]: ... def validate_image_file_extension(value: File) -> None: ... @@ -143,4 +136,3 @@ class ProhibitNullCharactersValidator: code: str = ... def __init__(self, message: Optional[str] = ..., code: Optional[str] = ...) -> None: ... def __call__(self, value: Optional[Union[Dict[Any, Any], str, UUID]]) -> None: ... - def __eq__(self, other: Union[ProhibitNullCharactersValidator, RegexValidator]) -> bool: ... diff --git a/django-stubs/db/models/__init__.pyi b/django-stubs/db/models/__init__.pyi index ce783ef..94bc5ad 100644 --- a/django-stubs/db/models/__init__.pyi +++ b/django-stubs/db/models/__init__.pyi @@ -9,6 +9,7 @@ from .fields import ( PositiveSmallIntegerField as PositiveSmallIntegerField, SmallIntegerField as SmallIntegerField, BigIntegerField as BigIntegerField, + FloatField as FloatField, CharField as CharField, EmailField as EmailField, URLField as URLField, @@ -19,14 +20,27 @@ from .fields import ( NullBooleanField as NullBooleanField, FileField as FileField, DateField as DateField, + TimeField as TimeField, DateTimeField as DateTimeField, IPAddressField as IPAddressField, GenericIPAddressField as GenericIPAddressField, + UUIDField as UUIDField, + DecimalField as DecimalField, + FilePathField as FilePathField, + BinaryField as BinaryField, + DurationField as DurationField, ) from .fields.related import ForeignKey as ForeignKey, OneToOneField as OneToOneField, ManyToManyField as ManyToManyField +from .fields.files import ImageField as ImageField, FileField as FileField -from .deletion import CASCADE as CASCADE, SET_DEFAULT as SET_DEFAULT, SET_NULL as SET_NULL, DO_NOTHING as DO_NOTHING +from .deletion import ( + CASCADE as CASCADE, + SET_DEFAULT as SET_DEFAULT, + SET_NULL as SET_NULL, + DO_NOTHING as DO_NOTHING, + PROTECT as PROTECT, +) from .query import QuerySet as QuerySet, RawQuerySet as RawQuerySet diff --git a/django-stubs/db/models/deletion.pyi b/django-stubs/db/models/deletion.pyi index 2685835..96fed2c 100644 --- a/django-stubs/db/models/deletion.pyi +++ b/django-stubs/db/models/deletion.pyi @@ -2,3 +2,4 @@ def CASCADE(collector, field, sub_objs, using): ... def SET_NULL(collector, field, sub_objs, using): ... def SET_DEFAULT(collector, field, sub_objs, using): ... def DO_NOTHING(collector, field, sub_objs, using): ... +def PROTECT(collector, field, sub_objs, using): ... diff --git a/django-stubs/db/models/fields/__init__.pyi b/django-stubs/db/models/fields/__init__.pyi index cdc6b61..41f4eae 100644 --- a/django-stubs/db/models/fields/__init__.pyi +++ b/django-stubs/db/models/fields/__init__.pyi @@ -16,18 +16,27 @@ class PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField): ... class PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField): ... class SmallIntegerField(IntegerField): ... class BigIntegerField(IntegerField): ... +class FloatField(Field): ... + +class DecimalField(IntegerField): + def __init__(self, *, max_digits: Optional[int] = ..., decimal_places: Optional[int] = ..., **kwargs): ... class AutoField(Field): def __get__(self, instance, owner) -> int: ... class CharField(Field): - def __init__(self, max_length: int, **kwargs: Any): ... + def __init__(self, max_length: int = ..., **kwargs: Any): ... def __set__(self, instance, value: str) -> None: ... def __get__(self, instance, owner) -> str: ... -class SlugField(CharField): ... -class EmailField(CharField): ... -class URLField(CharField): ... +class SlugField(CharField): + def __init__(self, max_length: int = ..., **kwargs: Any): ... + +class EmailField(CharField): + def __init__(self, max_length: int = ..., **kwargs: Any): ... + +class URLField(CharField): + def __init__(self, max_length: int = ..., **kwargs: Any): ... class TextField(Field): def __set__(self, instance, value: str) -> None: ... @@ -57,5 +66,36 @@ class GenericIPAddressField(Field): **kwargs: Any ) -> None: ... -class DateField(Field): ... +class DateTimeCheckMixin: ... + +class DateField(DateTimeCheckMixin, Field): + def __init__( + self, + verbose_name: Optional[str] = ..., + name: Optional[str] = ..., + auto_now: bool = ..., + auto_now_add: bool = ..., + **kwargs + ): ... + +class TimeField(DateTimeCheckMixin, Field): ... class DateTimeField(DateField): ... +class UUIDField(Field): ... + +class FilePathField(Field): + def __init__( + self, + verbose_name: Optional[str] = ..., + name: Optional[str] = ..., + path: str = ..., + match: Optional[Any] = ..., + recursive: bool = ..., + allow_files: bool = ..., + allow_folders: bool = ..., + **kwargs + ): ... + +class BinaryField(Field): + def __init__(self, editable: bool = ..., **kwargs: Any): ... + +class DurationField(Field): ... diff --git a/django-stubs/db/models/fields/files.pyi b/django-stubs/db/models/fields/files.pyi index 19fdfcb..74aa9e7 100644 --- a/django-stubs/db/models/fields/files.pyi +++ b/django-stubs/db/models/fields/files.pyi @@ -3,15 +3,15 @@ from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union from django.core.checks.messages import Error from django.core.files.base import File from django.core.files.images import ImageFile -from django.core.files.storage import FileSystemStorage, Storage +from django.core.files.storage import FileSystemStorage, Storage, DefaultStorage from django.db.models.base import Model from django.db.models.fields import Field -from django.forms.fields import FileField, ImageField +from django.forms import fields as form_fields class FieldFile(File): instance: Model = ... - field: django.db.models.fields.files.FileField = ... - storage: django.core.files.storage.FileSystemStorage = ... + field: FileField = ... + storage: FileSystemStorage = ... def __init__(self, instance: Model, field: FileField, name: Optional[str]) -> None: ... def __eq__(self, other: Any) -> bool: ... def __hash__(self): ... @@ -31,7 +31,7 @@ class FieldFile(File): def close(self) -> None: ... class FileDescriptor: - field: django.db.models.fields.files.FileField = ... + field: FileField = ... def __init__(self, field: FileField) -> None: ... def __get__(self, instance: Optional[Model], cls: Type[Model] = ...) -> Union[FieldFile, FileDescriptor]: ... def __set__(self, instance: Model, value: Optional[Union[File, str]]) -> None: ... @@ -45,48 +45,43 @@ class FileField(Field): def __init__( self, verbose_name: Optional[str] = ..., - name: None = ..., + name: Optional[str] = ..., upload_to: Union[Callable, str] = ..., storage: Optional[Storage] = ..., **kwargs: Any ) -> None: ... def check(self, **kwargs: Any) -> List[Error]: ... - def deconstruct(self) -> Tuple[Optional[str], str, List[Any], Dict[str, Union[bool, str]]]: ... + def deconstruct(self) -> Any: ... def get_internal_type(self) -> str: ... def get_prep_value(self, value: Union[FieldFile, str]) -> str: ... def pre_save(self, model_instance: Model, add: bool) -> FieldFile: ... def contribute_to_class(self, cls: Type[Model], name: str, **kwargs: Any) -> None: ... def generate_filename(self, instance: Optional[Model], filename: str) -> str: ... def save_form_data(self, instance: Model, data: Optional[Union[bool, File, str]]) -> None: ... - def formfield(self, **kwargs: Any) -> FileField: ... + def formfield(self, **kwargs: Any) -> form_fields.FileField: ... class ImageFileDescriptor(FileDescriptor): - field: django.db.models.fields.files.ImageField + field: ImageField def __set__(self, instance: Model, value: Optional[str]) -> None: ... class ImageFieldFile(ImageFile, FieldFile): - field: django.db.models.fields.files.ImageField + field: ImageField instance: Model name: Optional[str] - storage: django.core.files.storage.DefaultStorage + storage: DefaultStorage def delete(self, save: bool = ...) -> None: ... class ImageField(FileField): - attr_class: Any = ... - descriptor_class: Any = ... - description: Any = ... def __init__( self, - verbose_name: None = ..., - name: None = ..., + verbose_name: Optional[str] = ..., + name: Optional[str] = ..., width_field: Optional[str] = ..., height_field: Optional[str] = ..., **kwargs: Any ) -> None: ... def check(self, **kwargs: Any) -> List[Any]: ... - def deconstruct( - self - ) -> Tuple[Optional[str], str, List[Any], Dict[str, Union[Callable, bool, FileSystemStorage, str]]]: ... + def deconstruct(self) -> Any: ... def contribute_to_class(self, cls: Type[Model], name: str, **kwargs: Any) -> None: ... def update_dimension_fields(self, instance: Model, force: bool = ..., *args: Any, **kwargs: Any) -> None: ... - def formfield(self, **kwargs: Any) -> ImageField: ... + def formfield(self, **kwargs: Any) -> form_fields.ImageField: ... diff --git a/django-stubs/db/models/fields/related.pyi b/django-stubs/db/models/fields/related.pyi index 20015d7..4367ff7 100644 --- a/django-stubs/db/models/fields/related.pyi +++ b/django-stubs/db/models/fields/related.pyi @@ -59,7 +59,7 @@ class ManyToManyField(RelatedField, Generic[_T]): related_query_name: Optional[str] = ..., limit_choices_to: Optional[Callable] = ..., symmetrical: Optional[bool] = ..., - through: Optional[str] = ..., + through: Optional[Union[str, Type[Model]]] = ..., through_fields: Optional[Tuple[str, str]] = ..., db_constraint: bool = ..., db_table: None = ..., diff --git a/django-stubs/db/models/manager.pyi b/django-stubs/db/models/manager.pyi index 36a25f1..f612049 100644 --- a/django-stubs/db/models/manager.pyi +++ b/django-stubs/db/models/manager.pyi @@ -10,8 +10,8 @@ class BaseManager(QuerySet[_T]): auto_created: bool = ... use_in_migrations: bool = ... def __new__(cls: Type[BaseManager], *args: Any, **kwargs: Any) -> BaseManager: ... - model: Any = ... - name: Any = ... + model: Optional[Any] = ... + name: Optional[Any] = ... def __init__(self) -> None: ... def deconstruct(self) -> Tuple[bool, str, None, Tuple, Dict[str, int]]: ... def check(self, **kwargs: Any) -> List[Any]: ... diff --git a/django-stubs/views/debug.pyi b/django-stubs/views/debug.pyi index 8307c44..a4c9b72 100644 --- a/django-stubs/views/debug.pyi +++ b/django-stubs/views/debug.pyi @@ -31,7 +31,7 @@ class SafeExceptionReporterFilter(ExceptionReporterFilter): def get_traceback_frame_variables(self, request: Any, tb_frame: Any): ... class ExceptionReporter: - request: Optional[django.core.handlers.wsgi.WSGIRequest] = ... + request: Optional[WSGIRequest] = ... filter: django.views.debug.SafeExceptionReporterFilter = ... exc_type: None = ... exc_value: Optional[str] = ... diff --git a/scripts/typecheck_django_tests.xsh b/scripts/typecheck_django_tests.xsh index d596f3d..504b114 100644 --- a/scripts/typecheck_django_tests.xsh +++ b/scripts/typecheck_django_tests.xsh @@ -2,7 +2,7 @@ import os if not os.path.exists('./django-sources'): git clone -b stable/2.1.x https://github.com/django/django.git django-sources -ignored_error_patterns = ["Need type annotation for"] +ignored_error_patterns = ["Need type annotation for", "already defined on", "Cannot assign to a"] for line in $(mypy --config-file ./scripts/mypy.ini ./django-sources/tests/files).split('\n'): for pattern in ignored_error_patterns: if pattern in line: