Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ClassVar annotations on mutable ModelAdmin types for ruff #2524

Merged
merged 6 commits into from
Mar 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 44 additions & 42 deletions django-stubs/contrib/admin/options.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import enum
from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
from typing import Any, Generic, Literal, TypeVar, cast, overload, type_check_only
from typing import Any, ClassVar, Generic, Literal, TypeVar, cast, overload, type_check_only

from django import forms
from django.contrib.admin.filters import FieldListFilter, ListFilter
Expand Down Expand Up @@ -84,23 +84,25 @@ _ListFilterT: TypeAlias = (
_ModelT = TypeVar("_ModelT", bound=Model)
_DisplayT: TypeAlias = _ListOrTuple[str | Callable[[_ModelT], str | bool]]

# Options `form`, `list_display`, `list_display_links` and `actions` are not marked as `ClassVar` due to the
# limitations of the current type system: `ClassVar` cannot contain type variables.
class BaseModelAdmin(Generic[_ModelT]):
autocomplete_fields: _ListOrTuple[str]
raw_id_fields: _ListOrTuple[str]
fields: _FieldGroups | None
exclude: _ListOrTuple[str] | None
fieldsets: _FieldsetSpec | None
autocomplete_fields: ClassVar[_ListOrTuple[str]]
raw_id_fields: ClassVar[_ListOrTuple[str]]
fields: ClassVar[_FieldGroups | None]
exclude: ClassVar[_ListOrTuple[str] | None]
fieldsets: ClassVar[_FieldsetSpec | None]
form: type[forms.ModelForm[_ModelT]]
filter_vertical: _ListOrTuple[str]
filter_horizontal: _ListOrTuple[str]
radio_fields: Mapping[str, _Direction]
prepopulated_fields: dict[str, Sequence[str]]
formfield_overrides: Mapping[type[Field], Mapping[str, Any]]
readonly_fields: _ListOrTuple[str]
ordering: _ListOrTuple[str] | None
sortable_by: _ListOrTuple[str] | None
show_full_result_count: bool
checks_class: Any
filter_vertical: ClassVar[_ListOrTuple[str]]
filter_horizontal: ClassVar[_ListOrTuple[str]]
radio_fields: ClassVar[Mapping[str, _Direction]]
prepopulated_fields: ClassVar[dict[str, Sequence[str]]]
formfield_overrides: ClassVar[Mapping[type[Field], Mapping[str, Any]]]
readonly_fields: ClassVar[_ListOrTuple[str]]
ordering: ClassVar[_ListOrTuple[str] | None]
sortable_by: ClassVar[_ListOrTuple[str] | None]
show_full_result_count: ClassVar[bool]
checks_class: ClassVar[Any]
model: type[_ModelT]
opts: Options[_ModelT]
admin_site: AdminSite
Expand Down Expand Up @@ -150,33 +152,33 @@ _ActionCallable: TypeAlias = Callable[[_ModelAdmin, HttpRequest, QuerySet[_Model
class ModelAdmin(BaseModelAdmin[_ModelT]):
list_display: _DisplayT[_ModelT]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, add a comment: why do we left these two without a ClassVar, so future users won't be confused.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in 3e2fdc8.

list_display_links: _DisplayT[_ModelT] | None
list_filter: _ListOrTuple[_ListFilterT]
list_select_related: bool | _ListOrTuple[str]
list_per_page: int
list_max_show_all: int
list_editable: _ListOrTuple[str]
search_fields: _ListOrTuple[str]
search_help_text: _StrOrPromise | None
date_hierarchy: str | None
save_as: bool
save_as_continue: bool
save_on_top: bool
paginator: type
preserve_filters: bool
show_facets: ShowFacets
inlines: _ListOrTuple[type[InlineModelAdmin]]
add_form_template: _TemplateForResponseT | None
change_form_template: _TemplateForResponseT | None
change_list_template: _TemplateForResponseT | None
delete_confirmation_template: _TemplateForResponseT | None
delete_selected_confirmation_template: _TemplateForResponseT | None
object_history_template: _TemplateForResponseT | None
popup_response_template: _TemplateForResponseT | None
list_filter: ClassVar[_ListOrTuple[_ListFilterT]]
list_select_related: ClassVar[bool | _ListOrTuple[str]]
list_per_page: ClassVar[int]
list_max_show_all: ClassVar[int]
list_editable: ClassVar[_ListOrTuple[str]]
search_fields: ClassVar[_ListOrTuple[str]]
search_help_text: ClassVar[_StrOrPromise | None]
date_hierarchy: ClassVar[str | None]
save_as: ClassVar[bool]
save_as_continue: ClassVar[bool]
save_on_top: ClassVar[bool]
paginator: ClassVar[type]
preserve_filters: ClassVar[bool]
show_facets: ClassVar[ShowFacets]
inlines: ClassVar[_ListOrTuple[type[InlineModelAdmin]]]
add_form_template: ClassVar[_TemplateForResponseT | None]
change_form_template: ClassVar[_TemplateForResponseT | None]
change_list_template: ClassVar[_TemplateForResponseT | None]
delete_confirmation_template: ClassVar[_TemplateForResponseT | None]
delete_selected_confirmation_template: ClassVar[_TemplateForResponseT | None]
object_history_template: ClassVar[_TemplateForResponseT | None]
popup_response_template: ClassVar[_TemplateForResponseT | None]
actions: Sequence[_ActionCallable[Self, _ModelT] | str] | None
action_form: Any
actions_on_top: bool
actions_on_bottom: bool
actions_selection_counter: bool
action_form: ClassVar[Any]
actions_on_top: ClassVar[bool]
actions_on_bottom: ClassVar[bool]
actions_selection_counter: ClassVar[bool]
model: type[_ModelT]
opts: Options[_ModelT]
admin_site: AdminSite
Expand Down
8 changes: 4 additions & 4 deletions django-stubs/contrib/flatpages/admin.pyi
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from typing import Any
from typing import Any, ClassVar

from django.contrib import admin
from django.contrib.flatpages.models import FlatPage

class FlatPageAdmin(admin.ModelAdmin[FlatPage]):
form: Any
fieldsets: Any
fieldsets: ClassVar[Any]
list_display: Any
list_filter: Any
search_fields: Any
list_filter: ClassVar[Any]
search_fields: ClassVar[Any]
8 changes: 4 additions & 4 deletions django-stubs/contrib/redirects/admin.pyi
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import Any
from typing import Any, ClassVar

from django.contrib import admin

class RedirectAdmin(admin.ModelAdmin):
list_display: Any
list_filter: Any
search_fields: Any
radio_fields: Any
list_filter: ClassVar[Any]
search_fields: ClassVar[Any]
radio_fields: ClassVar[Any]
4 changes: 2 additions & 2 deletions django-stubs/contrib/sites/admin.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Any
from typing import Any, ClassVar

from django.contrib import admin

class SiteAdmin(admin.ModelAdmin):
list_display: Any
search_fields: Any
search_fields: ClassVar[Any]
Loading