diff --git a/django-stubs/contrib/admin/models.pyi b/django-stubs/contrib/admin/models.pyi index 4af0c7dc1..72d1439d0 100644 --- a/django-stubs/contrib/admin/models.pyi +++ b/django-stubs/contrib/admin/models.pyi @@ -1,4 +1,4 @@ -from typing import Any, Optional, Union +from typing import Any, ClassVar, Optional, Union from uuid import UUID from django.db import models @@ -28,7 +28,7 @@ class LogEntry(models.Model): object_repr: models.CharField[Any] = ... action_flag: models.PositiveSmallIntegerField[Any] = ... change_message: models.TextField[Any] = ... - objects: LogEntryManager = ... + objects: ClassVar[LogEntryManager] = ... def is_addition(self) -> bool: ... def is_change(self) -> bool: ... def is_deletion(self) -> bool: ... diff --git a/django-stubs/contrib/auth/models.pyi b/django-stubs/contrib/auth/models.pyi index babfb17c3..2471203c2 100644 --- a/django-stubs/contrib/auth/models.pyi +++ b/django-stubs/contrib/auth/models.pyi @@ -1,5 +1,5 @@ import sys -from typing import Any, Collection, Optional, Set, Tuple, Type, TypeVar, Union +from typing import Any, ClassVar, Collection, Optional, Set, Tuple, Type, TypeVar, Union from django.contrib.auth.backends import ModelBackend from django.contrib.auth.base_user import AbstractBaseUser as AbstractBaseUser @@ -15,6 +15,11 @@ if sys.version_info < (3, 8): else: from typing import Literal +if sys.version_info < (3, 11): + from typing_extensions import Self +else: + from typing import Self + _AnyUser = Union[Model, "AnonymousUser"] def update_last_login( @@ -28,7 +33,7 @@ class PermissionManager(models.Manager["Permission"]): class Permission(models.Model): content_type_id: int - objects: PermissionManager + objects: ClassVar[PermissionManager] name = models.CharField(max_length=255) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) @@ -39,7 +44,7 @@ class GroupManager(models.Manager["Group"]): def get_by_natural_key(self, name: str) -> Group: ... class Group(models.Model): - objects: GroupManager + objects: ClassVar[GroupManager] name = models.CharField(max_length=150) permissions = models.ManyToManyField[Permission, Any](Permission) @@ -104,7 +109,7 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin): ) -> None: ... class User(AbstractUser): - objects: UserManager[User] + objects: ClassVar[UserManager[Self]] # type: ignore[assignment] class AnonymousUser: id: Any = ... diff --git a/django-stubs/contrib/contenttypes/models.pyi b/django-stubs/contrib/contenttypes/models.pyi index e5a305343..c12890453 100644 --- a/django-stubs/contrib/contenttypes/models.pyi +++ b/django-stubs/contrib/contenttypes/models.pyi @@ -1,4 +1,4 @@ -from typing import Any, Dict, Optional, Tuple, Type, Union +from typing import Any, ClassVar, Dict, Optional, Tuple, Type, Union from django.contrib.auth.models import Permission from django.db import models @@ -22,7 +22,7 @@ class ContentType(models.Model): id: int app_label: models.CharField[Any] = ... model: models.CharField[Any] = ... - objects: ContentTypeManager = ... + objects: ClassVar[ContentTypeManager] = ... permission_set: Manager[Permission] @property def name(self) -> str: ... diff --git a/django-stubs/contrib/sessions/base_session.pyi b/django-stubs/contrib/sessions/base_session.pyi index f26817121..300799081 100644 --- a/django-stubs/contrib/sessions/base_session.pyi +++ b/django-stubs/contrib/sessions/base_session.pyi @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Any, Dict, Optional, Type +from typing import Any, ClassVar, Dict, Optional, Type from django.contrib.sessions.backends.base import SessionBase from django.db import models @@ -14,7 +14,7 @@ class AbstractBaseSession(models.Model): expire_date: datetime session_data: str session_key: str - objects: Any = ... + objects: ClassVar[BaseSessionManager] = ... @classmethod def get_session_store_class(cls) -> Optional[Type[SessionBase]]: ... def get_decoded(self) -> Dict[str, int]: ... diff --git a/django-stubs/contrib/sites/models.pyi b/django-stubs/contrib/sites/models.pyi index 099ab2629..5a2e19999 100644 --- a/django-stubs/contrib/sites/models.pyi +++ b/django-stubs/contrib/sites/models.pyi @@ -1,4 +1,4 @@ -from typing import Any, Optional, Tuple, Type +from typing import Any, ClassVar, Optional, Tuple, Type from django.db import models from django.http.request import HttpRequest @@ -11,7 +11,7 @@ class SiteManager(models.Manager["Site"]): def get_by_natural_key(self, domain: str) -> Site: ... class Site(models.Model): - objects: SiteManager + objects: ClassVar[SiteManager] domain = models.CharField(max_length=100) name = models.CharField(max_length=50) diff --git a/django-stubs/db/models/__init__.pyi b/django-stubs/db/models/__init__.pyi index 02d4a2baa..35c434a0e 100644 --- a/django-stubs/db/models/__init__.pyi +++ b/django-stubs/db/models/__init__.pyi @@ -11,9 +11,9 @@ from .aggregates import StdDev as StdDev from .aggregates import Sum as Sum from .aggregates import Variance as Variance from .base import Model as Model -from .constraints import Deferrable as Deferrable from .constraints import BaseConstraint as BaseConstraint from .constraints import CheckConstraint as CheckConstraint +from .constraints import Deferrable as Deferrable from .constraints import UniqueConstraint as UniqueConstraint from .deletion import CASCADE as CASCADE from .deletion import DO_NOTHING as DO_NOTHING diff --git a/django-stubs/db/models/base.pyi b/django-stubs/db/models/base.pyi index 5d063aa94..e79278c99 100644 --- a/django-stubs/db/models/base.pyi +++ b/django-stubs/db/models/base.pyi @@ -1,3 +1,4 @@ +import sys from typing import ( Any, Callable, @@ -22,6 +23,11 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.db.models.manager import BaseManager from django.db.models.options import Options +if sys.version_info < (3, 11): + from typing_extensions import Self +else: + from typing import Self + _M = TypeVar("_M", bound=Any) _Self = TypeVar("_Self", bound="Model") @@ -32,24 +38,18 @@ class ModelState: adding: bool = ... fields_cache: ModelStateFieldsCacheDescriptor = ... -class ModelBase(type): - # FIXME: It would be better to use _Self instead of _M here, - # but pyright says Type[_Self] cannot be assigned here... Maybe a bug in pyright? - @property - def objects(cls: Type[_M]) -> BaseManager[_M]: ... - @property - def _meta(cls: Type[_M]) -> Options[_M]: ... - @property - def _default_manager(cls: Type[_M]) -> BaseManager[_M]: ... +class ModelBase(type): ... class Model(metaclass=ModelBase): DoesNotExist: ClassVar[type[ObjectDoesNotExist]] MultipleObjectsReturned: ClassVar[type[BaseMultipleObjectsReturned]] + _meta: ClassVar[Options[Self]] + _default_manager: ClassVar[BaseManager[Self]] + objects: ClassVar[BaseManager[Self]] class Meta: ... pk: Any = ... _state: ModelState - _meta: Options[Any] def __init__(self, *args: Any, **kwargs: Any) -> None: ... @classmethod def add_to_class(cls, name: str, value: Any) -> Any: ... @@ -67,7 +67,10 @@ class Model(metaclass=ModelBase): self, using: Any = ..., keep_parents: bool = ... ) -> Tuple[int, Dict[str, int]]: ... def full_clean( - self, exclude: Optional[Collection[str]] = ..., validate_unique: bool = True, validate_constraints: bool = True + self, + exclude: Optional[Collection[str]] = ..., + validate_unique: bool = True, + validate_constraints: bool = True, ) -> None: ... def clean(self) -> None: ... def clean_fields(self, exclude: Optional[Collection[str]] = ...) -> None: ... diff --git a/django-stubs/db/transaction.pyi b/django-stubs/db/transaction.pyi index 60db02161..8e41d64ab 100644 --- a/django-stubs/db/transaction.pyi +++ b/django-stubs/db/transaction.pyi @@ -28,7 +28,9 @@ _C = TypeVar("_C", bound=Callable[..., Any]) class Atomic: using: Optional[str] = ... savepoint: bool = ... - def __init__(self, using: Optional[str], savepoint: bool, durable: bool = ...) -> None: ... + def __init__( + self, using: Optional[str], savepoint: bool, durable: bool = ... + ) -> None: ... # When decorating, return the decorated function as-is, rather than clobbering it as ContextDecorator does. def __call__(self, func: _C) -> _C: ... def __enter__(self) -> None: ... @@ -40,7 +42,9 @@ def atomic(using: _C) -> _C: ... # Decorator or context-manager with parameters @overload -def atomic(using: Optional[str] = ..., savepoint: bool = ..., durable: bool = ...) -> Atomic: ... +def atomic( + using: Optional[str] = ..., savepoint: bool = ..., durable: bool = ... +) -> Atomic: ... # Bare decorator @overload diff --git a/package.json b/package.json index bf6c97cc3..3126547b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "devDependencies": { - "pyright": "1.1.301" + "pyright": "1.1.324" }, "volta": { "node": "18.15.0" diff --git a/yarn.lock b/yarn.lock index 50dd13ec9..936e50ff4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,7 +2,14 @@ # yarn lockfile v1 -pyright@1.1.301: - version "1.1.301" - resolved "https://registry.npmjs.org/pyright/-/pyright-1.1.301.tgz" - integrity sha512-Y4MMELxQ/5+/FlWjbQTg5wbP3z+V4IyFcATSsNLpZbJm0y4gz6ijf/b0zZV1sA8yJstf6xJ98vw5qxPM0yU8Zg== +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +pyright@1.1.324: + version "1.1.324" + resolved "https://registry.yarnpkg.com/pyright/-/pyright-1.1.324.tgz#6a964835c0e1aabf039cb35d8587e0d9ce7b37bf" + integrity sha512-/Ng8G2Gb17dzQEHKgPa+Z5a6LPCLYNA4BVno1UdpDjnC9iLw0VAn5k/RNuaGkB/mhA82lV0OBcd5JEdaWcA3qg== + optionalDependencies: + fsevents "~2.3.2"