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 deprecated decorators for multiple classes and methods #2458

Merged
merged 1 commit into from
Dec 6, 2024
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
2 changes: 2 additions & 0 deletions django-stubs/contrib/admin/models.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ from uuid import UUID

from django.db import models
from django.db.models.base import Model
from typing_extensions import deprecated

ADDITION: int
CHANGE: int
DELETION: int
ACTION_FLAG_CHOICES: Any

class LogEntryManager(models.Manager[LogEntry]):
@deprecated("log_action() is deprecated and will be removed in Django 6.0. Use log_action_new() instead.")
def log_action(
self,
user_id: int,
Expand Down
4 changes: 3 additions & 1 deletion django-stubs/contrib/admin/options.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ from django.urls.resolvers import URLPattern
from django.utils.datastructures import _ListOrTuple
from django.utils.functional import _StrOrPromise
from django.utils.safestring import SafeString
from typing_extensions import Self, TypeAlias, TypedDict
from typing_extensions import Self, TypeAlias, TypedDict, deprecated

IS_POPUP_VAR: str
TO_FIELD_VAR: str
Expand Down Expand Up @@ -129,6 +129,7 @@ class BaseModelAdmin(Generic[_ModelT]):
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) -> _DisplayT[_ModelT]: ...
@deprecated("The None value for the request parameter will be removed in Django 6.0.")
Copy link
Contributor

Choose a reason for hiding this comment

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

This one should be removed. @deprecated can only be used if the whole function is deprecated, not changes to types for individual parameters. This will cause the deprecation to be shown even if request is not None.

Copy link
Contributor

Choose a reason for hiding this comment

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

Alternatively, deprecated overloads can be used.

Copy link
Contributor

Choose a reason for hiding this comment

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

Of course, yes!

def lookup_allowed(self, lookup: str, value: str, request: HttpRequest | None = ...) -> bool: ...
def to_field_allowed(self, request: HttpRequest, to_field: str) -> bool: ...
def has_add_permission(self, request: HttpRequest) -> bool: ...
Expand Down Expand Up @@ -205,6 +206,7 @@ class ModelAdmin(BaseModelAdmin[_ModelT]):
) -> Paginator: ...
def log_addition(self, request: HttpRequest, obj: _ModelT, message: Any) -> LogEntry: ...
def log_change(self, request: HttpRequest, obj: _ModelT, message: Any) -> LogEntry: ...
@deprecated("log_deletion() is deprecated and will be removed in Django 6.0. Use log_deletions() instead.")
def log_deletion(self, request: HttpRequest, obj: _ModelT, object_repr: str) -> LogEntry: ...
def action_checkbox(self, obj: _ModelT) -> SafeString: ...
def get_actions(self, request: HttpRequest) -> dict[str, tuple[Callable[..., str], str, str] | None]: ...
Expand Down
4 changes: 4 additions & 0 deletions django-stubs/contrib/contenttypes/fields.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ from django.db.models.fields.reverse_related import ForeignObjectRel
from django.db.models.query import QuerySet
from django.db.models.query_utils import FilteredRelation, PathInfo
from django.db.models.sql.where import WhereNode
from typing_extensions import deprecated

class GenericForeignKey(FieldCacheMixin):
# django-stubs implementation only fields
Expand Down Expand Up @@ -45,6 +46,9 @@ class GenericForeignKey(FieldCacheMixin):
def get_content_type(
self, obj: Model | None = ..., id: int | None = ..., using: str | None = ..., model: type[Model] | None = ...
) -> ContentType: ...
@deprecated(
"get_prefetch_queryset() is deprecated and will be removed in Django 6.0. Use get_prefetch_querysets() instead."
)
def get_prefetch_queryset(
self, instances: list[Model] | QuerySet, queryset: QuerySet | None = ...
) -> tuple[list[Model], Callable, Callable, bool, str, bool]: ...
Expand Down
3 changes: 3 additions & 0 deletions django-stubs/contrib/gis/geoip2/base.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ from typing import Any

from django.contrib.gis.geos import Point
from django.utils.functional import cached_property
from typing_extensions import deprecated

GEOIP_SETTINGS: dict[str, Any]

Expand All @@ -28,11 +29,13 @@ class GeoIP2:
def is_city(self) -> bool: ...
@cached_property
def is_country(self) -> bool: ...
@deprecated("The coords() is deprecated and will be removed in Django 6.0. Use lon_lat() instead.")
def coords(self, query: str, ordering: Sequence[str] = ...) -> tuple[float, float] | tuple[None, None]: ...
def lon_lat(self, query: str) -> tuple[float, float] | tuple[None, None]: ...
def lat_lon(self, query: str) -> tuple[float, float] | tuple[None, None]: ...
def geos(self, query: str) -> Point: ...
@property
def info(self) -> str: ...
@classmethod
@deprecated("The open() is deprecated and will be removed in Django 6.0. Use GeoIP2() instead.")
def open(cls, full_path: Path | str | None, cache: int) -> Any: ...
1 change: 1 addition & 0 deletions django-stubs/core/files/storage/filesystem.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ from .base import Storage
from .mixins import StorageSettingsMixin

