Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ These changes are available on the `master` branch, but have not yet been releas

### Changed

- Migrated away from `utils.deprecated` in favor of `warnings.deprecated` for
deprecation warnings.
Comment thread
Paillat-dev marked this conversation as resolved.
Outdated
([#3042](https://github.com/Pycord-Development/pycord/pull/3042))
- Updated `Role.is_assignable()` to also check whether the bot has the `MANAGE_ROLES`
permission. ([#3048](https://github.com/Pycord-Development/pycord/pull/3048))

Expand Down
24 changes: 16 additions & 8 deletions discord/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,12 @@
import warnings
from importlib.metadata import PackageNotFoundError, version

from typing_extensions import TypedDict
from typing_extensions import TypedDict, deprecated

__all__ = ("__version__", "VersionInfo", "version_info")

from typing import Literal, NamedTuple

from .utils import deprecated

try:
__version__ = version("py-cord")
except PackageNotFoundError:
Expand Down Expand Up @@ -84,27 +82,37 @@ def advanced(self, value: object) -> None:
_advanced = value

@property
@deprecated("releaselevel", "2.4")
@deprecated(
"VersionInfo.release_level is deprecated since version 2.4, consider using releaselevel instead."
)
def release_level(self) -> Literal["alpha", "beta", "candidate", "final"]:
return self.releaselevel

@property
@deprecated('.advanced["serial"]', "2.4")
@deprecated(
'VersionInfo.serial is deprecated since version 2.4, consider using .advanced["serial"] instead.'
)
def serial(self) -> int:
return self.advanced["serial"]

@property
@deprecated('.advanced["build"]', "2.4")
@deprecated(
'VersionInfo.build is deprecated since version 2.4, consider using .advanced["build"] instead.'
)
def build(self) -> int | None:
return self.advanced["build"]

@property
@deprecated('.advanced["commit"]', "2.4")
@deprecated(
'VersionInfo.commit is deprecated since version 2.4, consider using .advanced["commit"] instead.'
)
def commit(self) -> str | None:
return self.advanced["commit"]

@property
@deprecated('.advanced["date"]', "2.4")
@deprecated(
'VersionInfo.date is deprecated since version 2.4, consider using .advanced["date"] instead.'
)
def date(self) -> datetime.date | None:
return self.advanced["date"]

Expand Down
14 changes: 6 additions & 8 deletions discord/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
overload,
)

from typing_extensions import deprecated

import discord.abc

from . import utils
Expand Down Expand Up @@ -3118,21 +3120,17 @@ async def create_forum_channel(self, name: str, **options: Any) -> ForumChannel:
"""
return await self.guild.create_forum_channel(name, category=self, **options)

@utils.deprecated(
since="2.7",
removed="3.0",
reference="NSFW categories are not available in the Discord API.",
@deprecated(
"CategoryChannel.is_nsfw is deprecated since version 2.7 and will be removed in version 3.0. NSFW categories are not available in the Discord API."
)
def is_nsfw(self) -> bool:
return False

# TODO: Remove in 3.0

@property
@utils.deprecated(
since="2.7",
removed="3.0",
reference="NSFW categories are not available in the Discord API.",
@deprecated(
"CategoryChannel.nsfw is deprecated since version 2.7 and will be removed in version 3.0. NSFW categories are not available in the Discord API."
)
def nsfw(self) -> bool:
return False
Expand Down
7 changes: 3 additions & 4 deletions discord/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
)

import aiohttp
from typing_extensions import deprecated

from . import utils
from .activity import ActivityTypes, BaseActivity, create_activity
Expand Down Expand Up @@ -1181,10 +1182,8 @@ def get_all_members(self) -> Generator[Member]:
for guild in self.guilds:
yield from guild.members

@utils.deprecated(
instead="Client.get_or_fetch(User, id)",
since="2.7",
removed="3.0",
@deprecated(
"Client.get_or_fetch_user is deprecated since version 2.7 and will be removed in version 3.0, consider using Client.get_or_fetch(User, id) instead."
)
async def get_or_fetch_user(self, id: int, /) -> User | None: # TODO: Remove in 3.0
"""|coro|
Expand Down
38 changes: 27 additions & 11 deletions discord/interactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import datetime
from typing import TYPE_CHECKING, Any, Coroutine, Union

from typing_extensions import deprecated

from . import utils
from .channel import ChannelType, PartialMessageable, _threaded_channel_factory
from .enums import (
Expand Down Expand Up @@ -222,6 +224,7 @@ def __init__(self, *, data: InteractionPayload, state: ConnectionState):
self._session: ClientSession = state.http._HTTPClient__session
self._original_response: InteractionMessage | None = None
self.callback: InteractionCallback | None = None
self._cs_channel: InteractionChannel | None = MISSING
self._from_data(data)

def _from_data(self, data: InteractionPayload):
Expand Down Expand Up @@ -356,14 +359,19 @@ def is_component(self) -> bool:
"""Indicates whether the interaction is a message component."""
return self.type == InteractionType.component

@utils.cached_slot_property("_cs_channel")
@utils.deprecated("Interaction.channel", "2.7", stacklevel=4)
@property
@deprecated(
"Interaction.cached_channel is deprecated since version 2.7, consider using Interaction.channel instead."
)
def cached_channel(self) -> InteractionChannel | None:
"""The cached channel from which the interaction was sent.
DM channels are not resolved. These are :class:`PartialMessageable` instead.

.. deprecated:: 2.7
"""
if self._cs_channel is not MISSING:
return self._cs_channel
r: InteractionChannel | None = None
guild = self.guild
channel = guild and guild._resolve_channel(self.channel_id)
if channel is None:
Expand All @@ -373,11 +381,11 @@ def cached_channel(self) -> InteractionChannel | None:
if self.guild_id is not None
else ChannelType.private
)
return PartialMessageable(
state=self._state, id=self.channel_id, type=type
)
return None
return channel
r = PartialMessageable(state=self._state, id=self.channel_id, type=type)
else:
r = channel
self._cs_channel = r
return r

@property
def permissions(self) -> Permissions:
Expand Down Expand Up @@ -495,7 +503,9 @@ async def original_response(self) -> InteractionMessage:
self._original_response = message
return message

@utils.deprecated("Interaction.original_response", "2.2")
@deprecated(
"Interaction.original_message is deprecated since version 2.2, consider using Interaction.original_response instead."
)
async def original_message(self):
"""An alias for :meth:`original_response`.

Expand Down Expand Up @@ -628,7 +638,9 @@ async def edit_original_response(

return message

@utils.deprecated("Interaction.edit_original_response", "2.2")
@deprecated(
"Interaction.edit_original_message is deprecated since version 2.2, consider using Interaction.edit_original_response instead."
)
async def edit_original_message(self, **kwargs):
"""An alias for :meth:`edit_original_response`.

Expand Down Expand Up @@ -686,7 +698,9 @@ async def delete_original_response(self, *, delay: float | None = None) -> None:
else:
await func

@utils.deprecated("Interaction.delete_original_response", "2.2")
@deprecated(
"Interaction.delete_original_message is deprecated since version 2.2, consider using Interaction.delete_original_response instead."
)
async def delete_original_message(self, **kwargs):
"""An alias for :meth:`delete_original_response`.

Expand Down Expand Up @@ -1384,7 +1398,9 @@ async def send_modal(self, modal: Modal) -> Interaction:
self._parent._state.store_modal(modal, self._parent.user.id)
return self._parent

@utils.deprecated("a button with type ButtonType.premium", "2.6")
@deprecated(
"InteractionResponse.premium_required is deprecated since version 2.6, consider using a button with type ButtonType.premium instead."
)
async def premium_required(self) -> Interaction:
"""|coro|

Expand Down
11 changes: 7 additions & 4 deletions discord/role.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

from typing import TYPE_CHECKING, Any, TypeVar

from typing_extensions import Self
from typing_extensions import Self, deprecated

from .asset import Asset
from .colour import Colour
Expand All @@ -39,7 +39,6 @@
MISSING,
_bytes_to_base64_data,
_get_as_snowflake,
deprecated,
snowflake_time,
warn_deprecated,
)
Expand Down Expand Up @@ -489,7 +488,9 @@ def permissions(self) -> Permissions:
return Permissions(self._permissions)

@property
@deprecated("colours.primary", "2.7")
@deprecated(
"Role.colour is deprecated since version 2.7, consider using colours.primary instead."
)
def colour(self) -> Colour:
"""Returns the role colour. Equivalent to :attr:`colours.primary`.
An alias exists under ``color``.
Expand All @@ -499,7 +500,9 @@ def colour(self) -> Colour:
return self.colours.primary

@property
@deprecated("colors.primary", "2.7")
@deprecated(
"Role.color is deprecated since version 2.7, consider using colors.primary instead."
)
def color(self) -> Colour:
"""Returns the role's primary color. Equivalent to :attr:`colors.primary`.
An alias exists under ``colour``.
Expand Down
52 changes: 0 additions & 52 deletions discord/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@
__all__ = (
"parse_time",
"warn_deprecated",
"deprecated",
"oauth_url",
"snowflake_time",
"time_snowflake",
Expand Down Expand Up @@ -345,57 +344,6 @@ def warn_deprecated(
warnings.warn(message, stacklevel=stacklevel, category=DeprecationWarning)


def deprecated(
instead: str | None = None,
since: str | None = None,
removed: str | None = None,
reference: str | None = None,
stacklevel: int = 3,
*,
use_qualname: bool = True,
) -> Callable[[Callable[[P], T]], Callable[[P], T]]:
"""A decorator implementation of :func:`warn_deprecated`. This will automatically call :func:`warn_deprecated` when
the decorated function is called.

Parameters
----------
instead: Optional[:class:`str`]
A recommended alternative to the function.
since: Optional[:class:`str`]
The version in which the function was deprecated. This should be in the format ``major.minor(.patch)``, where
the patch version is optional.
removed: Optional[:class:`str`]
The version in which the function is planned to be removed. This should be in the format
``major.minor(.patch)``, where the patch version is optional.
reference: Optional[:class:`str`]
A reference that explains the deprecation, typically a URL to a page such as a changelog entry or a GitHub
issue/PR.
stacklevel: :class:`int`
The stacklevel kwarg passed to :func:`warnings.warn`. Defaults to 3.
use_qualname: :class:`bool`
Whether to use the qualified name of the function in the deprecation warning. If ``False``, the short name of
the function will be used instead. For example, __qualname__ will display as ``Client.login`` while __name__
will display as ``login``. Defaults to ``True``.
"""

def actual_decorator(func: Callable[[P], T]) -> Callable[[P], T]:
@functools.wraps(func)
def decorated(*args: P.args, **kwargs: P.kwargs) -> T:
warn_deprecated(
name=func.__qualname__ if use_qualname else func.__name__,
instead=instead,
since=since,
removed=removed,
reference=reference,
stacklevel=stacklevel,
)
return func(*args, **kwargs)

return decorated

return actual_decorator


def oauth_url(
client_id: int | str,
*,
Expand Down