Skip to content

Commit 6c6505b

Browse files
authored
Upgrade utils.deprecated & add utils.warn_deprecated (#1657)
1 parent 759cedb commit 6c6505b

File tree

1 file changed

+75
-8
lines changed

1 file changed

+75
-8
lines changed

discord/utils.py

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -268,20 +268,87 @@ def decorator(overridden: T) -> T:
268268
return decorator
269269

270270

271+
def warn_deprecated(
272+
name: str,
273+
instead: Optional[str] = None,
274+
since: Optional[str] = None,
275+
removed: Optional[str] = None,
276+
reference: Optional[str] = None,
277+
) -> None:
278+
"""Warn about a deprecated function, with the ability to specify details about the deprecation. Emits a
279+
DeprecationWarning.
280+
281+
Parameters
282+
----------
283+
name: str
284+
The name of the deprecated function.
285+
instead: Optional[:class:`str`]
286+
A recommended alternative to the function.
287+
since: Optional[:class:`str`]
288+
The version in which the function was deprecated. This should be in the format ``major.minor(.patch)``, where
289+
the patch version is optional.
290+
removed: Optional[:class:`str]
291+
The version in which the function is planned to be removed. This should be in the format
292+
``major.minor(.patch)``, where the patch version is optional.
293+
reference: Optional[:class:`str`]
294+
A reference that explains the deprecation, typically a URL to a page such as a changelog entry or a GitHub
295+
issue/PR.
296+
"""
297+
warnings.simplefilter("always", DeprecationWarning) # turn off filter
298+
message = f"{name} is deprecated"
299+
if since:
300+
message += f" since version {since}"
301+
if removed:
302+
message += f" and will be removed in version {removed}"
303+
if instead:
304+
message += f", consider using {instead} instead"
305+
message += "."
306+
if reference:
307+
message += f" See {reference} for more information."
308+
309+
warnings.warn(message, stacklevel=3, category=DeprecationWarning)
310+
warnings.simplefilter("default", DeprecationWarning) # reset filter
311+
312+
271313
def deprecated(
272314
instead: Optional[str] = None,
315+
since: Optional[str] = None,
316+
removed: Optional[str] = None,
317+
reference: Optional[str] = None,
318+
*,
319+
use_qualname: bool = True,
273320
) -> Callable[[Callable[[P], T]], Callable[[P], T]]:
321+
"""A decorator implementation of :func:`warn_deprecated`. This will automatically call :func:`warn_deprecated` when
322+
the decorated function is called.
323+
324+
Parameters
325+
----------
326+
instead: Optional[:class:`str`]
327+
A recommended alternative to the function.
328+
since: Optional[:class:`str`]
329+
The version in which the function was deprecated. This should be in the format ``major.minor(.patch)``, where
330+
the patch version is optional.
331+
removed: Optional[:class:`str]
332+
The version in which the function is planned to be removed. This should be in the format
333+
``major.minor(.patch)``, where the patch version is optional.
334+
reference: Optional[:class:`str`]
335+
A reference that explains the deprecation, typically a URL to a page such as a changelog entry or a GitHub
336+
issue/PR.
337+
use_qualname: :class:`bool`
338+
Whether to use the qualified name of the function in the deprecation warning. If ``False``, the short name of
339+
the function will be used instead. For example, __qualname__ will display as ``Client.login`` while __name__
340+
will display as ``login``. Defaults to ``True``.
341+
"""
274342
def actual_decorator(func: Callable[[P], T]) -> Callable[[P], T]:
275343
@functools.wraps(func)
276344
def decorated(*args: P.args, **kwargs: P.kwargs) -> T:
277-
warnings.simplefilter("always", DeprecationWarning) # turn off filter
278-
if instead:
279-
fmt = "{0.__name__} is deprecated, use {1} instead."
280-
else:
281-
fmt = "{0.__name__} is deprecated."
282-
283-
warnings.warn(fmt.format(func, instead), stacklevel=3, category=DeprecationWarning)
284-
warnings.simplefilter("default", DeprecationWarning) # reset filter
345+
warn_deprecated(
346+
name=func.__qualname__ if use_qualname else func.__name__,
347+
instead=instead,
348+
since=since,
349+
removed=removed,
350+
reference=reference,
351+
)
285352
return func(*args, **kwargs)
286353

287354
return decorated

0 commit comments

Comments
 (0)