diff --git a/django-stubs/contrib/auth/base_user.pyi b/django-stubs/contrib/auth/base_user.pyi index 79ff0fa29..5d36c30cc 100644 --- a/django-stubs/contrib/auth/base_user.pyi +++ b/django-stubs/contrib/auth/base_user.pyi @@ -20,9 +20,6 @@ class AbstractBaseUser(models.Model): last_login = models.DateTimeField(blank=True, null=True) is_active: bool | BooleanField[bool | Combinable, bool] - class Meta: - abstract: Literal[True] - def get_username(self) -> str: ... def natural_key(self) -> tuple[str]: ... @property diff --git a/django-stubs/contrib/auth/models.pyi b/django-stubs/contrib/auth/models.pyi index a0f9d3fe6..78702f1e7 100644 --- a/django-stubs/contrib/auth/models.pyi +++ b/django-stubs/contrib/auth/models.pyi @@ -61,9 +61,6 @@ class PermissionsMixin(models.Model): groups = models.ManyToManyField(Group) user_permissions = models.ManyToManyField(Permission) - class Meta: - abstract: Literal[True] - def get_user_permissions(self, obj: _AnyUser | None = ...) -> set[str]: ... def get_group_permissions(self, obj: _AnyUser | None = ...) -> set[str]: ... def get_all_permissions(self, obj: _AnyUser | None = ...) -> set[str]: ... @@ -87,9 +84,6 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin): EMAIL_FIELD: str USERNAME_FIELD: str - class Meta: - abstract: Literal[True] - def get_full_name(self) -> str: ... def get_short_name(self) -> str: ... def email_user( diff --git a/django-stubs/contrib/sessions/base_session.pyi b/django-stubs/contrib/sessions/base_session.pyi index 9e50cea7b..f016f4b98 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, Literal, TypeVar +from typing import Any, TypeVar from django.contrib.sessions.backends.base import SessionBase from django.db import models @@ -16,9 +16,6 @@ class AbstractBaseSession(models.Model): session_key: str objects: Any - class Meta: - abstract: Literal[True] - @classmethod def get_session_store_class(cls) -> type[SessionBase] | None: ... def get_decoded(self) -> dict[str, Any]: ... diff --git a/mypy_django_plugin/lib/fullnames.py b/mypy_django_plugin/lib/fullnames.py index 45fa3a452..e718c4a6c 100644 --- a/mypy_django_plugin/lib/fullnames.py +++ b/mypy_django_plugin/lib/fullnames.py @@ -58,3 +58,12 @@ OBJECT_DOES_NOT_EXIST = "django.core.exceptions.ObjectDoesNotExist" MULTIPLE_OBJECTS_RETURNED = "django.core.exceptions.MultipleObjectsReturned" + +DJANGO_ABSTRACT_MODELS = frozenset( + ( + "django.contrib.auth.base_user.AbstractBaseUser", + ABSTRACT_USER_MODEL_FULLNAME, + PERMISSION_MIXIN_CLASS_FULLNAME, + "django.contrib.sessions.base_session.AbstractBaseSession", + ) +) diff --git a/mypy_django_plugin/lib/helpers.py b/mypy_django_plugin/lib/helpers.py index 8e226a231..412ab9872 100644 --- a/mypy_django_plugin/lib/helpers.py +++ b/mypy_django_plugin/lib/helpers.py @@ -416,6 +416,9 @@ def add_new_manager_base(api: SemanticAnalyzerPluginInterface, fullname: str) -> def is_abstract_model(model: TypeInfo) -> bool: + if model.fullname in fullnames.DJANGO_ABSTRACT_MODELS: + return True + if not is_model_type(model): return False