mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-08 17:13:56 +00:00
Merge pull request #185 from Birdi7/add_rename_argument_decorator
Add rename argument decorator
This commit is contained in:
commit
f27b262335
2 changed files with 68 additions and 8 deletions
|
|
@ -1,10 +1,7 @@
|
|||
"""
|
||||
Source: https://stackoverflow.com/questions/2536307/decorators-in-the-python-standard-lib-deprecated-specifically
|
||||
"""
|
||||
|
||||
import functools
|
||||
import inspect
|
||||
import warnings
|
||||
import asyncio
|
||||
|
||||
|
||||
def deprecated(reason):
|
||||
|
|
@ -12,6 +9,8 @@ def deprecated(reason):
|
|||
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/decorators-in-the-python-standard-lib-deprecated-specifically
|
||||
"""
|
||||
|
||||
if isinstance(reason, str):
|
||||
|
|
@ -41,7 +40,7 @@ def deprecated(reason):
|
|||
|
||||
return decorator
|
||||
|
||||
elif inspect.isclass(reason) or inspect.isfunction(reason):
|
||||
if inspect.isclass(reason) or inspect.isfunction(reason):
|
||||
|
||||
# The @deprecated is used without any 'reason'.
|
||||
#
|
||||
|
|
@ -65,11 +64,71 @@ def deprecated(reason):
|
|||
|
||||
return wrapper1
|
||||
|
||||
else:
|
||||
raise TypeError(repr(type(reason)))
|
||||
raise TypeError(repr(type(reason)))
|
||||
|
||||
|
||||
def warn_deprecated(message, warning=DeprecationWarning, stacklevel=2):
|
||||
warnings.simplefilter('always', warning)
|
||||
warnings.warn(message, category=warning, stacklevel=stacklevel)
|
||||
warnings.simplefilter('default', warning)
|
||||
|
||||
|
||||
def renamed_argument(old_name: str, new_name: str, until_version: str, stacklevel: int = 3):
|
||||
"""
|
||||
A meta-decorator to mark an argument as deprecated.
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
@renamed_argument("chat", "chat_id", "3.0") # stacklevel=3 by default
|
||||
@renamed_argument("user", "user_id", "3.0", stacklevel=4)
|
||||
def some_function(user_id, chat_id=None):
|
||||
print(f"user_id={user_id}, chat_id={chat_id}")
|
||||
|
||||
some_function(user=123) # prints 'user_id=123, chat_id=None' with warning
|
||||
some_function(123) # prints 'user_id=123, chat_id=None' without warning
|
||||
some_function(user_id=123) # prints 'user_id=123, chat_id=None' without warning
|
||||
|
||||
|
||||
:param old_name:
|
||||
:param new_name:
|
||||
:param until_version: the version in which the argument is scheduled to be removed
|
||||
:param stacklevel: leave it to default if it's the first decorator used.
|
||||
Increment with any new decorator used.
|
||||
:return: decorator
|
||||
"""
|
||||
|
||||
def decorator(func):
|
||||
if asyncio.iscoroutinefunction(func):
|
||||
@functools.wraps(func)
|
||||
async def wrapped(*args, **kwargs):
|
||||
if old_name in kwargs:
|
||||
warn_deprecated(f"In coroutine '{func.__name__}' argument '{old_name}' "
|
||||
f"is renamed to '{new_name}' "
|
||||
f"and will be removed in aiogram {until_version}",
|
||||
stacklevel=stacklevel)
|
||||
kwargs.update(
|
||||
{
|
||||
new_name: kwargs[old_name],
|
||||
}
|
||||
)
|
||||
kwargs.pop(old_name)
|
||||
await func(*args, **kwargs)
|
||||
else:
|
||||
@functools.wraps(func)
|
||||
def wrapped(*args, **kwargs):
|
||||
if old_name in kwargs:
|
||||
warn_deprecated(f"In function `{func.__name__}` argument `{old_name}` "
|
||||
f"is renamed to `{new_name}` "
|
||||
f"and will be removed in aiogram {until_version}",
|
||||
stacklevel=stacklevel)
|
||||
kwargs.update(
|
||||
{
|
||||
new_name: kwargs[old_name],
|
||||
}
|
||||
)
|
||||
kwargs.pop(old_name)
|
||||
func(*args, **kwargs)
|
||||
|
||||
return wrapped
|
||||
|
||||
return decorator
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
==========
|
||||
Deprecated
|
||||
==========
|
||||
Coming soon...
|
||||
.. automodule:: aiogram.utils.deprecated
|
||||
:members:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue