Last active
March 20, 2020 14:11
-
-
Save victorusachev/6ed2b03ed5bcd83197b1e2a95c0345fc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from __future__ import annotations | |
| import functools | |
| import inspect | |
| import warnings | |
| from typing import Callable, Type, Union | |
| __all__ = ('DEFAULT_STACK_LEVEL', 'deprecated', 'pending_deprecation', 'warn') | |
| DEFAULT_STACK_LEVEL = 3 | |
| def deprecated( | |
| reason: Union[str, Callable], | |
| warning: Type[Warning] = DeprecationWarning, | |
| stacklevel: int = DEFAULT_STACK_LEVEL, | |
| ) -> Callable: | |
| """ | |
| This is a decorator which can be used to mark functions | |
| as deprecated. It will result in a warning being emitted | |
| when the function is used. | |
| Source: https://stackoverflow.com/questions/2536307/ | |
| """ | |
| def _factory(msg_fmt, **extra): | |
| def decorated(func): | |
| if inspect.isfunction(func): | |
| type_ = 'function' | |
| class_ = None | |
| elif inspect.isclass(func): | |
| type_ = 'class' | |
| class_, func = func, func.__init__ | |
| else: | |
| raise TypeError( | |
| f'decorated object must be str, function or class, ' | |
| f'not {func}' | |
| ) | |
| msg = msg_fmt.format( | |
| name=(class_ or func).__qualname__, type=type_, **extra | |
| ) | |
| @functools.wraps(func) | |
| def wrapper(*args, **kwargs): | |
| warn(msg, warning=warning, stacklevel=stacklevel) | |
| return func(*args, **kwargs) | |
| if class_: | |
| class_.__init__ = wrapper | |
| wrapper = class_ | |
| return wrapper | |
| return decorated | |
| if isinstance(reason, str): | |
| return _factory( | |
| 'Call to deprecated {type} {name} ({reason}).', reason=reason | |
| ) | |
| else: | |
| return _factory('Call to deprecated {type} {name}.')(func=reason) | |
| def warn( | |
| msg: str, | |
| warning: Type[Warning] = DeprecationWarning, | |
| stacklevel: int = DEFAULT_STACK_LEVEL, | |
| ): | |
| warnings.simplefilter('always', warning) | |
| warnings.warn(msg, category=warning, stacklevel=stacklevel) | |
| warnings.simplefilter('default', warning) | |
| def pending_deprecation(reason: Union[str, Callable]): | |
| default_reason = 'This feature will be deprecated in the future' | |
| if isinstance(reason, str): | |
| return deprecated(reason, warning=PendingDeprecationWarning) | |
| f = reason | |
| return deprecated(default_reason, warning=PendingDeprecationWarning)(f) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment