From 13f6687dcdf9e3a586866568f1300fb95b05921d Mon Sep 17 00:00:00 2001 From: Marti Raudsepp Date: Thu, 16 May 2024 22:50:32 +0300 Subject: [PATCH 1/3] Restore inner `class Meta` in models where it is accessible Turns out that the inner `Meta` class is accessible for some models, but not others. Added `class Meta` only to stub model classes where it's accessible from outside (e.g. `AbstractBaseUser.Meta` does not crash with AttributeError). --- django-stubs/contrib/admin/models.pyi | 1 + django-stubs/contrib/auth/base_user.pyi | 3 +++ django-stubs/contrib/auth/models.pyi | 10 ++++++++++ django-stubs/contrib/contenttypes/models.pyi | 1 + django-stubs/contrib/flatpages/models.pyi | 1 + django-stubs/contrib/redirects/models.pyi | 1 + django-stubs/contrib/sessions/base_session.pyi | 5 +++++ django-stubs/contrib/sites/models.pyi | 1 + 8 files changed, 23 insertions(+) diff --git a/django-stubs/contrib/admin/models.pyi b/django-stubs/contrib/admin/models.pyi index a1ac77b49..6f129089e 100644 --- a/django-stubs/contrib/admin/models.pyi +++ b/django-stubs/contrib/admin/models.pyi @@ -21,6 +21,7 @@ class LogEntryManager(models.Manager[LogEntry]): ) -> LogEntry: ... class LogEntry(models.Model): + # Note: do not create `class Meta` here. action_time: models.DateTimeField user: models.ForeignKey content_type: models.ForeignKey diff --git a/django-stubs/contrib/auth/base_user.pyi b/django-stubs/contrib/auth/base_user.pyi index 4740dd504..73e65b0f6 100644 --- a/django-stubs/contrib/auth/base_user.pyi +++ b/django-stubs/contrib/auth/base_user.pyi @@ -20,6 +20,9 @@ class AbstractBaseUser(models.Model): last_login = models.DateTimeField(blank=True, null=True) is_active: bool | BooleanField[bool | Combinable, bool] + class Meta: + abstract: bool + 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 78702f1e7..5684c2bc9 100644 --- a/django-stubs/contrib/auth/models.pyi +++ b/django-stubs/contrib/auth/models.pyi @@ -20,6 +20,7 @@ class PermissionManager(models.Manager[Permission]): def get_by_natural_key(self, codename: str, app_label: str, model: str) -> Permission: ... class Permission(models.Model): + # Note: do not create `class Meta` here. content_type_id: int objects: ClassVar[PermissionManager] @@ -32,6 +33,7 @@ class GroupManager(models.Manager[Group]): def get_by_natural_key(self, name: str) -> Group: ... class Group(models.Model): + # Note: do not create `class Meta` here. objects: ClassVar[GroupManager] name = models.CharField(max_length=150) @@ -61,6 +63,9 @@ class PermissionsMixin(models.Model): groups = models.ManyToManyField(Group) user_permissions = models.ManyToManyField(Permission) + class Meta: + abstract: bool + 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]: ... @@ -84,6 +89,11 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin): EMAIL_FIELD: str USERNAME_FIELD: str + class Meta: + verbose_name: str + verbose_name_plural: str + abstract: bool + def get_full_name(self) -> str: ... def get_short_name(self) -> str: ... def email_user( diff --git a/django-stubs/contrib/contenttypes/models.pyi b/django-stubs/contrib/contenttypes/models.pyi index e7206aed0..dd196e89f 100644 --- a/django-stubs/contrib/contenttypes/models.pyi +++ b/django-stubs/contrib/contenttypes/models.pyi @@ -12,6 +12,7 @@ class ContentTypeManager(models.Manager[ContentType]): def clear_cache(self) -> None: ... class ContentType(models.Model): + # Note: do not create `class Meta` here. id: int app_label: models.CharField model: models.CharField diff --git a/django-stubs/contrib/flatpages/models.pyi b/django-stubs/contrib/flatpages/models.pyi index 4b578fe03..4226ad953 100644 --- a/django-stubs/contrib/flatpages/models.pyi +++ b/django-stubs/contrib/flatpages/models.pyi @@ -2,6 +2,7 @@ from django.contrib.sites.models import Site from django.db import models class FlatPage(models.Model): + # Note: do not create `class Meta` here. url: models.CharField title: models.CharField content: models.TextField diff --git a/django-stubs/contrib/redirects/models.pyi b/django-stubs/contrib/redirects/models.pyi index 444960881..4436a5c02 100644 --- a/django-stubs/contrib/redirects/models.pyi +++ b/django-stubs/contrib/redirects/models.pyi @@ -1,6 +1,7 @@ from django.db import models class Redirect(models.Model): + # Note: do not create `class Meta` here. site: models.ForeignKey old_path: models.CharField new_path: models.CharField diff --git a/django-stubs/contrib/sessions/base_session.pyi b/django-stubs/contrib/sessions/base_session.pyi index f016f4b98..359a10398 100644 --- a/django-stubs/contrib/sessions/base_session.pyi +++ b/django-stubs/contrib/sessions/base_session.pyi @@ -16,6 +16,11 @@ class AbstractBaseSession(models.Model): session_key: str objects: Any + class Meta: + verbose_name: str + verbose_name_plural: str + abstract: bool + @classmethod def get_session_store_class(cls) -> type[SessionBase] | None: ... def get_decoded(self) -> dict[str, Any]: ... diff --git a/django-stubs/contrib/sites/models.pyi b/django-stubs/contrib/sites/models.pyi index e4181d66f..2aa9adb11 100644 --- a/django-stubs/contrib/sites/models.pyi +++ b/django-stubs/contrib/sites/models.pyi @@ -11,6 +11,7 @@ class SiteManager(models.Manager[Site]): def get_by_natural_key(self, domain: str) -> Site: ... class Site(models.Model): + # Note: do not create `class Meta` here. objects: ClassVar[SiteManager] domain = models.CharField(max_length=100) From 280361498e50332210efe9d2d525f525d245bf0c Mon Sep 17 00:00:00 2001 From: Marti Raudsepp Date: Thu, 16 May 2024 23:26:53 +0300 Subject: [PATCH 2/3] Fix allowlist --- scripts/stubtest/allowlist.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/scripts/stubtest/allowlist.txt b/scripts/stubtest/allowlist.txt index ef6a09219..ee90bfcbd 100644 --- a/scripts/stubtest/allowlist.txt +++ b/scripts/stubtest/allowlist.txt @@ -399,14 +399,9 @@ django.contrib.gis.db.models.Q.referenced_base_fields django.db.backends.oracle.features.DatabaseFeatures.django_test_skips # Ignore missing inner `Meta` class, see PR #2000 for the related discussion -django.contrib.auth.base_user.AbstractBaseUser.Meta django.contrib.auth.forms.BaseUserCreationForm.Meta django.contrib.auth.forms.UserChangeForm.Meta -django.contrib.auth.models.AbstractBaseUser.Meta -django.contrib.auth.models.AbstractUser.Meta -django.contrib.auth.models.PermissionsMixin.Meta django.contrib.flatpages.forms.FlatpageForm.Meta -django.contrib.sessions.base_session.AbstractBaseSession.Meta # Custom __str__ that we don't want to overcomplicate: django.forms.utils.RenderableMixin.__str__ From 2247b8490d9e20678ec7437d383427b00f0d464f Mon Sep 17 00:00:00 2001 From: Marti Raudsepp Date: Thu, 16 May 2024 23:27:31 +0300 Subject: [PATCH 3/3] Update comment --- scripts/stubtest/allowlist.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/stubtest/allowlist.txt b/scripts/stubtest/allowlist.txt index ee90bfcbd..d697d6f8e 100644 --- a/scripts/stubtest/allowlist.txt +++ b/scripts/stubtest/allowlist.txt @@ -398,7 +398,7 @@ django.db.models.query_utils.Q.referenced_base_fields django.contrib.gis.db.models.Q.referenced_base_fields django.db.backends.oracle.features.DatabaseFeatures.django_test_skips -# Ignore missing inner `Meta` class, see PR #2000 for the related discussion +# Ignore missing inner `Meta` class, see PR #2000 and #2168 django.contrib.auth.forms.BaseUserCreationForm.Meta django.contrib.auth.forms.UserChangeForm.Meta django.contrib.flatpages.forms.FlatpageForm.Meta