diff --git a/telegram/bot.py b/telegram/bot.py index 46a77b39791..ee6ba4e10d5 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -405,6 +405,7 @@ def send_message( timeout: float = None, api_kwargs: JSONDict = None, allow_sending_without_reply: bool = None, + entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ) -> Optional[Message]: """Use this method to send text messages. @@ -416,6 +417,8 @@ def send_message( parse_mode (:obj:`str`): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. See the constants in :class:`telegram.ParseMode` for the available modes. + entities (List[:class:`telegram.MessageEntity`], optional): List of special entities + that appear in message text, which can be specified instead of :attr:`parse_mode`. disable_web_page_preview (:obj:`bool`, optional): Disables link previews for links in this message. disable_notification (:obj:`bool`, optional): Sends the message silently. Users will @@ -444,6 +447,8 @@ def send_message( if parse_mode: data['parse_mode'] = parse_mode + if entities: + data['entities'] = [me.to_dict() for me in entities] if disable_web_page_preview: data['disable_web_page_preview'] = disable_web_page_preview @@ -566,6 +571,7 @@ def send_photo( parse_mode: str = None, api_kwargs: JSONDict = None, allow_sending_without_reply: bool = None, + caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ) -> Optional[Message]: """Use this method to send photos. @@ -586,6 +592,9 @@ def send_photo( parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in message text, which can be specified instead of + :attr:`parse_mode`. disable_notification (:obj:`bool`, optional): Sends the message silently. Users will receive a notification with no sound. reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the @@ -618,6 +627,8 @@ def send_photo( data['caption'] = caption if parse_mode: data['parse_mode'] = parse_mode + if caption_entities: + data['caption_entities'] = [me.to_dict() for me in caption_entities] return self._message( # type: ignore[return-value] 'sendPhoto', @@ -647,6 +658,7 @@ def send_audio( thumb: FileLike = None, api_kwargs: JSONDict = None, allow_sending_without_reply: bool = None, + caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ) -> Optional[Message]: """ Use this method to send audio files, if you want Telegram clients to display them in the @@ -674,6 +686,9 @@ def send_audio( parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in message text, which can be specified instead of + :attr:`parse_mode`. duration (:obj:`int`, optional): Duration of sent audio in seconds. performer (:obj:`str`, optional): Performer. title (:obj:`str`, optional): Track name. @@ -720,6 +735,8 @@ def send_audio( data['caption'] = caption if parse_mode: data['parse_mode'] = parse_mode + if caption_entities: + data['caption_entities'] = [me.to_dict() for me in caption_entities] if thumb: if InputFile.is_file(thumb): thumb = cast(IO, thumb) @@ -753,6 +770,7 @@ def send_document( api_kwargs: JSONDict = None, disable_content_type_detection: bool = None, allow_sending_without_reply: bool = None, + caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ) -> Optional[Message]: """ Use this method to send general files. @@ -781,6 +799,9 @@ def send_document( parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in message text, which can be specified instead of + :attr:`parse_mode`. disable_notification (:obj:`bool`, optional): Sends the message silently. Users will receive a notification with no sound. reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the @@ -818,6 +839,8 @@ def send_document( data['caption'] = caption if parse_mode: data['parse_mode'] = parse_mode + if caption_entities: + data['caption_entities'] = [me.to_dict() for me in caption_entities] if disable_content_type_detection is not None: data['disable_content_type_detection'] = disable_content_type_detection if thumb: @@ -921,6 +944,7 @@ def send_video( thumb: FileLike = None, api_kwargs: JSONDict = None, allow_sending_without_reply: bool = None, + caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ) -> Optional[Message]: """ Use this method to send video files, Telegram clients support mp4 videos @@ -952,6 +976,9 @@ def send_video( parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in message text, which can be specified instead of + :attr:`parse_mode`. supports_streaming (:obj:`bool`, optional): Pass :obj:`True`, if the uploaded video is suitable for streaming. disable_notification (:obj:`bool`, optional): Sends the message silently. Users will @@ -993,6 +1020,8 @@ def send_video( data['caption'] = caption if parse_mode: data['parse_mode'] = parse_mode + if caption_entities: + data['caption_entities'] = [me.to_dict() for me in caption_entities] if supports_streaming: data['supports_streaming'] = supports_streaming if width: @@ -1124,6 +1153,7 @@ def send_animation( timeout: float = 20, api_kwargs: JSONDict = None, allow_sending_without_reply: bool = None, + caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ) -> Optional[Message]: """ Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound). @@ -1156,6 +1186,9 @@ def send_animation( parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in message text, which can be specified instead of + :attr:`parse_mode`. disable_notification (:obj:`bool`, optional): Sends the message silently. Users will receive a notification with no sound. reply_to_message_id (:obj:`int`, optional): If the message is a reply, ID of the @@ -1199,6 +1232,8 @@ def send_animation( data['caption'] = caption if parse_mode: data['parse_mode'] = parse_mode + if caption_entities: + data['caption_entities'] = [me.to_dict() for me in caption_entities] return self._message( # type: ignore[return-value] 'sendAnimation', @@ -1225,6 +1260,7 @@ def send_voice( parse_mode: str = None, api_kwargs: JSONDict = None, allow_sending_without_reply: bool = None, + caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ) -> Optional[Message]: """ Use this method to send audio files, if you want Telegram clients to display the file @@ -1249,6 +1285,9 @@ def send_voice( parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in message text, which can be specified instead of + :attr:`parse_mode`. duration (:obj:`int`, optional): Duration of the voice message in seconds. disable_notification (:obj:`bool`, optional): Sends the message silently. Users will receive a notification with no sound. @@ -1284,6 +1323,8 @@ def send_voice( data['caption'] = caption if parse_mode: data['parse_mode'] = parse_mode + if caption_entities: + data['caption_entities'] = [me.to_dict() for me in caption_entities] return self._message( # type: ignore[return-value] 'sendVoice', @@ -2290,6 +2331,7 @@ def edit_message_text( reply_markup: ReplyMarkup = None, timeout: float = None, api_kwargs: JSONDict = None, + entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ) -> Union[Optional[Message], bool]: """ Use this method to edit text and game messages. @@ -2306,6 +2348,8 @@ def edit_message_text( parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. See the constants in :class:`telegram.ParseMode` for the available modes. + entities (List[:class:`telegram.MessageEntity`], optional): List of special entities + that appear in message text, which can be specified instead of :attr:`parse_mode`. disable_web_page_preview (:obj:`bool`, optional): Disables link previews for links in this message. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): A JSON-serialized @@ -2334,6 +2378,8 @@ def edit_message_text( data['inline_message_id'] = inline_message_id if parse_mode: data['parse_mode'] = parse_mode + if entities: + data['entities'] = [me.to_dict() for me in entities] if disable_web_page_preview: data['disable_web_page_preview'] = disable_web_page_preview @@ -2356,6 +2402,7 @@ def edit_message_caption( timeout: float = None, parse_mode: str = None, api_kwargs: JSONDict = None, + caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ) -> Union[Message, bool]: """ Use this method to edit captions of messages. @@ -2373,6 +2420,9 @@ def edit_message_caption( parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in message text, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): A JSON-serialized object for an inline keyboard. timeout (:obj:`int` | :obj:`float`, optional): If this value is specified, use it as @@ -2401,6 +2451,8 @@ def edit_message_caption( data['caption'] = caption if parse_mode: data['parse_mode'] = parse_mode + if caption_entities: + data['caption_entities'] = [me.to_dict() for me in caption_entities] if chat_id: data['chat_id'] = chat_id if message_id: @@ -4283,6 +4335,7 @@ def send_poll( close_date: Union[int, datetime] = None, api_kwargs: JSONDict = None, allow_sending_without_reply: bool = None, + explanation_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ) -> Message: """ Use this method to send a native poll. @@ -4306,6 +4359,9 @@ def send_poll( explanation_parse_mode (:obj:`str`, optional): Mode for parsing entities in the explanation. See the constants in :class:`telegram.ParseMode` for the available modes. + explanation_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in message text, which can be specified instead of + :attr:`parse_mode`. open_period (:obj:`int`, optional): Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with :attr:`close_date`. close_date (:obj:`int` | :obj:`datetime.datetime`, optional): Point in time (Unix @@ -4360,6 +4416,8 @@ def send_poll( data['explanation'] = explanation if explanation_parse_mode: data['explanation_parse_mode'] = explanation_parse_mode + if explanation_entities: + data['explanation_entities'] = [me.to_dict() for me in explanation_entities] if open_period: data['open_period'] = open_period if close_date: diff --git a/telegram/files/inputmedia.py b/telegram/files/inputmedia.py index 2bae6cd0699..6cc69406c99 100644 --- a/telegram/files/inputmedia.py +++ b/telegram/files/inputmedia.py @@ -18,11 +18,20 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """Base class for Telegram InputMedia Objects.""" -from typing import IO, Union, cast - -from telegram import Animation, Audio, Document, InputFile, PhotoSize, TelegramObject, Video +from typing import IO, Union, cast, List, Tuple + +from telegram import ( + Animation, + Audio, + Document, + InputFile, + PhotoSize, + TelegramObject, + Video, + MessageEntity, +) from telegram.utils.helpers import DEFAULT_NONE, DefaultValue -from telegram.utils.types import FileLike +from telegram.utils.types import FileLike, JSONDict class InputMedia(TelegramObject): @@ -34,6 +43,18 @@ class InputMedia(TelegramObject): """ + caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...], None] = None + + def to_dict(self) -> JSONDict: + data = super().to_dict() + + if self.caption_entities: + data['caption_entities'] = [ + ce.to_dict() for ce in self.caption_entities # pylint: disable=E1133 + ] + + return data + class InputMediaAnimation(InputMedia): """Represents an animation file (GIF or H.264/MPEG-4 AVC video without sound) to be sent. @@ -43,6 +64,8 @@ class InputMediaAnimation(InputMedia): media (:obj:`str` | :class:`telegram.InputFile`): Animation to send. caption (:obj:`str`): Optional. Caption of the document to be sent. parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption. thumb (:class:`telegram.InputFile`): Optional. Thumbnail of the file to send. width (:obj:`int`): Optional. Animation width. height (:obj:`int`): Optional. Animation height. @@ -64,6 +87,8 @@ class InputMediaAnimation(InputMedia): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of parse_mode. width (:obj:`int`, optional): Animation width. height (:obj:`int`, optional): Animation height. duration (:obj:`int`, optional): Animation duration. @@ -83,6 +108,7 @@ def __init__( width: int = None, height: int = None, duration: int = None, + caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ): self.type = 'animation' @@ -107,6 +133,7 @@ def __init__( if caption: self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities if width: self.width = width if height: @@ -123,6 +150,8 @@ class InputMediaPhoto(InputMedia): media (:obj:`str` | :class:`telegram.InputFile`): Photo to send. caption (:obj:`str`): Optional. Caption of the document to be sent. parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption. Args: media (:obj:`str` | `filelike object` | :class:`telegram.PhotoSize`): File to send. Pass a @@ -134,6 +163,8 @@ class InputMediaPhoto(InputMedia): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of parse_mode. """ def __init__( @@ -141,6 +172,7 @@ def __init__( media: Union[str, FileLike, PhotoSize], caption: str = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ): self.type = 'photo' @@ -155,6 +187,7 @@ def __init__( if caption: self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities class InputMediaVideo(InputMedia): @@ -165,6 +198,8 @@ class InputMediaVideo(InputMedia): media (:obj:`str` | :class:`telegram.InputFile`): Video file to send. caption (:obj:`str`): Optional. Caption of the document to be sent. parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption. width (:obj:`int`): Optional. Video width. height (:obj:`int`): Optional. Video height. duration (:obj:`int`): Optional. Video duration. @@ -182,6 +217,8 @@ class InputMediaVideo(InputMedia): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of parse_mode. width (:obj:`int`, optional): Video width. height (:obj:`int`, optional): Video height. duration (:obj:`int`, optional): Video duration. @@ -212,6 +249,7 @@ def __init__( supports_streaming: bool = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, thumb: FileLike = None, + caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ): self.type = 'video' @@ -236,6 +274,7 @@ def __init__( if caption: self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities if width: self.width = width if height: @@ -254,6 +293,8 @@ class InputMediaAudio(InputMedia): media (:obj:`str` | :class:`telegram.InputFile`): Audio file to send. caption (:obj:`str`): Optional. Caption of the document to be sent. parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption. duration (:obj:`int`): Duration of the audio in seconds. performer (:obj:`str`): Optional. Performer of the audio as defined by sender or by audio tags. @@ -270,6 +311,8 @@ class InputMediaAudio(InputMedia): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of parse_mode. duration (:obj:`int`): Duration of the audio in seconds as defined by sender. performer (:obj:`str`, optional): Performer of the audio as defined by sender or by audio tags. @@ -295,6 +338,7 @@ def __init__( duration: int = None, performer: str = None, title: str = None, + caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ): self.type = 'audio' @@ -319,6 +363,7 @@ def __init__( if caption: self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities if duration: self.duration = duration if performer: @@ -335,6 +380,8 @@ class InputMediaDocument(InputMedia): media (:obj:`str` | :class:`telegram.InputFile`): File to send. caption (:obj:`str`): Optional. Caption of the document to be sent. parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption. thumb (:class:`telegram.InputFile`): Optional. Thumbnail of the file to send. disable_content_type_detection (:obj:`bool`): Optional. Disables automatic server-side content type detection for files uploaded using multipart/form-data. Always true, if @@ -350,6 +397,8 @@ class InputMediaDocument(InputMedia): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of parse_mode. thumb (`filelike object`, optional): Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should @@ -367,6 +416,7 @@ def __init__( caption: str = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, disable_content_type_detection: bool = None, + caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None, ): self.type = 'document' @@ -388,4 +438,5 @@ def __init__( if caption: self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.disable_content_type_detection = disable_content_type_detection diff --git a/telegram/inline/inlinequeryresult.py b/telegram/inline/inlinequeryresult.py index 5891538dbf6..496af1c116a 100644 --- a/telegram/inline/inlinequeryresult.py +++ b/telegram/inline/inlinequeryresult.py @@ -22,6 +22,7 @@ from typing import Any from telegram import TelegramObject +from telegram.utils.types import JSONDict class InlineQueryResult(TelegramObject): @@ -55,3 +56,17 @@ def _has_parse_mode(self) -> bool: @property def _has_input_message_content(self) -> bool: return hasattr(self, 'input_message_content') + + def to_dict(self) -> JSONDict: + data = super().to_dict() + + # pylint: disable=E1101 + if ( + hasattr(self, 'caption_entities') + and self.caption_entities # type: ignore[attr-defined] + ): + data['caption_entities'] = [ + ce.to_dict() for ce in self.caption_entities # type: ignore[attr-defined] + ] + + return data diff --git a/telegram/inline/inlinequeryresultaudio.py b/telegram/inline/inlinequeryresultaudio.py index bc56e104094..3d240be0717 100644 --- a/telegram/inline/inlinequeryresultaudio.py +++ b/telegram/inline/inlinequeryresultaudio.py @@ -18,9 +18,9 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the classes that represent Telegram InlineQueryResultAudio.""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -44,6 +44,9 @@ class InlineQueryResultAudio(InlineQueryResult): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the @@ -59,6 +62,9 @@ class InlineQueryResultAudio(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the @@ -78,6 +84,7 @@ def __init__( reply_markup: 'ReplyMarkup' = None, input_message_content: 'InputMessageContent' = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): @@ -91,5 +98,6 @@ def __init__( self.audio_duration = audio_duration self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.reply_markup = reply_markup self.input_message_content = input_message_content diff --git a/telegram/inline/inlinequeryresultcachedaudio.py b/telegram/inline/inlinequeryresultcachedaudio.py index eddcb532286..b0889ee8837 100644 --- a/telegram/inline/inlinequeryresultcachedaudio.py +++ b/telegram/inline/inlinequeryresultcachedaudio.py @@ -18,9 +18,9 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the classes that represent Telegram InlineQueryResultCachedAudio.""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -41,6 +41,9 @@ class InlineQueryResultCachedAudio(InlineQueryResult): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the @@ -53,6 +56,9 @@ class InlineQueryResultCachedAudio(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the @@ -69,6 +75,7 @@ def __init__( reply_markup: 'ReplyMarkup' = None, input_message_content: 'InputMessageContent' = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): # Required @@ -78,5 +85,6 @@ def __init__( # Optionals self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.reply_markup = reply_markup self.input_message_content = input_message_content diff --git a/telegram/inline/inlinequeryresultcacheddocument.py b/telegram/inline/inlinequeryresultcacheddocument.py index 8adae15b7ec..68346e9124e 100644 --- a/telegram/inline/inlinequeryresultcacheddocument.py +++ b/telegram/inline/inlinequeryresultcacheddocument.py @@ -19,9 +19,9 @@ # pylint: disable=W0622 """This module contains the classes that represent Telegram InlineQueryResultCachedDocument.""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -45,6 +45,9 @@ class InlineQueryResultCachedDocument(InlineQueryResult): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption.. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the @@ -60,6 +63,9 @@ class InlineQueryResultCachedDocument(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption.. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the @@ -78,6 +84,7 @@ def __init__( reply_markup: 'ReplyMarkup' = None, input_message_content: 'InputMessageContent' = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): # Required @@ -89,5 +96,6 @@ def __init__( self.description = description self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.reply_markup = reply_markup self.input_message_content = input_message_content diff --git a/telegram/inline/inlinequeryresultcachedgif.py b/telegram/inline/inlinequeryresultcachedgif.py index 5a406116eb8..ddce04cdee4 100644 --- a/telegram/inline/inlinequeryresultcachedgif.py +++ b/telegram/inline/inlinequeryresultcachedgif.py @@ -18,9 +18,9 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the classes that represent Telegram InlineQueryResultCachedGif.""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -44,6 +44,9 @@ class InlineQueryResultCachedGif(InlineQueryResult): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the @@ -58,6 +61,9 @@ class InlineQueryResultCachedGif(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the @@ -75,6 +81,7 @@ def __init__( reply_markup: 'ReplyMarkup' = None, input_message_content: 'InputMessageContent' = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): # Required @@ -85,5 +92,6 @@ def __init__( self.title = title self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.reply_markup = reply_markup self.input_message_content = input_message_content diff --git a/telegram/inline/inlinequeryresultcachedmpeg4gif.py b/telegram/inline/inlinequeryresultcachedmpeg4gif.py index 9e244d7d743..a8dd6bef7da 100644 --- a/telegram/inline/inlinequeryresultcachedmpeg4gif.py +++ b/telegram/inline/inlinequeryresultcachedmpeg4gif.py @@ -18,9 +18,9 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the classes that represent Telegram InlineQueryResultMpeg4Gif.""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -41,9 +41,12 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult): title (:obj:`str`): Optional. Title for the result. caption (:obj:`str`): Optional. Caption of the MPEG-4 file to be sent, 0-1024 characters after entities parsing. - parse_mode (:obj:`str`): Send Markdown or HTML, if you want Telegram apps to show + parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the @@ -58,6 +61,9 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the @@ -75,6 +81,7 @@ def __init__( reply_markup: 'ReplyMarkup' = None, input_message_content: 'InputMessageContent' = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): # Required @@ -85,5 +92,6 @@ def __init__( self.title = title self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.reply_markup = reply_markup self.input_message_content = input_message_content diff --git a/telegram/inline/inlinequeryresultcachedphoto.py b/telegram/inline/inlinequeryresultcachedphoto.py index 43da3460573..e80a9e03d83 100644 --- a/telegram/inline/inlinequeryresultcachedphoto.py +++ b/telegram/inline/inlinequeryresultcachedphoto.py @@ -19,9 +19,9 @@ # pylint: disable=W0622 """This module contains the classes that represent Telegram InlineQueryResultPhoto""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -46,6 +46,9 @@ class InlineQueryResultCachedPhoto(InlineQueryResult): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the @@ -61,6 +64,9 @@ class InlineQueryResultCachedPhoto(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the @@ -79,6 +85,7 @@ def __init__( reply_markup: 'ReplyMarkup' = None, input_message_content: 'InputMessageContent' = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): # Required @@ -90,5 +97,6 @@ def __init__( self.description = description self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.reply_markup = reply_markup self.input_message_content = input_message_content diff --git a/telegram/inline/inlinequeryresultcachedvideo.py b/telegram/inline/inlinequeryresultcachedvideo.py index df187142904..3fda4456a5e 100644 --- a/telegram/inline/inlinequeryresultcachedvideo.py +++ b/telegram/inline/inlinequeryresultcachedvideo.py @@ -18,9 +18,9 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the classes that represent Telegram InlineQueryResultCachedVideo.""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -45,6 +45,9 @@ class InlineQueryResultCachedVideo(InlineQueryResult): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the @@ -60,6 +63,9 @@ class InlineQueryResultCachedVideo(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the @@ -78,6 +84,7 @@ def __init__( reply_markup: 'ReplyMarkup' = None, input_message_content: 'InputMessageContent' = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): # Required @@ -89,5 +96,6 @@ def __init__( self.description = description self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.reply_markup = reply_markup self.input_message_content = input_message_content diff --git a/telegram/inline/inlinequeryresultcachedvoice.py b/telegram/inline/inlinequeryresultcachedvoice.py index 3b079df9e33..54314bb68bf 100644 --- a/telegram/inline/inlinequeryresultcachedvoice.py +++ b/telegram/inline/inlinequeryresultcachedvoice.py @@ -18,9 +18,9 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the classes that represent Telegram InlineQueryResultCachedVoice.""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -42,6 +42,9 @@ class InlineQueryResultCachedVoice(InlineQueryResult): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the @@ -55,6 +58,9 @@ class InlineQueryResultCachedVoice(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the @@ -72,6 +78,7 @@ def __init__( reply_markup: 'ReplyMarkup' = None, input_message_content: 'InputMessageContent' = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): # Required @@ -82,5 +89,6 @@ def __init__( # Optionals self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.reply_markup = reply_markup self.input_message_content = input_message_content diff --git a/telegram/inline/inlinequeryresultdocument.py b/telegram/inline/inlinequeryresultdocument.py index e54d9ac5a67..24e803c3880 100644 --- a/telegram/inline/inlinequeryresultdocument.py +++ b/telegram/inline/inlinequeryresultdocument.py @@ -18,9 +18,9 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the classes that represent Telegram InlineQueryResultDocument""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -43,6 +43,9 @@ class InlineQueryResultDocument(InlineQueryResult): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. document_url (:obj:`str`): A valid URL for the file. mime_type (:obj:`str`): Mime type of the content of the file, either "application/pdf" or "application/zip". @@ -63,6 +66,9 @@ class InlineQueryResultDocument(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. document_url (:obj:`str`): A valid URL for the file. mime_type (:obj:`str`): Mime type of the content of the file, either "application/pdf" or "application/zip". @@ -92,6 +98,7 @@ def __init__( thumb_width: int = None, thumb_height: int = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): # Required @@ -103,6 +110,7 @@ def __init__( # Optionals self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.description = description self.reply_markup = reply_markup self.input_message_content = input_message_content diff --git a/telegram/inline/inlinequeryresultgif.py b/telegram/inline/inlinequeryresultgif.py index 557f981e0a6..460d6f04603 100644 --- a/telegram/inline/inlinequeryresultgif.py +++ b/telegram/inline/inlinequeryresultgif.py @@ -19,9 +19,9 @@ # pylint: disable=W0622 """This module contains the classes that represent Telegram InlineQueryResultGif.""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -50,6 +50,9 @@ class InlineQueryResultGif(InlineQueryResult): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the @@ -71,6 +74,9 @@ class InlineQueryResultGif(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the @@ -93,6 +99,7 @@ def __init__( gif_duration: int = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, thumb_mime_type: str = None, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): @@ -108,6 +115,7 @@ def __init__( self.title = title self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.reply_markup = reply_markup self.input_message_content = input_message_content self.thumb_mime_type = thumb_mime_type diff --git a/telegram/inline/inlinequeryresultmpeg4gif.py b/telegram/inline/inlinequeryresultmpeg4gif.py index cb762c14014..ff9794c4ec5 100644 --- a/telegram/inline/inlinequeryresultmpeg4gif.py +++ b/telegram/inline/inlinequeryresultmpeg4gif.py @@ -18,9 +18,9 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the classes that represent Telegram InlineQueryResultMpeg4Gif.""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -50,6 +50,9 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the @@ -70,6 +73,9 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the @@ -92,6 +98,7 @@ def __init__( mpeg4_duration: int = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, thumb_mime_type: str = None, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): @@ -107,6 +114,7 @@ def __init__( self.title = title self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.reply_markup = reply_markup self.input_message_content = input_message_content self.thumb_mime_type = thumb_mime_type diff --git a/telegram/inline/inlinequeryresultphoto.py b/telegram/inline/inlinequeryresultphoto.py index f5dacc1e1aa..721e23bc36e 100644 --- a/telegram/inline/inlinequeryresultphoto.py +++ b/telegram/inline/inlinequeryresultphoto.py @@ -18,9 +18,9 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the classes that represent Telegram InlineQueryResultPhoto.""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -48,6 +48,9 @@ class InlineQueryResultPhoto(InlineQueryResult): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the @@ -67,6 +70,9 @@ class InlineQueryResultPhoto(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the @@ -88,6 +94,7 @@ def __init__( reply_markup: 'ReplyMarkup' = None, input_message_content: 'InputMessageContent' = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): # Required @@ -102,5 +109,6 @@ def __init__( self.description = description self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.reply_markup = reply_markup self.input_message_content = input_message_content diff --git a/telegram/inline/inlinequeryresultvideo.py b/telegram/inline/inlinequeryresultvideo.py index 113ce11e8ce..75fa7901c19 100644 --- a/telegram/inline/inlinequeryresultvideo.py +++ b/telegram/inline/inlinequeryresultvideo.py @@ -18,9 +18,9 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the classes that represent Telegram InlineQueryResultVideo.""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -50,6 +50,9 @@ class InlineQueryResultVideo(InlineQueryResult): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. video_width (:obj:`int`): Optional. Video width. video_height (:obj:`int`): Optional. Video height. video_duration (:obj:`int`): Optional. Video duration in seconds. @@ -71,6 +74,9 @@ class InlineQueryResultVideo(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. video_width (:obj:`int`, optional): Video width. video_height (:obj:`int`, optional): Video height. video_duration (:obj:`int`, optional): Video duration in seconds. @@ -100,6 +106,7 @@ def __init__( reply_markup: 'ReplyMarkup' = None, input_message_content: 'InputMessageContent' = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): @@ -113,6 +120,7 @@ def __init__( # Optional self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.video_width = video_width self.video_height = video_height self.video_duration = video_duration diff --git a/telegram/inline/inlinequeryresultvoice.py b/telegram/inline/inlinequeryresultvoice.py index 6ac3e144347..87d3baeab80 100644 --- a/telegram/inline/inlinequeryresultvoice.py +++ b/telegram/inline/inlinequeryresultvoice.py @@ -18,9 +18,9 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the classes that represent Telegram InlineQueryResultVoice.""" -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any, Union, Tuple, List -from telegram import InlineQueryResult +from telegram import InlineQueryResult, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue if TYPE_CHECKING: @@ -43,6 +43,9 @@ class InlineQueryResultVoice(InlineQueryResult): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. voice_duration (:obj:`int`): Optional. Recording duration in seconds. reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached to the message. @@ -57,6 +60,9 @@ class InlineQueryResultVoice(InlineQueryResult): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. voice_duration (:obj:`int`, optional): Recording duration in seconds. reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached to the message. @@ -76,6 +82,7 @@ def __init__( reply_markup: 'ReplyMarkup' = None, input_message_content: 'InputMessageContent' = None, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): @@ -88,5 +95,6 @@ def __init__( self.voice_duration = voice_duration self.caption = caption self.parse_mode = parse_mode + self.caption_entities = caption_entities self.reply_markup = reply_markup self.input_message_content = input_message_content diff --git a/telegram/inline/inputtextmessagecontent.py b/telegram/inline/inputtextmessagecontent.py index 6cd61ee1e2c..c168a0e472c 100644 --- a/telegram/inline/inputtextmessagecontent.py +++ b/telegram/inline/inputtextmessagecontent.py @@ -18,10 +18,11 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the classes that represent Telegram InputTextMessageContent.""" -from typing import Any, Union +from typing import Any, Union, Tuple, List -from telegram import InputMessageContent +from telegram import InputMessageContent, MessageEntity from telegram.utils.helpers import DEFAULT_NONE, DefaultValue +from telegram.utils.types import JSONDict class InputTextMessageContent(InputMessageContent): @@ -37,6 +38,9 @@ class InputTextMessageContent(InputMessageContent): parse_mode (:obj:`str`): Optional. Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`]): Optional. List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. disable_web_page_preview (:obj:`bool`): Optional. Disables link previews for links in the sent message. @@ -46,6 +50,9 @@ class InputTextMessageContent(InputMessageContent): parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. See the constants in :class:`telegram.ParseMode` for the available modes. + caption_entities (List[:class:`telegram.MessageEntity`], optional): List of special + entities that appear in the caption, which can be specified instead of + :attr:`parse_mode`. disable_web_page_preview (:obj:`bool`, optional): Disables link previews for links in the sent message. **kwargs (:obj:`dict`): Arbitrary keyword arguments. @@ -57,12 +64,22 @@ def __init__( message_text: str, parse_mode: Union[str, DefaultValue] = DEFAULT_NONE, disable_web_page_preview: Union[bool, DefaultValue] = DEFAULT_NONE, + caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None, **_kwargs: Any, ): # Required self.message_text = message_text # Optionals self.parse_mode = parse_mode + self.caption_entities = caption_entities self.disable_web_page_preview = disable_web_page_preview self._id_attrs = (self.message_text,) + + def to_dict(self) -> JSONDict: + data = super().to_dict() + + if self.caption_entities: + data['caption_entities'] = [ce.to_dict() for ce in self.caption_entities] + + return data diff --git a/telegram/utils/request.py b/telegram/utils/request.py index 69a509e028f..a4ff09883f3 100644 --- a/telegram/utils/request.py +++ b/telegram/utils/request.py @@ -337,6 +337,10 @@ def post(self, url: str, data: JSONDict, timeout: float = None) -> Union[JSONDic data[med.thumb.attach] = med.thumb.field_tuple data[key] = json.dumps(media) files = True + elif isinstance(val, list): + # In case we're sending files, we need to json-dump lists manually + # As we can't know if that's the case, we just json-dump here + data[key] = json.dumps(val) # Use multipart upload if we're uploading files, otherwise use JSON if files: diff --git a/tests/test_animation.py b/tests/test_animation.py index fee205c7346..abf5dbbad35 100644 --- a/tests/test_animation.py +++ b/tests/test_animation.py @@ -21,7 +21,7 @@ import pytest from flaky import flaky -from telegram import PhotoSize, Animation, Voice, TelegramError +from telegram import PhotoSize, Animation, Voice, TelegramError, MessageEntity from telegram.error import BadRequest from telegram.utils.helpers import escape_markdown @@ -127,6 +127,22 @@ def test_send_animation_url_file(self, bot, chat_id, animation): assert message.animation.mime_type == animation.mime_type assert message.animation.file_size == animation.file_size + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_send_animation_caption_entities(self, bot, chat_id, animation): + test_string = 'Italic Bold Code' + entities = [ + MessageEntity(MessageEntity.ITALIC, 0, 6), + MessageEntity(MessageEntity.ITALIC, 7, 4), + MessageEntity(MessageEntity.ITALIC, 12, 4), + ] + message = bot.send_animation( + chat_id, animation, caption=test_string, caption_entities=entities + ) + + assert message.caption == test_string + assert message.caption_entities == entities + @flaky(3, 1) @pytest.mark.timeout(10) @pytest.mark.parametrize('default_bot', [{'parse_mode': 'Markdown'}], indirect=True) diff --git a/tests/test_audio.py b/tests/test_audio.py index df1a53b0b72..c720853da95 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -21,7 +21,7 @@ import pytest from flaky import flaky -from telegram import Audio, TelegramError, Voice +from telegram import Audio, TelegramError, Voice, MessageEntity from telegram.utils.helpers import escape_markdown @@ -152,6 +152,20 @@ def test(url, data, **kwargs): message = bot.send_audio(audio=audio, chat_id=chat_id) assert message + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_send_audio_caption_entities(self, bot, chat_id, audio): + test_string = 'Italic Bold Code' + entities = [ + MessageEntity(MessageEntity.ITALIC, 0, 6), + MessageEntity(MessageEntity.ITALIC, 7, 4), + MessageEntity(MessageEntity.ITALIC, 12, 4), + ] + message = bot.send_audio(chat_id, audio, caption=test_string, caption_entities=entities) + + assert message.caption == test_string + assert message.caption_entities == entities + @flaky(3, 1) @pytest.mark.timeout(10) @pytest.mark.parametrize('default_bot', [{'parse_mode': 'Markdown'}], indirect=True) diff --git a/tests/test_bot.py b/tests/test_bot.py index b87f479d96d..0e8149e3332 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -372,6 +372,28 @@ def test_send_close_date_default_tz(self, tz_bot, super_group_id): assert new_message.poll.id == message.poll.id assert new_message.poll.is_closed + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_send_poll_explanation_entities(self, bot, chat_id): + test_string = 'Italic Bold Code' + entities = [ + MessageEntity(MessageEntity.ITALIC, 0, 6), + MessageEntity(MessageEntity.ITALIC, 7, 4), + MessageEntity(MessageEntity.ITALIC, 12, 4), + ] + message = bot.send_poll( + chat_id, + 'question', + options=['a', 'b'], + correct_option_id=0, + type=Poll.QUIZ, + explanation=test_string, + explanation_entities=entities, + ) + + assert message.poll.explanation == test_string + assert message.poll.explanation_entities == entities + @flaky(3, 1) @pytest.mark.timeout(10) @pytest.mark.parametrize('default_bot', [{'parse_mode': 'Markdown'}], indirect=True) @@ -843,6 +865,25 @@ def test_edit_message_text(self, bot, message): assert message.text == 'new_text' + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_edit_message_text_entities(self, bot, message): + test_string = 'Italic Bold Code' + entities = [ + MessageEntity(MessageEntity.ITALIC, 0, 6), + MessageEntity(MessageEntity.ITALIC, 7, 4), + MessageEntity(MessageEntity.ITALIC, 12, 4), + ] + message = bot.edit_message_text( + text=test_string, + chat_id=message.chat_id, + message_id=message.message_id, + entities=entities, + ) + + assert message.text == test_string + assert message.entities == entities + @flaky(3, 1) @pytest.mark.timeout(10) @pytest.mark.parametrize('default_bot', [{'parse_mode': 'Markdown'}], indirect=True) @@ -900,6 +941,25 @@ def test_edit_message_caption(self, bot, media_message): assert message.caption == 'new_caption' + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_edit_message_caption_entities(self, bot, media_message): + test_string = 'Italic Bold Code' + entities = [ + MessageEntity(MessageEntity.ITALIC, 0, 6), + MessageEntity(MessageEntity.ITALIC, 7, 4), + MessageEntity(MessageEntity.ITALIC, 12, 4), + ] + message = bot.edit_message_caption( + caption=test_string, + chat_id=media_message.chat_id, + message_id=media_message.message_id, + caption_entities=entities, + ) + + assert message.caption == test_string + assert message.caption_entities == entities + # edit_message_media is tested in test_inputmedia @flaky(3, 1) @@ -1466,6 +1526,19 @@ def request_wrapper(*args, **kwargs): with pytest.raises(OkException): bot.send_photo(chat_id, open('tests/data/telegram.jpg', 'rb')) + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_send_message_entities(self, bot, chat_id): + test_string = 'Italic Bold Code' + entities = [ + MessageEntity(MessageEntity.ITALIC, 0, 6), + MessageEntity(MessageEntity.ITALIC, 7, 4), + MessageEntity(MessageEntity.ITALIC, 12, 4), + ] + message = bot.send_message(chat_id=chat_id, text=test_string, entities=entities) + assert message.text == test_string + assert message.entities == entities + @flaky(3, 1) @pytest.mark.timeout(10) @pytest.mark.parametrize('default_bot', [{'parse_mode': 'Markdown'}], indirect=True) diff --git a/tests/test_document.py b/tests/test_document.py index aa4c25c0466..434cf268920 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -21,7 +21,7 @@ import pytest from flaky import flaky -from telegram import Document, PhotoSize, TelegramError, Voice +from telegram import Document, PhotoSize, TelegramError, Voice, MessageEntity from telegram.error import BadRequest from telegram.utils.helpers import escape_markdown @@ -150,6 +150,22 @@ def make_assertion(url, data, **kwargs): assert message + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_send_document_caption_entities(self, bot, chat_id, document): + test_string = 'Italic Bold Code' + entities = [ + MessageEntity(MessageEntity.ITALIC, 0, 6), + MessageEntity(MessageEntity.ITALIC, 7, 4), + MessageEntity(MessageEntity.ITALIC, 12, 4), + ] + message = bot.send_document( + chat_id, document, caption=test_string, caption_entities=entities + ) + + assert message.caption == test_string + assert message.caption_entities == entities + @flaky(3, 1) @pytest.mark.timeout(10) @pytest.mark.parametrize('default_bot', [{'parse_mode': 'Markdown'}], indirect=True) diff --git a/tests/test_inlinequeryresultaudio.py b/tests/test_inlinequeryresultaudio.py index a560f51b56f..cf76cb9755a 100644 --- a/tests/test_inlinequeryresultaudio.py +++ b/tests/test_inlinequeryresultaudio.py @@ -25,6 +25,7 @@ InlineQueryResultAudio, InputTextMessageContent, InlineQueryResultVoice, + MessageEntity, ) @@ -38,6 +39,7 @@ def inline_query_result_audio(): audio_duration=TestInlineQueryResultAudio.audio_duration, caption=TestInlineQueryResultAudio.caption, parse_mode=TestInlineQueryResultAudio.parse_mode, + caption_entities=TestInlineQueryResultAudio.caption_entities, input_message_content=TestInlineQueryResultAudio.input_message_content, reply_markup=TestInlineQueryResultAudio.reply_markup, ) @@ -52,6 +54,7 @@ class TestInlineQueryResultAudio: audio_duration = 'audio_duration' caption = 'caption' parse_mode = 'Markdown' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) @@ -64,6 +67,7 @@ def test_expected_values(self, inline_query_result_audio): assert inline_query_result_audio.audio_duration == self.audio_duration assert inline_query_result_audio.caption == self.caption assert inline_query_result_audio.parse_mode == self.parse_mode + assert inline_query_result_audio.caption_entities == self.caption_entities assert ( inline_query_result_audio.input_message_content.to_dict() == self.input_message_content.to_dict() @@ -85,6 +89,9 @@ def test_to_dict(self, inline_query_result_audio): ) assert inline_query_result_audio_dict['caption'] == inline_query_result_audio.caption assert inline_query_result_audio_dict['parse_mode'] == inline_query_result_audio.parse_mode + assert inline_query_result_audio_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_audio.caption_entities + ] assert ( inline_query_result_audio_dict['input_message_content'] == inline_query_result_audio.input_message_content.to_dict() diff --git a/tests/test_inlinequeryresultcachedaudio.py b/tests/test_inlinequeryresultcachedaudio.py index b98834e3f85..216adff185e 100644 --- a/tests/test_inlinequeryresultcachedaudio.py +++ b/tests/test_inlinequeryresultcachedaudio.py @@ -25,6 +25,7 @@ InlineKeyboardMarkup, InlineKeyboardButton, InlineQueryResultCachedVoice, + MessageEntity, ) @@ -35,6 +36,7 @@ def inline_query_result_cached_audio(): TestInlineQueryResultCachedAudio.audio_file_id, caption=TestInlineQueryResultCachedAudio.caption, parse_mode=TestInlineQueryResultCachedAudio.parse_mode, + caption_entities=TestInlineQueryResultCachedAudio.caption_entities, input_message_content=TestInlineQueryResultCachedAudio.input_message_content, reply_markup=TestInlineQueryResultCachedAudio.reply_markup, ) @@ -46,6 +48,7 @@ class TestInlineQueryResultCachedAudio: audio_file_id = 'audio file id' caption = 'caption' parse_mode = 'HTML' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) @@ -55,6 +58,7 @@ def test_expected_values(self, inline_query_result_cached_audio): assert inline_query_result_cached_audio.audio_file_id == self.audio_file_id assert inline_query_result_cached_audio.caption == self.caption assert inline_query_result_cached_audio.parse_mode == self.parse_mode + assert inline_query_result_cached_audio.caption_entities == self.caption_entities assert ( inline_query_result_cached_audio.input_message_content.to_dict() == self.input_message_content.to_dict() @@ -83,6 +87,9 @@ def test_to_dict(self, inline_query_result_cached_audio): inline_query_result_cached_audio_dict['parse_mode'] == inline_query_result_cached_audio.parse_mode ) + assert inline_query_result_cached_audio_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_cached_audio.caption_entities + ] assert ( inline_query_result_cached_audio_dict['input_message_content'] == inline_query_result_cached_audio.input_message_content.to_dict() diff --git a/tests/test_inlinequeryresultcacheddocument.py b/tests/test_inlinequeryresultcacheddocument.py index 611532bcbb6..11503c6b0bb 100644 --- a/tests/test_inlinequeryresultcacheddocument.py +++ b/tests/test_inlinequeryresultcacheddocument.py @@ -25,6 +25,7 @@ InlineKeyboardMarkup, InputTextMessageContent, InlineQueryResultCachedVoice, + MessageEntity, ) @@ -36,6 +37,7 @@ def inline_query_result_cached_document(): TestInlineQueryResultCachedDocument.document_file_id, caption=TestInlineQueryResultCachedDocument.caption, parse_mode=TestInlineQueryResultCachedDocument.parse_mode, + caption_entities=TestInlineQueryResultCachedDocument.caption_entities, description=TestInlineQueryResultCachedDocument.description, input_message_content=TestInlineQueryResultCachedDocument.input_message_content, reply_markup=TestInlineQueryResultCachedDocument.reply_markup, @@ -49,6 +51,7 @@ class TestInlineQueryResultCachedDocument: title = 'title' caption = 'caption' parse_mode = 'Markdown' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] description = 'description' input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) @@ -60,6 +63,7 @@ def test_expected_values(self, inline_query_result_cached_document): assert inline_query_result_cached_document.title == self.title assert inline_query_result_cached_document.caption == self.caption assert inline_query_result_cached_document.parse_mode == self.parse_mode + assert inline_query_result_cached_document.caption_entities == self.caption_entities assert inline_query_result_cached_document.description == self.description assert ( inline_query_result_cached_document.input_message_content.to_dict() @@ -98,6 +102,9 @@ def test_to_dict(self, inline_query_result_cached_document): inline_query_result_cached_document_dict['parse_mode'] == inline_query_result_cached_document.parse_mode ) + assert inline_query_result_cached_document_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_cached_document.caption_entities + ] assert ( inline_query_result_cached_document_dict['description'] == inline_query_result_cached_document.description diff --git a/tests/test_inlinequeryresultcachedgif.py b/tests/test_inlinequeryresultcachedgif.py index 89c2433ca2b..e76a820b7fa 100644 --- a/tests/test_inlinequeryresultcachedgif.py +++ b/tests/test_inlinequeryresultcachedgif.py @@ -25,6 +25,7 @@ InlineQueryResultCachedVoice, InlineKeyboardMarkup, InlineQueryResultCachedGif, + MessageEntity, ) @@ -36,6 +37,7 @@ def inline_query_result_cached_gif(): title=TestInlineQueryResultCachedGif.title, caption=TestInlineQueryResultCachedGif.caption, parse_mode=TestInlineQueryResultCachedGif.parse_mode, + caption_entities=TestInlineQueryResultCachedGif.caption_entities, input_message_content=TestInlineQueryResultCachedGif.input_message_content, reply_markup=TestInlineQueryResultCachedGif.reply_markup, ) @@ -48,6 +50,7 @@ class TestInlineQueryResultCachedGif: title = 'title' caption = 'caption' parse_mode = 'HTML' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) @@ -58,6 +61,7 @@ def test_expected_values(self, inline_query_result_cached_gif): assert inline_query_result_cached_gif.title == self.title assert inline_query_result_cached_gif.caption == self.caption assert inline_query_result_cached_gif.parse_mode == self.parse_mode + assert inline_query_result_cached_gif.caption_entities == self.caption_entities assert ( inline_query_result_cached_gif.input_message_content.to_dict() == self.input_message_content.to_dict() @@ -83,6 +87,9 @@ def test_to_dict(self, inline_query_result_cached_gif): inline_query_result_cached_gif_dict['parse_mode'] == inline_query_result_cached_gif.parse_mode ) + assert inline_query_result_cached_gif_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_cached_gif.caption_entities + ] assert ( inline_query_result_cached_gif_dict['input_message_content'] == inline_query_result_cached_gif.input_message_content.to_dict() diff --git a/tests/test_inlinequeryresultcachedmpeg4gif.py b/tests/test_inlinequeryresultcachedmpeg4gif.py index eb12918adf4..6c24f5406d0 100644 --- a/tests/test_inlinequeryresultcachedmpeg4gif.py +++ b/tests/test_inlinequeryresultcachedmpeg4gif.py @@ -25,6 +25,7 @@ InputTextMessageContent, InlineKeyboardMarkup, InlineQueryResultCachedVoice, + MessageEntity, ) @@ -36,6 +37,7 @@ def inline_query_result_cached_mpeg4_gif(): title=TestInlineQueryResultCachedMpeg4Gif.title, caption=TestInlineQueryResultCachedMpeg4Gif.caption, parse_mode=TestInlineQueryResultCachedMpeg4Gif.parse_mode, + caption_entities=TestInlineQueryResultCachedMpeg4Gif.caption_entities, input_message_content=TestInlineQueryResultCachedMpeg4Gif.input_message_content, reply_markup=TestInlineQueryResultCachedMpeg4Gif.reply_markup, ) @@ -48,6 +50,7 @@ class TestInlineQueryResultCachedMpeg4Gif: title = 'title' caption = 'caption' parse_mode = 'Markdown' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) @@ -58,6 +61,7 @@ def test_expected_values(self, inline_query_result_cached_mpeg4_gif): assert inline_query_result_cached_mpeg4_gif.title == self.title assert inline_query_result_cached_mpeg4_gif.caption == self.caption assert inline_query_result_cached_mpeg4_gif.parse_mode == self.parse_mode + assert inline_query_result_cached_mpeg4_gif.caption_entities == self.caption_entities assert ( inline_query_result_cached_mpeg4_gif.input_message_content.to_dict() == self.input_message_content.to_dict() @@ -95,6 +99,9 @@ def test_to_dict(self, inline_query_result_cached_mpeg4_gif): inline_query_result_cached_mpeg4_gif_dict['parse_mode'] == inline_query_result_cached_mpeg4_gif.parse_mode ) + assert inline_query_result_cached_mpeg4_gif_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_cached_mpeg4_gif.caption_entities + ] assert ( inline_query_result_cached_mpeg4_gif_dict['input_message_content'] == inline_query_result_cached_mpeg4_gif.input_message_content.to_dict() diff --git a/tests/test_inlinequeryresultcachedphoto.py b/tests/test_inlinequeryresultcachedphoto.py index 5898e81a10f..b652ad71df6 100644 --- a/tests/test_inlinequeryresultcachedphoto.py +++ b/tests/test_inlinequeryresultcachedphoto.py @@ -25,6 +25,7 @@ InlineKeyboardButton, InlineQueryResultCachedVoice, InlineKeyboardMarkup, + MessageEntity, ) @@ -37,6 +38,7 @@ def inline_query_result_cached_photo(): description=TestInlineQueryResultCachedPhoto.description, caption=TestInlineQueryResultCachedPhoto.caption, parse_mode=TestInlineQueryResultCachedPhoto.parse_mode, + caption_entities=TestInlineQueryResultCachedPhoto.caption_entities, input_message_content=TestInlineQueryResultCachedPhoto.input_message_content, reply_markup=TestInlineQueryResultCachedPhoto.reply_markup, ) @@ -50,6 +52,7 @@ class TestInlineQueryResultCachedPhoto: description = 'description' caption = 'caption' parse_mode = 'HTML' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) @@ -61,6 +64,7 @@ def test_expected_values(self, inline_query_result_cached_photo): assert inline_query_result_cached_photo.description == self.description assert inline_query_result_cached_photo.caption == self.caption assert inline_query_result_cached_photo.parse_mode == self.parse_mode + assert inline_query_result_cached_photo.caption_entities == self.caption_entities assert ( inline_query_result_cached_photo.input_message_content.to_dict() == self.input_message_content.to_dict() @@ -97,6 +101,9 @@ def test_to_dict(self, inline_query_result_cached_photo): inline_query_result_cached_photo_dict['parse_mode'] == inline_query_result_cached_photo.parse_mode ) + assert inline_query_result_cached_photo_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_cached_photo.caption_entities + ] assert ( inline_query_result_cached_photo_dict['input_message_content'] == inline_query_result_cached_photo.input_message_content.to_dict() diff --git a/tests/test_inlinequeryresultcachedvideo.py b/tests/test_inlinequeryresultcachedvideo.py index 26ee771c729..bf2cb0d0fbc 100644 --- a/tests/test_inlinequeryresultcachedvideo.py +++ b/tests/test_inlinequeryresultcachedvideo.py @@ -25,6 +25,7 @@ InputTextMessageContent, InlineQueryResultCachedVideo, InlineQueryResultCachedVoice, + MessageEntity, ) @@ -36,6 +37,7 @@ def inline_query_result_cached_video(): TestInlineQueryResultCachedVideo.title, caption=TestInlineQueryResultCachedVideo.caption, parse_mode=TestInlineQueryResultCachedVideo.parse_mode, + caption_entities=TestInlineQueryResultCachedVideo.caption_entities, description=TestInlineQueryResultCachedVideo.description, input_message_content=TestInlineQueryResultCachedVideo.input_message_content, reply_markup=TestInlineQueryResultCachedVideo.reply_markup, @@ -49,6 +51,7 @@ class TestInlineQueryResultCachedVideo: title = 'title' caption = 'caption' parse_mode = 'Markdown' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] description = 'description' input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) @@ -61,6 +64,7 @@ def test_expected_values(self, inline_query_result_cached_video): assert inline_query_result_cached_video.description == self.description assert inline_query_result_cached_video.caption == self.caption assert inline_query_result_cached_video.parse_mode == self.parse_mode + assert inline_query_result_cached_video.caption_entities == self.caption_entities assert ( inline_query_result_cached_video.input_message_content.to_dict() == self.input_message_content.to_dict() @@ -97,6 +101,9 @@ def test_to_dict(self, inline_query_result_cached_video): inline_query_result_cached_video_dict['parse_mode'] == inline_query_result_cached_video.parse_mode ) + assert inline_query_result_cached_video_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_cached_video.caption_entities + ] assert ( inline_query_result_cached_video_dict['input_message_content'] == inline_query_result_cached_video.input_message_content.to_dict() diff --git a/tests/test_inlinequeryresultcachedvoice.py b/tests/test_inlinequeryresultcachedvoice.py index ebeec0982e9..a3b0d7c5374 100644 --- a/tests/test_inlinequeryresultcachedvoice.py +++ b/tests/test_inlinequeryresultcachedvoice.py @@ -25,6 +25,7 @@ InlineKeyboardMarkup, InlineQueryResultCachedAudio, InputTextMessageContent, + MessageEntity, ) @@ -36,6 +37,7 @@ def inline_query_result_cached_voice(): TestInlineQueryResultCachedVoice.title, caption=TestInlineQueryResultCachedVoice.caption, parse_mode=TestInlineQueryResultCachedVoice.parse_mode, + caption_entities=TestInlineQueryResultCachedVoice.caption_entities, input_message_content=TestInlineQueryResultCachedVoice.input_message_content, reply_markup=TestInlineQueryResultCachedVoice.reply_markup, ) @@ -48,6 +50,7 @@ class TestInlineQueryResultCachedVoice: title = 'title' caption = 'caption' parse_mode = 'HTML' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) @@ -58,6 +61,7 @@ def test_expected_values(self, inline_query_result_cached_voice): assert inline_query_result_cached_voice.title == self.title assert inline_query_result_cached_voice.caption == self.caption assert inline_query_result_cached_voice.parse_mode == self.parse_mode + assert inline_query_result_cached_voice.caption_entities == self.caption_entities assert ( inline_query_result_cached_voice.input_message_content.to_dict() == self.input_message_content.to_dict() @@ -90,6 +94,9 @@ def test_to_dict(self, inline_query_result_cached_voice): inline_query_result_cached_voice_dict['parse_mode'] == inline_query_result_cached_voice.parse_mode ) + assert inline_query_result_cached_voice_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_cached_voice.caption_entities + ] assert ( inline_query_result_cached_voice_dict['input_message_content'] == inline_query_result_cached_voice.input_message_content.to_dict() diff --git a/tests/test_inlinequeryresultdocument.py b/tests/test_inlinequeryresultdocument.py index cec8b1cbab9..896d448de3c 100644 --- a/tests/test_inlinequeryresultdocument.py +++ b/tests/test_inlinequeryresultdocument.py @@ -25,6 +25,7 @@ InlineQueryResultDocument, InlineKeyboardMarkup, InlineQueryResultVoice, + MessageEntity, ) @@ -37,6 +38,7 @@ def inline_query_result_document(): TestInlineQueryResultDocument.mime_type, caption=TestInlineQueryResultDocument.caption, parse_mode=TestInlineQueryResultDocument.parse_mode, + caption_entities=TestInlineQueryResultDocument.caption_entities, description=TestInlineQueryResultDocument.description, thumb_url=TestInlineQueryResultDocument.thumb_url, thumb_width=TestInlineQueryResultDocument.thumb_width, @@ -53,6 +55,7 @@ class TestInlineQueryResultDocument: title = 'title' caption = 'caption' parse_mode = 'Markdown' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] mime_type = 'mime type' description = 'description' thumb_url = 'thumb url' @@ -68,6 +71,7 @@ def test_expected_values(self, inline_query_result_document): assert inline_query_result_document.title == self.title assert inline_query_result_document.caption == self.caption assert inline_query_result_document.parse_mode == self.parse_mode + assert inline_query_result_document.caption_entities == self.caption_entities assert inline_query_result_document.mime_type == self.mime_type assert inline_query_result_document.description == self.description assert inline_query_result_document.thumb_url == self.thumb_url @@ -95,6 +99,9 @@ def test_to_dict(self, inline_query_result_document): inline_query_result_document_dict['parse_mode'] == inline_query_result_document.parse_mode ) + assert inline_query_result_document_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_document.caption_entities + ] assert ( inline_query_result_document_dict['mime_type'] == inline_query_result_document.mime_type diff --git a/tests/test_inlinequeryresultgif.py b/tests/test_inlinequeryresultgif.py index 309d6efabda..2bb33a288f7 100644 --- a/tests/test_inlinequeryresultgif.py +++ b/tests/test_inlinequeryresultgif.py @@ -25,6 +25,7 @@ InlineQueryResultGif, InlineQueryResultVoice, InlineKeyboardMarkup, + MessageEntity, ) @@ -40,6 +41,7 @@ def inline_query_result_gif(): title=TestInlineQueryResultGif.title, caption=TestInlineQueryResultGif.caption, parse_mode=TestInlineQueryResultGif.parse_mode, + caption_entities=TestInlineQueryResultGif.caption_entities, input_message_content=TestInlineQueryResultGif.input_message_content, reply_markup=TestInlineQueryResultGif.reply_markup, thumb_mime_type=TestInlineQueryResultGif.thumb_mime_type, @@ -58,6 +60,7 @@ class TestInlineQueryResultGif: title = 'title' caption = 'caption' parse_mode = 'HTML' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) @@ -73,6 +76,7 @@ def test_expected_values(self, inline_query_result_gif): assert inline_query_result_gif.title == self.title assert inline_query_result_gif.caption == self.caption assert inline_query_result_gif.parse_mode == self.parse_mode + assert inline_query_result_gif.caption_entities == self.caption_entities assert ( inline_query_result_gif.input_message_content.to_dict() == self.input_message_content.to_dict() @@ -97,6 +101,9 @@ def test_to_dict(self, inline_query_result_gif): assert inline_query_result_gif_dict['title'] == inline_query_result_gif.title assert inline_query_result_gif_dict['caption'] == inline_query_result_gif.caption assert inline_query_result_gif_dict['parse_mode'] == inline_query_result_gif.parse_mode + assert inline_query_result_gif_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_gif.caption_entities + ] assert ( inline_query_result_gif_dict['input_message_content'] == inline_query_result_gif.input_message_content.to_dict() diff --git a/tests/test_inlinequeryresultmpeg4gif.py b/tests/test_inlinequeryresultmpeg4gif.py index 6312732eb35..531e756261a 100644 --- a/tests/test_inlinequeryresultmpeg4gif.py +++ b/tests/test_inlinequeryresultmpeg4gif.py @@ -25,6 +25,7 @@ InlineQueryResultVoice, InlineKeyboardMarkup, InputTextMessageContent, + MessageEntity, ) @@ -40,6 +41,7 @@ def inline_query_result_mpeg4_gif(): title=TestInlineQueryResultMpeg4Gif.title, caption=TestInlineQueryResultMpeg4Gif.caption, parse_mode=TestInlineQueryResultMpeg4Gif.parse_mode, + caption_entities=TestInlineQueryResultMpeg4Gif.caption_entities, input_message_content=TestInlineQueryResultMpeg4Gif.input_message_content, reply_markup=TestInlineQueryResultMpeg4Gif.reply_markup, thumb_mime_type=TestInlineQueryResultMpeg4Gif.thumb_mime_type, @@ -58,6 +60,7 @@ class TestInlineQueryResultMpeg4Gif: title = 'title' caption = 'caption' parse_mode = 'Markdown' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) @@ -73,6 +76,7 @@ def test_expected_values(self, inline_query_result_mpeg4_gif): assert inline_query_result_mpeg4_gif.title == self.title assert inline_query_result_mpeg4_gif.caption == self.caption assert inline_query_result_mpeg4_gif.parse_mode == self.parse_mode + assert inline_query_result_mpeg4_gif.caption_entities == self.caption_entities assert ( inline_query_result_mpeg4_gif.input_message_content.to_dict() == self.input_message_content.to_dict() @@ -117,6 +121,9 @@ def test_to_dict(self, inline_query_result_mpeg4_gif): inline_query_result_mpeg4_gif_dict['parse_mode'] == inline_query_result_mpeg4_gif.parse_mode ) + assert inline_query_result_mpeg4_gif_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_mpeg4_gif.caption_entities + ] assert ( inline_query_result_mpeg4_gif_dict['input_message_content'] == inline_query_result_mpeg4_gif.input_message_content.to_dict() diff --git a/tests/test_inlinequeryresultphoto.py b/tests/test_inlinequeryresultphoto.py index 40b0ecd3d1b..563bdaca159 100644 --- a/tests/test_inlinequeryresultphoto.py +++ b/tests/test_inlinequeryresultphoto.py @@ -25,6 +25,7 @@ InlineKeyboardMarkup, InlineQueryResultPhoto, InlineQueryResultVoice, + MessageEntity, ) @@ -40,6 +41,7 @@ def inline_query_result_photo(): description=TestInlineQueryResultPhoto.description, caption=TestInlineQueryResultPhoto.caption, parse_mode=TestInlineQueryResultPhoto.parse_mode, + caption_entities=TestInlineQueryResultPhoto.caption_entities, input_message_content=TestInlineQueryResultPhoto.input_message_content, reply_markup=TestInlineQueryResultPhoto.reply_markup, ) @@ -56,6 +58,8 @@ class TestInlineQueryResultPhoto: description = 'description' caption = 'caption' parse_mode = 'HTML' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] + input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) @@ -70,6 +74,7 @@ def test_expected_values(self, inline_query_result_photo): assert inline_query_result_photo.description == self.description assert inline_query_result_photo.caption == self.caption assert inline_query_result_photo.parse_mode == self.parse_mode + assert inline_query_result_photo.caption_entities == self.caption_entities assert ( inline_query_result_photo.input_message_content.to_dict() == self.input_message_content.to_dict() @@ -97,6 +102,9 @@ def test_to_dict(self, inline_query_result_photo): ) assert inline_query_result_photo_dict['caption'] == inline_query_result_photo.caption assert inline_query_result_photo_dict['parse_mode'] == inline_query_result_photo.parse_mode + assert inline_query_result_photo_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_photo.caption_entities + ] assert ( inline_query_result_photo_dict['input_message_content'] == inline_query_result_photo.input_message_content.to_dict() diff --git a/tests/test_inlinequeryresultvideo.py b/tests/test_inlinequeryresultvideo.py index 6f2971d44d8..76eee5a1117 100644 --- a/tests/test_inlinequeryresultvideo.py +++ b/tests/test_inlinequeryresultvideo.py @@ -25,6 +25,7 @@ InlineQueryResultVideo, InlineKeyboardMarkup, InlineQueryResultVoice, + MessageEntity, ) @@ -41,6 +42,7 @@ def inline_query_result_video(): video_duration=TestInlineQueryResultVideo.video_duration, caption=TestInlineQueryResultVideo.caption, parse_mode=TestInlineQueryResultVideo.parse_mode, + caption_entities=TestInlineQueryResultVideo.caption_entities, description=TestInlineQueryResultVideo.description, input_message_content=TestInlineQueryResultVideo.input_message_content, reply_markup=TestInlineQueryResultVideo.reply_markup, @@ -59,6 +61,7 @@ class TestInlineQueryResultVideo: title = 'title' caption = 'caption' parse_mode = 'Markdown' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] description = 'description' input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) @@ -76,6 +79,7 @@ def test_expected_values(self, inline_query_result_video): assert inline_query_result_video.description == self.description assert inline_query_result_video.caption == self.caption assert inline_query_result_video.parse_mode == self.parse_mode + assert inline_query_result_video.caption_entities == self.caption_entities assert ( inline_query_result_video.input_message_content.to_dict() == self.input_message_content.to_dict() @@ -108,6 +112,9 @@ def test_to_dict(self, inline_query_result_video): ) assert inline_query_result_video_dict['caption'] == inline_query_result_video.caption assert inline_query_result_video_dict['parse_mode'] == inline_query_result_video.parse_mode + assert inline_query_result_video_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_video.caption_entities + ] assert ( inline_query_result_video_dict['input_message_content'] == inline_query_result_video.input_message_content.to_dict() diff --git a/tests/test_inlinequeryresultvoice.py b/tests/test_inlinequeryresultvoice.py index eece3590e17..3119874b7e1 100644 --- a/tests/test_inlinequeryresultvoice.py +++ b/tests/test_inlinequeryresultvoice.py @@ -25,6 +25,7 @@ InlineQueryResultAudio, InlineQueryResultVoice, InlineKeyboardMarkup, + MessageEntity, ) @@ -38,6 +39,7 @@ def inline_query_result_voice(): voice_duration=TestInlineQueryResultVoice.voice_duration, caption=TestInlineQueryResultVoice.caption, parse_mode=TestInlineQueryResultVoice.parse_mode, + caption_entities=TestInlineQueryResultVoice.caption_entities, input_message_content=TestInlineQueryResultVoice.input_message_content, reply_markup=TestInlineQueryResultVoice.reply_markup, ) @@ -51,6 +53,7 @@ class TestInlineQueryResultVoice: voice_duration = 'voice_duration' caption = 'caption' parse_mode = 'HTML' + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) @@ -62,6 +65,7 @@ def test_expected_values(self, inline_query_result_voice): assert inline_query_result_voice.voice_duration == self.voice_duration assert inline_query_result_voice.caption == self.caption assert inline_query_result_voice.parse_mode == self.parse_mode + assert inline_query_result_voice.caption_entities == self.caption_entities assert ( inline_query_result_voice.input_message_content.to_dict() == self.input_message_content.to_dict() @@ -82,6 +86,9 @@ def test_to_dict(self, inline_query_result_voice): ) assert inline_query_result_voice_dict['caption'] == inline_query_result_voice.caption assert inline_query_result_voice_dict['parse_mode'] == inline_query_result_voice.parse_mode + assert inline_query_result_voice_dict['caption_entities'] == [ + ce.to_dict() for ce in inline_query_result_voice.caption_entities + ] assert ( inline_query_result_voice_dict['input_message_content'] == inline_query_result_voice.input_message_content.to_dict() diff --git a/tests/test_inputmedia.py b/tests/test_inputmedia.py index b4a040de803..b13025b65cd 100644 --- a/tests/test_inputmedia.py +++ b/tests/test_inputmedia.py @@ -27,6 +27,7 @@ InputFile, InputMediaAudio, InputMediaDocument, + MessageEntity, ) # noinspection PyUnresolvedReferences @@ -56,6 +57,7 @@ def input_media_video(class_thumb_file): height=TestInputMediaVideo.height, duration=TestInputMediaVideo.duration, parse_mode=TestInputMediaVideo.parse_mode, + caption_entities=TestInputMediaVideo.caption_entities, thumb=class_thumb_file, supports_streaming=TestInputMediaVideo.supports_streaming, ) @@ -67,6 +69,7 @@ def input_media_photo(class_thumb_file): media=TestInputMediaPhoto.media, caption=TestInputMediaPhoto.caption, parse_mode=TestInputMediaPhoto.parse_mode, + caption_entities=TestInputMediaPhoto.caption_entities, ) @@ -76,6 +79,7 @@ def input_media_animation(class_thumb_file): media=TestInputMediaAnimation.media, caption=TestInputMediaAnimation.caption, parse_mode=TestInputMediaAnimation.parse_mode, + caption_entities=TestInputMediaAnimation.caption_entities, width=TestInputMediaAnimation.width, height=TestInputMediaAnimation.height, thumb=class_thumb_file, @@ -93,6 +97,7 @@ def input_media_audio(class_thumb_file): title=TestInputMediaAudio.title, thumb=class_thumb_file, parse_mode=TestInputMediaAudio.parse_mode, + caption_entities=TestInputMediaAudio.caption_entities, ) @@ -103,6 +108,7 @@ def input_media_document(class_thumb_file): caption=TestInputMediaDocument.caption, thumb=class_thumb_file, parse_mode=TestInputMediaDocument.parse_mode, + caption_entities=TestInputMediaDocument.caption_entities, disable_content_type_detection=TestInputMediaDocument.disable_content_type_detection, ) @@ -116,6 +122,7 @@ class TestInputMediaVideo: duration = 5 parse_mode = 'HTML' supports_streaming = True + caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] def test_expected_values(self, input_media_video): assert input_media_video.type == self.type_ @@ -125,6 +132,7 @@ def test_expected_values(self, input_media_video): assert input_media_video.height == self.height assert input_media_video.duration == self.duration assert input_media_video.parse_mode == self.parse_mode + assert input_media_video.caption_entities == self.caption_entities assert input_media_video.supports_streaming == self.supports_streaming assert isinstance(input_media_video.thumb, InputFile) @@ -137,6 +145,9 @@ def test_to_dict(self, input_media_video): assert input_media_video_dict['height'] == input_media_video.height assert input_media_video_dict['duration'] == input_media_video.duration assert input_media_video_dict['parse_mode'] == input_media_video.parse_mode + assert input_media_video_dict['caption_entities'] == [ + ce.to_dict() for ce in input_media_video.caption_entities + ] assert input_media_video_dict['supports_streaming'] == input_media_video.supports_streaming def test_with_video(self, video): # noqa: F811 @@ -162,12 +173,14 @@ class TestInputMediaPhoto: media = "NOTAREALFILEID" caption = "My Caption" parse_mode = 'Markdown' + caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] def test_expected_values(self, input_media_photo): assert input_media_photo.type == self.type_ assert input_media_photo.media == self.media assert input_media_photo.caption == self.caption assert input_media_photo.parse_mode == self.parse_mode + assert input_media_photo.caption_entities == self.caption_entities def test_to_dict(self, input_media_photo): input_media_photo_dict = input_media_photo.to_dict() @@ -175,6 +188,9 @@ def test_to_dict(self, input_media_photo): assert input_media_photo_dict['media'] == input_media_photo.media assert input_media_photo_dict['caption'] == input_media_photo.caption assert input_media_photo_dict['parse_mode'] == input_media_photo.parse_mode + assert input_media_photo_dict['caption_entities'] == [ + ce.to_dict() for ce in input_media_photo.caption_entities + ] def test_with_photo(self, photo): # noqa: F811 # fixture found in test_photo @@ -196,6 +212,7 @@ class TestInputMediaAnimation: media = "NOTAREALFILEID" caption = "My Caption" parse_mode = 'Markdown' + caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] width = 30 height = 30 duration = 1 @@ -205,6 +222,7 @@ def test_expected_values(self, input_media_animation): assert input_media_animation.media == self.media assert input_media_animation.caption == self.caption assert input_media_animation.parse_mode == self.parse_mode + assert input_media_animation.caption_entities == self.caption_entities assert isinstance(input_media_animation.thumb, InputFile) def test_to_dict(self, input_media_animation): @@ -213,6 +231,9 @@ def test_to_dict(self, input_media_animation): assert input_media_animation_dict['media'] == input_media_animation.media assert input_media_animation_dict['caption'] == input_media_animation.caption assert input_media_animation_dict['parse_mode'] == input_media_animation.parse_mode + assert input_media_animation_dict['caption_entities'] == [ + ce.to_dict() for ce in input_media_animation.caption_entities + ] assert input_media_animation_dict['width'] == input_media_animation.width assert input_media_animation_dict['height'] == input_media_animation.height assert input_media_animation_dict['duration'] == input_media_animation.duration @@ -240,6 +261,7 @@ class TestInputMediaAudio: performer = 'performer' title = 'title' parse_mode = 'HTML' + caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] def test_expected_values(self, input_media_audio): assert input_media_audio.type == self.type_ @@ -249,6 +271,7 @@ def test_expected_values(self, input_media_audio): assert input_media_audio.performer == self.performer assert input_media_audio.title == self.title assert input_media_audio.parse_mode == self.parse_mode + assert input_media_audio.caption_entities == self.caption_entities assert isinstance(input_media_audio.thumb, InputFile) def test_to_dict(self, input_media_audio): @@ -260,6 +283,9 @@ def test_to_dict(self, input_media_audio): assert input_media_audio_dict['performer'] == input_media_audio.performer assert input_media_audio_dict['title'] == input_media_audio.title assert input_media_audio_dict['parse_mode'] == input_media_audio.parse_mode + assert input_media_audio_dict['caption_entities'] == [ + ce.to_dict() for ce in input_media_audio.caption_entities + ] def test_with_audio(self, audio): # noqa: F811 # fixture found in test_audio @@ -284,6 +310,7 @@ class TestInputMediaDocument: media = "NOTAREALFILEID" caption = "My Caption" parse_mode = 'HTML' + caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] disable_content_type_detection = True def test_expected_values(self, input_media_document): @@ -291,6 +318,7 @@ def test_expected_values(self, input_media_document): assert input_media_document.media == self.media assert input_media_document.caption == self.caption assert input_media_document.parse_mode == self.parse_mode + assert input_media_document.caption_entities == self.caption_entities assert ( input_media_document.disable_content_type_detection == self.disable_content_type_detection @@ -303,6 +331,9 @@ def test_to_dict(self, input_media_document): assert input_media_document_dict['media'] == input_media_document.media assert input_media_document_dict['caption'] == input_media_document.caption assert input_media_document_dict['parse_mode'] == input_media_document.parse_mode + assert input_media_document_dict['caption_entities'] == [ + ce.to_dict() for ce in input_media_document.caption_entities + ] assert ( input_media_document['disable_content_type_detection'] == input_media_document.disable_content_type_detection @@ -326,8 +357,11 @@ def test_with_document_file(self, document_file): # noqa: F811 @pytest.fixture(scope='function') # noqa: F811 def media_group(photo, thumb): # noqa: F811 return [ - InputMediaPhoto(photo, caption='photo `1`', parse_mode='Markdown'), + InputMediaPhoto(photo, caption='*photo* 1', parse_mode='Markdown'), InputMediaPhoto(thumb, caption='photo 2', parse_mode='HTML'), + InputMediaPhoto( + photo, caption='photo 3', caption_entities=[MessageEntity(MessageEntity.BOLD, 0, 5)] + ), ] @@ -337,9 +371,13 @@ class TestSendMediaGroup: def test_send_media_group_photo(self, bot, chat_id, media_group): messages = bot.send_media_group(chat_id, media_group) assert isinstance(messages, list) - assert len(messages) == 2 + assert len(messages) == 3 assert all([isinstance(mes, Message) for mes in messages]) assert all([mes.media_group_id == messages[0].media_group_id for mes in messages]) + assert all(mes.caption == f'photo {idx+1}' for idx, mes in enumerate(messages)) + assert all( + mes.caption_entities == [MessageEntity(MessageEntity.BOLD, 0, 5)] for mes in messages + ) @flaky(3, 1) @pytest.mark.timeout(10) @@ -349,9 +387,13 @@ def test_send_media_group_all_args(self, bot, chat_id, media_group): chat_id, media_group, disable_notification=True, reply_to_message_id=m1.message_id ) assert isinstance(messages, list) - assert len(messages) == 2 + assert len(messages) == 3 assert all([isinstance(mes, Message) for mes in messages]) assert all([mes.media_group_id == messages[0].media_group_id for mes in messages]) + assert all(mes.caption == f'photo {idx+1}' for idx, mes in enumerate(messages)) + assert all( + mes.caption_entities == [MessageEntity(MessageEntity.BOLD, 0, 5)] for mes in messages + ) def test_send_media_group_with_thumbs( self, bot, chat_id, video_file, photo_file, monkeypatch # noqa: F811 diff --git a/tests/test_inputtextmessagecontent.py b/tests/test_inputtextmessagecontent.py index 143cd21c966..a37b20117ba 100644 --- a/tests/test_inputtextmessagecontent.py +++ b/tests/test_inputtextmessagecontent.py @@ -19,7 +19,7 @@ import pytest -from telegram import InputTextMessageContent, ParseMode +from telegram import InputTextMessageContent, ParseMode, MessageEntity @pytest.fixture(scope='class') @@ -27,6 +27,7 @@ def input_text_message_content(): return InputTextMessageContent( TestInputTextMessageContent.message_text, parse_mode=TestInputTextMessageContent.parse_mode, + caption_entities=TestInputTextMessageContent.caption_entities, disable_web_page_preview=TestInputTextMessageContent.disable_web_page_preview, ) @@ -34,12 +35,14 @@ def input_text_message_content(): class TestInputTextMessageContent: message_text = '*message text*' parse_mode = ParseMode.MARKDOWN + caption_entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] disable_web_page_preview = True def test_expected_values(self, input_text_message_content): assert input_text_message_content.parse_mode == self.parse_mode assert input_text_message_content.message_text == self.message_text assert input_text_message_content.disable_web_page_preview == self.disable_web_page_preview + assert input_text_message_content.caption_entities == self.caption_entities def test_to_dict(self, input_text_message_content): input_text_message_content_dict = input_text_message_content.to_dict() @@ -52,6 +55,9 @@ def test_to_dict(self, input_text_message_content): assert ( input_text_message_content_dict['parse_mode'] == input_text_message_content.parse_mode ) + assert input_text_message_content_dict['caption_entities'] == [ + ce.to_dict() for ce in input_text_message_content.caption_entities + ] assert ( input_text_message_content_dict['disable_web_page_preview'] == input_text_message_content.disable_web_page_preview diff --git a/tests/test_photo.py b/tests/test_photo.py index 696c352cb9b..def14290a47 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -22,7 +22,7 @@ import pytest from flaky import flaky -from telegram import Sticker, TelegramError, PhotoSize, InputFile +from telegram import Sticker, TelegramError, PhotoSize, InputFile, MessageEntity from telegram.error import BadRequest from telegram.utils.helpers import escape_markdown from tests.conftest import expect_bad_request @@ -164,6 +164,25 @@ def test_send_photo_parse_mode_html(self, bot, chat_id, photo_file, thumb, photo assert message.caption == TestPhoto.caption.replace('', '').replace('', '') assert len(message.caption_entities) == 1 + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_send_photo_caption_entities(self, bot, chat_id, photo_file, thumb, photo): + test_string = 'Italic Bold Code' + entities = [ + MessageEntity(MessageEntity.ITALIC, 0, 6), + MessageEntity(MessageEntity.ITALIC, 7, 4), + MessageEntity(MessageEntity.ITALIC, 12, 4), + ] + message = bot.send_photo( + chat_id, photo_file, caption=test_string, caption_entities=entities + ) + # message = bot.send_photo( + # chat_id, photo_file, caption=test_string, caption_entities=entities + # ) + + assert message.caption == test_string + assert message.caption_entities == entities + @flaky(3, 1) @pytest.mark.timeout(10) @pytest.mark.parametrize('default_bot', [{'parse_mode': 'Markdown'}], indirect=True) diff --git a/tests/test_video.py b/tests/test_video.py index 3d3deb965ab..7b3cf4e7158 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -21,7 +21,7 @@ import pytest from flaky import flaky -from telegram import Video, TelegramError, Voice, PhotoSize +from telegram import Video, TelegramError, Voice, PhotoSize, MessageEntity from telegram.error import BadRequest from telegram.utils.helpers import escape_markdown @@ -153,6 +153,20 @@ def test_send_mp4_file_url(self, bot, chat_id, video): assert message.caption == self.caption + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_send_video_caption_entities(self, bot, chat_id, video): + test_string = 'Italic Bold Code' + entities = [ + MessageEntity(MessageEntity.ITALIC, 0, 6), + MessageEntity(MessageEntity.ITALIC, 7, 4), + MessageEntity(MessageEntity.ITALIC, 12, 4), + ] + message = bot.send_video(chat_id, video, caption=test_string, caption_entities=entities) + + assert message.caption == test_string + assert message.caption_entities == entities + @flaky(3, 1) @pytest.mark.timeout(10) def test_resend(self, bot, chat_id, video): diff --git a/tests/test_voice.py b/tests/test_voice.py index 8f3fce4850f..718e251ca2b 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -21,7 +21,7 @@ import pytest from flaky import flaky -from telegram import Audio, Voice, TelegramError +from telegram import Audio, Voice, TelegramError, MessageEntity from telegram.error import BadRequest from telegram.utils.helpers import escape_markdown @@ -128,6 +128,22 @@ def test(url, data, **kwargs): message = bot.send_voice(chat_id, voice=voice) assert message + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_send_voice_caption_entities(self, bot, chat_id, voice_file): + test_string = 'Italic Bold Code' + entities = [ + MessageEntity(MessageEntity.ITALIC, 0, 6), + MessageEntity(MessageEntity.ITALIC, 7, 4), + MessageEntity(MessageEntity.ITALIC, 12, 4), + ] + message = bot.send_voice( + chat_id, voice_file, caption=test_string, caption_entities=entities + ) + + assert message.caption == test_string + assert message.caption_entities == entities + @flaky(3, 1) @pytest.mark.timeout(10) @pytest.mark.parametrize('default_bot', [{'parse_mode': 'Markdown'}], indirect=True)