class FileSystemStorage(_Deconstructible, Storage, StorageSettingsMixin):
# RemovedInDjango60Warning
OS_OPEN_FLAGS: int

def __init__(
Expand Down
2 changes: 2 additions & 0 deletions django-stubs/db/backends/base/operations.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ from django.db.models.constants import OnConflict
from django.db.models.expressions import Case, Col, Expression
from django.db.models.fields import Field
from django.db.models.sql.compiler import SQLCompiler
from typing_extensions import deprecated

class BaseDatabaseOperations:
compiler_module: str
Expand Down Expand Up @@ -44,6 +45,7 @@ class BaseDatabaseOperations:
def deferrable_sql(self) -> str: ...
def distinct_sql(self, fields: list[str], params: list[Any] | None) -> tuple[list[str], list[str]]: ...
def fetch_returned_insert_columns(self, cursor: Any, returning_params: Any) -> Any: ...
@deprecated("The field_cast_sql() is deprecated and will be removed in Django 6.0. Use lookup_cast() instead.")
def field_cast_sql(self, db_type: str | None, internal_type: str) -> str: ...
def force_no_ordering(self) -> list[Any]: ...
def for_update_sql(
Expand Down
3 changes: 2 additions & 1 deletion django-stubs/db/models/enums.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ from typing import Any, TypeVar, overload, type_check_only

from _typeshed import ConvertibleToInt
from django.utils.functional import _StrOrPromise
from typing_extensions import TypeAlias
from typing_extensions import TypeAlias, deprecated

_Self = TypeVar("_Self")

Expand All @@ -21,6 +21,7 @@ else:
class IntEnum(int, ReprEnum): ...
class StrEnum(str, ReprEnum): ...

@deprecated("ChoicesMeta is deprecated in favor of ChoicesType and will be removed in Django 6.0.")
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure that this works either as ChoicesType is aliased to ChoicesMeta so will show the same deprecation warning.

As an aside, we should probably also invert the alias so that we have class ChoicesType(EnumType) and ChoicesMeta = ChoicesType for the alias.

class ChoicesMeta(EnumType):
# There's a contradiction between mypy and PYI019 regarding metaclasses. Where mypy
# disallows 'typing_extensions.Self' on metaclasses, while PYI019 try to enforce
Expand Down
2 changes: 2 additions & 0 deletions django-stubs/db/models/fields/mixins.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ from typing import Any

from django.db.models.base import Model
from django.utils.functional import cached_property
from typing_extensions import deprecated

NOT_PROVIDED: Any

class FieldCacheMixin:
def get_cache_name(self) -> str: ...
@cached_property
@deprecated("The cache_name() is deprecated and will be removed in Django 6.0. Use get_cache_name() instead.")
def cache_name(self) -> str: ...
def get_cached_value(self, instance: Model, default: Any = ...) -> Model | None: ...
def is_cached(self, instance: Model) -> bool: ...
Expand Down
8 changes: 7 additions & 1 deletion django-stubs/db/models/fields/related_descriptors.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ from django.db.models.manager import BaseManager, Manager
from django.db.models.query import QuerySet
from django.db.models.query_utils import DeferredAttribute
from django.utils.functional import cached_property
from typing_extensions import Self
from typing_extensions import Self, deprecated

_M = TypeVar("_M", bound=Model)
_F = TypeVar("_F", bound=Field)
Expand All @@ -28,6 +28,9 @@ class ForwardManyToOneDescriptor(Generic[_F]):
def RelatedObjectDoesNotExist(self) -> type[ObjectDoesNotExist]: ...
def is_cached(self, instance: Model) -> bool: ...
def get_queryset(self, **hints: Any) -> QuerySet[Any]: ...
@deprecated(
"get_prefetch_queryset() is deprecated and will be removed in Django 6.0. Use get_prefetch_querysets() instead."
)
def get_prefetch_queryset(
self, instances: list[Model], queryset: QuerySet[Any] | None = None
) -> tuple[QuerySet[Any], Callable[..., Any], Callable[..., Any], bool, str, bool]: ...
Expand Down Expand Up @@ -60,6 +63,9 @@ class ReverseOneToOneDescriptor(Generic[_From, _To]):
def RelatedObjectDoesNotExist(self) -> type[ObjectDoesNotExist]: ...
def is_cached(self, instance: _From) -> bool: ...
def get_queryset(self, **hints: Any) -> QuerySet[_To]: ...
@deprecated(
"get_prefetch_queryset() is deprecated and will be removed in Django 6.0. Use get_prefetch_querysets() instead."
)
def get_prefetch_queryset(
self, instances: list[_From], queryset: QuerySet[_To] | None = None
) -> tuple[QuerySet[_To], Callable[..., Any], Callable[..., Any], bool, str, bool]: ...
Expand Down
4 changes: 4 additions & 0 deletions django-stubs/db/models/fields/reverse_related.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ from django.db.models.lookups import Lookup, StartsWith, Transform
from django.db.models.query_utils import FilteredRelation, PathInfo
from django.db.models.sql.where import WhereNode
from django.utils.functional import cached_property
from typing_extensions import deprecated

from .mixins import FieldCacheMixin

Expand Down Expand Up @@ -77,6 +78,9 @@ class ForeignObjectRel(FieldCacheMixin):
ordering: Sequence[str] = (),
) -> _ChoicesList: ...
def is_hidden(self) -> bool: ...
@deprecated(
"The get_joining_columns() is deprecated and will be removed in Django 6.0. Use get_joining_fields() instead."
)
def get_joining_columns(self) -> tuple: ...
def get_joining_fields(self) -> tuple[tuple[Field, Field], ...]: ...
def get_extra_restriction(
Expand Down
5 changes: 4 additions & 1 deletion django-stubs/db/models/query.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ from django.db.models.base import Model
from django.db.models.expressions import Combinable, OrderBy
from django.db.models.sql.query import Query, RawQuery
from django.utils.functional import cached_property
from typing_extensions import Self, TypeAlias, TypeVar
from typing_extensions import Self, TypeAlias, TypeVar, deprecated

_T = TypeVar("_T", covariant=True)
_Model = TypeVar("_Model", bound=Model, covariant=True)
Expand Down Expand Up @@ -240,6 +240,9 @@ class Prefetch:
def add_prefix(self, prefix: str) -> None: ...
def get_current_prefetch_to(self, level: int) -> str: ...
def get_current_to_attr(self, level: int) -> tuple[str, str]: ...
@deprecated(
"The get_current_queryset() is deprecated and will be removed in Django 6.0. Use get_current_querysets() instead."
)
def get_current_queryset(self, level: int) -> QuerySet | None: ...
def get_current_querysets(self, level: int) -> list[QuerySet] | None: ...

Expand Down
4 changes: 4 additions & 0 deletions django-stubs/forms/renderers.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ from django.template.backends.django import DjangoTemplates as DjangoTemplatesR
from django.template.backends.jinja2 import Jinja2 as Jinja2R
from django.template.base import Template
from django.utils.functional import cached_property
from typing_extensions import deprecated

def get_default_renderer() -> BaseRenderer: ...

Expand All @@ -28,6 +29,9 @@ class Jinja2(EngineMixin, BaseRenderer):
@cached_property
def backend(self) -> type[Jinja2R]: ...

@deprecated(
"The Jinja2DivFormRenderer transitional form renderer is deprecated and will be removed in Django 6.0. Use Jinja2 instead."
)
class Jinja2DivFormRenderer(Jinja2):
form_template_name: str
formset_template_name: str
Expand Down
2 changes: 2 additions & 0 deletions django-stubs/utils/html.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ from typing import Any
from _typeshed import Incomplete
from django.utils.functional import SimpleLazyObject, _StrOrPromise
from django.utils.safestring import SafeData, SafeString
from typing_extensions import deprecated

VOID_ELEMENTS: frozenset[str]
MAX_URL_LENGTH: int
Expand All @@ -19,6 +20,7 @@ def json_script(value: Any, element_id: str | None = None, encoder: type[JSONEnc

# conditional_escape could use a protocol to be more precise, see https://github.com/typeddjango/django-stubs/issues/1474
def conditional_escape(text: _StrOrPromise | SafeData) -> SafeString: ...
@deprecated("Calling format_html() without passing args or kwargs is deprecated.")
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, it's not possible to use @deprecated here without false positives.

def format_html(format_string: str, *args: Any, **kwargs: Any) -> SafeString: ...
def format_html_join(sep: str, format_string: str, args_generator: Iterable[Iterable[Any]]) -> SafeString: ...
def linebreaks(value: Any, autoescape: bool = False) -> str: ...
Expand Down
5 changes: 5 additions & 0 deletions django-stubs/utils/itercompat.pyi
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
from typing import Any

from typing_extensions import deprecated

@deprecated(
"The django.utils.itercompat.is_iterable() is deprecated and will be removed in Django 6.0. Use isinstance(..., collections.abc.Iterable) instead."
Copy link
Contributor

Choose a reason for hiding this comment

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

There is a lot of "The module.function() is deprecated..." which doesn't read properly. In most cases we can probably drop the "The":

Suggested change
"The django.utils.itercompat.is_iterable() is deprecated and will be removed in Django 6.0. Use isinstance(..., collections.abc.Iterable) instead."
"django.utils.itercompat.is_iterable() is deprecated and will be removed in Django 6.0. Use isinstance(..., collections.abc.Iterable) instead."

Please review all the other introductions of this.

)
def is_iterable(x: Any) -> bool: ...
Loading