Skip to content

Commit

Permalink
feature(ooo): add deprecated function decorator (#778)
Browse files Browse the repository at this point in the history
* Add deprecated function decorator

* add None for up_to default

* apply suggestion: \n- add unittest\n- add typelint\n- fix docstring style

* remove blank row
  • Loading branch information
ooooo-create committed Mar 7, 2024
1 parent e28438c commit 0591b5e
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
52 changes: 52 additions & 0 deletions ding/utils/deprecation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import functools
import textwrap
import warnings
from typing import Optional


def deprecated(since: str, removed_in: str, up_to: Optional[str] = None):
"""
Overview:
Decorate a function to signify its deprecation.
Arguments:
- since (:obj:`str`): the version when the function was first deprecated.
- removed_in (:obj:`str`): the version when the function will be removed.
- up_to (:obj:`Optional[str]`): the new API users should use.
Returns:
- decorator (:obj:`Callable`): decorated function.
Examples:
>>> from ding.utils.deprecation import deprecated
>>> @deprecated('0.4.1', '0.5.1')
>>> def hello():
>>> print('hello')
"""

def decorator(func):
existing_docstring = func.__doc__ or ""

deprecated_doc = f'.. deprecated:: {since}\n Deprecated and will be removed in version {removed_in}'

if up_to is not None:
deprecated_doc += f', please use `{up_to}` instead.'
else:
deprecated_doc += '.'

func.__doc__ = deprecated_doc + "\n\n" + textwrap.dedent(existing_docstring)

@functools.wraps(func)
def wrapper(*args, **kwargs):
warning_msg = (
f'API `{func.__module__}.{func.__name__}` is deprecated since version {since} '
f'and will be removed in version {removed_in}'
)
if up_to is not None:
warning_msg += f", please use `{up_to}` instead."
else:
warning_msg += "."

warnings.warn(warning_msg, category=FutureWarning, stacklevel=2)
return func(*args, **kwargs)

return wrapper

return decorator
28 changes: 28 additions & 0 deletions ding/utils/tests/test_deprecation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import pytest
import warnings
from ding.utils.deprecation import deprecated


@pytest.mark.unittest
def test_deprecated():

@deprecated('0.4.1', '0.5.1')
def deprecated_func1():
pass

@deprecated('0.4.1', '0.5.1', 'deprecated_func3')
def deprecated_func2():
pass

with warnings.catch_warnings(record=True) as w:
deprecated_func1()
assert (
'API `test_deprecation.deprecated_func1` is deprecated '
'since version 0.4.1 and will be removed in version 0.5.1.'
) == str(w[-1].message)
deprecated_func2()
assert (
'API `test_deprecation.deprecated_func2` is deprecated '
'since version 0.4.1 and will be removed in version 0.5.1, '
'please use `deprecated_func3` instead.'
) == str(w[-1].message)

0 comments on commit 0591b5e

Please sign in to comment.