From b5d94f17b567fbc49a1c809e9fee6e19931b977f Mon Sep 17 00:00:00 2001 From: Alex Root Junior Date: Mon, 27 May 2024 14:58:39 +0300 Subject: [PATCH] Removed deprecated arguments from Bot class (#1494) * Remove deprecated attributes from Bot class The deprecated attributes `parse_mode`, `disable_web_page_preview`, and `protect_content` have been removed from the Bot class. Additionally, the associated warnings and test cases have been deleted. These attributes should now be passed using the `default=DefaultBotProperties(...)` syntax instead. * Added docs and changelog --- CHANGES/1494.removal.rst | 2 + aiogram/client/bot.py | 72 +++++++---------------- docs/api/defaults.rst | 81 ++++++++++++++++++++++++++ docs/api/index.rst | 1 + tests/test_api/test_client/test_bot.py | 43 ++++---------- 5 files changed, 117 insertions(+), 82 deletions(-) create mode 100644 CHANGES/1494.removal.rst create mode 100644 docs/api/defaults.rst diff --git a/CHANGES/1494.removal.rst b/CHANGES/1494.removal.rst new file mode 100644 index 00000000..935d2f0a --- /dev/null +++ b/CHANGES/1494.removal.rst @@ -0,0 +1,2 @@ +Removed deprecated arguments from Bot class +:code:`parse_mode`, :code:`disable_web_page_preview`, :code:`protect_content` as previously announced in v3.4.0. diff --git a/aiogram/client/bot.py b/aiogram/client/bot.py index 3722bd4b..94ffa3dc 100644 --- a/aiogram/client/bot.py +++ b/aiogram/client/bot.py @@ -3,7 +3,6 @@ from __future__ import annotations import datetime import io import pathlib -import warnings from contextlib import asynccontextmanager from types import TracebackType from typing import ( @@ -251,10 +250,8 @@ class Bot: self, token: str, session: Optional[BaseSession] = None, - parse_mode: Optional[str] = None, - disable_web_page_preview: Optional[bool] = None, - protect_content: Optional[bool] = None, default: Optional[DefaultBotProperties] = None, + **kwargs: Any, ) -> None: """ Bot class @@ -262,12 +259,6 @@ class Bot: :param token: Telegram Bot token `Obtained from @BotFather `_ :param session: HTTP Client session (For example AiohttpSession). If not specified it will be automatically created. - :param parse_mode: Default parse mode. - If specified it will be propagated into the API methods at runtime. - :param disable_web_page_preview: Default disable_web_page_preview mode. - If specified it will be propagated into the API methods at runtime. - :param protect_content: Default protect_content mode. - If specified it will be propagated into the API methods at runtime. :param default: Default bot properties. If specified it will be propagated into the API methods at runtime. :raise TokenValidationError: When token has invalid format this exception will be raised @@ -278,24 +269,33 @@ class Bot: if session is None: session = AiohttpSession() if default is None: - default = DefaultBotProperties( - parse_mode=parse_mode, - link_preview_is_disabled=disable_web_page_preview, - protect_content=protect_content, - ) + default = DefaultBotProperties() self.session = session + + # Few arguments are completely removed in 3.7.0 version + # Temporary solution to raise an error if user passed these arguments + # with explanation how to fix it + parse_mode = kwargs.get("parse_mode", None) + link_preview_is_disabled = kwargs.get("disable_web_page_preview", None) + protect_content = kwargs.get("protect_content", None) if ( parse_mode is not None - or disable_web_page_preview is not None + or link_preview_is_disabled is not None or protect_content is not None ): - warnings.warn( + example_kwargs = { + "parse_mode": parse_mode, + "link_preview_is_disabled": link_preview_is_disabled, + "protect_content": protect_content, + } + replacement_spec = ", ".join( + f"{k}={v!r}" for k, v in example_kwargs.items() if v is not None + ) + raise TypeError( "Passing `parse_mode`, `disable_web_page_preview` or `protect_content` " - "to Bot initializer is deprecated. This arguments will be removed in 3.7.0 version\n" - "Use `default=DefaultBotProperties(...)` instead.", - category=DeprecationWarning, - stacklevel=2, + "to Bot initializer is not supported anymore. These arguments have been removed " + f"in 3.7.0 version. Use `default=DefaultBotProperties({replacement_spec})` argument instead." ) self.default = default @@ -314,36 +314,6 @@ class Bot: ) -> None: await self.session.close() - @property - def parse_mode(self) -> Optional[str]: - warnings.warn( - "Accessing `parse_mode` from Bot instance is deprecated. This attribute will be removed in 3.5.0 version\n" - "Use `bot.default.parse_mode` instead.", - category=DeprecationWarning, - stacklevel=2, - ) - return self.default.parse_mode - - @property - def disable_web_page_preview(self) -> Optional[bool]: - warnings.warn( - "Accessing `disable_web_page_preview` from Bot instance is deprecated. This attribute will be removed in 3.5.0 version\n" - "Use `bot.default.link_preview_is_disabled` instead.", - category=DeprecationWarning, - stacklevel=2, - ) - return self.default.link_preview_is_disabled - - @property - def protect_content(self) -> Optional[bool]: - warnings.warn( - "Accessing `protect_content` from Bot instance is deprecated. This attribute will be removed in 3.5.0 version\n" - "Use `bot.default.protect_content` instead.", - category=DeprecationWarning, - stacklevel=2, - ) - return self.default.protect_content - @property def token(self) -> str: return self.__token diff --git a/docs/api/defaults.rst b/docs/api/defaults.rst new file mode 100644 index 00000000..93f3a59b --- /dev/null +++ b/docs/api/defaults.rst @@ -0,0 +1,81 @@ +=============== +Global defaults +=============== + +aiogram provides mechanism to set some global defaults for all requests to Telegram Bot API +in your application using :class:`aiogram.client.default.DefaultBotProperties` class. + +There are some properties that can be set: + +.. autoclass:: aiogram.client.default.DefaultBotProperties + :members: + :member-order: bysource + :undoc-members: True + +.. note:: + + If you need to override default properties for some requests, you should use `aiogram.client.default.DefaultBotProperties` + only for properties that you want to set as defaults and pass explicit values for other properties. + +.. danger:: + + If you upgrading from aiogram 3.0-3.6 to 3.7, + you should update your code to use `aiogram.client.default.DefaultBotProperties`. + +Example +======= + +Here is an example of setting default parse mode for all requests to Telegram Bot API: + +.. code-block:: python + + bot = Bot( + token=..., + defaults=DefaultBotProperties( + parse_mode=ParseMode.HTML, + ) + ) + +In this case all messages sent by this bot will be parsed as HTML, so you don't need to specify `parse_mode` +in every message you send. + +Instead of + +.. code-block:: python + + await bot.send_message(chat_id, text, parse_mode=ParseMode.HTML) + +you can use + +.. code-block:: python + + await bot.send_message(chat_id, text) + +and the message will be sent with HTML parse mode. + +In some cases you may want to override default properties for some requests. You can do it by passing +explicit values to the method: + +.. code-block:: python + + await bot.send_message(chat_id, text, parse_mode=ParseMode.MARKDOWN_V2) + +In this case the message will be sent with Markdown parse mode instead of default HTML. + +Another example of overriding default properties: + +.. code-block:: python + + await bot.send_message(chat_id, text, parse_mode=None) + +In this case the message will be send withoout parse mode, even if default parse mode is set it may be useful +if you want to send message with plain text or :ref:`aiogram.types.message_entity.MessageEntity`. + +.. code-block:: python + + await bot.send_message( + chat_id=chat_id, + text=text, + entities=[MessageEntity(type='bold', offset=0, length=4)], + parse_mode=None + ) diff --git a/docs/api/index.rst b/docs/api/index.rst index d323ecf0..89a35839 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -14,3 +14,4 @@ All methods and types is fully autogenerated from Telegram Bot API docs by parse enums/index download_file upload_file + defaults diff --git a/tests/test_api/test_client/test_bot.py b/tests/test_api/test_client/test_bot.py index 5db1845a..34593864 100644 --- a/tests/test_api/test_client/test_bot.py +++ b/tests/test_api/test_client/test_bot.py @@ -12,7 +12,6 @@ from aiogram.client.session.aiohttp import AiohttpSession from aiogram.client.telegram import TelegramAPIServer from aiogram.methods import GetFile, GetMe from aiogram.types import File, PhotoSize -from tests.deprecated import check_deprecated from tests.mocked_bot import MockedBot from tests.test_api.test_client.test_session.test_base_session import CustomSession @@ -55,36 +54,18 @@ class TestBot: mocked_close.assert_awaited_once() - def test_init_default(self): - with check_deprecated( - max_version="3.7.0", - exception=TypeError, - ): - bot = Bot(token="42:Test", parse_mode="HTML") - - def test_deprecated_parse_mode(self): - with check_deprecated( - max_version="3.7.0", - exception=AttributeError, - ): - bot = Bot(token="42:Test", parse_mode="HTML") - assert bot.parse_mode == "HTML" - - def test_disable_web_page_preview(self): - with check_deprecated( - max_version="3.7.0", - exception=TypeError, - ): - bot = Bot(token="42:Test", disable_web_page_preview=True) - assert bot.disable_web_page_preview is True - - def test_deprecated_protect_content(self): - with check_deprecated( - max_version="3.7.0", - exception=AttributeError, - ): - bot = Bot(token="42:Test", protect_content=True) - assert bot.protect_content is True + @pytest.mark.parametrize( + "kwargs", + [ + {"parse_mode": "HTML"}, + {"disable_web_page_preview": True}, + {"protect_content": True}, + {"parse_mode": True, "disable_web_page_preview": True}, + ], + ) + def test_init_default(self, kwargs): + with pytest.raises(TypeError): + Bot(token="42:Test", **kwargs) def test_hashable(self): bot = Bot("42:TEST")