Skip to content

Commit eb4d051

Browse files
Fix a few errors related to the metaclass MediaDefiningClass (#2662)
* Add missing metaclass * Add `MediaDefiningClass.__new__` types _typeshed.Self
1 parent 1a71eba commit eb4d051

File tree

4 files changed

+11
-28
lines changed

4 files changed

+11
-28
lines changed

django-stubs/contrib/admin/options.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ from django.forms.models import (
2525
ModelForm,
2626
ModelMultipleChoiceField,
2727
)
28-
from django.forms.widgets import Media
28+
from django.forms.widgets import Media, MediaDefiningClass
2929
from django.http.request import HttpRequest
3030
from django.http.response import HttpResponse, HttpResponseBase, HttpResponseRedirect
3131
from django.template.response import _TemplateForResponseT
@@ -84,7 +84,7 @@ _ListDisplayT: TypeAlias = _ListOrTuple[_DisplayT[_ModelT]]
8484

8585
# Options `form`, `list_display`, `list_display_links` and `actions` are not marked as `ClassVar` due to the
8686
# limitations of the current type system: `ClassVar` cannot contain type variables.
87-
class BaseModelAdmin(Generic[_ModelT]):
87+
class BaseModelAdmin(Generic[_ModelT], metaclass=MediaDefiningClass):
8888
autocomplete_fields: ClassVar[_ListOrTuple[str]]
8989
raw_id_fields: ClassVar[_ListOrTuple[str]]
9090
fields: ClassVar[_FieldGroups | None]

django-stubs/forms/widgets.pyi

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import datetime
22
from collections.abc import Iterable, Iterator, Mapping, Sequence
33
from typing import Any, Literal, Protocol, TypeAlias, type_check_only
44

5+
import _typeshed
56
from django.core.files.base import File
67
from django.forms.renderers import BaseRenderer
78
from django.forms.utils import _DataT, _FilesT
@@ -45,7 +46,13 @@ class Media:
4546
def merge(*lists: Iterable[Any]) -> list[Any]: ...
4647
def __add__(self, other: Media) -> Media: ...
4748

48-
class MediaDefiningClass(type): ...
49+
class MediaDefiningClass(type):
50+
def __new__(
51+
mcs: type[_typeshed.Self], # noqa: TID251
52+
name: str,
53+
bases: tuple[type, ...],
54+
attrs: dict[str, Any],
55+
) -> _typeshed.Self: ... # noqa: TID251
4956

5057
class Widget(metaclass=MediaDefiningClass):
5158
needs_multipart_form: bool

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ ignore = [
4444
"setup.py" = ["INP001"]
4545

4646
[tool.ruff.lint.flake8-tidy-imports.banned-api]
47-
"_typeshed.Self".msg = "Use typing_extensions.Self (PEP 673) instead."
47+
"_typeshed.Self".msg = "Use typing_extensions.Self (PEP 673) instead. If you type a metaclass, add a noqa"
4848
"typing.assert_type".msg = "Use typing_extensions.assert_type instead."
4949

5050
[tool.ruff.lint.isort]

scripts/stubtest/allowlist_todo.txt

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
django.__main__
55
django.conf.global_settings.gettext_noop
66
django.contrib.admin.FieldListFilter.title
7-
django.contrib.admin.ModelAdmin
8-
django.contrib.admin.StackedInline
9-
django.contrib.admin.TabularInline
107
django.contrib.admin.filters.FieldListFilter.title
118
django.contrib.admin.helpers.AdminForm.fields
129
django.contrib.admin.helpers.AdminForm.is_bound
@@ -26,15 +23,10 @@ django.contrib.admin.models.LogEntry.object_id
2623
django.contrib.admin.models.LogEntry.object_repr
2724
django.contrib.admin.models.LogEntry.user
2825
django.contrib.admin.models.LogEntry.user_id
29-
django.contrib.admin.options.BaseModelAdmin
3026
django.contrib.admin.options.BaseModelAdmin.form
3127
django.contrib.admin.options.BaseModelAdmin.media
32-
django.contrib.admin.options.InlineModelAdmin
3328
django.contrib.admin.options.InlineModelAdmin.model
3429
django.contrib.admin.options.InlineModelAdmin.template
35-
django.contrib.admin.options.ModelAdmin
36-
django.contrib.admin.options.StackedInline
37-
django.contrib.admin.options.TabularInline
3830
django.contrib.admin.site
3931
django.contrib.admin.sites.site
4032
django.contrib.admin.tests.AdminSeleniumTestCase
@@ -54,9 +46,7 @@ django.contrib.admin.widgets.BaseAdminDateWidget.Media
5446
django.contrib.admindocs.utils.non_capturing_group_matcher
5547
django.contrib.admindocs.utils.remove_non_capturing_groups
5648
django.contrib.admindocs.utils.replace_metacharacters
57-
django.contrib.auth.admin.GroupAdmin
5849
django.contrib.auth.admin.GroupAdmin.formfield_for_manytomany
59-
django.contrib.auth.admin.UserAdmin
6050
django.contrib.auth.admin.UserAdmin.fieldsets
6151
django.contrib.auth.admin.UserAdmin.form
6252
django.contrib.auth.admin.UserAdmin.get_form
@@ -124,12 +114,9 @@ django.contrib.auth.views.LoginView.form_class
124114
django.contrib.auth.views.PasswordChangeView.form_class
125115
django.contrib.auth.views.PasswordResetConfirmView.form_class
126116
django.contrib.auth.views.PasswordResetView.form_class
127-
django.contrib.contenttypes.admin.GenericInlineModelAdmin
128117
django.contrib.contenttypes.admin.GenericInlineModelAdmin.ct_field
129118
django.contrib.contenttypes.admin.GenericInlineModelAdmin.ct_fk_field
130119
django.contrib.contenttypes.admin.GenericInlineModelAdmin.template
131-
django.contrib.contenttypes.admin.GenericStackedInline
132-
django.contrib.contenttypes.admin.GenericTabularInline
133120
django.contrib.contenttypes.fields.GenericRelation.contribute_to_class
134121
django.contrib.contenttypes.fields.GenericRelation.get_extra_restriction
135122
django.contrib.contenttypes.forms.generic_inlineformset_factory
@@ -139,7 +126,6 @@ django.contrib.contenttypes.models.ContentType.app_labeled_name
139126
django.contrib.contenttypes.models.ContentType.id
140127
django.contrib.contenttypes.models.ContentType.model
141128
django.contrib.contenttypes.models.ContentTypeManager.__init__
142-
django.contrib.flatpages.admin.FlatPageAdmin
143129
django.contrib.flatpages.models.FlatPage.content
144130
django.contrib.flatpages.models.FlatPage.enable_comments
145131
django.contrib.flatpages.models.FlatPage.id
@@ -148,12 +134,7 @@ django.contrib.flatpages.models.FlatPage.sites
148134
django.contrib.flatpages.models.FlatPage.template_name
149135
django.contrib.flatpages.models.FlatPage.title
150136
django.contrib.flatpages.models.FlatPage.url
151-
django.contrib.gis.admin.GISModelAdmin
152137
django.contrib.gis.admin.GISModelAdmin.gis_widget
153-
django.contrib.gis.admin.ModelAdmin
154-
django.contrib.gis.admin.StackedInline
155-
django.contrib.gis.admin.TabularInline
156-
django.contrib.gis.admin.options.GISModelAdmin
157138
django.contrib.gis.admin.options.GISModelAdmin.gis_widget
158139
django.contrib.gis.admin.options.GeoModelAdminMixin
159140
django.contrib.gis.admin.site
@@ -388,7 +369,6 @@ django.contrib.postgres.fields.hstore.HStoreField.formfield
388369
django.contrib.postgres.fields.ranges.RangeField.formfield
389370
django.contrib.postgres.forms.BaseRangeField.hidden_widget
390371
django.contrib.postgres.forms.ranges.BaseRangeField.hidden_widget
391-
django.contrib.redirects.admin.RedirectAdmin
392372
django.contrib.redirects.models.Redirect.id
393373
django.contrib.redirects.models.Redirect.new_path
394374
django.contrib.redirects.models.Redirect.old_path
@@ -407,7 +387,6 @@ django.contrib.sessions.models.Session.get_previous_by_expire_date
407387
django.contrib.sessions.models.Session.session_data
408388
django.contrib.sessions.models.Session.session_key
409389
django.contrib.sitemaps.views.SitemapIndexItem
410-
django.contrib.sites.admin.SiteAdmin
411390
django.contrib.sites.models.Site.domain
412391
django.contrib.sites.models.Site.flatpage_set
413392
django.contrib.sites.models.Site.id
@@ -984,7 +963,6 @@ django.forms.fields.MultiValueField.__deepcopy__
984963
django.forms.fields.MultipleChoiceField.hidden_widget
985964
django.forms.fields.SplitDateTimeField.hidden_widget
986965
django.forms.forms.BaseForm.__init__
987-
django.forms.forms.DeclarativeFieldsMetaclass.__new__
988966
django.forms.formset_factory
989967
django.forms.formsets.BaseFormSet.__init__
990968
django.forms.formsets.ManagementForm.__init__
@@ -995,7 +973,6 @@ django.forms.modelformset_factory
995973
django.forms.models.BaseModelForm.__init__
996974
django.forms.models.BaseModelFormSet.model
997975
django.forms.models.ModelChoiceField.__deepcopy__
998-
django.forms.models.ModelFormMetaclass.__new__
999976
django.forms.models.ModelMultipleChoiceField.hidden_widget
1000977
django.forms.models.inlineformset_factory
1001978
django.forms.models.modelform_factory
@@ -1004,7 +981,6 @@ django.forms.renderers.DjangoDivFormRenderer
1004981
django.forms.widgets.ChoiceWidget.template_name
1005982
django.forms.widgets.Input.input_type
1006983
django.forms.widgets.Media.__html__
1007-
django.forms.widgets.MediaDefiningClass.__new__
1008984
django.forms.widgets.MultiWidget.use_fieldset
1009985
django.forms.widgets.RadioSelect.id_for_label
1010986
django.forms.widgets.RadioSelect.use_fieldset

0 commit comments

Comments
 (0)