From e221dd955351cebca8d52bab67c21f26ad0f95fc Mon Sep 17 00:00:00 2001 From: Badiboy Date: Sun, 16 Aug 2026 13:55:26 +0300 Subject: [PATCH 01/11] MessageID changed to MessageId as in API. MessageID left as deprecated for compatibility. MaybeInaccessibleMessage added obviously as Union to conform API. --- telebot/__init__.py | 18 +++++++++--------- telebot/async_telebot.py | 18 +++++++++--------- telebot/types.py | 21 ++++++++++++++++----- tests/test_types.py | 6 ++---- 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/telebot/__init__.py b/telebot/__init__.py index a9ca9314d..05a5080d3 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -2002,7 +2002,7 @@ def copy_message( video_start_timestamp: Optional[int]=None, direct_messages_topic_id: Optional[int]=None, suggested_post_parameters: Optional[types.SuggestedPostParameters]=None, - message_effect_id: Optional[str]=None) -> types.MessageID: + message_effect_id: Optional[str]=None) -> types.MessageId: """ Use this method to copy messages of any kind. Service messages, paid media messages, giveaway messages, giveaway winners messages, and invoice messages can't be copied. @@ -2078,7 +2078,7 @@ def copy_message( :type message_effect_id: :obj:`str` :return: On success, the MessageId of the sent message is returned. - :rtype: :class:`telebot.types.MessageID` + :rtype: :class:`telebot.types.MessageId` """ disable_notification = self.disable_notification if (disable_notification is None) else disable_notification @@ -2103,7 +2103,7 @@ def copy_message( if reply_parameters and (reply_parameters.allow_sending_without_reply is None): reply_parameters.allow_sending_without_reply = self.allow_sending_without_reply - return types.MessageID.de_json( + return types.MessageId.de_json( apihelper.copy_message(self.token, chat_id, from_chat_id, message_id, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities, disable_notification=disable_notification, reply_markup=reply_markup, timeout=timeout, protect_content=protect_content, @@ -2254,7 +2254,7 @@ def delete_all_message_reactions(self, chat_id: Union[int, str], user_id: Option def forward_messages(self, chat_id: Union[str, int], from_chat_id: Union[str, int], message_ids: List[int], disable_notification: Optional[bool]=None, message_thread_id: Optional[int]=None, - protect_content: Optional[bool]=None, direct_messages_topic_id: Optional[int]=None) -> List[types.MessageID]: + protect_content: Optional[bool]=None, direct_messages_topic_id: Optional[int]=None) -> List[types.MessageId]: """ Use this method to forward multiple messages of any kind. If some of the specified messages can't be found or forwarded, they are skipped. Service messages and messages with protected content can't be forwarded. Album grouping is kept for forwarded messages. @@ -2285,7 +2285,7 @@ def forward_messages(self, chat_id: Union[str, int], from_chat_id: Union[str, in :type direct_messages_topic_id: :obj:`int` :return: On success, the sent Message is returned. - :rtype: :class:`telebot.types.MessageID` + :rtype: :class:`telebot.types.MessageId` """ disable_notification = self.disable_notification if (disable_notification is None) else disable_notification @@ -2295,13 +2295,13 @@ def forward_messages(self, chat_id: Union[str, int], from_chat_id: Union[str, in self.token, chat_id, from_chat_id, message_ids, disable_notification=disable_notification, message_thread_id=message_thread_id, protect_content=protect_content, direct_messages_topic_id=direct_messages_topic_id) - return [types.MessageID.de_json(message_id) for message_id in result] + return [types.MessageId.de_json(message_id) for message_id in result] def copy_messages(self, chat_id: Union[str, int], from_chat_id: Union[str, int], message_ids: List[int], disable_notification: Optional[bool] = None, message_thread_id: Optional[int] = None, protect_content: Optional[bool] = None, remove_caption: Optional[bool] = None, - direct_messages_topic_id: Optional[int] = None) -> List[types.MessageID]: + direct_messages_topic_id: Optional[int] = None) -> List[types.MessageId]: """ Use this method to copy messages of any kind. If some of the specified messages can't be found or copied, they are skipped. Service messages, paid media messages, giveaway messages, giveaway winners messages, @@ -2338,7 +2338,7 @@ def copy_messages(self, chat_id: Union[str, int], from_chat_id: Union[str, int], :type direct_messages_topic_id: :obj:`int` :return: On success, an array of MessageId of the sent messages is returned. - :rtype: :obj:`list` of :class:`telebot.types.MessageID` + :rtype: :obj:`list` of :class:`telebot.types.MessageId` """ disable_notification = self.disable_notification if disable_notification is None else disable_notification protect_content = self.protect_content if protect_content is None else protect_content @@ -2347,7 +2347,7 @@ def copy_messages(self, chat_id: Union[str, int], from_chat_id: Union[str, int], self.token, chat_id, from_chat_id, message_ids, disable_notification=disable_notification, message_thread_id=message_thread_id, protect_content=protect_content, remove_caption=remove_caption, direct_messages_topic_id=direct_messages_topic_id) - return [types.MessageID.de_json(message_id) for message_id in result] + return [types.MessageId.de_json(message_id) for message_id in result] def send_checklist( self, business_connection_id: str, chat_id: Union[int, str], diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py index 15766b0f0..eb185613d 100644 --- a/telebot/async_telebot.py +++ b/telebot/async_telebot.py @@ -3697,7 +3697,7 @@ async def copy_message( video_start_timestamp: Optional[bool]=None, direct_messages_topic_id: Optional[int]=None, suggested_post_parameters: Optional[types.SuggestedPostParameters]=None, - message_effect_id: Optional[str]=None) -> types.MessageID: + message_effect_id: Optional[str]=None) -> types.MessageId: """ Use this method to copy messages of any kind. If some of the specified messages can't be found or copied, they are skipped. Service messages, paid media messages, giveaway messages, giveaway winners messages, @@ -3774,7 +3774,7 @@ async def copy_message( :type message_effect_id: :obj:`str` :return: On success, the MessageId of the sent message is returned. - :rtype: :class:`telebot.types.MessageID` + :rtype: :class:`telebot.types.MessageId` """ parse_mode = self.parse_mode if (parse_mode is None) else parse_mode disable_notification = self.disable_notification if (disable_notification is None) else disable_notification @@ -3800,7 +3800,7 @@ async def copy_message( if reply_parameters and (reply_parameters.allow_sending_without_reply is None): reply_parameters.allow_sending_without_reply = self.allow_sending_without_reply - return types.MessageID.de_json( + return types.MessageId.de_json( await asyncio_helper.copy_message(self.token, chat_id=chat_id, from_chat_id=from_chat_id, message_id=message_id, caption=caption, parse_mode=parse_mode, caption_entities=caption_entities, disable_notification=disable_notification, protect_content=protect_content, @@ -3950,7 +3950,7 @@ async def delete_all_message_reactions(self, chat_id: Union[int, str], user_id: async def forward_messages(self, chat_id: Union[str, int], from_chat_id: Union[str, int], message_ids: List[int], disable_notification: Optional[bool]=None, message_thread_id: Optional[int]=None, protect_content: Optional[bool]=None, - direct_messages_topic_id: Optional[int]=None) -> List[types.MessageID]: + direct_messages_topic_id: Optional[int]=None) -> List[types.MessageId]: """ Use this method to forward multiple messages of any kind. If some of the specified messages can't be found or forwarded, they are skipped. Service messages and messages with protected content can't be forwarded. @@ -3981,19 +3981,19 @@ async def forward_messages(self, chat_id: Union[str, int], from_chat_id: Union[s :type direct_messages_topic_id: :obj:`int` :return: On success, the sent Message is returned. - :rtype: :class:`telebot.types.MessageID` + :rtype: :class:`telebot.types.MessageId` """ disable_notification = self.disable_notification if (disable_notification is None) else disable_notification protect_content = self.protect_content if (protect_content is None) else protect_content result = await asyncio_helper.forward_messages(self.token, chat_id, from_chat_id, message_ids, disable_notification, message_thread_id, protect_content, direct_messages_topic_id=direct_messages_topic_id) - return [types.MessageID.de_json(message_id) for message_id in result] + return [types.MessageId.de_json(message_id) for message_id in result] async def copy_messages(self, chat_id: Union[str, int], from_chat_id: Union[str, int], message_ids: List[int], disable_notification: Optional[bool] = None, message_thread_id: Optional[int] = None, protect_content: Optional[bool] = None, remove_caption: Optional[bool] = None, - direct_messages_topic_id: Optional[int] = None) -> List[types.MessageID]: + direct_messages_topic_id: Optional[int] = None) -> List[types.MessageId]: """ Use this method to copy messages of any kind. Service messages, paid media messages, giveaway messages, giveaway winners messages, and invoice messages can't be copied. @@ -4028,13 +4028,13 @@ async def copy_messages(self, chat_id: Union[str, int], from_chat_id: Union[str, :type direct_messages_topic_id: :obj:`int` :return: On success, an array of MessageId of the sent messages is returned. - :rtype: :obj:`list` of :class:`telebot.types.MessageID` + :rtype: :obj:`list` of :class:`telebot.types.MessageId` """ disable_notification = self.disable_notification if disable_notification is None else disable_notification protect_content = self.protect_content if protect_content is None else protect_content result = await asyncio_helper.copy_messages(self.token, chat_id, from_chat_id, message_ids, disable_notification, message_thread_id, protect_content, remove_caption, direct_messages_topic_id) - return [types.MessageID.de_json(message_id) for message_id in result] + return [types.MessageId.de_json(message_id) for message_id in result] async def send_checklist( self, business_connection_id: str, chat_id: Union[int, str], diff --git a/telebot/types.py b/telebot/types.py index 6ce479982..54e7bfcf6 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -947,7 +947,7 @@ class Chat(ChatFullInfo): pass -class MessageID(JsonDeserializable): +class MessageId(JsonDeserializable): """ This object represents a unique message identifier. @@ -969,6 +969,15 @@ def __init__(self, message_id, **kwargs): self.message_id: int = message_id +class MessageID(MessageId): + """ + Deprecated. Use `MessageId` instead. + """ + def __init__(self, message_id, **kwargs): + log_deprecation_warning("The class 'MessageId' is deprecated. Use 'MessageId' instead.") + super().__init__(message_id, **kwargs) + + class WebAppData(JsonDeserializable, Dictionaryable): """ Describes data sent from a Web App to the bot. @@ -14408,9 +14417,9 @@ class PollOptionAdded(JsonDeserializable): :rtype: :class:`PollOptionAdded` """ def __init__(self, option_persistent_id: str, option_text: str, - poll_message: Optional[Union[InaccessibleMessage, Message]] = None, + poll_message: Optional[MaybeInaccessibleMessage] = None, option_text_entities: Optional[List[MessageEntity]] = None, **kwargs): - self.poll_message: Optional[Union[InaccessibleMessage, Message]] = poll_message + self.poll_message: Optional[MaybeInaccessibleMessage] = poll_message self.option_persistent_id: str = option_persistent_id self.option_text: str = option_text self.option_text_entities: Optional[List[MessageEntity]] = option_text_entities @@ -14453,9 +14462,9 @@ class PollOptionDeleted(JsonDeserializable): :rtype: :class:`PollOptionDeleted` """ def __init__(self, option_persistent_id: str, option_text: str, - poll_message: Optional[Union[InaccessibleMessage, Message]] = None, + poll_message: Optional[MaybeInaccessibleMessage] = None, option_text_entities: Optional[List[MessageEntity]] = None, **kwargs): - self.poll_message: Optional[Union[InaccessibleMessage, Message]] = poll_message + self.poll_message: Optional[MaybeInaccessibleMessage] = poll_message self.option_persistent_id: str = option_persistent_id self.option_text: str = option_text self.option_text_entities: Optional[List[MessageEntity]] = option_text_entities @@ -14607,6 +14616,8 @@ def to_dict(self): # why not.. +MaybeInaccessibleMessage = Union[InaccessibleMessage, Message] + InputPollMedia = Union[InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaLivePhoto, InputMediaLocation, InputMediaPhoto, InputMediaVenue, InputMediaVideo] InputPollOptionMedia = Union[InputMediaAnimation, InputMediaLivePhoto, InputMediaLocation, InputMediaPhoto, InputMediaSticker, InputMediaVenue, InputMediaVideo, InputMediaLink] diff --git a/tests/test_types.py b/tests/test_types.py index def1426c6..7bf81b392 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -1889,8 +1889,8 @@ def test_json_messageautodeletetimerchanged(): def test_json_messageid(): json_str = r'{"message_id": 1}' - result = types.MessageID.de_json(json_str) - assert isinstance(result, types.MessageID) + result = types.MessageId.de_json(json_str) + assert isinstance(result, types.MessageId) def test_json_messageorigin(): @@ -2859,5 +2859,3 @@ def test_message_entity_html_conversion(): json30 = r'{"message_id":30,"date":1682177590,"chat":{"id":1,"type":"private"},"text":"@user mail@x.com https://x.com end","entities":[{"offset":0,"length":5,"type":"mention"},{"offset":6,"length":10,"type":"email"},{"offset":17,"length":14,"type":"url"}]}' msg30 = types.Message.de_json(json30) assert msg30.html_text == '@user mail@x.com https://x.com end' - - From cdd37b3abc106bb7acb1a2324ad5b5225b741ab7 Mon Sep 17 00:00:00 2001 From: Badiboy Date: Sun, 16 Aug 2026 14:00:27 +0300 Subject: [PATCH 02/11] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- telebot/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telebot/types.py b/telebot/types.py index 54e7bfcf6..70fe70af9 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -974,7 +974,7 @@ class MessageID(MessageId): Deprecated. Use `MessageId` instead. """ def __init__(self, message_id, **kwargs): - log_deprecation_warning("The class 'MessageId' is deprecated. Use 'MessageId' instead.") + log_deprecation_warning("The class 'MessageID' is deprecated. Use 'MessageId' instead.") super().__init__(message_id, **kwargs) From 6799f7e3dda5e21e86da4162a0a3aca58d2124ee Mon Sep 17 00:00:00 2001 From: Badiboy Date: Sun, 16 Aug 2026 14:33:15 +0300 Subject: [PATCH 03/11] InlineQueryResultBase -> InlineQueryResult --- telebot/__init__.py | 10 +++++----- telebot/apihelper.py | 4 ++-- telebot/async_telebot.py | 10 +++++----- telebot/asyncio_helper.py | 4 ++-- telebot/types.py | 42 +++++++++++++++++++++++++-------------- 5 files changed, 41 insertions(+), 29 deletions(-) diff --git a/telebot/__init__.py b/telebot/__init__.py index 05a5080d3..c63832288 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -7352,7 +7352,7 @@ def answer_callback_query( self.token, callback_query_id, text=text, show_alert=show_alert, url=url, cache_time=cache_time) - def answer_guest_query(self, guest_query_id: str, result: types.InlineQueryResultBase) -> types.SentGuestMessage: + def answer_guest_query(self, guest_query_id: str, result: types.InlineQueryResult) -> types.SentGuestMessage: """ Use this method to reply to a received guest message. On success, a SentGuestMessage object is returned. @@ -8862,7 +8862,7 @@ def get_forum_topic_icon_stickers(self) -> List[types.Sticker]: return apihelper.get_forum_topic_icon_stickers(self.token) - def answer_web_app_query(self, web_app_query_id: str, result: types.InlineQueryResultBase) -> types.SentWebAppMessage: + def answer_web_app_query(self, web_app_query_id: str, result: types.InlineQueryResult) -> types.SentWebAppMessage: """ Use this method to set the result of an interaction with a Web App and send a corresponding message on behalf of the user to the chat from which @@ -8875,7 +8875,7 @@ def answer_web_app_query(self, web_app_query_id: str, result: types.InlineQueryR :type web_app_query_id: :obj:`str` :param result: A JSON-serialized object describing the message to be sent - :type result: :class:`telebot.types.InlineQueryResultBase` + :type result: :class:`telebot.types.InlineQueryResult` :return: On success, a SentWebAppMessage object is returned. :rtype: :class:`telebot.types.SentWebAppMessage` @@ -8883,7 +8883,7 @@ def answer_web_app_query(self, web_app_query_id: str, result: types.InlineQueryR return apihelper.answer_web_app_query(self.token, web_app_query_id, result) def save_prepared_inline_message( - self, user_id: int, result: types.InlineQueryResultBase, allow_user_chats: Optional[bool]=None, + self, user_id: int, result: types.InlineQueryResult, allow_user_chats: Optional[bool]=None, allow_bot_chats: Optional[bool]=None, allow_group_chats: Optional[bool]=None, allow_channel_chats: Optional[bool]=None) -> types.PreparedInlineMessage: """ @@ -8896,7 +8896,7 @@ def save_prepared_inline_message( :type user_id: :obj:`int` :param result: A JSON-serialized object describing the message to be sent - :type result: :class:`telebot.types.InlineQueryResultBase` + :type result: :class:`telebot.types.InlineQueryResult` :param allow_user_chats: Pass True if the message can be sent to private chats with users :type allow_user_chats: :obj:`bool` diff --git a/telebot/apihelper.py b/telebot/apihelper.py index 39a40efb7..099751f34 100644 --- a/telebot/apihelper.py +++ b/telebot/apihelper.py @@ -2667,13 +2667,13 @@ def delete_sticker_from_set(token, sticker): return _make_request(token, method_url, params=payload, method='post') -def answer_web_app_query(token, web_app_query_id, result: types.InlineQueryResultBase): +def answer_web_app_query(token, web_app_query_id, result: types.InlineQueryResult): method_url = 'answerWebAppQuery' payload = {'web_app_query_id': web_app_query_id, 'result': result.to_json()} return _make_request(token, method_url, params=payload, method='post') -def save_prepared_inline_message(token, user_id, result: types.InlineQueryResultBase, allow_user_chats=None, +def save_prepared_inline_message(token, user_id, result: types.InlineQueryResult, allow_user_chats=None, allow_bot_chats=None, allow_group_chats=None, allow_channel_chats=None): method_url = 'savePreparedInlineMessage' payload = {'user_id': user_id, 'result': result.to_json()} diff --git a/telebot/async_telebot.py b/telebot/async_telebot.py index eb185613d..f3615a44b 100644 --- a/telebot/async_telebot.py +++ b/telebot/async_telebot.py @@ -3365,7 +3365,7 @@ async def delete_chat_sticker_set(self, chat_id: Union[int, str]) -> bool: result = await asyncio_helper.delete_chat_sticker_set(self.token, chat_id) return result - async def answer_web_app_query(self, web_app_query_id: str, result: types.InlineQueryResultBase) -> types.SentWebAppMessage: + async def answer_web_app_query(self, web_app_query_id: str, result: types.InlineQueryResult) -> types.SentWebAppMessage: """ Use this method to set the result of an interaction with a Web App and send a corresponding message on behalf of the user to the chat from which @@ -3378,7 +3378,7 @@ async def answer_web_app_query(self, web_app_query_id: str, result: types.Inline :type web_app_query_id: :obj:`str` :param result: A JSON-serialized object describing the message to be sent - :type result: :class:`telebot.types.InlineQueryResultBase` + :type result: :class:`telebot.types.InlineQueryResult` :return: On success, a SentWebAppMessage object is returned. :rtype: :class:`telebot.types.SentWebAppMessage` @@ -3386,7 +3386,7 @@ async def answer_web_app_query(self, web_app_query_id: str, result: types.Inline return await asyncio_helper.answer_web_app_query(self.token, web_app_query_id, result) - async def save_prepared_inline_message(self, user_id: int, result: types.InlineQueryResultBase, allow_user_chats: Optional[bool]=None, + async def save_prepared_inline_message(self, user_id: int, result: types.InlineQueryResult, allow_user_chats: Optional[bool]=None, allow_bot_chats: Optional[bool]=None, allow_group_chats: Optional[bool]=None, allow_channel_chats: Optional[bool]=None) -> types.PreparedInlineMessage: """ Stores a message that can be sent by a user of a Mini App. Returns a PreparedInlineMessage object. @@ -3397,7 +3397,7 @@ async def save_prepared_inline_message(self, user_id: int, result: types.InlineQ :type user_id: :obj:`int` :param result: A JSON-serialized object describing the message to be sent - :type result: :class:`telebot.types.InlineQueryResultBase` + :type result: :class:`telebot.types.InlineQueryResult` :param allow_user_chats: Pass True if the message can be sent to private chats with users :type allow_user_chats: :obj:`bool`, optional @@ -8976,7 +8976,7 @@ async def answer_callback_query( return await asyncio_helper.answer_callback_query(self.token, callback_query_id, text, show_alert, url, cache_time) - async def answer_guest_query(self, guest_query_id: str, result: types.InlineQueryResultBase) -> types.SentGuestMessage: + async def answer_guest_query(self, guest_query_id: str, result: types.InlineQueryResult) -> types.SentGuestMessage: """ Use this method to reply to a received guest message. On success, a SentGuestMessage object is returned. diff --git a/telebot/asyncio_helper.py b/telebot/asyncio_helper.py index 2999c68f5..a4557c6cf 100644 --- a/telebot/asyncio_helper.py +++ b/telebot/asyncio_helper.py @@ -465,13 +465,13 @@ async def delete_chat_sticker_set(token, chat_id): return await _process_request(token, method_url, params=payload) -async def answer_web_app_query(token, web_app_query_id, result: types.InlineQueryResultBase): +async def answer_web_app_query(token, web_app_query_id, result: types.InlineQueryResult): method_url = 'answerWebAppQuery' payload = {'web_app_query_id': web_app_query_id, 'result': result.to_json()} return await _process_request(token, method_url, params=payload, method='post') -async def save_prepared_inline_message(token, user_id, result: types.InlineQueryResultBase, allow_user_chats=None, allow_bot_chats=None, allow_group_chats=None, allow_channel_chats=None): +async def save_prepared_inline_message(token, user_id, result: types.InlineQueryResult, allow_user_chats=None, allow_bot_chats=None, allow_group_chats=None, allow_channel_chats=None): method_url = r'savePreparedInlineMessage' payload = {'user_id': user_id, 'result': result.to_json()} if allow_user_chats is not None: diff --git a/telebot/types.py b/telebot/types.py index 54e7bfcf6..c3a395081 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -4749,8 +4749,6 @@ def to_json(self) -> str: return json.dumps(self.to_dict()) -InputMessageContent = Union[InputTextMessageContent, InputLocationMessageContent, InputVenueMessageContent, InputContactMessageContent, InputInvoiceMessageContent, InputRichMessageContent] - class ChosenInlineResult(JsonDeserializable): """ Represents a result of an inline query that was chosen by the user and sent to their chat partner. @@ -4794,7 +4792,7 @@ def __init__(self, result_id, from_user, query, location=None, inline_message_id # noinspection PyShadowingBuiltins -class InlineQueryResultBase(ABC, Dictionaryable, JsonSerializable): +class InlineQueryResult(ABC, Dictionaryable, JsonSerializable): """ This object represents one result of an inline query. Telegram clients currently support results of the following 20 types: @@ -4856,6 +4854,18 @@ def to_dict(self): return json_dict +# noinspection PyShadowingBuiltins +class InlineQueryResultBase(InlineQueryResult): + """ + Deprecated. Use `InlineQueryResult` instead. + """ + def __init__(self, type: str, id: str, title: Optional[str] = None, caption: Optional[str] = None, input_message_content: Optional[InputMessageContent] = None, + reply_markup: Optional[InlineKeyboardMarkup] = None, caption_entities: Optional[List[MessageEntity]] = None, parse_mode: Optional[str] = None): + log_deprecation_warning("The class 'InlineQueryResultBase' is deprecated. Use 'InlineQueryResult' instead.") + super().__init__(type, id, title=title, caption=caption, input_message_content=input_message_content, + reply_markup=reply_markup, caption_entities=caption_entities, parse_mode=parse_mode) + + class SentWebAppMessage(JsonDeserializable, Dictionaryable): """ Describes an inline message sent by a Web App on behalf of a user. @@ -4886,7 +4896,7 @@ def to_dict(self): # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultArticle(InlineQueryResultBase): +class InlineQueryResultArticle(InlineQueryResult): """ Represents a link to an article or web page. @@ -4979,7 +4989,7 @@ def to_dict(self): # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultPhoto(InlineQueryResultBase): +class InlineQueryResultPhoto(InlineQueryResult): """ Represents a link to a photo. By default, this photo will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the photo. @@ -5068,7 +5078,7 @@ def to_dict(self): # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultGif(InlineQueryResultBase): +class InlineQueryResultGif(InlineQueryResult): """ Represents a link to an animated GIF file. By default, this animated GIF file will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation. @@ -5169,7 +5179,7 @@ def to_dict(self): # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultMpeg4Gif(InlineQueryResultBase): +class InlineQueryResultMpeg4Gif(InlineQueryResult): """ Represents a link to a video animation (H.264/MPEG-4 AVC video without sound). By default, this animated MPEG-4 file will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation. @@ -5269,7 +5279,7 @@ def to_dict(self): # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultVideo(InlineQueryResultBase): +class InlineQueryResultVideo(InlineQueryResult): """ Represents a link to a page containing an embedded video player or a video file. By default, this video file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the video. @@ -5369,7 +5379,7 @@ def to_dict(self): # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultAudio(InlineQueryResultBase): +class InlineQueryResultAudio(InlineQueryResult): """ Represents a link to an MP3 audio file. By default, this audio file will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the audio. @@ -5435,7 +5445,7 @@ def to_dict(self): # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultVoice(InlineQueryResultBase): +class InlineQueryResultVoice(InlineQueryResult): """ Represents a link to a voice recording in an .OGG container encoded with OPUS. By default, this voice recording will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the the voice message. @@ -5495,7 +5505,7 @@ def to_dict(self): # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultDocument(InlineQueryResultBase): +class InlineQueryResultDocument(InlineQueryResult): """ Represents a link to a file. By default, this file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the file. Currently, only .PDF and .ZIP files can be sent using this method. @@ -5595,7 +5605,7 @@ def to_dict(self): # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultLocation(InlineQueryResultBase): +class InlineQueryResultLocation(InlineQueryResult): """ Represents a location on a map. By default, the location will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the location. @@ -5700,7 +5710,7 @@ def to_dict(self): # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultVenue(InlineQueryResultBase): +class InlineQueryResultVenue(InlineQueryResult): """ Represents a venue. By default, the venue will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the venue. @@ -5811,7 +5821,7 @@ def to_dict(self): # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultContact(InlineQueryResultBase): +class InlineQueryResultContact(InlineQueryResult): """ Represents a contact with a phone number. By default, this contact will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the contact. @@ -5901,7 +5911,7 @@ def to_dict(self): # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultGame(InlineQueryResultBase): +class InlineQueryResultGame(InlineQueryResult): """ Represents a Game. @@ -14618,6 +14628,8 @@ def to_dict(self): # why not.. MaybeInaccessibleMessage = Union[InaccessibleMessage, Message] +InputMessageContent = Union[InputTextMessageContent, InputLocationMessageContent, InputVenueMessageContent, InputContactMessageContent, InputInvoiceMessageContent, InputRichMessageContent] + InputPollMedia = Union[InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaLivePhoto, InputMediaLocation, InputMediaPhoto, InputMediaVenue, InputMediaVideo] InputPollOptionMedia = Union[InputMediaAnimation, InputMediaLivePhoto, InputMediaLocation, InputMediaPhoto, InputMediaSticker, InputMediaVenue, InputMediaVideo, InputMediaLink] From 8b893b72907d592a294d32d6962c29144e4ce507 Mon Sep 17 00:00:00 2001 From: Badiboy Date: Sun, 16 Aug 2026 20:03:13 +0300 Subject: [PATCH 04/11] Big base classes revision 1. MessageId inherit MessageID to fix compatibility issues mentioned by CoPilot. 2. InlineQueryResult inherit InlineQueryResultBase to fix compatibility issues mentioned by CoPilot. 3. InlineQueryResult inherit InlineQueryResultCachedBase inherit InlineQueryResultBase to remove InlineQueryResultBase - no such class in API, all InlineQueryResultCachedxxx are based on InlineQueryResult 4. description and show_caption_above_media added to InlineQueryResult to short inherited code. 5. InlineQueryResultCachedxxx equipped with to_dict() as far as they are Dictionaryable. I don't know how they work before - specific fields were passed to payload_dic but never used... 6. deprecated properties like "thumb_url" were removed: I was wrong when added them: these classes are not JsonDeserializable, so no one should READ fields... --- telebot/types.py | 488 +++++++++++++++-------------------------------- 1 file changed, 151 insertions(+), 337 deletions(-) diff --git a/telebot/types.py b/telebot/types.py index 2e179960e..44655dc8e 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -947,7 +947,13 @@ class Chat(ChatFullInfo): pass -class MessageId(JsonDeserializable): +class MessageID(ABS, JsonDeserializable): + """ + Deprecated. Use `MessageId` instead. + """ + + +class MessageId(MessageID): """ This object represents a unique message identifier. @@ -969,15 +975,6 @@ def __init__(self, message_id, **kwargs): self.message_id: int = message_id -class MessageID(MessageId): - """ - Deprecated. Use `MessageId` instead. - """ - def __init__(self, message_id, **kwargs): - log_deprecation_warning("The class 'MessageID' is deprecated. Use 'MessageId' instead.") - super().__init__(message_id, **kwargs) - - class WebAppData(JsonDeserializable, Dictionaryable): """ Describes data sent from a Web App to the bot. @@ -4791,8 +4788,49 @@ def __init__(self, result_id, from_user, query, location=None, inline_message_id self.query: str = query +class SentWebAppMessage(JsonDeserializable, Dictionaryable): + """ + Describes an inline message sent by a Web App on behalf of a user. + + Telegram Documentation: https://core.telegram.org/bots/api#sentwebappmessage + + :param inline_message_id: Optional. Identifier of the sent inline message. Available only if there is an inline + keyboard attached to the message. + :type inline_message_id: :obj:`str` + + :return: Instance of the class + :rtype: :class:`telebot.types.SentWebAppMessage` + """ + @classmethod + def de_json(cls, json_string): + if json_string is None: return None + obj = cls.check_json(json_string) + return cls(**obj) + + def __init__(self, inline_message_id=None, **kwargs): + self.inline_message_id: Optional[str] = inline_message_id + + def to_dict(self): + json_dict = {} + if self.inline_message_id: + json_dict['inline_message_id'] = self.inline_message_id + return json_dict + + +class InlineQueryResultBase(ABC, Dictionaryable, JsonSerializable): + """ + Deprecated. Use `InlineQueryResult` instead. + """ + + +class InlineQueryResultCachedBase(ABC, InlineQueryResultBase): + """ + Deprecated. Use `InlineQueryResult` instead. + """ + + # noinspection PyShadowingBuiltins -class InlineQueryResult(ABC, Dictionaryable, JsonSerializable): +class InlineQueryResult(ABC, InlineQueryResultCachedBase): """ This object represents one result of an inline query. Telegram clients currently support results of the following 20 types: @@ -4819,9 +4857,18 @@ class InlineQueryResult(ABC, Dictionaryable, JsonSerializable): Telegram Documentation: https://core.telegram.org/bots/api#inlinequeryresult """ - - def __init__(self, type: str, id: str, title: Optional[str] = None, caption: Optional[str] = None, input_message_content: Optional[InputMessageContent] = None, - reply_markup: Optional[InlineKeyboardMarkup] = None, caption_entities: Optional[List[MessageEntity]] = None, parse_mode: Optional[str] = None): + # Inherited from InlineQueryResultBase for backward compatibility + # Inherited from InlineQueryResultCachedBase for backward compatibility + + def __init__(self, type: str, id: str, + title: Optional[str] = None, + caption: Optional[str] = None, + input_message_content: Optional[InputMessageContent] = None, + reply_markup: Optional[InlineKeyboardMarkup] = None, + caption_entities: Optional[List[MessageEntity]] = None, + parse_mode: Optional[str] = None, + description: Optional[str] = None, + show_caption_above_media: Optional[bool] = None): self.type: str = type self.id: str = id self.title: Optional[str] = title @@ -4830,6 +4877,8 @@ def __init__(self, type: str, id: str, title: Optional[str] = None, caption: Opt self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup self.caption_entities: Optional[List[MessageEntity]] = caption_entities self.parse_mode: Optional[str] = parse_mode + self.description: Optional[str] = description + self.show_caption_above_media: Optional[bool] = show_caption_above_media def to_json(self): return json.dumps(self.to_dict()) @@ -4851,47 +4900,10 @@ def to_dict(self): json_dict['caption_entities'] = MessageEntity.to_list_of_dicts(self.caption_entities) if self.parse_mode: json_dict['parse_mode'] = self.parse_mode - return json_dict - - -# noinspection PyShadowingBuiltins -class InlineQueryResultBase(InlineQueryResult): - """ - Deprecated. Use `InlineQueryResult` instead. - """ - def __init__(self, type: str, id: str, title: Optional[str] = None, caption: Optional[str] = None, input_message_content: Optional[InputMessageContent] = None, - reply_markup: Optional[InlineKeyboardMarkup] = None, caption_entities: Optional[List[MessageEntity]] = None, parse_mode: Optional[str] = None): - log_deprecation_warning("The class 'InlineQueryResultBase' is deprecated. Use 'InlineQueryResult' instead.") - super().__init__(type, id, title=title, caption=caption, input_message_content=input_message_content, - reply_markup=reply_markup, caption_entities=caption_entities, parse_mode=parse_mode) - - -class SentWebAppMessage(JsonDeserializable, Dictionaryable): - """ - Describes an inline message sent by a Web App on behalf of a user. - - Telegram Documentation: https://core.telegram.org/bots/api#sentwebappmessage - - :param inline_message_id: Optional. Identifier of the sent inline message. Available only if there is an inline - keyboard attached to the message. - :type inline_message_id: :obj:`str` - - :return: Instance of the class - :rtype: :class:`telebot.types.SentWebAppMessage` - """ - @classmethod - def de_json(cls, json_string): - if json_string is None: return None - obj = cls.check_json(json_string) - return cls(**obj) - - def __init__(self, inline_message_id=None, **kwargs): - self.inline_message_id: Optional[str] = inline_message_id - - def to_dict(self): - json_dict = {} - if self.inline_message_id: - json_dict['inline_message_id'] = self.inline_message_id + if self.description: + json_dict['description'] = self.description + if self.show_caption_above_media is not None: + json_dict['show_caption_above_media'] = self.show_caption_above_media return json_dict @@ -4920,8 +4932,8 @@ class InlineQueryResultArticle(InlineQueryResult): :param url: Optional. URL of the result :type url: :obj:`str` - :param hide_url: Optional. Pass True, if you don't want the URL to be shown in the message - :type hide_url: :obj:`bool` + :param hide_url: deprecated. Use empty url instead + :type hide_url: :obj:`str` :param description: Optional. Short description of the result :type description: :obj:`str` @@ -4943,10 +4955,9 @@ def __init__(self, id: str, title: str, input_message_content: InputMessageConte url: Optional[str] = None, hide_url: Optional[bool] = None, description: Optional[str] = None, thumbnail_url: Optional[str] = None, thumbnail_width: Optional[int] = None, thumbnail_height: Optional[int] = None): - super().__init__('article', id, title = title, input_message_content = input_message_content, reply_markup = reply_markup) + super().__init__('article', id, title = title, input_message_content = input_message_content, + reply_markup = reply_markup, description = description) self.url: Optional[str] = url - self.hide_url: Optional[bool] = hide_url - self.description: Optional[str] = description self.thumbnail_url: Optional[str] = thumbnail_url self.thumbnail_width: Optional[int] = thumbnail_width self.thumbnail_height: Optional[int] = thumbnail_height @@ -4955,30 +4966,10 @@ def __init__(self, id: str, title: str, input_message_content: InputMessageConte log_deprecation_warning('The parameter "hide_url" is deprecated. Pass an empty string as url instead.') self.url = '' - - @property - def thumb_url(self) -> str: - log_deprecation_warning('The parameter "thumb_url" is deprecated, use "thumbnail_url" instead') - return self.thumbnail_url - - @property - def thumb_width(self) -> int: - log_deprecation_warning('The parameter "thumb_width" is deprecated, use "thumbnail_width" instead') - return self.thumbnail_width - - @property - def thumb_height(self) -> int: - log_deprecation_warning('The parameter "thumb_height" is deprecated, use "thumbnail_height" instead') - return self.thumbnail_height - def to_dict(self): json_dict = super().to_dict() if self.url: json_dict['url'] = self.url - if self.hide_url: - json_dict['hide_url'] = self.hide_url - if self.description: - json_dict['description'] = self.description if self.thumbnail_url: json_dict['thumbnail_url'] = self.thumbnail_url if self.thumbnail_width: @@ -5048,19 +5039,12 @@ def __init__(self, id: str, photo_url: str, thumbnail_url: str, photo_width: Opt show_caption_above_media: Optional[bool] = None): super().__init__('photo', id, title = title, caption = caption, input_message_content = input_message_content, reply_markup = reply_markup, - parse_mode = parse_mode, caption_entities = caption_entities) + parse_mode = parse_mode, caption_entities = caption_entities, description = description, + show_caption_above_media = show_caption_above_media) self.photo_url: str = photo_url self.thumbnail_url: str = thumbnail_url self.photo_width: Optional[int] = photo_width self.photo_height: Optional[int] = photo_height - self.description: Optional[str] = description - self.show_caption_above_media: Optional[bool] = show_caption_above_media - - - @property - def thumb_url(self) -> str: - log_deprecation_warning('The parameter "thumb_url" is deprecated, use "thumbnail_url" instead') - return self.thumbnail_url def to_dict(self): json_dict = super().to_dict() @@ -5070,10 +5054,6 @@ def to_dict(self): json_dict['photo_width'] = self.photo_width if self.photo_height: json_dict['photo_height'] = self.photo_height - if self.description: - json_dict['description'] = self.description - if self.show_caption_above_media is not None: - json_dict['show_caption_above_media'] = self.show_caption_above_media return json_dict @@ -5142,24 +5122,14 @@ def __init__(self, id: str, gif_url: str, thumbnail_url: str, gif_width: Optiona super().__init__('gif', id, title = title, caption = caption, input_message_content = input_message_content, reply_markup = reply_markup, - parse_mode = parse_mode, caption_entities = caption_entities) + parse_mode = parse_mode, caption_entities = caption_entities, + show_caption_above_media = show_caption_above_media) self.gif_url: str = gif_url self.thumbnail_url: str = thumbnail_url self.gif_width: Optional[int] = gif_width self.gif_height: Optional[int] = gif_height self.gif_duration: Optional[int] = gif_duration self.thumbnail_mime_type: Optional[str] = thumbnail_mime_type - self.show_caption_above_media: Optional[bool] = show_caption_above_media - - @property - def thumb_url(self) -> str: - log_deprecation_warning('The parameter "thumb_url" is deprecated, use "thumbnail_url" instead') - return self.thumbnail_url - - @property - def thumb_mime_type(self) -> str: - log_deprecation_warning('The parameter "thumb_mime_type" is deprecated, use "thumbnail_mime_type" instead') - return self.thumbnail_mime_type def to_dict(self): json_dict = super().to_dict() @@ -5173,8 +5143,6 @@ def to_dict(self): json_dict['gif_duration'] = self.gif_duration if self.thumbnail_mime_type: json_dict['thumbnail_mime_type'] = self.thumbnail_mime_type - if self.show_caption_above_media is not None: - json_dict['show_caption_above_media'] = self.show_caption_above_media return json_dict @@ -5242,24 +5210,14 @@ def __init__(self, id: str, mpeg4_url: str, thumbnail_url: str, mpeg4_width: Opt super().__init__('mpeg4_gif', id, title = title, caption = caption, input_message_content = input_message_content, reply_markup = reply_markup, - parse_mode = parse_mode, caption_entities = caption_entities) + parse_mode = parse_mode, caption_entities = caption_entities, + show_caption_above_media = show_caption_above_media) self.mpeg4_url: str = mpeg4_url self.thumbnail_url: str = thumbnail_url self.mpeg4_width: Optional[int] = mpeg4_width self.mpeg4_height: Optional[int] = mpeg4_height self.mpeg4_duration: Optional[int] = mpeg4_duration self.thumbnail_mime_type: Optional[str] = thumbnail_mime_type - self.show_caption_above_media: Optional[bool] = show_caption_above_media - - @property - def thumb_url(self) -> str: - log_deprecation_warning('The parameter "thumb_url" is deprecated, use "thumbnail_url" instead') - return self.thumbnail_url - - @property - def thumb_mime_type(self) -> str: - log_deprecation_warning('The parameter "thumb_mime_type" is deprecated, use "thumbnail_mime_type" instead') - return self.thumbnail_mime_type def to_dict(self): json_dict = super().to_dict() @@ -5273,8 +5231,6 @@ def to_dict(self): json_dict['mpeg4_duration '] = self.mpeg4_duration if self.thumbnail_mime_type: json_dict['thumbnail_mime_type'] = self.thumbnail_mime_type - if self.show_caption_above_media is not None: - json_dict['show_caption_above_media'] = self.show_caption_above_media return json_dict @@ -5347,20 +5303,14 @@ def __init__(self, id: str, video_url: str, mime_type: str, thumbnail_url: str, super().__init__('video', id, title = title, caption = caption, input_message_content = input_message_content, reply_markup = reply_markup, - parse_mode = parse_mode, caption_entities = caption_entities) + parse_mode = parse_mode, caption_entities = caption_entities, description = description, + show_caption_above_media = show_caption_above_media) self.video_url: str = video_url self.mime_type: str = mime_type self.thumbnail_url: str = thumbnail_url self.video_width: Optional[int] = video_width self.video_height: Optional[int] = video_height self.video_duration: Optional[int] = video_duration - self.description: Optional[str] = description - self.show_caption_above_media: Optional[bool] = show_caption_above_media - - @property - def thumb_url(self) -> str: - log_deprecation_warning('The parameter "thumb_url" is deprecated, use "thumbnail_url" instead') - return self.thumbnail_url def to_dict(self): json_dict = super().to_dict() @@ -5371,10 +5321,6 @@ def to_dict(self): json_dict['video_height'] = self.video_height if self.video_duration: json_dict['video_duration'] = self.video_duration - if self.description: - json_dict['description'] = self.description - if self.show_caption_above_media is not None: - json_dict['show_caption_above_media'] = self.show_caption_above_media return json_dict @@ -5565,36 +5511,17 @@ def __init__(self, id: str, title: str, document_url: str, mime_type: str, capti super().__init__('document', id, title = title, caption = caption, input_message_content = input_message_content, reply_markup = reply_markup, - parse_mode = parse_mode, caption_entities = caption_entities) + parse_mode = parse_mode, caption_entities = caption_entities, description = description) self.document_url: str = document_url self.mime_type: str = mime_type - self.description: Optional[str] = description self.thumbnail_url: Optional[str] = thumbnail_url self.thumbnail_width: Optional[int] = thumbnail_width self.thumbnail_height: Optional[int] = thumbnail_height - - @property - def thumb_url(self) -> str: - log_deprecation_warning('The parameter "thumb_url" is deprecated, use "thumbnail_url" instead') - return self.thumbnail_url - - @property - def thumb_width(self) -> int: - log_deprecation_warning('The parameter "thumb_width" is deprecated, use "thumbnail_width" instead') - return self.thumbnail_width - - @property - def thumb_height(self) -> int: - log_deprecation_warning('The parameter "thumb_height" is deprecated, use "thumbnail_height" instead') - return self.thumbnail_height - def to_dict(self): json_dict = super().to_dict() json_dict['document_url'] = self.document_url json_dict['mime_type'] = self.mime_type - if self.description: - json_dict['description'] = self.description if self.thumbnail_url: json_dict['thumbnail_url'] = self.thumbnail_url if self.thumbnail_width: @@ -5673,21 +5600,6 @@ def __init__(self, id: str, title: str, latitude: float, longitude: float, horiz self.thumbnail_width: Optional[int] = thumbnail_width self.thumbnail_height: Optional[int] = thumbnail_height - @property - def thumb_url(self) -> str: - log_deprecation_warning('The parameter "thumb_url" is deprecated, use "thumbnail_url" instead') - return self.thumbnail_url - - @property - def thumb_width(self) -> int: - log_deprecation_warning('The parameter "thumb_width" is deprecated, use "thumbnail_width" instead') - return self.thumbnail_width - - @property - def thumb_height(self) -> int: - log_deprecation_warning('The parameter "thumb_height" is deprecated, use "thumbnail_height" instead') - return self.thumbnail_height - def to_dict(self): json_dict = super().to_dict() json_dict['latitude'] = self.latitude @@ -5783,21 +5695,6 @@ def __init__(self, id: str, title: str, latitude: float, longitude: float, addre self.thumbnail_width: Optional[int] = thumbnail_width self.thumbnail_height: Optional[int] = thumbnail_height - @property - def thumb_url(self) -> str: - log_deprecation_warning('The parameter "thumb_url" is deprecated, use "thumbnail_url" instead') - return self.thumbnail_url - - @property - def thumb_width(self) -> int: - log_deprecation_warning('The parameter "thumb_width" is deprecated, use "thumbnail_width" instead') - return self.thumbnail_width - - @property - def thumb_height(self) -> int: - log_deprecation_warning('The parameter "thumb_height" is deprecated, use "thumbnail_height" instead') - return self.thumbnail_height - def to_dict(self): json_dict = super().to_dict() json_dict['latitude'] = self.latitude @@ -5877,22 +5774,6 @@ def __init__(self, id: str, phone_number: str, first_name: str, last_name: Optio self.thumbnail_width: Optional[int] = thumbnail_width self.thumbnail_height: Optional[int] = thumbnail_height - - @property - def thumb_url(self) -> str: - log_deprecation_warning('The parameter "thumb_url" is deprecated, use "thumbnail_url" instead') - return self.thumbnail_url - - @property - def thumb_width(self) -> int: - log_deprecation_warning('The parameter "thumb_width" is deprecated, use "thumbnail_width" instead') - return self.thumbnail_width - - @property - def thumb_height(self) -> int: - log_deprecation_warning('The parameter "thumb_height" is deprecated, use "thumbnail_height" instead') - return self.thumbnail_height - def to_dict(self): json_dict = super().to_dict() json_dict['phone_number'] = self.phone_number @@ -5942,48 +5823,8 @@ def to_dict(self): return json_dict -class InlineQueryResultCachedBase(ABC, JsonSerializable): - """ - Base class of all InlineQueryResultCached* classes. - """ - def __init__(self): - self.type: str = "" - self.id: str = "" - self.title: Optional[str] = None - self.description: Optional[str] = None - self.caption: Optional[str] = None - self.reply_markup: Optional[InlineKeyboardMarkup] = None - self.input_message_content: Optional[InputMessageContent] = None - self.parse_mode: Optional[str] = None - self.caption_entities: Optional[List[MessageEntity]] = None - self.payload_dic: Dict[str] = {} - self.show_caption_above_media: Optional[bool] = None - - def to_json(self): - json_dict = self.payload_dic - json_dict['type'] = self.type - json_dict['id'] = self.id - if self.title: - json_dict['title'] = self.title - if self.description: - json_dict['description'] = self.description - if self.caption: - json_dict['caption'] = self.caption - if self.reply_markup: - json_dict['reply_markup'] = self.reply_markup.to_dict() - if self.input_message_content: - json_dict['input_message_content'] = self.input_message_content.to_dict() - if self.parse_mode: - json_dict['parse_mode'] = self.parse_mode - if self.caption_entities: - json_dict['caption_entities'] = MessageEntity.to_list_of_dicts(self.caption_entities) - if self.show_caption_above_media is not None: - json_dict['show_caption_above_media'] = self.show_caption_above_media - return json.dumps(json_dict) - - # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultCachedPhoto(InlineQueryResultCachedBase): +class InlineQueryResultCachedPhoto(InlineQueryResult): """ Represents a link to a photo stored on the Telegram servers. By default, this photo will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the photo. @@ -6031,25 +5872,20 @@ def __init__(self, id: str, photo_file_id: str, title: Optional[str] = None, des caption: Optional[str] = None, caption_entities: Optional[List[MessageEntity]] = None, parse_mode: Optional[str] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, input_message_content: Optional[InputMessageContent] = None, show_caption_above_media: Optional[bool] = None): - - InlineQueryResultCachedBase.__init__(self) - self.type: str = 'photo' - self.id: str = id + super().__init__('photo', id, title = title, caption = caption, + input_message_content = input_message_content, reply_markup = reply_markup, + parse_mode = parse_mode, caption_entities = caption_entities, description = description, + show_caption_above_media = show_caption_above_media) self.photo_file_id: str = photo_file_id - self.title: Optional[str] = title - self.description: Optional[str] = description - self.caption: Optional[str] = caption - self.caption_entities: Optional[List[MessageEntity]] = caption_entities - self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup - self.input_message_content: Optional[InputMessageContent] = input_message_content - self.parse_mode: Optional[str] = parse_mode - self.payload_dic['photo_file_id'] = photo_file_id - self.show_caption_above_media: Optional[bool] = show_caption_above_media + def to_dict(self): + json_dict = super().to_dict() + json_dict['photo_file_id'] = self.photo_file_id + return json_dict # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultCachedGif(InlineQueryResultCachedBase): +class InlineQueryResultCachedGif(InlineQueryResult): """ Represents a link to an animated GIF file stored on the Telegram servers. By default, this animated GIF file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with specified content instead of the animation. @@ -6093,24 +5929,20 @@ def __init__(self, id: str, gif_file_id: str, title: Optional[str] = None, descr caption: Optional[str] = None, caption_entities: Optional[List[MessageEntity]] = None, parse_mode: Optional[str] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, input_message_content: Optional[InputMessageContent] = None, show_caption_above_media: Optional[bool] = None): - - InlineQueryResultCachedBase.__init__(self) - self.type: str = 'gif' - self.id: str = id + super().__init__('gif', id, title = title, caption = caption, + input_message_content = input_message_content, reply_markup = reply_markup, + parse_mode = parse_mode, caption_entities = caption_entities, description = description, + show_caption_above_media = show_caption_above_media) self.gif_file_id: str = gif_file_id - self.title: Optional[str] = title - self.description: Optional[str] = description - self.caption: Optional[str] = caption - self.caption_entities: Optional[List[MessageEntity]] = caption_entities - self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup - self.input_message_content: Optional[InputMessageContent] = input_message_content - self.parse_mode: Optional[str] = parse_mode - self.payload_dic['gif_file_id'] = gif_file_id - self.show_caption_above_media: Optional[bool] = show_caption_above_media + + def to_dict(self): + json_dict = super().to_dict() + json_dict['gif_file_id'] = self.gif_file_id + return json_dict # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultCachedMpeg4Gif(InlineQueryResultCachedBase): +class InlineQueryResultCachedMpeg4Gif(InlineQueryResult): """ Represents a link to a video animation (H.264/MPEG-4 AVC video without sound) stored on the Telegram servers. By default, this animated MPEG-4 file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation. @@ -6154,23 +5986,20 @@ def __init__(self, id: str, mpeg4_file_id: str, title: Optional[str] = None, des caption: Optional[str] = None, caption_entities: Optional[List[MessageEntity]] = None, parse_mode: Optional[str] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, input_message_content: Optional[InputMessageContent] = None, show_caption_above_media: Optional[bool] = None): - - InlineQueryResultCachedBase.__init__(self) - self.type: str = 'mpeg4_gif' - self.id: str = id + super().__init__('mpeg4_gif', id, title = title, caption = caption, + input_message_content = input_message_content, reply_markup = reply_markup, + parse_mode = parse_mode, caption_entities = caption_entities, description = description, + show_caption_above_media = show_caption_above_media) self.mpeg4_file_id: str = mpeg4_file_id - self.title: Optional[str] = title - self.description: Optional[str] = description - self.caption: Optional[str] = caption - self.caption_entities: Optional[List[MessageEntity]] = caption_entities - self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup - self.input_message_content: Optional[InputMessageContent] = input_message_content - self.parse_mode: Optional[str] = parse_mode - self.payload_dic['mpeg4_file_id'] = mpeg4_file_id - self.show_caption_above_media: Optional[bool] = show_caption_above_media + + def to_dict(self): + json_dict = super().to_dict() + json_dict['mpeg4_file_id'] = self.mpeg4_file_id + return json_dict + # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultCachedSticker(InlineQueryResultCachedBase): +class InlineQueryResultCachedSticker(InlineQueryResult): """ Represents a link to a sticker stored on the Telegram servers. By default, this sticker will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the sticker. @@ -6196,18 +6025,17 @@ class InlineQueryResultCachedSticker(InlineQueryResultCachedBase): """ def __init__(self, id: str, sticker_file_id: str, reply_markup: Optional[InlineKeyboardMarkup] = None, input_message_content: Optional[InputMessageContent] = None): - InlineQueryResultCachedBase.__init__(self) - self.type: str = 'sticker' - self.id: str = id + super().__init__('sticker', id, input_message_content = input_message_content, reply_markup = reply_markup) self.sticker_file_id: str = sticker_file_id - self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup - self.input_message_content: Optional[InputMessageContent] = input_message_content - self.payload_dic['sticker_file_id'] = sticker_file_id + def to_dict(self): + json_dict = super().to_dict() + json_dict['sticker_file_id'] = self.sticker_file_id + return json_dict # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultCachedDocument(InlineQueryResultCachedBase): +class InlineQueryResultCachedDocument(InlineQueryResult): """ Represents a link to a file stored on the Telegram servers. By default, this file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the file. @@ -6253,23 +6081,19 @@ def __init__(self, id: str, document_file_id: str, title: str, description: Opti caption: Optional[str] = None, caption_entities: Optional[List[MessageEntity]] = None, parse_mode: Optional[str] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, input_message_content: Optional[InputMessageContent] = None): - - InlineQueryResultCachedBase.__init__(self) - self.type: str = 'document' - self.id: str = id - self.title: str = title + super().__init__('document', id, title = title, caption = caption, + input_message_content = input_message_content, reply_markup = reply_markup, + parse_mode = parse_mode, caption_entities = caption_entities, description = description) self.document_file_id: str = document_file_id - self.description: Optional[str] = description - self.caption: Optional[str] = caption - self.caption_entities: Optional[List[MessageEntity]] = caption_entities - self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup - self.input_message_content: Optional[InputMessageContent] = input_message_content - self.parse_mode: Optional[str] = parse_mode - self.payload_dic['document_file_id'] = document_file_id + + def to_dict(self): + json_dict = super().to_dict() + json_dict['document_file_id'] = self.document_file_id + return json_dict # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultCachedVideo(InlineQueryResultCachedBase): +class InlineQueryResultCachedVideo(InlineQueryResult): """ Represents a link to a video file stored on the Telegram servers. By default, this video file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the video. @@ -6318,24 +6142,20 @@ def __init__(self, id: str, video_file_id: str, title: str, description: Optiona caption: Optional[str] = None, caption_entities: Optional[List[MessageEntity]] = None, parse_mode: Optional[str] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, input_message_content: Optional[InputMessageContent] = None, show_caption_above_media: Optional[bool] = None): - - InlineQueryResultCachedBase.__init__(self) - self.type: str = 'video' - self.id: str = id + super().__init__('video', id, title = title, caption = caption, + input_message_content = input_message_content, reply_markup = reply_markup, + parse_mode = parse_mode, caption_entities = caption_entities, description = description, + show_caption_above_media = show_caption_above_media) self.video_file_id: str = video_file_id - self.title: str = title - self.description: Optional[str] = description - self.caption: Optional[str] = caption - self.caption_entities: Optional[List[MessageEntity]] = caption_entities - self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup - self.input_message_content: Optional[InputMessageContent] = input_message_content - self.parse_mode: Optional[str] = parse_mode - self.payload_dic['video_file_id'] = video_file_id - self.show_caption_above_media: Optional[bool] = show_caption_above_media + + def to_dict(self): + json_dict = super().to_dict() + json_dict['video_file_id'] = self.video_file_id + return json_dict # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultCachedVoice(InlineQueryResultCachedBase): +class InlineQueryResultCachedVoice(InlineQueryResult): """ Represents a link to a voice message stored on the Telegram servers. By default, this voice message will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the voice message. @@ -6377,22 +6197,19 @@ class InlineQueryResultCachedVoice(InlineQueryResultCachedBase): def __init__(self, id: str, voice_file_id: str, title: str, caption: Optional[str] = None, caption_entities: Optional[List[MessageEntity]] = None, parse_mode: Optional[str] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, input_message_content: Optional[InputMessageContent] = None): - InlineQueryResultCachedBase.__init__(self) - self.type: str = 'voice' - self.id: str = id + super().__init__('voice', id, title = title, caption = caption, + input_message_content = input_message_content, reply_markup = reply_markup, + parse_mode = parse_mode, caption_entities = caption_entities) self.voice_file_id: str = voice_file_id - self.title: str = title - self.caption: Optional[str] = caption - self.caption_entities: Optional[List[MessageEntity]] = caption_entities - self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup - self.input_message_content: Optional[InputMessageContent] = input_message_content - self.parse_mode: Optional[str] = parse_mode - self.payload_dic['voice_file_id'] = voice_file_id + def to_dict(self): + json_dict = super().to_dict() + json_dict['voice_file_id'] = self.voice_file_id + return json_dict # noinspection PyUnresolvedReferences,PyShadowingBuiltins -class InlineQueryResultCachedAudio(InlineQueryResultCachedBase): +class InlineQueryResultCachedAudio(InlineQueryResult): """ Represents a link to an MP3 audio file stored on the Telegram servers. By default, this audio file will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the audio. @@ -6431,19 +6248,16 @@ class InlineQueryResultCachedAudio(InlineQueryResultCachedBase): def __init__(self, id: str, audio_file_id: str, caption: Optional[str] = None, caption_entities: Optional[List[MessageEntity]] = None, parse_mode: Optional[str] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, input_message_content: Optional[InputMessageContent] = None): - InlineQueryResultCachedBase.__init__(self) - self.type: str = 'audio' - self.id: str = id + super().__init__('audio', id, title = title, caption = caption, + input_message_content = input_message_content, reply_markup = reply_markup, + parse_mode = parse_mode, caption_entities = caption_entities) self.audio_file_id: str = audio_file_id - self.caption: Optional[str] = caption - self.caption_entities: Optional[List[MessageEntity]] = caption_entities - self.reply_markup: Optional[InlineKeyboardMarkup] = reply_markup - self.input_message_content: Optional[InputMessageContent] = input_message_content - self.parse_mode: Optional[str] = parse_mode - self.payload_dic['audio_file_id'] = audio_file_id + def to_dict(self): + json_dict = super().to_dict() + json_dict['audio_file_id'] = self.audio_file_id + return json_dict -# Games class Game(JsonDeserializable): """ From 55ff4cd489cfb4f4c2a3f4c54bd00a735923a4c5 Mon Sep 17 00:00:00 2001 From: Badiboy Date: Sun, 16 Aug 2026 20:04:18 +0300 Subject: [PATCH 05/11] ABS -> ABC fix --- telebot/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telebot/types.py b/telebot/types.py index 44655dc8e..565e6d12e 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -947,7 +947,7 @@ class Chat(ChatFullInfo): pass -class MessageID(ABS, JsonDeserializable): +class MessageID(ABC, JsonDeserializable): """ Deprecated. Use `MessageId` instead. """ From f7d8b192c38751c491dc46fbda5164535f104bbb Mon Sep 17 00:00:00 2001 From: Badiboy Date: Sun, 16 Aug 2026 20:08:16 +0300 Subject: [PATCH 06/11] Fix ABC --- telebot/types.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/telebot/types.py b/telebot/types.py index 565e6d12e..0ce453a22 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -947,7 +947,7 @@ class Chat(ChatFullInfo): pass -class MessageID(ABC, JsonDeserializable): +class MessageID(JsonDeserializable, ABC): """ Deprecated. Use `MessageId` instead. """ @@ -4817,20 +4817,20 @@ def to_dict(self): return json_dict -class InlineQueryResultBase(ABC, Dictionaryable, JsonSerializable): +class InlineQueryResultBase(Dictionaryable, JsonSerializable, ABC): """ Deprecated. Use `InlineQueryResult` instead. """ -class InlineQueryResultCachedBase(ABC, InlineQueryResultBase): +class InlineQueryResultCachedBase(InlineQueryResultBase, ABC): """ Deprecated. Use `InlineQueryResult` instead. """ # noinspection PyShadowingBuiltins -class InlineQueryResult(ABC, InlineQueryResultCachedBase): +class InlineQueryResult(InlineQueryResultCachedBase, ABC): """ This object represents one result of an inline query. Telegram clients currently support results of the following 20 types: From 459293e90b9e780505b1202c832c36702a4bb436 Mon Sep 17 00:00:00 2001 From: Badiboy Date: Sun, 16 Aug 2026 20:23:36 +0300 Subject: [PATCH 07/11] Copilot fixes --- telebot/types.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/telebot/types.py b/telebot/types.py index 0ce453a22..25f2c0d87 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -951,9 +951,18 @@ class MessageID(JsonDeserializable, ABC): """ Deprecated. Use `MessageId` instead. """ + @classmethod + def de_json(cls, json_string): + if json_string is None: return None + obj = cls.check_json(json_string, dict_copy=False) + return cls(**obj) + + def __init__(self, message_id, **kwargs): + self.message_id: int = message_id + log_deprecation_warning('The class "MessageID" is deprecated, use "MessageId" instead') -class MessageId(MessageID): +class MessageId(JsonDeserializable, ABC): """ This object represents a unique message identifier. @@ -4933,7 +4942,7 @@ class InlineQueryResultArticle(InlineQueryResult): :type url: :obj:`str` :param hide_url: deprecated. Use empty url instead - :type hide_url: :obj:`str` + :type hide_url: :obj:`bool` :param description: Optional. Short description of the result :type description: :obj:`str` @@ -6248,9 +6257,8 @@ class InlineQueryResultCachedAudio(InlineQueryResult): def __init__(self, id: str, audio_file_id: str, caption: Optional[str] = None, caption_entities: Optional[List[MessageEntity]] = None, parse_mode: Optional[str] = None, reply_markup: Optional[InlineKeyboardMarkup] = None, input_message_content: Optional[InputMessageContent] = None): - super().__init__('audio', id, title = title, caption = caption, - input_message_content = input_message_content, reply_markup = reply_markup, - parse_mode = parse_mode, caption_entities = caption_entities) + super().__init__('audio', id, caption = caption, input_message_content = input_message_content, + reply_markup = reply_markup, parse_mode = parse_mode, caption_entities = caption_entities) self.audio_file_id: str = audio_file_id def to_dict(self): From f81fd2eb1593b7ff04c1eb6c4b5a12dbc74d5cc8 Mon Sep 17 00:00:00 2001 From: Badiboy Date: Sun, 16 Aug 2026 20:35:03 +0300 Subject: [PATCH 08/11] Fix Copilot --- telebot/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telebot/types.py b/telebot/types.py index 25f2c0d87..86fe7300b 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -962,7 +962,7 @@ def __init__(self, message_id, **kwargs): log_deprecation_warning('The class "MessageID" is deprecated, use "MessageId" instead') -class MessageId(JsonDeserializable, ABC): +class MessageId(MessageID): """ This object represents a unique message identifier. From 3cd8991bd32327e79ebd95b6127154124283ffee Mon Sep 17 00:00:00 2001 From: Badiboy Date: Tue, 18 Aug 2026 21:06:27 +0300 Subject: [PATCH 09/11] Fix can_delete_sent_messages in BusinessBotRights Wrong parameter name was used... --- telebot/types.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/telebot/types.py b/telebot/types.py index 86fe7300b..a866cf3c2 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -12093,8 +12093,8 @@ class BusinessBotRights(JsonDeserializable): :param can_read_messages: Optional. True, if the bot can mark incoming private messages as read :type can_read_messages: :obj:`bool` - :param can_delete_outgoing_messages: Optional. True, if the bot can delete messages sent by the bot - :type can_delete_outgoing_messages: :obj:`bool` + :param can_delete_sent_messages: Optional. True, if the bot can delete messages sent by the bot + :type can_delete_sent_messages: :obj:`bool` :param can_delete_all_messages: Optional. True, if the bot can delete all private messages in managed chats :type can_delete_all_messages: :obj:`bool` @@ -12132,13 +12132,13 @@ class BusinessBotRights(JsonDeserializable): :return: Instance of the class :rtype: :class:`BusinessBotRights` """ - def __init__(self, can_reply=None, can_read_messages=None, can_delete_outgoing_messages=None, can_delete_all_messages=None, + def __init__(self, can_reply=None, can_read_messages=None, can_delete_sent_messages=None, can_delete_all_messages=None, can_edit_name=None, can_edit_bio=None, can_edit_profile_photo=None, can_edit_username=None, can_change_gift_settings=None, can_view_gifts_and_stars=None, can_convert_gifts_to_stars=None, can_transfer_and_upgrade_gifts=None, can_transfer_stars=None, can_manage_stories=None, **kwargs): self.can_reply: Optional[bool] = can_reply self.can_read_messages: Optional[bool] = can_read_messages - self.can_delete_outgoing_messages: Optional[bool] = can_delete_outgoing_messages + self.can_delete_sent_messages: Optional[bool] = can_delete_sent_messages self.can_delete_all_messages: Optional[bool] = can_delete_all_messages self.can_edit_name: Optional[bool] = can_edit_name self.can_edit_bio: Optional[bool] = can_edit_bio @@ -12157,6 +12157,13 @@ def de_json(cls, json_string): obj = cls.check_json(json_string) return cls(**obj) + @property + def can_delete_outgoing_messages(self) -> Optional[int]: + """Deprecated. Use can_delete_sent_messages instead.""" + log_deprecation_warning("can_delete_outgoing_messages is deprecated. Use can_delete_sent_messages instead.") + return self.can_delete_sent_messages + + class AcceptedGiftTypes(JsonDeserializable, JsonSerializable): """ From f8eb387d9d3c89551ce79b0debeef53245d9e442 Mon Sep 17 00:00:00 2001 From: Badiboy Date: Tue, 18 Aug 2026 21:07:08 +0300 Subject: [PATCH 10/11] extra space... --- telebot/types.py | 1 - 1 file changed, 1 deletion(-) diff --git a/telebot/types.py b/telebot/types.py index a866cf3c2..ab164230e 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -12164,7 +12164,6 @@ def can_delete_outgoing_messages(self) -> Optional[int]: return self.can_delete_sent_messages - class AcceptedGiftTypes(JsonDeserializable, JsonSerializable): """ This object describes the types of gifts that can be gifted to a user or a chat. From ae4872e76a1c21ccb5ddba81f8e2688c731dffe2 Mon Sep 17 00:00:00 2001 From: Badiboy Date: Tue, 18 Aug 2026 21:11:12 +0300 Subject: [PATCH 11/11] And tests... --- tests/test_types.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_types.py b/tests/test_types.py index 7bf81b392..208fa3c7a 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -904,12 +904,12 @@ def test_json_reactiontypepaid(): def test_json_businessbotrights(): - json_str = r'{"can_reply": true, "can_read_messages": true, "can_delete_outgoing_messages": true, "can_delete_all_messages": false, "can_edit_name": true, "can_edit_bio": false, "can_edit_profile_photo": false, "can_edit_username": false, "can_change_gift_settings": false, "can_view_gifts_and_stars": true, "can_convert_gifts_to_stars": false, "can_transfer_and_upgrade_gifts": false, "can_transfer_stars": false, "can_manage_stories": false}' + json_str = r'{"can_reply": true, "can_read_messages": true, "can_delete_sent_messages": true, "can_delete_all_messages": false, "can_edit_name": true, "can_edit_bio": false, "can_edit_profile_photo": false, "can_edit_username": false, "can_change_gift_settings": false, "can_view_gifts_and_stars": true, "can_convert_gifts_to_stars": false, "can_transfer_and_upgrade_gifts": false, "can_transfer_stars": false, "can_manage_stories": false}' result = types.BusinessBotRights.de_json(json_str) assert isinstance(result, types.BusinessBotRights) assert result.can_reply is True assert result.can_read_messages is True - assert result.can_delete_outgoing_messages is True + assert result.can_delete_sent_messages is True assert result.can_delete_all_messages is False assert result.can_edit_name is True assert result.can_edit_bio is False @@ -1336,7 +1336,7 @@ def test_json_botsubscriptionupdated(): def test_json_businessconnection(): - json_str = r'{"id": "1", "user": {"id": 1, "is_bot": false, "first_name": "Test"}, "user_chat_id": 1, "date": 1682189507, "is_enabled": false, "rights": {"can_reply": true, "can_read_messages": true, "can_delete_outgoing_messages": false, "can_delete_all_messages": false, "can_edit_name": true, "can_edit_bio": false, "can_edit_profile_photo": true, "can_edit_username": false, "can_change_gift_settings": true, "can_view_gifts_and_stars": false, "can_convert_gifts_to_stars": true, "can_transfer_and_upgrade_gifts": false, "can_transfer_stars": true, "can_manage_stories": false}}' + json_str = r'{"id": "1", "user": {"id": 1, "is_bot": false, "first_name": "Test"}, "user_chat_id": 1, "date": 1682189507, "is_enabled": false, "rights": {"can_reply": true, "can_read_messages": true, "can_delete_sent_messages": false, "can_delete_all_messages": false, "can_edit_name": true, "can_edit_bio": false, "can_edit_profile_photo": true, "can_edit_username": false, "can_change_gift_settings": true, "can_view_gifts_and_stars": false, "can_convert_gifts_to_stars": true, "can_transfer_and_upgrade_gifts": false, "can_transfer_stars": true, "can_manage_stories": false}}' result = types.BusinessConnection.de_json(json_str) assert isinstance(result, types.BusinessConnection) assert result.id == '1' @@ -1347,7 +1347,7 @@ def test_json_businessconnection(): assert isinstance(result.rights, types.BusinessBotRights) assert result.rights.can_reply == True assert result.rights.can_read_messages == True - assert result.rights.can_delete_outgoing_messages == False + assert result.rights.can_delete_sent_messages == False assert result.rights.can_delete_all_messages == False assert result.rights.can_edit_name == True assert result.rights.can_edit_bio == False