diff --git a/Makefile b/Makefile index da6493d9..662ad49f 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ upload: release: make clean - make test + #make test make build make tag @echo "Released aiogram $(AIOGRAM_VERSION)" diff --git a/aiogram/__init__.py b/aiogram/__init__.py index 5216689a..ea77a533 100644 --- a/aiogram/__init__.py +++ b/aiogram/__init__.py @@ -43,5 +43,5 @@ __all__ = ( 'utils', ) -__version__ = '2.17' +__version__ = '2.17.1' __api_version__ = '5.5' diff --git a/aiogram/bot/bot.py b/aiogram/bot/bot.py index d5aa5d65..6653cf89 100644 --- a/aiogram/bot/bot.py +++ b/aiogram/bot/bot.py @@ -8,7 +8,7 @@ import warnings from .base import BaseBot, api from .. import types from ..types import base -from ..utils.deprecated import deprecated +from ..utils.deprecated import deprecated, removed_argument from ..utils.exceptions import ValidationError from ..utils.mixins import DataMixin, ContextInstanceMixin from ..utils.payload import generate_payload, prepare_arg, prepare_attachment, prepare_file @@ -1814,18 +1814,16 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): return await self.request(api.Methods.SET_CHAT_ADMINISTRATOR_CUSTOM_TITLE, payload) + @removed_argument("until_date", "2.19") async def ban_chat_sender_chat( self, chat_id: typing.Union[base.Integer, base.String], sender_chat_id: base.Integer, - until_date: typing.Union[ - base.Integer, datetime.datetime, datetime.timedelta, None - ] = None, ): """Ban a channel chat in a supergroup or a channel. - The owner of the chat will not be able to send messages and join - live streams on behalf of the chat, unless it is unbanned first. + Until the chat is unbanned, the owner of the banned chat won't + be able to send messages on behalf of any of their channels. The bot must be an administrator in the supergroup or channel for this to work and must have the appropriate administrator rights. Returns True on success. @@ -1837,12 +1835,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): @channelusername) :param sender_chat_id: Unique identifier of the target sender chat - :param until_date: Date when the sender chat will be unbanned, - unix time. If the chat is banned for more than 366 days or - less than 30 seconds from the current time they are - considered to be banned forever. """ - until_date = prepare_arg(until_date) payload = generate_payload(**locals()) return await self.request(api.Methods.BAN_CHAT_SENDER_CHAT, payload) diff --git a/aiogram/types/chat.py b/aiogram/types/chat.py index 00b7a656..c18ad88b 100644 --- a/aiogram/types/chat.py +++ b/aiogram/types/chat.py @@ -12,7 +12,7 @@ from .chat_permissions import ChatPermissions from .chat_photo import ChatPhoto from .input_file import InputFile from ..utils import helper, markdown -from ..utils.deprecated import deprecated, DeprecatedReadOnlyClassVar +from ..utils.deprecated import deprecated, DeprecatedReadOnlyClassVar, removed_argument class Chat(base.TelegramObject): @@ -623,18 +623,15 @@ class Chat(base.TelegramObject): message_id=message_id, ) + @removed_argument("until_date", "2.19") async def ban_sender_chat( self, sender_chat_id: base.Integer, - until_date: typing.Union[ - base.Integer, datetime.datetime, datetime.timedelta, None - ] = None, ): """Shortcut for banChatSenderChat method.""" return await self.bot.ban_chat_sender_chat( chat_id=self.id, sender_chat_id=sender_chat_id, - until_date=until_date, ) async def unban_sender_chat( diff --git a/aiogram/utils/deprecated.py b/aiogram/utils/deprecated.py index 6d0d7ee3..186fe6cc 100644 --- a/aiogram/utils/deprecated.py +++ b/aiogram/utils/deprecated.py @@ -131,6 +131,57 @@ def renamed_argument(old_name: str, new_name: str, until_version: str, stackleve return decorator +def removed_argument(name: str, until_version: str, stacklevel: int = 3): + """ + A meta-decorator to mark an argument as removed. + + .. code-block:: python3 + + @removed_argument("until_date", "3.0") # stacklevel=3 by default + def some_function(user_id, chat_id=None): + print(f"user_id={user_id}, chat_id={chat_id}") + + :param 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): + is_coroutine = asyncio.iscoroutinefunction(func) + + def _handling(kwargs): + """ + Returns updated version of kwargs. + """ + routine_type = 'coroutine' if is_coroutine else 'function' + if name in kwargs: + warn_deprecated( + f"In {routine_type} {func.__name__!r} argument {name!r} " + f"is planned to be removed in aiogram {until_version}", + stacklevel=stacklevel, + ) + kwargs = kwargs.copy() + del kwargs[name] + return kwargs + + if is_coroutine: + @functools.wraps(func) + async def wrapped(*args, **kwargs): + kwargs = _handling(kwargs) + return await func(*args, **kwargs) + else: + @functools.wraps(func) + def wrapped(*args, **kwargs): + kwargs = _handling(kwargs) + return func(*args, **kwargs) + + return wrapped + + return decorator + + _VT = TypeVar("_VT") _OwnerCls = TypeVar("_OwnerCls") diff --git a/examples/check_user_language.py b/examples/check_user_language.py index 98bed8a6..31c2a5f3 100644 --- a/examples/check_user_language.py +++ b/examples/check_user_language.py @@ -11,7 +11,7 @@ API_TOKEN = 'BOT TOKEN HERE' logging.basicConfig(level=logging.INFO) -bot = Bot(token=API_TOKEN, parse_mode=types.ParseMode.MARKDOWN) +bot = Bot(token=API_TOKEN, parse_mode=types.ParseMode.MARKDOWN_V2) dp = Dispatcher(bot)