From 062a1717ab7bd8c4a97d43e00ea050df7dd026f9 Mon Sep 17 00:00:00 2001 From: Petter Friberg Date: Thu, 9 Nov 2023 10:13:26 +0100 Subject: [PATCH 1/2] Ensure multiple admin get methods returns either list or tuple The get methods serves as extension points for corresponding attributes on the admin class. Thus we align the return type of the the methods with their corresponding attribute's type. --- django-stubs/contrib/admin/options.pyi | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/django-stubs/contrib/admin/options.pyi b/django-stubs/contrib/admin/options.pyi index d364a5968..926c1669d 100644 --- a/django-stubs/contrib/admin/options.pyi +++ b/django-stubs/contrib/admin/options.pyi @@ -87,7 +87,7 @@ class BaseModelAdmin(Generic[_ModelT]): radio_fields: Mapping[str, _Direction] prepopulated_fields: dict[str, Sequence[str]] formfield_overrides: Mapping[type[Field], Mapping[str, Any]] - readonly_fields: _ListOrTuple[str] | None + readonly_fields: _ListOrTuple[str] ordering: _ListOrTuple[str] | None sortable_by: _ListOrTuple[str] | None view_on_site: bool | Callable[[_ModelT], str] @@ -107,18 +107,18 @@ class BaseModelAdmin(Generic[_ModelT]): def formfield_for_manytomany( self, db_field: ManyToManyField, request: HttpRequest, **kwargs: Any ) -> ModelMultipleChoiceField | None: ... - def get_autocomplete_fields(self, request: HttpRequest) -> Sequence[str]: ... + def get_autocomplete_fields(self, request: HttpRequest) -> _ListOrTuple[str]: ... def get_view_on_site_url(self, obj: _ModelT | None = ...) -> str | None: ... def get_empty_value_display(self) -> SafeString: ... - def get_exclude(self, request: HttpRequest, obj: _ModelT | None = ...) -> Sequence[str] | None: ... + def get_exclude(self, request: HttpRequest, obj: _ModelT | None = ...) -> _ListOrTuple[str] | None: ... def get_fields(self, request: HttpRequest, obj: _ModelT | None = ...) -> _FieldGroups: ... def get_fieldsets(self, request: HttpRequest, obj: _ModelT | None = ...) -> _FieldsetSpec: ... def get_inlines(self, request: HttpRequest, obj: _ModelT | None) -> list[type[InlineModelAdmin]]: ... - def get_ordering(self, request: HttpRequest) -> Sequence[str]: ... - def get_readonly_fields(self, request: HttpRequest, obj: _ModelT | None = ...) -> Sequence[str]: ... + def get_ordering(self, request: HttpRequest) -> _ListOrTuple[str]: ... + def get_readonly_fields(self, request: HttpRequest, obj: _ModelT | None = ...) -> _ListOrTuple[str]: ... def get_prepopulated_fields(self, request: HttpRequest, obj: _ModelT | None = ...) -> dict[str, Sequence[str]]: ... def get_queryset(self, request: HttpRequest) -> QuerySet[_ModelT]: ... - def get_sortable_by(self, request: HttpRequest) -> Sequence[str]: ... + def get_sortable_by(self, request: HttpRequest) -> _ListOrTuple[str] | _DisplayT: ... def lookup_allowed(self, lookup: str, value: str) -> bool: ... def to_field_allowed(self, request: HttpRequest, to_field: str) -> bool: ... def has_add_permission(self, request: HttpRequest) -> bool: ... @@ -202,9 +202,9 @@ class ModelAdmin(BaseModelAdmin[_ModelT]): def get_action(self, action: Callable | str) -> tuple[Callable[..., str], str, str] | None: ... def get_list_display(self, request: HttpRequest) -> _DisplayT: ... def get_list_display_links(self, request: HttpRequest, list_display: _DisplayT) -> _DisplayT: ... - def get_list_filter(self, request: HttpRequest) -> Sequence[_ListFilterT]: ... - def get_list_select_related(self, request: HttpRequest) -> bool | Sequence[str]: ... - def get_search_fields(self, request: HttpRequest) -> Sequence[str]: ... + def get_list_filter(self, request: HttpRequest) -> _ListOrTuple[_ListFilterT]: ... + def get_list_select_related(self, request: HttpRequest) -> bool | _ListOrTuple[str]: ... + def get_search_fields(self, request: HttpRequest) -> _ListOrTuple[str]: ... def get_search_results( self, request: HttpRequest, queryset: QuerySet, search_term: str ) -> tuple[QuerySet[_ModelT], bool]: ... From 4e881e762d1ad6250d412274976b2927fe523d12 Mon Sep 17 00:00:00 2001 From: Petter Friberg Date: Thu, 9 Nov 2023 10:33:13 +0100 Subject: [PATCH 2/2] fixup! Ensure multiple admin get methods returns either list or tuple --- django-stubs/contrib/admin/options.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/django-stubs/contrib/admin/options.pyi b/django-stubs/contrib/admin/options.pyi index 926c1669d..64cfb44a0 100644 --- a/django-stubs/contrib/admin/options.pyi +++ b/django-stubs/contrib/admin/options.pyi @@ -74,6 +74,7 @@ _ListFilterT: TypeAlias = ( # Generic type specifically for models, for use in BaseModelAdmin and subclasses # https://github.com/typeddjango/django-stubs/issues/482 _ModelT = TypeVar("_ModelT", bound=Model) +_DisplayT: TypeAlias = _ListOrTuple[str | Callable[[_ModelT], str | bool]] class BaseModelAdmin(Generic[_ModelT]): autocomplete_fields: _ListOrTuple[str] @@ -118,7 +119,7 @@ class BaseModelAdmin(Generic[_ModelT]): def get_readonly_fields(self, request: HttpRequest, obj: _ModelT | None = ...) -> _ListOrTuple[str]: ... def get_prepopulated_fields(self, request: HttpRequest, obj: _ModelT | None = ...) -> dict[str, Sequence[str]]: ... def get_queryset(self, request: HttpRequest) -> QuerySet[_ModelT]: ... - def get_sortable_by(self, request: HttpRequest) -> _ListOrTuple[str] | _DisplayT: ... + def get_sortable_by(self, request: HttpRequest) -> _DisplayT: ... def lookup_allowed(self, lookup: str, value: str) -> bool: ... def to_field_allowed(self, request: HttpRequest, to_field: str) -> bool: ... def has_add_permission(self, request: HttpRequest) -> bool: ... @@ -128,7 +129,6 @@ class BaseModelAdmin(Generic[_ModelT]): def has_view_or_change_permission(self, request: HttpRequest, obj: _ModelT | None = ...) -> bool: ... def has_module_permission(self, request: HttpRequest) -> bool: ... -_DisplayT: TypeAlias = _ListOrTuple[str | Callable[[_ModelT], str | bool]] _ModelAdmin = TypeVar("_ModelAdmin", bound=ModelAdmin) _ActionCallable: TypeAlias = Callable[[_ModelAdmin, HttpRequest, QuerySet[_ModelT]], HttpResponseBase | None]