mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2024-10-23 17:36:26 +02:00
Make TelegramObject
Immutable (#3249)
This commit is contained in:
parent
ff645c6fe2
commit
b11a0c7778
164 changed files with 2151 additions and 975 deletions
|
@ -4,4 +4,4 @@ telegram.TelegramObject
|
|||
.. autoclass:: telegram.TelegramObject
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:special-members: __repr__, __getitem__, __eq__, __hash__, __setstate__, __getstate__, __deepcopy__
|
||||
:special-members: __repr__, __getitem__, __eq__, __hash__, __setstate__, __getstate__, __deepcopy__, __setattr__, __delattr__
|
||||
|
|
|
@ -40,4 +40,10 @@
|
|||
|
||||
.. |disable_notification| replace:: Sends the message silently. Users will receive a notification with no sound.
|
||||
|
||||
.. |reply_to_msg_id| replace:: If the message is a reply, ID of the original message.
|
||||
.. |reply_to_msg_id| replace:: If the message is a reply, ID of the original message.
|
||||
|
||||
.. |sequenceclassargs| replace:: Accepts any :class:`collections.abc.Sequence` as input instead of just a list. The input is converted to a tuple.
|
||||
|
||||
.. |tupleclassattrs| replace:: This attribute is now an immutable tuple.
|
||||
|
||||
.. |alwaystuple| replace:: This attribute is now always a tuple, that may be empty.
|
||||
|
|
|
@ -21,6 +21,7 @@ disable = duplicate-code,too-many-arguments,too-many-public-methods,too-few-publ
|
|||
missing-class-docstring,too-many-locals,too-many-lines,too-many-branches,
|
||||
too-many-statements
|
||||
enable=useless-suppression ; Warns about unused pylint ignores
|
||||
exclude-protected=_unfrozen
|
||||
|
||||
[tool:pytest]
|
||||
testpaths = tests
|
||||
|
|
291
telegram/_bot.py
291
telegram/_bot.py
File diff suppressed because it is too large
Load diff
|
@ -55,6 +55,8 @@ class BotCommand(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.command, self.description)
|
||||
|
||||
self._freeze()
|
||||
|
||||
MIN_COMMAND: ClassVar[int] = constants.BotCommandLimit.MIN_COMMAND
|
||||
""":const:`telegram.constants.BotCommandLimit.MIN_COMMAND`
|
||||
|
||||
|
|
|
@ -80,6 +80,8 @@ class BotCommandScope(TelegramObject):
|
|||
self.type = type
|
||||
self._id_attrs = (self.type,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["BotCommandScope"]:
|
||||
"""Converts JSON data to the appropriate :class:`BotCommandScope` object, i.e. takes
|
||||
|
@ -128,6 +130,7 @@ class BotCommandScopeDefault(BotCommandScope):
|
|||
|
||||
def __init__(self, *, api_kwargs: JSONDict = None):
|
||||
super().__init__(type=BotCommandScope.DEFAULT, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class BotCommandScopeAllPrivateChats(BotCommandScope):
|
||||
|
@ -143,6 +146,7 @@ class BotCommandScopeAllPrivateChats(BotCommandScope):
|
|||
|
||||
def __init__(self, *, api_kwargs: JSONDict = None):
|
||||
super().__init__(type=BotCommandScope.ALL_PRIVATE_CHATS, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class BotCommandScopeAllGroupChats(BotCommandScope):
|
||||
|
@ -157,6 +161,7 @@ class BotCommandScopeAllGroupChats(BotCommandScope):
|
|||
|
||||
def __init__(self, *, api_kwargs: JSONDict = None):
|
||||
super().__init__(type=BotCommandScope.ALL_GROUP_CHATS, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class BotCommandScopeAllChatAdministrators(BotCommandScope):
|
||||
|
@ -171,6 +176,7 @@ class BotCommandScopeAllChatAdministrators(BotCommandScope):
|
|||
|
||||
def __init__(self, *, api_kwargs: JSONDict = None):
|
||||
super().__init__(type=BotCommandScope.ALL_CHAT_ADMINISTRATORS, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class BotCommandScopeChat(BotCommandScope):
|
||||
|
@ -193,10 +199,11 @@ class BotCommandScopeChat(BotCommandScope):
|
|||
|
||||
def __init__(self, chat_id: Union[str, int], *, api_kwargs: JSONDict = None):
|
||||
super().__init__(type=BotCommandScope.CHAT, api_kwargs=api_kwargs)
|
||||
self.chat_id = (
|
||||
chat_id if isinstance(chat_id, str) and chat_id.startswith("@") else int(chat_id)
|
||||
)
|
||||
self._id_attrs = (self.type, self.chat_id)
|
||||
with self._unfrozen():
|
||||
self.chat_id = (
|
||||
chat_id if isinstance(chat_id, str) and chat_id.startswith("@") else int(chat_id)
|
||||
)
|
||||
self._id_attrs = (self.type, self.chat_id)
|
||||
|
||||
|
||||
class BotCommandScopeChatAdministrators(BotCommandScope):
|
||||
|
@ -219,10 +226,11 @@ class BotCommandScopeChatAdministrators(BotCommandScope):
|
|||
|
||||
def __init__(self, chat_id: Union[str, int], *, api_kwargs: JSONDict = None):
|
||||
super().__init__(type=BotCommandScope.CHAT_ADMINISTRATORS, api_kwargs=api_kwargs)
|
||||
self.chat_id = (
|
||||
chat_id if isinstance(chat_id, str) and chat_id.startswith("@") else int(chat_id)
|
||||
)
|
||||
self._id_attrs = (self.type, self.chat_id)
|
||||
with self._unfrozen():
|
||||
self.chat_id = (
|
||||
chat_id if isinstance(chat_id, str) and chat_id.startswith("@") else int(chat_id)
|
||||
)
|
||||
self._id_attrs = (self.type, self.chat_id)
|
||||
|
||||
|
||||
class BotCommandScopeChatMember(BotCommandScope):
|
||||
|
@ -248,8 +256,9 @@ class BotCommandScopeChatMember(BotCommandScope):
|
|||
|
||||
def __init__(self, chat_id: Union[str, int], user_id: int, *, api_kwargs: JSONDict = None):
|
||||
super().__init__(type=BotCommandScope.CHAT_MEMBER, api_kwargs=api_kwargs)
|
||||
self.chat_id = (
|
||||
chat_id if isinstance(chat_id, str) and chat_id.startswith("@") else int(chat_id)
|
||||
)
|
||||
self.user_id = user_id
|
||||
self._id_attrs = (self.type, self.chat_id, self.user_id)
|
||||
with self._unfrozen():
|
||||
self.chat_id = (
|
||||
chat_id if isinstance(chat_id, str) and chat_id.startswith("@") else int(chat_id)
|
||||
)
|
||||
self.user_id = user_id
|
||||
self._id_attrs = (self.type, self.chat_id, self.user_id)
|
||||
|
|
|
@ -134,6 +134,8 @@ class CallbackQuery(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["CallbackQuery"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
@ -590,7 +592,7 @@ class CallbackQuery(TelegramObject):
|
|||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> List["GameHighScore"]:
|
||||
) -> Tuple["GameHighScore", ...]:
|
||||
"""Shortcut for either::
|
||||
|
||||
await update.callback_query.message.get_game_high_score(*args, **kwargs)
|
||||
|
@ -606,7 +608,7 @@ class CallbackQuery(TelegramObject):
|
|||
:meth:`telegram.Message.get_game_high_scores`.
|
||||
|
||||
Returns:
|
||||
List[:class:`telegram.GameHighScore`]
|
||||
Tuple[:class:`telegram.GameHighScore`]
|
||||
|
||||
"""
|
||||
if self.inline_message_id:
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
"""This module contains an object that represents a Telegram Chat."""
|
||||
from datetime import datetime
|
||||
from html import escape
|
||||
from typing import TYPE_CHECKING, ClassVar, List, Optional, Tuple, Union
|
||||
from typing import TYPE_CHECKING, ClassVar, List, Optional, Sequence, Tuple, Union
|
||||
|
||||
from telegram import constants
|
||||
from telegram._chatlocation import ChatLocation
|
||||
|
@ -30,6 +30,7 @@ from telegram._forumtopic import ForumTopic
|
|||
from telegram._menubutton import MenuButton
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils import enum
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup
|
||||
from telegram.helpers import escape_markdown
|
||||
|
@ -153,7 +154,7 @@ class Chat(TelegramObject):
|
|||
(has topics_ enabled).
|
||||
|
||||
.. versionadded:: 20.0
|
||||
active_usernames (List[:obj:`str`], optional): If set, the list of all `active chat
|
||||
active_usernames (Sequence[:obj:`str`], optional): If set, the list of all `active chat
|
||||
usernames <https://telegram.org/blog/topics-in-groups-collectible-usernames\
|
||||
#collectible-usernames>`_; for private chats, supergroups and channels. Returned
|
||||
only in :meth:`telegram.Bot.get_chat`.
|
||||
|
@ -234,10 +235,12 @@ class Chat(TelegramObject):
|
|||
(has topics_ enabled).
|
||||
|
||||
.. versionadded:: 20.0
|
||||
active_usernames (List[:obj:`str`]): Optional. If set, the list of all `active chat
|
||||
active_usernames (Tuple[:obj:`str`]): Optional. If set, the list of all `active chat
|
||||
usernames <https://telegram.org/blog/topics-in-groups-collectible-usernames\
|
||||
#collectible-usernames>`_; for private chats, supergroups and channels. Returned
|
||||
only in :meth:`telegram.Bot.get_chat`.
|
||||
This list is empty if the chat has no active usernames or this chat instance was not
|
||||
obtained via :meth:`~telegram.Bot.get_chat`.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
emoji_status_custom_emoji_id (:obj:`str`): Optional. Custom emoji identifier of emoji
|
||||
|
@ -318,7 +321,7 @@ class Chat(TelegramObject):
|
|||
join_by_request: bool = None,
|
||||
has_restricted_voice_and_video_messages: bool = None,
|
||||
is_forum: bool = None,
|
||||
active_usernames: List[str] = None,
|
||||
active_usernames: Sequence[str] = None,
|
||||
emoji_status_custom_emoji_id: str = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
|
@ -352,11 +355,13 @@ class Chat(TelegramObject):
|
|||
self.join_by_request = join_by_request
|
||||
self.has_restricted_voice_and_video_messages = has_restricted_voice_and_video_messages
|
||||
self.is_forum = is_forum
|
||||
self.active_usernames = active_usernames
|
||||
self.active_usernames = parse_sequence_arg(active_usernames)
|
||||
self.emoji_status_custom_emoji_id = emoji_status_custom_emoji_id
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@property
|
||||
def full_name(self) -> Optional[str]:
|
||||
"""
|
||||
|
@ -546,7 +551,7 @@ class Chat(TelegramObject):
|
|||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> List["ChatMember"]:
|
||||
) -> Tuple["ChatMember", ...]:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.get_chat_administrators(update.effective_chat.id, *args, **kwargs)
|
||||
|
@ -555,7 +560,7 @@ class Chat(TelegramObject):
|
|||
:meth:`telegram.Bot.get_chat_administrators`.
|
||||
|
||||
Returns:
|
||||
List[:class:`telegram.ChatMember`]: A list of administrators in a chat. An Array of
|
||||
Tuple[:class:`telegram.ChatMember`]: A tuple of administrators in a chat. An Array of
|
||||
:class:`telegram.ChatMember` objects that contains information about all
|
||||
chat administrators except other bots. If the chat is a group or a supergroup
|
||||
and no administrators were appointed, only the creator will be returned.
|
||||
|
@ -1292,7 +1297,7 @@ class Chat(TelegramObject):
|
|||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
|
||||
) -> List["Message"]:
|
||||
) -> Tuple["Message", ...]:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.send_media_group(update.effective_chat.id, *args, **kwargs)
|
||||
|
@ -1300,7 +1305,8 @@ class Chat(TelegramObject):
|
|||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_media_group`.
|
||||
|
||||
Returns:
|
||||
List[:class:`telegram.Message`]: On success, instance representing the message posted.
|
||||
Tuple[:class:`telegram.Message`]: On success, a tuple of :class:`~telegram.Message`
|
||||
instances that were sent is returned.
|
||||
|
||||
"""
|
||||
return await self.get_bot().send_media_group(
|
||||
|
|
|
@ -167,6 +167,8 @@ class ChatAdministratorRights(TelegramObject):
|
|||
self.can_manage_topics,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def all_rights(cls) -> "ChatAdministratorRights":
|
||||
"""
|
||||
|
|
|
@ -141,6 +141,8 @@ class ChatInviteLink(TelegramObject):
|
|||
self.is_revoked,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatInviteLink"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -88,6 +88,8 @@ class ChatJoinRequest(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.chat, self.from_user, self.date)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatJoinRequest"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -62,6 +62,8 @@ class ChatLocation(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.location,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatLocation"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -98,6 +98,8 @@ class ChatMember(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.user, self.status)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatMember"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
@ -159,8 +161,9 @@ class ChatMemberOwner(ChatMember):
|
|||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
super().__init__(status=ChatMember.OWNER, user=user, api_kwargs=api_kwargs)
|
||||
self.is_anonymous = is_anonymous
|
||||
self.custom_title = custom_title
|
||||
with self._unfrozen():
|
||||
self.is_anonymous = is_anonymous
|
||||
self.custom_title = custom_title
|
||||
|
||||
|
||||
class ChatMemberAdministrator(ChatMember):
|
||||
|
@ -295,20 +298,21 @@ class ChatMemberAdministrator(ChatMember):
|
|||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
super().__init__(status=ChatMember.ADMINISTRATOR, user=user, api_kwargs=api_kwargs)
|
||||
self.can_be_edited = can_be_edited
|
||||
self.is_anonymous = is_anonymous
|
||||
self.can_manage_chat = can_manage_chat
|
||||
self.can_delete_messages = can_delete_messages
|
||||
self.can_manage_video_chats = can_manage_video_chats
|
||||
self.can_restrict_members = can_restrict_members
|
||||
self.can_promote_members = can_promote_members
|
||||
self.can_change_info = can_change_info
|
||||
self.can_invite_users = can_invite_users
|
||||
self.can_post_messages = can_post_messages
|
||||
self.can_edit_messages = can_edit_messages
|
||||
self.can_pin_messages = can_pin_messages
|
||||
self.can_manage_topics = can_manage_topics
|
||||
self.custom_title = custom_title
|
||||
with self._unfrozen():
|
||||
self.can_be_edited = can_be_edited
|
||||
self.is_anonymous = is_anonymous
|
||||
self.can_manage_chat = can_manage_chat
|
||||
self.can_delete_messages = can_delete_messages
|
||||
self.can_manage_video_chats = can_manage_video_chats
|
||||
self.can_restrict_members = can_restrict_members
|
||||
self.can_promote_members = can_promote_members
|
||||
self.can_change_info = can_change_info
|
||||
self.can_invite_users = can_invite_users
|
||||
self.can_post_messages = can_post_messages
|
||||
self.can_edit_messages = can_edit_messages
|
||||
self.can_pin_messages = can_pin_messages
|
||||
self.can_manage_topics = can_manage_topics
|
||||
self.custom_title = custom_title
|
||||
|
||||
|
||||
class ChatMemberMember(ChatMember):
|
||||
|
@ -337,6 +341,7 @@ class ChatMemberMember(ChatMember):
|
|||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
super().__init__(status=ChatMember.MEMBER, user=user, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class ChatMemberRestricted(ChatMember):
|
||||
|
@ -439,17 +444,18 @@ class ChatMemberRestricted(ChatMember):
|
|||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
super().__init__(status=ChatMember.RESTRICTED, user=user, api_kwargs=api_kwargs)
|
||||
self.is_member = is_member
|
||||
self.can_change_info = can_change_info
|
||||
self.can_invite_users = can_invite_users
|
||||
self.can_pin_messages = can_pin_messages
|
||||
self.can_send_messages = can_send_messages
|
||||
self.can_send_media_messages = can_send_media_messages
|
||||
self.can_send_polls = can_send_polls
|
||||
self.can_send_other_messages = can_send_other_messages
|
||||
self.can_add_web_page_previews = can_add_web_page_previews
|
||||
self.can_manage_topics = can_manage_topics
|
||||
self.until_date = until_date
|
||||
with self._unfrozen():
|
||||
self.is_member = is_member
|
||||
self.can_change_info = can_change_info
|
||||
self.can_invite_users = can_invite_users
|
||||
self.can_pin_messages = can_pin_messages
|
||||
self.can_send_messages = can_send_messages
|
||||
self.can_send_media_messages = can_send_media_messages
|
||||
self.can_send_polls = can_send_polls
|
||||
self.can_send_other_messages = can_send_other_messages
|
||||
self.can_add_web_page_previews = can_add_web_page_previews
|
||||
self.can_manage_topics = can_manage_topics
|
||||
self.until_date = until_date
|
||||
|
||||
|
||||
class ChatMemberLeft(ChatMember):
|
||||
|
@ -477,6 +483,7 @@ class ChatMemberLeft(ChatMember):
|
|||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
super().__init__(status=ChatMember.LEFT, user=user, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class ChatMemberBanned(ChatMember):
|
||||
|
@ -510,4 +517,5 @@ class ChatMemberBanned(ChatMember):
|
|||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
super().__init__(status=ChatMember.BANNED, user=user, api_kwargs=api_kwargs)
|
||||
self.until_date = until_date
|
||||
with self._unfrozen():
|
||||
self.until_date = until_date
|
||||
|
|
|
@ -108,6 +108,8 @@ class ChatMemberUpdated(TelegramObject):
|
|||
self.new_chat_member,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChatMemberUpdated"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -142,6 +142,8 @@ class ChatPermissions(TelegramObject):
|
|||
self.can_manage_topics,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def all_permissions(cls) -> "ChatPermissions":
|
||||
"""
|
||||
|
|
|
@ -86,6 +86,8 @@ class ChosenInlineResult(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.result_id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ChosenInlineResult"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -88,6 +88,8 @@ class Dice(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.value, self.emoji)
|
||||
|
||||
self._freeze()
|
||||
|
||||
DICE: ClassVar[str] = constants.DiceEmoji.DICE # skipcq: PTC-W0052
|
||||
""":const:`telegram.constants.DiceEmoji.DICE`"""
|
||||
DARTS: ClassVar[str] = constants.DiceEmoji.DARTS
|
||||
|
|
|
@ -82,10 +82,11 @@ class Animation(_BaseThumbedMedium):
|
|||
thumb=thumb,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
# Required
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.duration = duration
|
||||
# Optional
|
||||
self.mime_type = mime_type
|
||||
self.file_name = file_name
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.duration = duration
|
||||
# Optional
|
||||
self.mime_type = mime_type
|
||||
self.file_name = file_name
|
||||
|
|
|
@ -86,10 +86,11 @@ class Audio(_BaseThumbedMedium):
|
|||
thumb=thumb,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
# Required
|
||||
self.duration = duration
|
||||
# Optional
|
||||
self.performer = performer
|
||||
self.title = title
|
||||
self.mime_type = mime_type
|
||||
self.file_name = file_name
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.duration = duration
|
||||
# Optional
|
||||
self.performer = performer
|
||||
self.title = title
|
||||
self.mime_type = mime_type
|
||||
self.file_name = file_name
|
||||
|
|
|
@ -100,6 +100,8 @@ class ChatPhoto(TelegramObject):
|
|||
self.big_file_unique_id,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
async def get_small_file(
|
||||
self,
|
||||
*,
|
||||
|
|
|
@ -66,3 +66,5 @@ class Contact(TelegramObject):
|
|||
self.vcard = vcard
|
||||
|
||||
self._id_attrs = (self.phone_number,)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -73,6 +73,7 @@ class Document(_BaseThumbedMedium):
|
|||
thumb=thumb,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
# Optional
|
||||
self.mime_type = mime_type
|
||||
self.file_name = file_name
|
||||
with self._unfrozen():
|
||||
# Optional
|
||||
self.mime_type = mime_type
|
||||
self.file_name = file_name
|
||||
|
|
|
@ -102,6 +102,8 @@ class File(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
def _get_encoded_url(self) -> str:
|
||||
"""Convert any UTF-8 char in :obj:`File.file_path` into a url encoded ASCII string."""
|
||||
sres = urllib_parse.urlsplit(str(self.file_path))
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""Base class for Telegram InputMedia Objects."""
|
||||
from typing import List, Optional, Tuple, Union
|
||||
from typing import Optional, Sequence, Union
|
||||
|
||||
from telegram._files.animation import Animation
|
||||
from telegram._files.audio import Audio
|
||||
|
@ -27,6 +27,7 @@ from telegram._files.photosize import PhotoSize
|
|||
from telegram._files.video import Video
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.files import parse_file_input
|
||||
from telegram._utils.types import FileInput, JSONDict, ODVInput
|
||||
|
@ -55,7 +56,11 @@ class InputMedia(TelegramObject):
|
|||
caption (:obj:`str`, optional): Caption of the media to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
|
||||
Attributes:
|
||||
|
@ -63,8 +68,13 @@ class InputMedia(TelegramObject):
|
|||
media (:obj:`str` | :class:`telegram.InputFile`): Media to send.
|
||||
caption (:obj:`str`): Optional. Caption of the media 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.
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("caption", "caption_entities", "media", "parse_mode", "type")
|
||||
|
@ -74,7 +84,7 @@ class InputMedia(TelegramObject):
|
|||
media_type: str,
|
||||
media: Union[str, InputFile, MediaType],
|
||||
caption: str = None,
|
||||
caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
|
@ -83,9 +93,11 @@ class InputMedia(TelegramObject):
|
|||
self.type = media_type
|
||||
self.media = media
|
||||
self.caption = caption
|
||||
self.caption_entities = caption_entities
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.parse_mode = parse_mode
|
||||
|
||||
self._freeze()
|
||||
|
||||
@staticmethod
|
||||
def _parse_thumb_input(thumb: Optional[FileInput]) -> Optional[Union[str, InputFile]]:
|
||||
# We use local_mode=True because we don't have access to the actual setting and want
|
||||
|
@ -124,7 +136,11 @@ class InputMediaAnimation(InputMedia):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
width (:obj:`int`, optional): Animation width.
|
||||
height (:obj:`int`, optional): Animation height.
|
||||
duration (:obj:`int`, optional): Animation duration in seconds.
|
||||
|
@ -134,8 +150,13 @@ 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.
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
|
||||
thumb (:class:`telegram.InputFile`): Optional. Thumbnail of the file to send.
|
||||
width (:obj:`int`): Optional. Animation width.
|
||||
height (:obj:`int`): Optional. Animation height.
|
||||
|
@ -154,7 +175,7 @@ class InputMediaAnimation(InputMedia):
|
|||
width: int = None,
|
||||
height: int = None,
|
||||
duration: int = None,
|
||||
caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
filename: str = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
|
@ -177,10 +198,11 @@ class InputMediaAnimation(InputMedia):
|
|||
parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
self.thumb = self._parse_thumb_input(thumb)
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.duration = duration
|
||||
with self._unfrozen():
|
||||
self.thumb = self._parse_thumb_input(thumb)
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.duration = duration
|
||||
|
||||
|
||||
class InputMediaPhoto(InputMedia):
|
||||
|
@ -202,15 +224,22 @@ class InputMediaPhoto(InputMedia):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): :tg-const:`telegram.constants.InputMediaType.PHOTO`.
|
||||
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.
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
|
||||
"""
|
||||
|
||||
|
@ -221,7 +250,7 @@ class InputMediaPhoto(InputMedia):
|
|||
media: Union[FileInput, PhotoSize],
|
||||
caption: str = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
filename: str = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
|
@ -238,6 +267,8 @@ class InputMediaPhoto(InputMedia):
|
|||
api_kwargs=api_kwargs,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class InputMediaVideo(InputMedia):
|
||||
"""Represents a video to be sent.
|
||||
|
@ -266,7 +297,11 @@ class InputMediaVideo(InputMedia):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
width (:obj:`int`, optional): Video width.
|
||||
height (:obj:`int`, optional): Video height.
|
||||
duration (:obj:`int`, optional): Video duration in seconds.
|
||||
|
@ -283,8 +318,12 @@ 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.
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
width (:obj:`int`): Optional. Video width.
|
||||
height (:obj:`int`): Optional. Video height.
|
||||
duration (:obj:`int`): Optional. Video duration in seconds.
|
||||
|
@ -306,7 +345,7 @@ class InputMediaVideo(InputMedia):
|
|||
supports_streaming: bool = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb: FileInput = None,
|
||||
caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
filename: str = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
|
@ -330,11 +369,12 @@ class InputMediaVideo(InputMedia):
|
|||
parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.duration = duration
|
||||
self.thumb = self._parse_thumb_input(thumb)
|
||||
self.supports_streaming = supports_streaming
|
||||
with self._unfrozen():
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.duration = duration
|
||||
self.thumb = self._parse_thumb_input(thumb)
|
||||
self.supports_streaming = supports_streaming
|
||||
|
||||
|
||||
class InputMediaAudio(InputMedia):
|
||||
|
@ -361,7 +401,11 @@ class InputMediaAudio(InputMedia):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
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.
|
||||
|
@ -377,8 +421,12 @@ 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.
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
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.
|
||||
|
@ -398,7 +446,7 @@ class InputMediaAudio(InputMedia):
|
|||
duration: int = None,
|
||||
performer: str = None,
|
||||
title: str = None,
|
||||
caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
filename: str = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
|
@ -421,10 +469,11 @@ class InputMediaAudio(InputMedia):
|
|||
parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
self.thumb = self._parse_thumb_input(thumb)
|
||||
self.duration = duration
|
||||
self.title = title
|
||||
self.performer = performer
|
||||
with self._unfrozen():
|
||||
self.thumb = self._parse_thumb_input(thumb)
|
||||
self.duration = duration
|
||||
self.title = title
|
||||
self.performer = performer
|
||||
|
||||
|
||||
class InputMediaDocument(InputMedia):
|
||||
|
@ -446,7 +495,11 @@ class InputMediaDocument(InputMedia):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
thumb (:term:`file object` | :obj:`bytes` | :class:`pathlib.Path` | :obj:`str`, \
|
||||
optional): |thumbdocstringnopath|
|
||||
|
||||
|
@ -461,8 +514,12 @@ 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.
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
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
|
||||
|
@ -479,7 +536,7 @@ class InputMediaDocument(InputMedia):
|
|||
caption: str = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_content_type_detection: bool = None,
|
||||
caption_entities: Union[List[MessageEntity], Tuple[MessageEntity, ...]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
filename: str = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
|
@ -495,5 +552,6 @@ class InputMediaDocument(InputMedia):
|
|||
parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
self.thumb = self._parse_thumb_input(thumb)
|
||||
self.disable_content_type_detection = disable_content_type_detection
|
||||
with self._unfrozen():
|
||||
self.thumb = self._parse_thumb_input(thumb)
|
||||
self.disable_content_type_detection = disable_content_type_detection
|
||||
|
|
|
@ -93,6 +93,8 @@ class Location(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.longitude, self.latitude)
|
||||
|
||||
self._freeze()
|
||||
|
||||
HORIZONTAL_ACCURACY: ClassVar[int] = constants.LocationLimit.HORIZONTAL_ACCURACY
|
||||
""":const:`telegram.constants.LocationLimit.HORIZONTAL_ACCURACY`
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ class PhotoSize(_BaseMedium):
|
|||
file_size=file_size,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
# Required
|
||||
self.width = width
|
||||
self.height = height
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.width = width
|
||||
self.height = height
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains objects that represent stickers."""
|
||||
|
||||
from typing import TYPE_CHECKING, ClassVar, List, Optional
|
||||
from typing import TYPE_CHECKING, ClassVar, Optional, Sequence
|
||||
|
||||
from telegram import constants
|
||||
from telegram._files._basethumbedmedium import _BaseThumbedMedium
|
||||
from telegram._files.file import File
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -150,18 +150,19 @@ class Sticker(_BaseThumbedMedium):
|
|||
thumb=thumb,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
# Required
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.is_animated = is_animated
|
||||
self.is_video = is_video
|
||||
self.type = type
|
||||
# Optional
|
||||
self.emoji = emoji
|
||||
self.set_name = set_name
|
||||
self.mask_position = mask_position
|
||||
self.premium_animation = premium_animation
|
||||
self.custom_emoji_id = custom_emoji_id
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.is_animated = is_animated
|
||||
self.is_video = is_video
|
||||
self.type = type
|
||||
# Optional
|
||||
self.emoji = emoji
|
||||
self.set_name = set_name
|
||||
self.mask_position = mask_position
|
||||
self.premium_animation = premium_animation
|
||||
self.custom_emoji_id = custom_emoji_id
|
||||
|
||||
REGULAR: ClassVar[str] = constants.StickerType.REGULAR
|
||||
""":const:`telegram.constants.StickerType.REGULAR`"""
|
||||
|
@ -206,7 +207,11 @@ class StickerSet(TelegramObject):
|
|||
is_video (:obj:`bool`): :obj:`True`, if the sticker set contains video stickers.
|
||||
|
||||
.. versionadded:: 13.11
|
||||
stickers (List[:class:`telegram.Sticker`]): List of all set stickers.
|
||||
stickers (Sequence[:class:`telegram.Sticker`]): List of all set stickers.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
sticker_type (:obj:`str`): Type of stickers in the set, currently one of
|
||||
:attr:`telegram.Sticker.REGULAR`, :attr:`telegram.Sticker.MASK`,
|
||||
:attr:`telegram.Sticker.CUSTOM_EMOJI`.
|
||||
|
@ -222,7 +227,11 @@ class StickerSet(TelegramObject):
|
|||
is_video (:obj:`bool`): :obj:`True`, if the sticker set contains video stickers.
|
||||
|
||||
.. versionadded:: 13.11
|
||||
stickers (List[:class:`telegram.Sticker`]): List of all set stickers.
|
||||
stickers (Tuple[:class:`telegram.Sticker`]): List of all set stickers.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
sticker_type (:obj:`str`): Type of stickers in the set.
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
@ -246,7 +255,7 @@ class StickerSet(TelegramObject):
|
|||
name: str,
|
||||
title: str,
|
||||
is_animated: bool,
|
||||
stickers: List[Sticker],
|
||||
stickers: Sequence[Sticker],
|
||||
is_video: bool,
|
||||
sticker_type: str,
|
||||
thumb: PhotoSize = None,
|
||||
|
@ -258,13 +267,15 @@ class StickerSet(TelegramObject):
|
|||
self.title = title
|
||||
self.is_animated = is_animated
|
||||
self.is_video = is_video
|
||||
self.stickers = stickers
|
||||
self.stickers = parse_sequence_arg(stickers)
|
||||
self.sticker_type = sticker_type
|
||||
# Optional
|
||||
self.thumb = thumb
|
||||
|
||||
self._id_attrs = (self.name,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["StickerSet"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
@ -339,3 +350,5 @@ class MaskPosition(TelegramObject):
|
|||
self.scale = scale
|
||||
|
||||
self._id_attrs = (self.point, self.x_shift, self.y_shift, self.scale)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -97,6 +97,8 @@ class Venue(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.location, self.title)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["Venue"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -82,10 +82,11 @@ class Video(_BaseThumbedMedium):
|
|||
thumb=thumb,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
# Required
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.duration = duration
|
||||
# Optional
|
||||
self.mime_type = mime_type
|
||||
self.file_name = file_name
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.duration = duration
|
||||
# Optional
|
||||
self.mime_type = mime_type
|
||||
self.file_name = file_name
|
||||
|
|
|
@ -73,6 +73,7 @@ class VideoNote(_BaseThumbedMedium):
|
|||
thumb=thumb,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
# Required
|
||||
self.length = length
|
||||
self.duration = duration
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.length = length
|
||||
self.duration = duration
|
||||
|
|
|
@ -67,7 +67,8 @@ class Voice(_BaseMedium):
|
|||
file_size=file_size,
|
||||
api_kwargs=api_kwargs,
|
||||
)
|
||||
# Required
|
||||
self.duration = duration
|
||||
# Optional
|
||||
self.mime_type = mime_type
|
||||
with self._unfrozen():
|
||||
# Required
|
||||
self.duration = duration
|
||||
# Optional
|
||||
self.mime_type = mime_type
|
||||
|
|
|
@ -83,6 +83,8 @@ class ForceReply(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.selective,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
MIN_INPUT_FIELD_PLACEHOLDER: ClassVar[int] = constants.ReplyLimit.MIN_INPUT_FIELD_PLACEHOLDER
|
||||
""":const:`telegram.constants.ReplyLimit.MIN_INPUT_FIELD_PLACEHOLDER`
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@ class ForumTopic(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.message_thread_id, self.name, self.icon_color)
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class ForumTopicCreated(TelegramObject):
|
||||
"""
|
||||
|
@ -107,6 +109,8 @@ class ForumTopicCreated(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.name, self.icon_color)
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class ForumTopicClosed(TelegramObject):
|
||||
"""
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Game."""
|
||||
|
||||
import sys
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Sequence
|
||||
|
||||
from telegram._files.animation import Animation
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -42,30 +42,46 @@ class Game(TelegramObject):
|
|||
Args:
|
||||
title (:obj:`str`): Title of the game.
|
||||
description (:obj:`str`): Description of the game.
|
||||
photo (List[:class:`telegram.PhotoSize`]): Photo that will be displayed in the game message
|
||||
in chats.
|
||||
photo (Sequence[:class:`telegram.PhotoSize`]): Photo that will be displayed in the game
|
||||
message in chats.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
text (:obj:`str`, optional): Brief description of the game or high scores included in the
|
||||
game message. Can be automatically edited to include current high scores for the game
|
||||
when the bot calls :meth:`telegram.Bot.set_game_score`, or manually edited
|
||||
using :meth:`telegram.Bot.edit_message_text`.
|
||||
0-:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters.
|
||||
text_entities (List[:class:`telegram.MessageEntity`], optional): Special entities that
|
||||
text_entities (Sequence[:class:`telegram.MessageEntity`], optional): Special entities that
|
||||
appear in text, such as usernames, URLs, bot commands, etc.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
animation (:class:`telegram.Animation`, optional): Animation that will be displayed in the
|
||||
game message in chats. Upload via `BotFather <https://t.me/BotFather>`_.
|
||||
|
||||
Attributes:
|
||||
title (:obj:`str`): Title of the game.
|
||||
description (:obj:`str`): Description of the game.
|
||||
photo (List[:class:`telegram.PhotoSize`]): Photo that will be displayed in the game message
|
||||
in chats.
|
||||
photo (Tuple[:class:`telegram.PhotoSize`]): Photo that will be displayed in the game
|
||||
message in chats.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
text (:obj:`str`): Optional. Brief description of the game or high scores included in the
|
||||
game message. Can be automatically edited to include current high scores for the game
|
||||
when the bot calls :meth:`telegram.Bot.set_game_score`, or manually edited
|
||||
using :meth:`telegram.Bot.edit_message_text`.
|
||||
text_entities (List[:class:`telegram.MessageEntity`]): Special entities that
|
||||
text_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. Special entities that
|
||||
appear in text, such as usernames, URLs, bot commands, etc.
|
||||
This list is empty if the message does not contain text entities.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
animation (:class:`telegram.Animation`): Optional. Animation that will be displayed in the
|
||||
game message in chats. Upload via `BotFather <https://t.me/BotFather>`_.
|
||||
|
||||
|
@ -84,9 +100,9 @@ class Game(TelegramObject):
|
|||
self,
|
||||
title: str,
|
||||
description: str,
|
||||
photo: List[PhotoSize],
|
||||
photo: Sequence[PhotoSize],
|
||||
text: str = None,
|
||||
text_entities: List[MessageEntity] = None,
|
||||
text_entities: Sequence[MessageEntity] = None,
|
||||
animation: Animation = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
|
@ -95,14 +111,16 @@ class Game(TelegramObject):
|
|||
# Required
|
||||
self.title = title
|
||||
self.description = description
|
||||
self.photo = photo
|
||||
self.photo = parse_sequence_arg(photo)
|
||||
# Optionals
|
||||
self.text = text
|
||||
self.text_entities = text_entities or []
|
||||
self.text_entities = parse_sequence_arg(text_entities)
|
||||
self.animation = animation
|
||||
|
||||
self._id_attrs = (self.title, self.description, self.photo)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["Game"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
@ -178,6 +196,3 @@ class Game(TelegramObject):
|
|||
for entity in self.text_entities
|
||||
if entity.type in types
|
||||
}
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash((self.title, self.description, tuple(p for p in self.photo)))
|
||||
|
|
|
@ -56,6 +56,8 @@ class GameHighScore(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.position, self.user, self.score)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["GameHighScore"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -202,6 +202,8 @@ class InlineKeyboardButton(TelegramObject):
|
|||
self._id_attrs = ()
|
||||
self._set_id_attrs()
|
||||
|
||||
self._freeze()
|
||||
|
||||
def _set_id_attrs(self) -> None:
|
||||
self._id_attrs = (
|
||||
self.text,
|
||||
|
@ -239,8 +241,9 @@ class InlineKeyboardButton(TelegramObject):
|
|||
Args:
|
||||
callback_data (:class:`object`): The new callback data.
|
||||
"""
|
||||
self.callback_data = callback_data
|
||||
self._set_id_attrs()
|
||||
with self._unfrozen():
|
||||
self.callback_data = callback_data
|
||||
self._set_id_attrs()
|
||||
|
||||
MIN_CALLBACK_DATA: ClassVar[int] = constants.InlineKeyboardButtonLimit.MIN_CALLBACK_DATA
|
||||
""":const:`telegram.constants.InlineKeyboardButtonLimit.MIN_CALLBACK_DATA`
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram InlineKeyboardMarkup."""
|
||||
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
from typing import TYPE_CHECKING, List, Optional, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardbutton import InlineKeyboardButton
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -41,12 +40,20 @@ class InlineKeyboardMarkup(TelegramObject):
|
|||
* :any:`Inline Keyboard 2 <examples.inlinekeyboard2>`
|
||||
|
||||
Args:
|
||||
inline_keyboard (List[List[:class:`telegram.InlineKeyboardButton`]]): List of button rows,
|
||||
each represented by a list of InlineKeyboardButton objects.
|
||||
inline_keyboard (Sequence[Sequence[:class:`telegram.InlineKeyboardButton`]]): Sequence of
|
||||
button rows, each represented by a sequence of :class:`~telegram.InlineKeyboardButton`
|
||||
objects.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
Attributes:
|
||||
inline_keyboard (List[List[:class:`telegram.InlineKeyboardButton`]]): List of button rows,
|
||||
each represented by a list of InlineKeyboardButton objects.
|
||||
inline_keyboard (Tuple[Tuple[:class:`telegram.InlineKeyboardButton`]]): Tuple of
|
||||
button rows, each represented by a tuple of :class:`~telegram.InlineKeyboardButton`
|
||||
objects.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
"""
|
||||
|
||||
|
@ -54,21 +61,23 @@ class InlineKeyboardMarkup(TelegramObject):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
inline_keyboard: List[List[InlineKeyboardButton]],
|
||||
inline_keyboard: Sequence[Sequence[InlineKeyboardButton]],
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
if not check_keyboard_type(inline_keyboard):
|
||||
raise ValueError(
|
||||
"The parameter `inline_keyboard` should be a list of "
|
||||
"list of InlineKeyboardButtons"
|
||||
"The parameter `inline_keyboard` should be a sequence of sequences of "
|
||||
"InlineKeyboardButtons"
|
||||
)
|
||||
# Required
|
||||
self.inline_keyboard = inline_keyboard
|
||||
self.inline_keyboard = tuple(tuple(row) for row in inline_keyboard)
|
||||
|
||||
self._id_attrs = (self.inline_keyboard,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["InlineKeyboardMarkup"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
@ -134,6 +143,3 @@ class InlineKeyboardMarkup(TelegramObject):
|
|||
"""
|
||||
button_grid = [[button] for button in button_column]
|
||||
return cls(button_grid, **kwargs) # type: ignore[arg-type]
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(tuple(tuple(button for button in row) for row in self.inline_keyboard))
|
||||
|
|
|
@ -106,6 +106,8 @@ class InlineQuery(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["InlineQuery"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -64,6 +64,8 @@ class InlineQueryResult(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
MIN_ID_LENGTH: ClassVar[int] = constants.InlineQueryResultLimit.MIN_ID_LENGTH
|
||||
""":const:`telegram.constants.InlineQueryResultLimit.MIN_ID_LENGTH`
|
||||
|
||||
|
|
|
@ -102,14 +102,15 @@ class InlineQueryResultArticle(InlineQueryResult):
|
|||
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.ARTICLE, id, api_kwargs=api_kwargs)
|
||||
self.title = title
|
||||
self.input_message_content = input_message_content
|
||||
with self._unfrozen():
|
||||
self.title = title
|
||||
self.input_message_content = input_message_content
|
||||
|
||||
# Optional
|
||||
self.reply_markup = reply_markup
|
||||
self.url = url
|
||||
self.hide_url = hide_url
|
||||
self.description = description
|
||||
self.thumb_url = thumb_url
|
||||
self.thumb_width = thumb_width
|
||||
self.thumb_height = thumb_height
|
||||
# Optional
|
||||
self.reply_markup = reply_markup
|
||||
self.url = url
|
||||
self.hide_url = hide_url
|
||||
self.description = description
|
||||
self.thumb_url = thumb_url
|
||||
self.thumb_width = thumb_width
|
||||
self.thumb_height = thumb_height
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# 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, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -49,7 +49,10 @@ class InlineQueryResultAudio(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
|
@ -68,7 +71,12 @@ class InlineQueryResultAudio(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
|
@ -99,21 +107,22 @@ class InlineQueryResultAudio(InlineQueryResult):
|
|||
reply_markup: InlineKeyboardMarkup = None,
|
||||
input_message_content: "InputMessageContent" = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.AUDIO, id, api_kwargs=api_kwargs)
|
||||
self.audio_url = audio_url
|
||||
self.title = title
|
||||
with self._unfrozen():
|
||||
self.audio_url = audio_url
|
||||
self.title = title
|
||||
|
||||
# Optionals
|
||||
self.performer = performer
|
||||
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
|
||||
# Optionals
|
||||
self.performer = performer
|
||||
self.audio_duration = audio_duration
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# 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, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -46,7 +46,11 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
|
@ -61,8 +65,13 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
|
|||
caption (:obj:`str`): Optional. Caption,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`, optionals): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
|
@ -87,17 +96,18 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
|
|||
reply_markup: InlineKeyboardMarkup = None,
|
||||
input_message_content: "InputMessageContent" = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.AUDIO, id, api_kwargs=api_kwargs)
|
||||
self.audio_file_id = audio_file_id
|
||||
with self._unfrozen():
|
||||
self.audio_file_id = audio_file_id
|
||||
|
||||
# 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
|
||||
# Optionals
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultCachedDocument."""
|
||||
|
||||
from typing import TYPE_CHECKING, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -48,7 +48,11 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
|
@ -66,7 +70,12 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
|
@ -95,19 +104,20 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
|
|||
reply_markup: InlineKeyboardMarkup = None,
|
||||
input_message_content: "InputMessageContent" = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.DOCUMENT, id, api_kwargs=api_kwargs)
|
||||
self.title = title
|
||||
self.document_file_id = document_file_id
|
||||
with self._unfrozen():
|
||||
self.title = title
|
||||
self.document_file_id = document_file_id
|
||||
|
||||
# Optionals
|
||||
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
|
||||
# Optionals
|
||||
self.description = description
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# 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, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -48,7 +48,11 @@ class InlineQueryResultCachedGif(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
|
@ -65,7 +69,12 @@ class InlineQueryResultCachedGif(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
|
@ -92,18 +101,19 @@ class InlineQueryResultCachedGif(InlineQueryResult):
|
|||
reply_markup: InlineKeyboardMarkup = None,
|
||||
input_message_content: "InputMessageContent" = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.GIF, id, api_kwargs=api_kwargs)
|
||||
self.gif_file_id = gif_file_id
|
||||
with self._unfrozen():
|
||||
self.gif_file_id = gif_file_id
|
||||
|
||||
# Optionals
|
||||
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
|
||||
# Optionals
|
||||
self.title = title
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# 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, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -48,7 +48,11 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
|
@ -65,7 +69,12 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
|
@ -92,18 +101,19 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
|
|||
reply_markup: InlineKeyboardMarkup = None,
|
||||
input_message_content: "InputMessageContent" = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.MPEG4GIF, id, api_kwargs=api_kwargs)
|
||||
self.mpeg4_file_id = mpeg4_file_id
|
||||
with self._unfrozen():
|
||||
self.mpeg4_file_id = mpeg4_file_id
|
||||
|
||||
# Optionals
|
||||
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
|
||||
# Optionals
|
||||
self.title = title
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# 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, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -49,7 +49,11 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
|
@ -67,7 +71,12 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
|
@ -96,19 +105,20 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
|
|||
reply_markup: InlineKeyboardMarkup = None,
|
||||
input_message_content: "InputMessageContent" = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.PHOTO, id, api_kwargs=api_kwargs)
|
||||
self.photo_file_id = photo_file_id
|
||||
with self._unfrozen():
|
||||
self.photo_file_id = photo_file_id
|
||||
|
||||
# Optionals
|
||||
self.title = title
|
||||
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
|
||||
# Optionals
|
||||
self.title = title
|
||||
self.description = description
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
|
|
|
@ -71,8 +71,9 @@ class InlineQueryResultCachedSticker(InlineQueryResult):
|
|||
):
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.STICKER, id, api_kwargs=api_kwargs)
|
||||
self.sticker_file_id = sticker_file_id
|
||||
with self._unfrozen():
|
||||
self.sticker_file_id = sticker_file_id
|
||||
|
||||
# Optionals
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
# Optionals
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# 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, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -49,7 +49,7 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
|
@ -67,7 +67,12 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
|
@ -96,19 +101,20 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
|
|||
reply_markup: InlineKeyboardMarkup = None,
|
||||
input_message_content: "InputMessageContent" = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.VIDEO, id, api_kwargs=api_kwargs)
|
||||
self.video_file_id = video_file_id
|
||||
self.title = title
|
||||
with self._unfrozen():
|
||||
self.video_file_id = video_file_id
|
||||
self.title = title
|
||||
|
||||
# Optionals
|
||||
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
|
||||
# Optionals
|
||||
self.description = description
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# 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, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -47,7 +47,10 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
|
@ -64,7 +67,12 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
|
@ -91,18 +99,19 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
|
|||
reply_markup: InlineKeyboardMarkup = None,
|
||||
input_message_content: "InputMessageContent" = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.VOICE, id, api_kwargs=api_kwargs)
|
||||
self.voice_file_id = voice_file_id
|
||||
self.title = title
|
||||
with self._unfrozen():
|
||||
self.voice_file_id = voice_file_id
|
||||
self.title = title
|
||||
|
||||
# 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
|
||||
# Optionals
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
|
|
|
@ -101,14 +101,15 @@ class InlineQueryResultContact(InlineQueryResult):
|
|||
):
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.CONTACT, id, api_kwargs=api_kwargs)
|
||||
self.phone_number = phone_number
|
||||
self.first_name = first_name
|
||||
with self._unfrozen():
|
||||
self.phone_number = phone_number
|
||||
self.first_name = first_name
|
||||
|
||||
# Optionals
|
||||
self.last_name = last_name
|
||||
self.vcard = vcard
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
self.thumb_url = thumb_url
|
||||
self.thumb_width = thumb_width
|
||||
self.thumb_height = thumb_height
|
||||
# Optionals
|
||||
self.last_name = last_name
|
||||
self.vcard = vcard
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
self.thumb_url = thumb_url
|
||||
self.thumb_width = thumb_width
|
||||
self.thumb_height = thumb_height
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# 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, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -47,7 +47,11 @@ class InlineQueryResultDocument(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
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".
|
||||
|
@ -70,7 +74,12 @@ class InlineQueryResultDocument(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
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".
|
||||
|
@ -114,23 +123,24 @@ class InlineQueryResultDocument(InlineQueryResult):
|
|||
thumb_width: int = None,
|
||||
thumb_height: int = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.DOCUMENT, id, api_kwargs=api_kwargs)
|
||||
self.document_url = document_url
|
||||
self.title = title
|
||||
self.mime_type = mime_type
|
||||
with self._unfrozen():
|
||||
self.document_url = document_url
|
||||
self.title = title
|
||||
self.mime_type = mime_type
|
||||
|
||||
# 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
|
||||
self.thumb_url = thumb_url
|
||||
self.thumb_width = thumb_width
|
||||
self.thumb_height = thumb_height
|
||||
# Optionals
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.description = description
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
self.thumb_url = thumb_url
|
||||
self.thumb_width = thumb_width
|
||||
self.thumb_height = thumb_height
|
||||
|
|
|
@ -58,7 +58,8 @@ class InlineQueryResultGame(InlineQueryResult):
|
|||
):
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.GAME, id, api_kwargs=api_kwargs)
|
||||
self.id = id
|
||||
self.game_short_name = game_short_name
|
||||
with self._unfrozen():
|
||||
self.id = id
|
||||
self.game_short_name = game_short_name
|
||||
|
||||
self.reply_markup = reply_markup
|
||||
self.reply_markup = reply_markup
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InlineQueryResultGif."""
|
||||
|
||||
from typing import TYPE_CHECKING, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -54,7 +54,11 @@ class InlineQueryResultGif(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
|
@ -77,7 +81,12 @@ class InlineQueryResultGif(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
|
@ -114,24 +123,25 @@ class InlineQueryResultGif(InlineQueryResult):
|
|||
gif_duration: int = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb_mime_type: str = None,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.GIF, id, api_kwargs=api_kwargs)
|
||||
self.gif_url = gif_url
|
||||
self.thumb_url = thumb_url
|
||||
with self._unfrozen():
|
||||
self.gif_url = gif_url
|
||||
self.thumb_url = thumb_url
|
||||
|
||||
# Optionals
|
||||
self.gif_width = gif_width
|
||||
self.gif_height = gif_height
|
||||
self.gif_duration = gif_duration
|
||||
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
|
||||
# Optionals
|
||||
self.gif_width = gif_width
|
||||
self.gif_height = gif_height
|
||||
self.gif_duration = gif_duration
|
||||
self.title = title
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
self.thumb_mime_type = thumb_mime_type
|
||||
|
|
|
@ -127,22 +127,23 @@ class InlineQueryResultLocation(InlineQueryResult):
|
|||
):
|
||||
# Required
|
||||
super().__init__(constants.InlineQueryResultType.LOCATION, id, api_kwargs=api_kwargs)
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.title = title
|
||||
with self._unfrozen():
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.title = title
|
||||
|
||||
# Optionals
|
||||
self.live_period = live_period
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
self.thumb_url = thumb_url
|
||||
self.thumb_width = thumb_width
|
||||
self.thumb_height = thumb_height
|
||||
self.horizontal_accuracy = horizontal_accuracy
|
||||
self.heading = heading
|
||||
self.proximity_alert_radius = (
|
||||
int(proximity_alert_radius) if proximity_alert_radius else None
|
||||
)
|
||||
# Optionals
|
||||
self.live_period = live_period
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
self.thumb_url = thumb_url
|
||||
self.thumb_width = thumb_width
|
||||
self.thumb_height = thumb_height
|
||||
self.horizontal_accuracy = horizontal_accuracy
|
||||
self.heading = heading
|
||||
self.proximity_alert_radius = (
|
||||
int(proximity_alert_radius) if proximity_alert_radius else None
|
||||
)
|
||||
|
||||
HORIZONTAL_ACCURACY: ClassVar[int] = constants.LocationLimit.HORIZONTAL_ACCURACY
|
||||
""":const:`telegram.constants.LocationLimit.HORIZONTAL_ACCURACY`
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# 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, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -54,7 +54,11 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
|
@ -77,7 +81,13 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
|
||||
after entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
|
@ -114,24 +124,25 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
|
|||
mpeg4_duration: int = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
thumb_mime_type: str = None,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.MPEG4GIF, id, api_kwargs=api_kwargs)
|
||||
self.mpeg4_url = mpeg4_url
|
||||
self.thumb_url = thumb_url
|
||||
with self._unfrozen():
|
||||
self.mpeg4_url = mpeg4_url
|
||||
self.thumb_url = thumb_url
|
||||
|
||||
# Optional
|
||||
self.mpeg4_width = mpeg4_width
|
||||
self.mpeg4_height = mpeg4_height
|
||||
self.mpeg4_duration = mpeg4_duration
|
||||
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
|
||||
# Optional
|
||||
self.mpeg4_width = mpeg4_width
|
||||
self.mpeg4_height = mpeg4_height
|
||||
self.mpeg4_duration = mpeg4_duration
|
||||
self.title = title
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
self.thumb_mime_type = thumb_mime_type
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# 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, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -52,7 +52,11 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
|
@ -74,7 +78,12 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
|
@ -109,22 +118,23 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
|||
reply_markup: InlineKeyboardMarkup = None,
|
||||
input_message_content: "InputMessageContent" = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.PHOTO, id, api_kwargs=api_kwargs)
|
||||
self.photo_url = photo_url
|
||||
self.thumb_url = thumb_url
|
||||
with self._unfrozen():
|
||||
self.photo_url = photo_url
|
||||
self.thumb_url = thumb_url
|
||||
|
||||
# Optionals
|
||||
self.photo_width = photo_width
|
||||
self.photo_height = photo_height
|
||||
self.title = title
|
||||
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
|
||||
# Optionals
|
||||
self.photo_width = photo_width
|
||||
self.photo_height = photo_height
|
||||
self.title = title
|
||||
self.description = description
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
|
|
|
@ -124,18 +124,19 @@ class InlineQueryResultVenue(InlineQueryResult):
|
|||
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.VENUE, id, api_kwargs=api_kwargs)
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.title = title
|
||||
self.address = address
|
||||
with self._unfrozen():
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.title = title
|
||||
self.address = address
|
||||
|
||||
# Optional
|
||||
self.foursquare_id = foursquare_id
|
||||
self.foursquare_type = foursquare_type
|
||||
self.google_place_id = google_place_id
|
||||
self.google_place_type = google_place_type
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
self.thumb_url = thumb_url
|
||||
self.thumb_width = thumb_width
|
||||
self.thumb_height = thumb_height
|
||||
# Optional
|
||||
self.foursquare_id = foursquare_id
|
||||
self.foursquare_type = foursquare_type
|
||||
self.google_place_id = google_place_id
|
||||
self.google_place_type = google_place_type
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
self.thumb_url = thumb_url
|
||||
self.thumb_width = thumb_width
|
||||
self.thumb_height = thumb_height
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# 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, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -54,7 +54,11 @@ class InlineQueryResultVideo(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
video_width (:obj:`int`, optional): Video width.
|
||||
video_height (:obj:`int`, optional): Video height.
|
||||
video_duration (:obj:`int`, optional): Video duration in seconds.
|
||||
|
@ -75,18 +79,24 @@ class InlineQueryResultVideo(InlineQueryResult):
|
|||
mime_type (:obj:`str`): Mime type of the content of video url, "text/html" or "video/mp4".
|
||||
thumb_url (:obj:`str`): URL of the thumbnail (JPEG only) for the video.
|
||||
title (:obj:`str`): Title for the result.
|
||||
caption (:obj:`str`, optional): Caption of the video to be sent,
|
||||
caption (:obj:`str`): Optional. Caption of the video to be sent,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
|
||||
entities parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
video_width (:obj:`int`, optional): Video width.
|
||||
video_height (:obj:`int`, optional): Video height.
|
||||
video_duration (:obj:`int`, optional): Video duration in seconds.
|
||||
description (:obj:`str`, optional): Short description of the result.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
|
||||
video_width (:obj:`int`): Optional. Video width.
|
||||
video_height (:obj:`int`): Optional. Video height.
|
||||
video_duration (:obj:`int`): Optional. Video duration in seconds.
|
||||
description (:obj:`str`): Optional. Short description of the result.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message.
|
||||
input_message_content (:class:`telegram.InputMessageContent`, optional): Content of the
|
||||
input_message_content (:class:`telegram.InputMessageContent`): Optional. Content of the
|
||||
message to be sent instead of the video. This field is required if
|
||||
InlineQueryResultVideo is used to send an HTML-page as a result
|
||||
(e.g., a YouTube video).
|
||||
|
@ -124,25 +134,26 @@ class InlineQueryResultVideo(InlineQueryResult):
|
|||
reply_markup: InlineKeyboardMarkup = None,
|
||||
input_message_content: "InputMessageContent" = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.VIDEO, id, api_kwargs=api_kwargs)
|
||||
self.video_url = video_url
|
||||
self.mime_type = mime_type
|
||||
self.thumb_url = thumb_url
|
||||
self.title = title
|
||||
with self._unfrozen():
|
||||
self.video_url = video_url
|
||||
self.mime_type = mime_type
|
||||
self.thumb_url = thumb_url
|
||||
self.title = title
|
||||
|
||||
# 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
|
||||
self.description = description
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
# Optional
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.video_width = video_width
|
||||
self.video_height = video_height
|
||||
self.video_duration = video_duration
|
||||
self.description = description
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# 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, List, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||
from telegram._inline.inlinequeryresult import InlineQueryResult
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
from telegram.constants import InlineQueryResultType
|
||||
|
@ -48,7 +48,11 @@ class InlineQueryResultVoice(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
voice_duration (:obj:`int`, optional): Recording duration in seconds.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`, optional): Inline keyboard attached
|
||||
to the message.
|
||||
|
@ -66,7 +70,12 @@ class InlineQueryResultVoice(InlineQueryResult):
|
|||
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
voice_duration (:obj:`int`): Optional. Recording duration in seconds.
|
||||
reply_markup (:class:`telegram.InlineKeyboardMarkup`): Optional. Inline keyboard attached
|
||||
to the message.
|
||||
|
@ -96,20 +105,21 @@ class InlineQueryResultVoice(InlineQueryResult):
|
|||
reply_markup: InlineKeyboardMarkup = None,
|
||||
input_message_content: "InputMessageContent" = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
caption_entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
|
||||
# Required
|
||||
super().__init__(InlineQueryResultType.VOICE, id, api_kwargs=api_kwargs)
|
||||
self.voice_url = voice_url
|
||||
self.title = title
|
||||
with self._unfrozen():
|
||||
self.voice_url = voice_url
|
||||
self.title = title
|
||||
|
||||
# Optional
|
||||
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
|
||||
# Optional
|
||||
self.voice_duration = voice_duration
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.reply_markup = reply_markup
|
||||
self.input_message_content = input_message_content
|
||||
|
|
|
@ -65,3 +65,5 @@ class InputContactMessageContent(InputMessageContent):
|
|||
self.vcard = vcard
|
||||
|
||||
self._id_attrs = (self.phone_number,)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains a class that represents a Telegram InputInvoiceMessageContent."""
|
||||
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
from typing import TYPE_CHECKING, Optional, Sequence
|
||||
|
||||
from telegram._inline.inputmessagecontent import InputMessageContent
|
||||
from telegram._payment.labeledprice import LabeledPrice
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -52,20 +52,30 @@ class InputInvoiceMessageContent(InputMessageContent):
|
|||
`@Botfather <https://t.me/Botfather>`_.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code, see more on
|
||||
`currencies <https://core.telegram.org/bots/payments#supported-currencies>`_
|
||||
prices (List[:class:`telegram.LabeledPrice`]): Price breakdown, a list of
|
||||
prices (Sequence[:class:`telegram.LabeledPrice`]): Price breakdown, a list of
|
||||
components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus,
|
||||
etc.)
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
max_tip_amount (:obj:`int`, optional): The maximum accepted amount for tips in the
|
||||
*smallest* units of the currency (integer, **not** float/double). For example, for a
|
||||
maximum tip of US$ 1.45 pass ``max_tip_amount = 145``. See the ``exp`` parameter in
|
||||
`currencies.json <https://core.telegram.org/bots/payments/currencies.json>`_, it
|
||||
shows the number of digits past the decimal point for each currency (2 for the majority
|
||||
of currencies). Defaults to ``0``.
|
||||
suggested_tip_amounts (List[:obj:`int`], optional): An array of suggested
|
||||
suggested_tip_amounts (Sequence[:obj:`int`], optional): An array of suggested
|
||||
amounts of tip in the *smallest* units of the currency (integer, **not** float/double).
|
||||
At most 4 suggested tip amounts can be specified. The suggested tip amounts must be
|
||||
positive, passed in a strictly increased order and must not exceed
|
||||
:attr:`max_tip_amount`.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
|
||||
provider_data (:obj:`str`, optional): An object for data about the invoice,
|
||||
which will be shared with the payment provider. A detailed description of the required
|
||||
fields should be provided by the payment provider.
|
||||
|
@ -104,12 +114,20 @@ class InputInvoiceMessageContent(InputMessageContent):
|
|||
`@Botfather <https://t.me/Botfather>`_.
|
||||
currency (:obj:`str`): Three-letter ISO 4217 currency code, see more on
|
||||
`currencies <https://core.telegram.org/bots/payments#supported-currencies>`_
|
||||
prices (List[:class:`telegram.LabeledPrice`]): Price breakdown, a list of
|
||||
prices (Tuple[:class:`telegram.LabeledPrice`]): Price breakdown, a list of
|
||||
components.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
max_tip_amount (:obj:`int`): Optional. The maximum accepted amount for tips in the smallest
|
||||
units of the currency (integer, not float/double).
|
||||
suggested_tip_amounts (List[:obj:`int`]): Optional. An array of suggested
|
||||
suggested_tip_amounts (Tuple[:obj:`int`]): Optional. An array of suggested
|
||||
amounts of tip in the smallest units of the currency (integer, not float/double).
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
provider_data (:obj:`str`): Optional. An object for data about the invoice,
|
||||
which will be shared with the payment provider.
|
||||
photo_url (:obj:`str`): Optional. URL of the product photo for the invoice.
|
||||
|
@ -163,9 +181,9 @@ class InputInvoiceMessageContent(InputMessageContent):
|
|||
payload: str,
|
||||
provider_token: str,
|
||||
currency: str,
|
||||
prices: List[LabeledPrice],
|
||||
prices: Sequence[LabeledPrice],
|
||||
max_tip_amount: int = None,
|
||||
suggested_tip_amounts: List[int] = None,
|
||||
suggested_tip_amounts: Sequence[int] = None,
|
||||
provider_data: str = None,
|
||||
photo_url: str = None,
|
||||
photo_size: int = None,
|
||||
|
@ -188,10 +206,10 @@ class InputInvoiceMessageContent(InputMessageContent):
|
|||
self.payload = payload
|
||||
self.provider_token = provider_token
|
||||
self.currency = currency
|
||||
self.prices = prices
|
||||
self.prices = parse_sequence_arg(prices)
|
||||
# Optionals
|
||||
self.max_tip_amount = max_tip_amount
|
||||
self.suggested_tip_amounts = suggested_tip_amounts
|
||||
self.suggested_tip_amounts = parse_sequence_arg(suggested_tip_amounts)
|
||||
self.provider_data = provider_data
|
||||
self.photo_url = photo_url
|
||||
self.photo_size = photo_size
|
||||
|
@ -214,19 +232,7 @@ class InputInvoiceMessageContent(InputMessageContent):
|
|||
self.prices,
|
||||
)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
# we override this as self.prices is a list and not hashable
|
||||
prices = tuple(self.prices)
|
||||
return hash(
|
||||
(
|
||||
self.title,
|
||||
self.description,
|
||||
self.payload,
|
||||
self.provider_token,
|
||||
self.currency,
|
||||
prices,
|
||||
)
|
||||
)
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
|
|
|
@ -97,6 +97,8 @@ class InputLocationMessageContent(InputMessageContent):
|
|||
|
||||
self._id_attrs = (self.latitude, self.longitude)
|
||||
|
||||
self._freeze()
|
||||
|
||||
HORIZONTAL_ACCURACY: ClassVar[int] = constants.LocationLimit.HORIZONTAL_ACCURACY
|
||||
""":const:`telegram.constants.LocationLimit.HORIZONTAL_ACCURACY`
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains the classes that represent Telegram InputTextMessageContent."""
|
||||
|
||||
from typing import List, Tuple, Union
|
||||
from typing import Sequence
|
||||
|
||||
from telegram._inline.inputmessagecontent import InputMessageContent
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
from telegram._utils.types import JSONDict, ODVInput
|
||||
|
||||
|
@ -42,7 +42,11 @@ class InputTextMessageContent(InputMessageContent):
|
|||
:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`, optional): |parse_mode|
|
||||
entities (List[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
disable_web_page_preview (:obj:`bool`, optional): Disables link previews for links in the
|
||||
sent message.
|
||||
|
||||
|
@ -51,7 +55,12 @@ class InputTextMessageContent(InputMessageContent):
|
|||
1-:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters after entities
|
||||
parsing.
|
||||
parse_mode (:obj:`str`): Optional. |parse_mode|
|
||||
entities (List[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
disable_web_page_preview (:obj:`bool`): Optional. Disables link previews for links in the
|
||||
sent message.
|
||||
|
||||
|
@ -64,7 +73,7 @@ class InputTextMessageContent(InputMessageContent):
|
|||
message_text: str,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
disable_web_page_preview: ODVInput[bool] = DEFAULT_NONE,
|
||||
entities: Union[Tuple[MessageEntity, ...], List[MessageEntity]] = None,
|
||||
entities: Sequence[MessageEntity] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
|
@ -73,7 +82,9 @@ class InputTextMessageContent(InputMessageContent):
|
|||
self.message_text = message_text
|
||||
# Optionals
|
||||
self.parse_mode = parse_mode
|
||||
self.entities = entities
|
||||
self.entities = parse_sequence_arg(entities)
|
||||
self.disable_web_page_preview = disable_web_page_preview
|
||||
|
||||
self._id_attrs = (self.message_text,)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -101,3 +101,5 @@ class InputVenueMessageContent(InputMessageContent):
|
|||
self.longitude,
|
||||
self.title,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -107,6 +107,8 @@ class KeyboardButton(TelegramObject):
|
|||
self.web_app,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["KeyboardButton"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -48,3 +48,5 @@ class KeyboardButtonPollType(TelegramObject):
|
|||
self.type = type
|
||||
|
||||
self._id_attrs = (self.type,)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -88,3 +88,5 @@ class LoginUrl(TelegramObject):
|
|||
self.request_write_access = request_write_access
|
||||
|
||||
self._id_attrs = (self.url,)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -62,6 +62,8 @@ class MenuButton(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.type,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["MenuButton"]:
|
||||
"""Converts JSON data to the appropriate :class:`MenuButton` object, i.e. takes
|
||||
|
@ -114,6 +116,7 @@ class MenuButtonCommands(MenuButton):
|
|||
|
||||
def __init__(self, *, api_kwargs: JSONDict = None):
|
||||
super().__init__(type=constants.MenuButtonType.COMMANDS, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class MenuButtonWebApp(MenuButton):
|
||||
|
@ -144,10 +147,11 @@ class MenuButtonWebApp(MenuButton):
|
|||
|
||||
def __init__(self, text: str, web_app: WebAppInfo, *, api_kwargs: JSONDict = None):
|
||||
super().__init__(type=constants.MenuButtonType.WEB_APP, api_kwargs=api_kwargs)
|
||||
self.text = text
|
||||
self.web_app = web_app
|
||||
with self._unfrozen():
|
||||
self.text = text
|
||||
self.web_app = web_app
|
||||
|
||||
self._id_attrs = (self.type, self.text, self.web_app)
|
||||
self._id_attrs = (self.type, self.text, self.web_app)
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["MenuButtonWebApp"]:
|
||||
|
@ -174,3 +178,4 @@ class MenuButtonDefault(MenuButton):
|
|||
|
||||
def __init__(self, *, api_kwargs: JSONDict = None):
|
||||
super().__init__(type=constants.MenuButtonType.DEFAULT, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
import datetime
|
||||
import sys
|
||||
from html import escape
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Sequence, Tuple, Union
|
||||
|
||||
from telegram._chat import Chat
|
||||
from telegram._dice import Dice
|
||||
|
@ -48,6 +48,7 @@ from telegram._poll import Poll
|
|||
from telegram._proximityalerttriggered import ProximityAlertTriggered
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._user import User
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.datetime import from_timestamp
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE, DefaultValue
|
||||
from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup
|
||||
|
@ -140,15 +141,23 @@ class Message(TelegramObject):
|
|||
message belongs to.
|
||||
text (:obj:`str`, optional): For text messages, the actual UTF-8 text of the message,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters.
|
||||
entities (List[:class:`telegram.MessageEntity`], optional): For text messages, special
|
||||
entities (Sequence[:class:`telegram.MessageEntity`], optional): For text messages, special
|
||||
entities like usernames, URLs, bot commands, etc. that appear in the text. See
|
||||
:attr:`parse_entity` and :attr:`parse_entities` methods for how to use properly.
|
||||
This list is empty if the message does not contain entities.
|
||||
caption_entities (List[:class:`telegram.MessageEntity`], optional): For messages with a
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): For messages with a
|
||||
Caption. Special entities like usernames, URLs, bot commands, etc. that appear in the
|
||||
caption. See :attr:`Message.parse_caption_entity` and :attr:`parse_caption_entities`
|
||||
methods for how to use properly. This list is empty if the message does not contain
|
||||
caption entities.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
audio (:class:`telegram.Audio`, optional): Message is an audio file, information
|
||||
about the file.
|
||||
document (:class:`telegram.Document`, optional): Message is a general file, information
|
||||
|
@ -157,8 +166,12 @@ class Message(TelegramObject):
|
|||
about the animation. For backward compatibility, when this field is set, the document
|
||||
field will also be set.
|
||||
game (:class:`telegram.Game`, optional): Message is a game, information about the game.
|
||||
photo (List[:class:`telegram.PhotoSize`], optional): Message is a photo, available sizes
|
||||
of the photo. This list is empty if the message does not contain a photo.
|
||||
photo (Sequence[:class:`telegram.PhotoSize`], optional): Message is a photo, available
|
||||
sizes of the photo. This list is empty if the message does not contain a photo.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
sticker (:class:`telegram.Sticker`, optional): Message is a sticker, information
|
||||
about the sticker.
|
||||
video (:class:`telegram.Video`, optional): Message is a video, information about the
|
||||
|
@ -167,9 +180,13 @@ class Message(TelegramObject):
|
|||
the file.
|
||||
video_note (:class:`telegram.VideoNote`, optional): Message is a video note, information
|
||||
about the video message.
|
||||
new_chat_members (List[:class:`telegram.User`], optional): New members that were added to
|
||||
the group or supergroup and information about them (the bot itself may be one of these
|
||||
members). This list is empty if the message does not contain new chat members.
|
||||
new_chat_members (Sequence[:class:`telegram.User`], optional): New members that were added
|
||||
to the group or supergroup and information about them (the bot itself may be one of
|
||||
these members). This list is empty if the message does not contain new chat members.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
caption (:obj:`str`, optional): Caption for the animation, audio, document, photo, video
|
||||
or voice, 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters.
|
||||
contact (:class:`telegram.Contact`, optional): Message is a shared contact, information
|
||||
|
@ -182,8 +199,12 @@ class Message(TelegramObject):
|
|||
left_chat_member (:class:`telegram.User`, optional): A member was removed from the group,
|
||||
information about them (this member may be the bot itself).
|
||||
new_chat_title (:obj:`str`, optional): A chat title was changed to this value.
|
||||
new_chat_photo (List[:class:`telegram.PhotoSize`], optional): A chat photo was changed to
|
||||
this value. This list is empty if the message does not contain a new chat photo.
|
||||
new_chat_photo (Sequence[:class:`telegram.PhotoSize`], optional): A chat photo was changed
|
||||
to this value. This list is empty if the message does not contain a new chat photo.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
delete_chat_photo (:obj:`bool`, optional): Service message: The chat photo was deleted.
|
||||
group_chat_created (:obj:`bool`, optional): Service message: The group has been created.
|
||||
supergroup_chat_created (:obj:`bool`, optional): Service message: The supergroup has been
|
||||
|
@ -309,15 +330,23 @@ class Message(TelegramObject):
|
|||
message belongs to.
|
||||
text (:obj:`str`): Optional. For text messages, the actual UTF-8 text of the message,
|
||||
0-:tg-const:`telegram.constants.MessageLimit.MAX_TEXT_LENGTH` characters.
|
||||
entities (List[:class:`telegram.MessageEntity`]): Optional. For text messages, special
|
||||
entities (Tuple[:class:`telegram.MessageEntity`]): Optional. For text messages, special
|
||||
entities like usernames, URLs, bot commands, etc. that appear in the text. See
|
||||
:attr:`parse_entity` and :attr:`parse_entities` methods for how to use properly.
|
||||
This list is empty if the message does not contain entities.
|
||||
caption_entities (List[:class:`telegram.MessageEntity`]): Optional. For messages with a
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. For messages with a
|
||||
Caption. Special entities like usernames, URLs, bot commands, etc. that appear in the
|
||||
caption. See :attr:`Message.parse_caption_entity` and :attr:`parse_caption_entities`
|
||||
methods for how to use properly. This list is empty if the message does not contain
|
||||
caption entities.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
audio (:class:`telegram.Audio`): Optional. Message is an audio file, information
|
||||
about the file.
|
||||
document (:class:`telegram.Document`): Optional. Message is a general file, information
|
||||
|
@ -326,8 +355,12 @@ class Message(TelegramObject):
|
|||
about the animation. For backward compatibility, when this field is set, the document
|
||||
field will also be set.
|
||||
game (:class:`telegram.Game`): Optional. Message is a game, information about the game.
|
||||
photo (List[:class:`telegram.PhotoSize`]): Optional. Message is a photo, available sizes
|
||||
of the photo. This list is empty if the message does not contain a photo.
|
||||
photo (Tuple[:class:`telegram.PhotoSize`]): Optional. Message is a photo, available
|
||||
sizes of the photo. This list is empty if the message does not contain a photo.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
sticker (:class:`telegram.Sticker`): Optional. Message is a sticker, information
|
||||
about the sticker.
|
||||
video (:class:`telegram.Video`): Optional. Message is a video, information about the
|
||||
|
@ -336,9 +369,13 @@ class Message(TelegramObject):
|
|||
the file.
|
||||
video_note (:class:`telegram.VideoNote`): Optional. Message is a video note, information
|
||||
about the video message.
|
||||
new_chat_members (List[:class:`telegram.User`]): Optional. New members that were added to
|
||||
the group or supergroup and information about them (the bot itself may be one of these
|
||||
members). This list is empty if the message does not contain new chat members.
|
||||
new_chat_members (Tuple[:class:`telegram.User`]): Optional. New members that were added
|
||||
to the group or supergroup and information about them (the bot itself may be one of
|
||||
these members). This list is empty if the message does not contain new chat members.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
caption (:obj:`str`): Optional. Caption for the animation, audio, document, photo, video
|
||||
or voice, 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters.
|
||||
contact (:class:`telegram.Contact`): Optional. Message is a shared contact, information
|
||||
|
@ -351,8 +388,12 @@ class Message(TelegramObject):
|
|||
left_chat_member (:class:`telegram.User`): Optional. A member was removed from the group,
|
||||
information about them (this member may be the bot itself).
|
||||
new_chat_title (:obj:`str`): Optional. A chat title was changed to this value.
|
||||
new_chat_photo (List[:class:`telegram.PhotoSize`]): A chat photo was changed to
|
||||
new_chat_photo (Tuple[:class:`telegram.PhotoSize`]): A chat photo was changed to
|
||||
this value. This list is empty if the message does not contain a new chat photo.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
delete_chat_photo (:obj:`bool`): Optional. Service message: The chat photo was deleted.
|
||||
group_chat_created (:obj:`bool`): Optional. Service message: The group has been created.
|
||||
supergroup_chat_created (:obj:`bool`): Optional. Service message: The supergroup has been
|
||||
|
@ -528,24 +569,24 @@ class Message(TelegramObject):
|
|||
reply_to_message: "Message" = None,
|
||||
edit_date: datetime.datetime = None,
|
||||
text: str = None,
|
||||
entities: List["MessageEntity"] = None,
|
||||
caption_entities: List["MessageEntity"] = None,
|
||||
entities: Sequence["MessageEntity"] = None,
|
||||
caption_entities: Sequence["MessageEntity"] = None,
|
||||
audio: Audio = None,
|
||||
document: Document = None,
|
||||
game: Game = None,
|
||||
photo: List[PhotoSize] = None,
|
||||
photo: Sequence[PhotoSize] = None,
|
||||
sticker: Sticker = None,
|
||||
video: Video = None,
|
||||
voice: Voice = None,
|
||||
video_note: VideoNote = None,
|
||||
new_chat_members: List[User] = None,
|
||||
new_chat_members: Sequence[User] = None,
|
||||
caption: str = None,
|
||||
contact: Contact = None,
|
||||
location: Location = None,
|
||||
venue: Venue = None,
|
||||
left_chat_member: User = None,
|
||||
new_chat_title: str = None,
|
||||
new_chat_photo: List[PhotoSize] = None,
|
||||
new_chat_photo: Sequence[PhotoSize] = None,
|
||||
delete_chat_photo: bool = None,
|
||||
group_chat_created: bool = None,
|
||||
supergroup_chat_created: bool = None,
|
||||
|
@ -601,12 +642,12 @@ class Message(TelegramObject):
|
|||
self.edit_date = edit_date
|
||||
self.has_protected_content = has_protected_content
|
||||
self.text = text
|
||||
self.entities = entities or []
|
||||
self.caption_entities = caption_entities or []
|
||||
self.entities = parse_sequence_arg(entities)
|
||||
self.caption_entities = parse_sequence_arg(caption_entities)
|
||||
self.audio = audio
|
||||
self.game = game
|
||||
self.document = document
|
||||
self.photo = photo or []
|
||||
self.photo = parse_sequence_arg(photo)
|
||||
self.sticker = sticker
|
||||
self.video = video
|
||||
self.voice = voice
|
||||
|
@ -615,10 +656,10 @@ class Message(TelegramObject):
|
|||
self.contact = contact
|
||||
self.location = location
|
||||
self.venue = venue
|
||||
self.new_chat_members = new_chat_members or []
|
||||
self.new_chat_members = parse_sequence_arg(new_chat_members)
|
||||
self.left_chat_member = left_chat_member
|
||||
self.new_chat_title = new_chat_title
|
||||
self.new_chat_photo = new_chat_photo or []
|
||||
self.new_chat_photo = parse_sequence_arg(new_chat_photo)
|
||||
self.delete_chat_photo = bool(delete_chat_photo)
|
||||
self.group_chat_created = bool(group_chat_created)
|
||||
self.supergroup_chat_created = bool(supergroup_chat_created)
|
||||
|
@ -657,6 +698,8 @@ class Message(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.message_id, self.chat)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@property
|
||||
def chat_id(self) -> int:
|
||||
""":obj:`int`: Shortcut for :attr:`telegram.Chat.id` for :attr:`chat`."""
|
||||
|
@ -1095,7 +1138,7 @@ class Message(TelegramObject):
|
|||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
|
||||
) -> List["Message"]:
|
||||
) -> Tuple["Message", ...]:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.send_media_group(update.effective_message.chat_id, *args, **kwargs)
|
||||
|
@ -1109,7 +1152,7 @@ class Message(TelegramObject):
|
|||
chats.
|
||||
|
||||
Returns:
|
||||
List[:class:`telegram.Message`]: An array of the sent Messages.
|
||||
Tuple[:class:`telegram.Message`]: An array of the sent Messages.
|
||||
|
||||
Raises:
|
||||
:class:`telegram.error.TelegramError`
|
||||
|
@ -2596,7 +2639,7 @@ class Message(TelegramObject):
|
|||
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> List["GameHighScore"]:
|
||||
) -> Tuple["GameHighScore", ...]:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.get_game_high_scores(
|
||||
|
@ -2612,7 +2655,7 @@ class Message(TelegramObject):
|
|||
behaviour is undocumented and might be changed by Telegram.
|
||||
|
||||
Returns:
|
||||
List[:class:`telegram.GameHighScore`]
|
||||
Tuple[:class:`telegram.GameHighScore`]
|
||||
"""
|
||||
return await self.get_bot().get_game_high_scores(
|
||||
chat_id=self.chat_id,
|
||||
|
|
|
@ -54,3 +54,5 @@ class MessageAutoDeleteTimerChanged(TelegramObject):
|
|||
self.message_auto_delete_time = message_auto_delete_time
|
||||
|
||||
self._id_attrs = (self.message_auto_delete_time,)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -115,6 +115,8 @@ class MessageEntity(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.type, self.offset, self.length)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["MessageEntity"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -42,3 +42,5 @@ class MessageId(TelegramObject):
|
|||
self.message_id = message_id
|
||||
|
||||
self._id_attrs = (self.message_id,)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
# pylint: disable=missing-module-docstring, redefined-builtin
|
||||
import json
|
||||
from base64 import b64decode
|
||||
from typing import TYPE_CHECKING, List, Optional, no_type_check
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, no_type_check
|
||||
|
||||
try:
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
|
@ -38,6 +38,7 @@ except ImportError:
|
|||
CRYPTO_INSTALLED = False
|
||||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
from telegram.error import PassportDecryptionError
|
||||
|
||||
|
@ -155,6 +156,8 @@ class EncryptedCredentials(TelegramObject):
|
|||
self._decrypted_secret: Optional[str] = None
|
||||
self._decrypted_data: Optional["Credentials"] = None
|
||||
|
||||
self._freeze()
|
||||
|
||||
@property
|
||||
def decrypted_secret(self) -> str:
|
||||
"""
|
||||
|
@ -226,6 +229,8 @@ class Credentials(TelegramObject):
|
|||
self.secure_data = secure_data
|
||||
self.nonce = nonce
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["Credentials"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
@ -312,6 +317,8 @@ class SecureData(TelegramObject):
|
|||
self.passport = passport
|
||||
self.personal_details = personal_details
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["SecureData"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
@ -356,14 +363,23 @@ class SecureValue(TelegramObject):
|
|||
selfie (:class:`telegram.FileCredentials`): Optional. Credentials for encrypted selfie
|
||||
of the user with a document. Can be available for "passport", "driver_license",
|
||||
"identity_card" and "internal_passport".
|
||||
translation (List[:class:`telegram.FileCredentials`]): Optional. Credentials for an
|
||||
translation (Tuple[:class:`telegram.FileCredentials`]): Optional. Credentials for an
|
||||
encrypted translation of the document. Available for "passport", "driver_license",
|
||||
"identity_card", "internal_passport", "utility_bill", "bank_statement",
|
||||
"rental_agreement", "passport_registration" and "temporary_registration".
|
||||
files (List[:class:`telegram.FileCredentials`]): Optional. Credentials for encrypted
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
files (Tuple[:class:`telegram.FileCredentials`]): Optional. Credentials for encrypted
|
||||
files. Available for "utility_bill", "bank_statement", "rental_agreement",
|
||||
"passport_registration" and "temporary_registration" types.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("data", "front_side", "reverse_side", "selfie", "files", "translation")
|
||||
|
@ -374,8 +390,8 @@ class SecureValue(TelegramObject):
|
|||
front_side: "FileCredentials" = None,
|
||||
reverse_side: "FileCredentials" = None,
|
||||
selfie: "FileCredentials" = None,
|
||||
files: List["FileCredentials"] = None,
|
||||
translation: List["FileCredentials"] = None,
|
||||
files: Sequence["FileCredentials"] = None,
|
||||
translation: Sequence["FileCredentials"] = None,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
|
@ -384,8 +400,10 @@ class SecureValue(TelegramObject):
|
|||
self.front_side = front_side
|
||||
self.reverse_side = reverse_side
|
||||
self.selfie = selfie
|
||||
self.files = files
|
||||
self.translation = translation
|
||||
self.files = parse_sequence_arg(files)
|
||||
self.translation = parse_sequence_arg(translation)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["SecureValue"]:
|
||||
|
@ -414,12 +432,13 @@ class _CredentialsBase(TelegramObject):
|
|||
self, hash: str, secret: str, *, api_kwargs: JSONDict = None # skipcq: PYL-W0622
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.hash = hash
|
||||
self.secret = secret
|
||||
with self._unfrozen():
|
||||
self.hash = hash
|
||||
self.secret = secret
|
||||
|
||||
# Aliases just to be sure
|
||||
self.file_hash = self.hash
|
||||
self.data_hash = self.hash
|
||||
# Aliases just to be sure
|
||||
self.file_hash = self.hash
|
||||
self.data_hash = self.hash
|
||||
|
||||
|
||||
class DataCredentials(_CredentialsBase):
|
||||
|
@ -440,6 +459,7 @@ class DataCredentials(_CredentialsBase):
|
|||
|
||||
def __init__(self, data_hash: str, secret: str, *, api_kwargs: JSONDict = None):
|
||||
super().__init__(hash=data_hash, secret=secret, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
||||
|
||||
class FileCredentials(_CredentialsBase):
|
||||
|
@ -460,3 +480,4 @@ class FileCredentials(_CredentialsBase):
|
|||
|
||||
def __init__(self, file_hash: str, secret: str, *, api_kwargs: JSONDict = None):
|
||||
super().__init__(hash=file_hash, secret=secret, api_kwargs=api_kwargs)
|
||||
self._freeze()
|
||||
|
|
|
@ -84,6 +84,8 @@ class PersonalDetails(TelegramObject):
|
|||
self.last_name_native = last_name_native
|
||||
self.middle_name_native = middle_name_native
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class ResidentialAddress(TelegramObject):
|
||||
"""
|
||||
|
@ -127,6 +129,8 @@ class ResidentialAddress(TelegramObject):
|
|||
self.country_code = country_code
|
||||
self.post_code = post_code
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class IdDocumentData(TelegramObject):
|
||||
"""
|
||||
|
@ -149,3 +153,5 @@ class IdDocumentData(TelegramObject):
|
|||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.document_no = document_no
|
||||
self.expiry_date = expiry_date
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -18,12 +18,13 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram EncryptedPassportElement."""
|
||||
from base64 import b64decode
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
from typing import TYPE_CHECKING, Optional, Sequence
|
||||
|
||||
from telegram._passport.credentials import decrypt_json
|
||||
from telegram._passport.data import IdDocumentData, PersonalDetails, ResidentialAddress
|
||||
from telegram._passport.passportfile import PassportFile
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -58,9 +59,14 @@ class EncryptedPassportElement(TelegramObject):
|
|||
"phone_number" type.
|
||||
email (:obj:`str`, optional): User's verified email address, available only for "email"
|
||||
type.
|
||||
files (List[:class:`telegram.PassportFile`], optional): Array of encrypted/decrypted files
|
||||
files (Sequence[:class:`telegram.PassportFile`], optional): Array of encrypted/decrypted
|
||||
files
|
||||
with documents provided by the user, available for "utility_bill", "bank_statement",
|
||||
"rental_agreement", "passport_registration" and "temporary_registration" types.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
front_side (:class:`telegram.PassportFile`, optional): Encrypted/decrypted file with the
|
||||
front side of the document, provided by the user. Available for "passport",
|
||||
"driver_license", "identity_card" and "internal_passport".
|
||||
|
@ -70,12 +76,16 @@ class EncryptedPassportElement(TelegramObject):
|
|||
selfie (:class:`telegram.PassportFile`, optional): Encrypted/decrypted file with the
|
||||
selfie of the user holding a document, provided by the user; available for "passport",
|
||||
"driver_license", "identity_card" and "internal_passport".
|
||||
translation (List[:class:`telegram.PassportFile`], optional): Array of encrypted/decrypted
|
||||
translation (Sequence[:class:`telegram.PassportFile`], optional): Array of
|
||||
encrypted/decrypted
|
||||
files with translated versions of documents provided by the user. Available if
|
||||
requested for "passport", "driver_license", "identity_card", "internal_passport",
|
||||
"utility_bill", "bank_statement", "rental_agreement", "passport_registration" and
|
||||
"temporary_registration" types.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
Attributes:
|
||||
type (:obj:`str`): Element type. One of "personal_details", "passport", "driver_license",
|
||||
"identity_card", "internal_passport", "address", "utility_bill", "bank_statement",
|
||||
|
@ -91,9 +101,16 @@ class EncryptedPassportElement(TelegramObject):
|
|||
"phone_number" type.
|
||||
email (:obj:`str`): Optional. User's verified email address, available only for "email"
|
||||
type.
|
||||
files (List[:class:`telegram.PassportFile`]): Optional. Array of encrypted/decrypted files
|
||||
files (Tuple[:class:`telegram.PassportFile`]): Optional. Array of encrypted/decrypted
|
||||
files
|
||||
with documents provided by the user, available for "utility_bill", "bank_statement",
|
||||
"rental_agreement", "passport_registration" and "temporary_registration" types.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
|
||||
front_side (:class:`telegram.PassportFile`): Optional. Encrypted/decrypted file with the
|
||||
front side of the document, provided by the user. Available for "passport",
|
||||
"driver_license", "identity_card" and "internal_passport".
|
||||
|
@ -103,12 +120,18 @@ class EncryptedPassportElement(TelegramObject):
|
|||
selfie (:class:`telegram.PassportFile`): Optional. Encrypted/decrypted file with the
|
||||
selfie of the user holding a document, provided by the user; available for "passport",
|
||||
"driver_license", "identity_card" and "internal_passport".
|
||||
translation (List[:class:`telegram.PassportFile`]): Optional. Array of encrypted/decrypted
|
||||
translation (Tuple[:class:`telegram.PassportFile`]): Optional. Array of
|
||||
encrypted/decrypted
|
||||
files with translated versions of documents provided by the user. Available if
|
||||
requested for "passport", "driver_license", "identity_card", "internal_passport",
|
||||
"utility_bill", "bank_statement", "rental_agreement", "passport_registration" and
|
||||
"temporary_registration" types.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* |tupleclassattrs|
|
||||
* |alwaystuple|
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = (
|
||||
|
@ -131,11 +154,11 @@ class EncryptedPassportElement(TelegramObject):
|
|||
data: PersonalDetails = None,
|
||||
phone_number: str = None,
|
||||
email: str = None,
|
||||
files: List[PassportFile] = None,
|
||||
files: Sequence[PassportFile] = None,
|
||||
front_side: PassportFile = None,
|
||||
reverse_side: PassportFile = None,
|
||||
selfie: PassportFile = None,
|
||||
translation: List[PassportFile] = None,
|
||||
translation: Sequence[PassportFile] = None,
|
||||
credentials: "Credentials" = None, # pylint: disable=unused-argument
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
|
@ -148,11 +171,11 @@ class EncryptedPassportElement(TelegramObject):
|
|||
self.data = data
|
||||
self.phone_number = phone_number
|
||||
self.email = email
|
||||
self.files = files
|
||||
self.files = parse_sequence_arg(files)
|
||||
self.front_side = front_side
|
||||
self.reverse_side = reverse_side
|
||||
self.selfie = selfie
|
||||
self.translation = translation
|
||||
self.translation = parse_sequence_arg(translation)
|
||||
self.hash = hash
|
||||
|
||||
self._id_attrs = (
|
||||
|
@ -166,6 +189,8 @@ class EncryptedPassportElement(TelegramObject):
|
|||
self.selfie,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["EncryptedPassportElement"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""Contains information about Telegram Passport data shared with the bot by the user."""
|
||||
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
from typing import TYPE_CHECKING, Optional, Sequence, Tuple
|
||||
|
||||
from telegram._passport.credentials import EncryptedCredentials
|
||||
from telegram._passport.encryptedpassportelement import EncryptedPassportElement
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -39,13 +39,23 @@ class PassportData(TelegramObject):
|
|||
attribute :attr:`telegram.Credentials.nonce`.
|
||||
|
||||
Args:
|
||||
data (List[:class:`telegram.EncryptedPassportElement`]): Array with encrypted information
|
||||
about documents and other Telegram Passport elements that was shared with the bot.
|
||||
data (Sequence[:class:`telegram.EncryptedPassportElement`]): Array with encrypted
|
||||
information about documents and other Telegram Passport elements that was shared with
|
||||
the bot.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
credentials (:class:`telegram.EncryptedCredentials`)): Encrypted credentials.
|
||||
|
||||
Attributes:
|
||||
data (List[:class:`telegram.EncryptedPassportElement`]): Array with encrypted information
|
||||
about documents and other Telegram Passport elements that was shared with the bot.
|
||||
data (Tuple[:class:`telegram.EncryptedPassportElement`]): Array with encrypted
|
||||
information about documents and other Telegram Passport elements that was shared with
|
||||
the bot.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
credentials (:class:`telegram.EncryptedCredentials`): Encrypted credentials.
|
||||
|
||||
|
||||
|
@ -55,19 +65,21 @@ class PassportData(TelegramObject):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
data: List[EncryptedPassportElement],
|
||||
data: Sequence[EncryptedPassportElement],
|
||||
credentials: EncryptedCredentials,
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
|
||||
self.data = data
|
||||
self.data = parse_sequence_arg(data)
|
||||
self.credentials = credentials
|
||||
|
||||
self._decrypted_data: Optional[List[EncryptedPassportElement]] = None
|
||||
self._decrypted_data: Optional[Tuple[EncryptedPassportElement]] = None
|
||||
self._id_attrs = tuple([x.type for x in data] + [credentials.hash])
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["PassportData"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
@ -82,23 +94,26 @@ class PassportData(TelegramObject):
|
|||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
@property
|
||||
def decrypted_data(self) -> List[EncryptedPassportElement]:
|
||||
def decrypted_data(self) -> Tuple[EncryptedPassportElement, ...]:
|
||||
"""
|
||||
List[:class:`telegram.EncryptedPassportElement`]: Lazily decrypt and return information
|
||||
Tuple[:class:`telegram.EncryptedPassportElement`]: Lazily decrypt and return information
|
||||
about documents and other Telegram Passport elements which were shared with the bot.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
Returns a tuple instead of a list.
|
||||
|
||||
Raises:
|
||||
telegram.error.PassportDecryptionError: Decryption failed. Usually due to bad
|
||||
private/public key but can also suggest malformed/tampered data.
|
||||
"""
|
||||
if self._decrypted_data is None:
|
||||
self._decrypted_data = [
|
||||
EncryptedPassportElement.de_json_decrypted( # type: ignore[misc]
|
||||
self._decrypted_data = tuple( # type: ignore[assignment]
|
||||
EncryptedPassportElement.de_json_decrypted(
|
||||
element.to_dict(), self.get_bot(), self.decrypted_credentials
|
||||
)
|
||||
for element in self.data
|
||||
]
|
||||
return self._decrypted_data
|
||||
)
|
||||
return self._decrypted_data # type: ignore[return-value]
|
||||
|
||||
@property
|
||||
def decrypted_credentials(self) -> "Credentials":
|
||||
|
|
|
@ -54,6 +54,8 @@ class PassportElementError(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.source, self.type)
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class PassportElementErrorDataField(PassportElementError):
|
||||
"""
|
||||
|
@ -95,10 +97,17 @@ class PassportElementErrorDataField(PassportElementError):
|
|||
):
|
||||
# Required
|
||||
super().__init__("data", type, message, api_kwargs=api_kwargs)
|
||||
self.field_name = field_name
|
||||
self.data_hash = data_hash
|
||||
with self._unfrozen():
|
||||
self.field_name = field_name
|
||||
self.data_hash = data_hash
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.field_name, self.data_hash, self.message)
|
||||
self._id_attrs = (
|
||||
self.source,
|
||||
self.type,
|
||||
self.field_name,
|
||||
self.data_hash,
|
||||
self.message,
|
||||
)
|
||||
|
||||
|
||||
class PassportElementErrorFile(PassportElementError):
|
||||
|
@ -131,9 +140,10 @@ class PassportElementErrorFile(PassportElementError):
|
|||
def __init__(self, type: str, file_hash: str, message: str, *, api_kwargs: JSONDict = None):
|
||||
# Required
|
||||
super().__init__("file", type, message, api_kwargs=api_kwargs)
|
||||
self.file_hash = file_hash
|
||||
with self._unfrozen():
|
||||
self.file_hash = file_hash
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
|
||||
|
||||
class PassportElementErrorFiles(PassportElementError):
|
||||
|
@ -166,9 +176,10 @@ class PassportElementErrorFiles(PassportElementError):
|
|||
def __init__(self, type: str, file_hashes: str, message: str, *, api_kwargs: JSONDict = None):
|
||||
# Required
|
||||
super().__init__("files", type, message, api_kwargs=api_kwargs)
|
||||
self.file_hashes = file_hashes
|
||||
with self._unfrozen():
|
||||
self.file_hashes = file_hashes
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.message) + tuple(file_hashes)
|
||||
self._id_attrs = (self.source, self.type, self.message) + tuple(file_hashes)
|
||||
|
||||
|
||||
class PassportElementErrorFrontSide(PassportElementError):
|
||||
|
@ -201,9 +212,10 @@ class PassportElementErrorFrontSide(PassportElementError):
|
|||
def __init__(self, type: str, file_hash: str, message: str, *, api_kwargs: JSONDict = None):
|
||||
# Required
|
||||
super().__init__("front_side", type, message, api_kwargs=api_kwargs)
|
||||
self.file_hash = file_hash
|
||||
with self._unfrozen():
|
||||
self.file_hash = file_hash
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
|
||||
|
||||
class PassportElementErrorReverseSide(PassportElementError):
|
||||
|
@ -236,9 +248,10 @@ class PassportElementErrorReverseSide(PassportElementError):
|
|||
def __init__(self, type: str, file_hash: str, message: str, *, api_kwargs: JSONDict = None):
|
||||
# Required
|
||||
super().__init__("reverse_side", type, message, api_kwargs=api_kwargs)
|
||||
self.file_hash = file_hash
|
||||
with self._unfrozen():
|
||||
self.file_hash = file_hash
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
|
||||
|
||||
class PassportElementErrorSelfie(PassportElementError):
|
||||
|
@ -269,9 +282,10 @@ class PassportElementErrorSelfie(PassportElementError):
|
|||
def __init__(self, type: str, file_hash: str, message: str, *, api_kwargs: JSONDict = None):
|
||||
# Required
|
||||
super().__init__("selfie", type, message, api_kwargs=api_kwargs)
|
||||
self.file_hash = file_hash
|
||||
with self._unfrozen():
|
||||
self.file_hash = file_hash
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
|
||||
|
||||
class PassportElementErrorTranslationFile(PassportElementError):
|
||||
|
@ -306,9 +320,10 @@ class PassportElementErrorTranslationFile(PassportElementError):
|
|||
def __init__(self, type: str, file_hash: str, message: str, *, api_kwargs: JSONDict = None):
|
||||
# Required
|
||||
super().__init__("translation_file", type, message, api_kwargs=api_kwargs)
|
||||
self.file_hash = file_hash
|
||||
with self._unfrozen():
|
||||
self.file_hash = file_hash
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
self._id_attrs = (self.source, self.type, self.file_hash, self.message)
|
||||
|
||||
|
||||
class PassportElementErrorTranslationFiles(PassportElementError):
|
||||
|
@ -343,9 +358,10 @@ class PassportElementErrorTranslationFiles(PassportElementError):
|
|||
def __init__(self, type: str, file_hashes: str, message: str, *, api_kwargs: JSONDict = None):
|
||||
# Required
|
||||
super().__init__("translation_files", type, message, api_kwargs=api_kwargs)
|
||||
self.file_hashes = file_hashes
|
||||
with self._unfrozen():
|
||||
self.file_hashes = file_hashes
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.message) + tuple(file_hashes)
|
||||
self._id_attrs = (self.source, self.type, self.message) + tuple(file_hashes)
|
||||
|
||||
|
||||
class PassportElementErrorUnspecified(PassportElementError):
|
||||
|
@ -374,6 +390,7 @@ class PassportElementErrorUnspecified(PassportElementError):
|
|||
def __init__(self, type: str, element_hash: str, message: str, *, api_kwargs: JSONDict = None):
|
||||
# Required
|
||||
super().__init__("unspecified", type, message, api_kwargs=api_kwargs)
|
||||
self.element_hash = element_hash
|
||||
with self._unfrozen():
|
||||
self.element_hash = element_hash
|
||||
|
||||
self._id_attrs = (self.source, self.type, self.element_hash, self.message)
|
||||
self._id_attrs = (self.source, self.type, self.element_hash, self.message)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Encrypted PassportFile."""
|
||||
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
from typing import TYPE_CHECKING, List, Optional, Tuple
|
||||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||
|
@ -87,6 +87,8 @@ class PassportFile(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.file_unique_id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json_decrypted(
|
||||
cls, data: Optional[JSONDict], bot: "Bot", credentials: "FileCredentials"
|
||||
|
@ -115,26 +117,35 @@ class PassportFile(TelegramObject):
|
|||
@classmethod
|
||||
def de_list_decrypted(
|
||||
cls, data: Optional[List[JSONDict]], bot: "Bot", credentials: List["FileCredentials"]
|
||||
) -> List[Optional["PassportFile"]]:
|
||||
) -> Tuple[Optional["PassportFile"], ...]:
|
||||
"""Variant of :meth:`telegram.TelegramObject.de_list` that also takes into account
|
||||
passport credentials.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* Returns a tuple instead of a list.
|
||||
* Filters out any :obj:`None` values
|
||||
|
||||
Args:
|
||||
data (Dict[:obj:`str`, ...]): The JSON data.
|
||||
data (List[Dict[:obj:`str`, ...]]): The JSON data.
|
||||
bot (:class:`telegram.Bot`): The bot associated with these objects.
|
||||
credentials (:class:`telegram.FileCredentials`): The credentials
|
||||
|
||||
Returns:
|
||||
List[:class:`telegram.PassportFile`]:
|
||||
Tuple[:class:`telegram.PassportFile`]:
|
||||
|
||||
"""
|
||||
if not data:
|
||||
return []
|
||||
return ()
|
||||
|
||||
return [
|
||||
cls.de_json_decrypted(passport_file, bot, credentials[i])
|
||||
for i, passport_file in enumerate(data)
|
||||
]
|
||||
return tuple(
|
||||
obj
|
||||
for obj in (
|
||||
cls.de_json_decrypted(passport_file, bot, credentials[i])
|
||||
for i, passport_file in enumerate(data)
|
||||
)
|
||||
if obj is not None
|
||||
)
|
||||
|
||||
async def get_file(
|
||||
self,
|
||||
|
|
|
@ -87,6 +87,8 @@ class Invoice(TelegramObject):
|
|||
self.total_amount,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
||||
MIN_TITLE_LENGTH: ClassVar[int] = constants.InvoiceLimit.MIN_TITLE_LENGTH
|
||||
""":const:`telegram.constants.InvoiceLimit.MIN_TITLE_LENGTH`
|
||||
|
||||
|
|
|
@ -54,3 +54,5 @@ class LabeledPrice(TelegramObject):
|
|||
self.amount = amount
|
||||
|
||||
self._id_attrs = (self.label, self.amount)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -68,6 +68,8 @@ class OrderInfo(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.name, self.phone_number, self.email, self.shipping_address)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["OrderInfo"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -100,6 +100,8 @@ class PreCheckoutQuery(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["PreCheckoutQuery"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -83,3 +83,5 @@ class ShippingAddress(TelegramObject):
|
|||
self.street_line2,
|
||||
self.post_code,
|
||||
)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram ShippingOption."""
|
||||
|
||||
from typing import TYPE_CHECKING, List
|
||||
from typing import TYPE_CHECKING, Sequence
|
||||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -39,12 +39,18 @@ class ShippingOption(TelegramObject):
|
|||
Args:
|
||||
id (:obj:`str`): Shipping option identifier.
|
||||
title (:obj:`str`): Option title.
|
||||
prices (List[:class:`telegram.LabeledPrice`]): List of price portions.
|
||||
prices (Sequence[:class:`telegram.LabeledPrice`]): List of price portions.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
Attributes:
|
||||
id (:obj:`str`): Shipping option identifier.
|
||||
title (:obj:`str`): Option title.
|
||||
prices (List[:class:`telegram.LabeledPrice`]): List of price portions.
|
||||
prices (Tuple[:class:`telegram.LabeledPrice`]): List of price portions.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
"""
|
||||
|
||||
|
@ -54,7 +60,7 @@ class ShippingOption(TelegramObject):
|
|||
self,
|
||||
id: str, # pylint: disable=redefined-builtin
|
||||
title: str,
|
||||
prices: List["LabeledPrice"],
|
||||
prices: Sequence["LabeledPrice"],
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
|
@ -62,6 +68,8 @@ class ShippingOption(TelegramObject):
|
|||
|
||||
self.id = id # pylint: disable=invalid-name
|
||||
self.title = title
|
||||
self.prices = prices
|
||||
self.prices = parse_sequence_arg(prices)
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -74,6 +74,8 @@ class ShippingQuery(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ShippingQuery"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -95,6 +95,8 @@ class SuccessfulPayment(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.telegram_payment_charge_id, self.provider_payment_charge_id)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["SuccessfulPayment"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -17,16 +17,16 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram Poll."""
|
||||
|
||||
import datetime
|
||||
import sys
|
||||
from typing import TYPE_CHECKING, ClassVar, Dict, List, Optional
|
||||
from typing import TYPE_CHECKING, ClassVar, Dict, List, Optional, Sequence
|
||||
|
||||
from telegram import constants
|
||||
from telegram._messageentity import MessageEntity
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._user import User
|
||||
from telegram._utils import enum
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.datetime import from_timestamp
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
|
@ -64,6 +64,8 @@ class PollOption(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.text, self.voter_count)
|
||||
|
||||
self._freeze()
|
||||
|
||||
MIN_LENGTH: ClassVar[int] = constants.PollLimit.MIN_OPTION_LENGTH
|
||||
""":const:`telegram.constants.PollLimit.MIN_OPTION_LENGTH`
|
||||
|
||||
|
@ -86,28 +88,37 @@ class PollAnswer(TelegramObject):
|
|||
Args:
|
||||
poll_id (:obj:`str`): Unique poll identifier.
|
||||
user (:class:`telegram.User`): The user, who changed the answer to the poll.
|
||||
option_ids (List[:obj:`int`]): 0-based identifiers of answer options, chosen by the user.
|
||||
May be empty if the user retracted their vote.
|
||||
option_ids (Sequence[:obj:`int`]): 0-based identifiers of answer options, chosen by the
|
||||
user. May be empty if the user retracted their vote.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
Attributes:
|
||||
poll_id (:obj:`str`): Unique poll identifier.
|
||||
user (:class:`telegram.User`): The user, who changed the answer to the poll.
|
||||
option_ids (List[:obj:`int`]): Identifiers of answer options, chosen by the user.
|
||||
option_ids (Tuple[:obj:`int`]): Identifiers of answer options, chosen by the user. May be
|
||||
empty if the user retracted their vote.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("option_ids", "user", "poll_id")
|
||||
|
||||
def __init__(
|
||||
self, poll_id: str, user: User, option_ids: List[int], *, api_kwargs: JSONDict = None
|
||||
self, poll_id: str, user: User, option_ids: Sequence[int], *, api_kwargs: JSONDict = None
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.poll_id = poll_id
|
||||
self.user = user
|
||||
self.option_ids = option_ids
|
||||
self.option_ids = parse_sequence_arg(option_ids)
|
||||
|
||||
self._id_attrs = (self.poll_id, self.user, tuple(self.option_ids))
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["PollAnswer"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
@ -135,7 +146,10 @@ class Poll(TelegramObject):
|
|||
id (:obj:`str`): Unique poll identifier.
|
||||
question (:obj:`str`): Poll question, :tg-const:`telegram.Poll.MIN_QUESTION_LENGTH`-
|
||||
:tg-const:`telegram.Poll.MAX_QUESTION_LENGTH` characters.
|
||||
options (List[:class:`PollOption`]): List of poll options.
|
||||
options (Sequence[:class:`PollOption`]): List of poll options.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
is_closed (:obj:`bool`): :obj:`True`, if the poll is closed.
|
||||
is_anonymous (:obj:`bool`): :obj:`True`, if the poll is anonymous.
|
||||
type (:obj:`str`): Poll type, currently can be :attr:`REGULAR` or :attr:`QUIZ`.
|
||||
|
@ -146,12 +160,15 @@ class Poll(TelegramObject):
|
|||
explanation (:obj:`str`, optional): Text that is shown when a user chooses an incorrect
|
||||
answer or taps on the lamp icon in a quiz-style poll,
|
||||
0-:tg-const:`telegram.Poll.MAX_EXPLANATION_LENGTH` characters.
|
||||
explanation_entities (List[:class:`telegram.MessageEntity`], optional): Special entities
|
||||
like usernames, URLs, bot commands, etc. that appear in the :attr:`explanation`.
|
||||
This list is empty if the message does not contain explanation entities.
|
||||
explanation_entities (Sequence[:class:`telegram.MessageEntity`], optional): Special
|
||||
entities like usernames, URLs, bot commands, etc. that appear in the
|
||||
:attr:`explanation`. This list is empty if the message does not contain explanation
|
||||
entities.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
This attribute is now always a (possibly empty) list and never :obj:`None`.
|
||||
|
||||
* This attribute is now always a (possibly empty) list and never :obj:`None`.
|
||||
* |sequenceclassargs|
|
||||
open_period (:obj:`int`, optional): Amount of time in seconds the poll will be active
|
||||
after creation.
|
||||
close_date (:obj:`datetime.datetime`, optional): Point in time (Unix timestamp) when the
|
||||
|
@ -161,7 +178,10 @@ class Poll(TelegramObject):
|
|||
id (:obj:`str`): Unique poll identifier.
|
||||
question (:obj:`str`): Poll question, :tg-const:`telegram.Poll.MIN_QUESTION_LENGTH`-
|
||||
:tg-const:`telegram.Poll.MAX_QUESTION_LENGTH` characters.
|
||||
options (List[:class:`PollOption`]): List of poll options.
|
||||
options (Tuple[:class:`PollOption`]): List of poll options.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
total_voter_count (:obj:`int`): Total number of users that voted in the poll.
|
||||
is_closed (:obj:`bool`): :obj:`True`, if the poll is closed.
|
||||
is_anonymous (:obj:`bool`): :obj:`True`, if the poll is anonymous.
|
||||
|
@ -173,10 +193,13 @@ class Poll(TelegramObject):
|
|||
explanation (:obj:`str`): Optional. Text that is shown when a user chooses an incorrect
|
||||
answer or taps on the lamp icon in a quiz-style poll,
|
||||
0-:tg-const:`telegram.Poll.MAX_EXPLANATION_LENGTH` characters.
|
||||
explanation_entities (List[:class:`telegram.MessageEntity`]): Special entities
|
||||
explanation_entities (Tuple[:class:`telegram.MessageEntity`]): Special entities
|
||||
like usernames, URLs, bot commands, etc. that appear in the :attr:`explanation`.
|
||||
This list is empty if the message does not contain explanation entities.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
This attribute is now always a (possibly empty) list and never :obj:`None`.
|
||||
open_period (:obj:`int`): Optional. Amount of time in seconds the poll will be active
|
||||
|
@ -206,7 +229,7 @@ class Poll(TelegramObject):
|
|||
self,
|
||||
id: str, # pylint: disable=redefined-builtin
|
||||
question: str,
|
||||
options: List[PollOption],
|
||||
options: Sequence[PollOption],
|
||||
total_voter_count: int,
|
||||
is_closed: bool,
|
||||
is_anonymous: bool,
|
||||
|
@ -214,7 +237,7 @@ class Poll(TelegramObject):
|
|||
allows_multiple_answers: bool,
|
||||
correct_option_id: int = None,
|
||||
explanation: str = None,
|
||||
explanation_entities: List[MessageEntity] = None,
|
||||
explanation_entities: Sequence[MessageEntity] = None,
|
||||
open_period: int = None,
|
||||
close_date: datetime.datetime = None,
|
||||
*,
|
||||
|
@ -223,7 +246,7 @@ class Poll(TelegramObject):
|
|||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.id = id # pylint: disable=invalid-name
|
||||
self.question = question
|
||||
self.options = options
|
||||
self.options = parse_sequence_arg(options)
|
||||
self.total_voter_count = total_voter_count
|
||||
self.is_closed = is_closed
|
||||
self.is_anonymous = is_anonymous
|
||||
|
@ -231,12 +254,14 @@ class Poll(TelegramObject):
|
|||
self.allows_multiple_answers = allows_multiple_answers
|
||||
self.correct_option_id = correct_option_id
|
||||
self.explanation = explanation
|
||||
self.explanation_entities = explanation_entities or []
|
||||
self.explanation_entities = parse_sequence_arg(explanation_entities)
|
||||
self.open_period = open_period
|
||||
self.close_date = close_date
|
||||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["Poll"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -59,6 +59,8 @@ class ProximityAlertTriggered(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.traveler, self.watcher, self.distance)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["ProximityAlertTriggered"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -41,8 +41,8 @@ class ReplyKeyboardMarkup(TelegramObject):
|
|||
* :any:`Conversation Bot 2 <examples.conversationbot2>`
|
||||
|
||||
Args:
|
||||
keyboard (List[List[:obj:`str` | :class:`telegram.KeyboardButton`]]): Array of button rows,
|
||||
each represented by an Array of :class:`telegram.KeyboardButton` objects.
|
||||
keyboard (Sequence[Sequence[:obj:`str` | :class:`telegram.KeyboardButton`]]): Array of
|
||||
button rows, each represented by an Array of :class:`telegram.KeyboardButton` objects.
|
||||
resize_keyboard (:obj:`bool`, optional): Requests clients to resize the keyboard vertically
|
||||
for optimal fit (e.g., make the keyboard smaller if there are just two rows of
|
||||
buttons). Defaults to :obj:`False`, in which case the custom keyboard is always of the
|
||||
|
@ -70,7 +70,8 @@ class ReplyKeyboardMarkup(TelegramObject):
|
|||
.. versionadded:: 13.7
|
||||
|
||||
Attributes:
|
||||
keyboard (List[List[:class:`telegram.KeyboardButton` | :obj:`str`]]): Array of button rows.
|
||||
keyboard (Tuple[Tuple[:class:`telegram.KeyboardButton` | :obj:`str`]]): Array of button
|
||||
rows.
|
||||
resize_keyboard (:obj:`bool`): Optional. Requests clients to resize the keyboard.
|
||||
one_time_keyboard (:obj:`bool`): Optional. Requests clients to hide the keyboard as soon as
|
||||
it's been used.
|
||||
|
@ -103,20 +104,15 @@ class ReplyKeyboardMarkup(TelegramObject):
|
|||
super().__init__(api_kwargs=api_kwargs)
|
||||
if not check_keyboard_type(keyboard):
|
||||
raise ValueError(
|
||||
"The parameter `keyboard` should be a list of list of "
|
||||
"The parameter `keyboard` should be a sequence of sequences of "
|
||||
"strings or KeyboardButtons"
|
||||
)
|
||||
|
||||
# Required
|
||||
self.keyboard = []
|
||||
for row in keyboard:
|
||||
button_row = []
|
||||
for button in row:
|
||||
if isinstance(button, KeyboardButton):
|
||||
button_row.append(button) # telegram.KeyboardButton
|
||||
else:
|
||||
button_row.append(KeyboardButton(button)) # str
|
||||
self.keyboard.append(button_row)
|
||||
self.keyboard = tuple(
|
||||
tuple(KeyboardButton(button) if isinstance(button, str) else button for button in row)
|
||||
for row in keyboard
|
||||
)
|
||||
|
||||
# Optionals
|
||||
self.resize_keyboard = resize_keyboard
|
||||
|
@ -126,6 +122,8 @@ class ReplyKeyboardMarkup(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.keyboard,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def from_button(
|
||||
cls,
|
||||
|
@ -282,16 +280,6 @@ class ReplyKeyboardMarkup(TelegramObject):
|
|||
**kwargs, # type: ignore[arg-type]
|
||||
)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(
|
||||
(
|
||||
tuple(tuple(button for button in row) for row in self.keyboard),
|
||||
self.resize_keyboard,
|
||||
self.one_time_keyboard,
|
||||
self.selective,
|
||||
)
|
||||
)
|
||||
|
||||
MIN_INPUT_FIELD_PLACEHOLDER: ClassVar[int] = constants.ReplyLimit.MIN_INPUT_FIELD_PLACEHOLDER
|
||||
""":const:`telegram.constants.ReplyLimit.MIN_INPUT_FIELD_PLACEHOLDER`
|
||||
|
||||
|
|
|
@ -63,3 +63,5 @@ class ReplyKeyboardRemove(TelegramObject):
|
|||
self.remove_keyboard = True
|
||||
# Optionals
|
||||
self.selective = selective
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -49,3 +49,5 @@ class SentWebAppMessage(TelegramObject):
|
|||
self.inline_message_id = inline_message_id
|
||||
|
||||
self._id_attrs = (self.inline_message_id,)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -20,16 +20,20 @@
|
|||
import datetime
|
||||
import inspect
|
||||
import json
|
||||
from collections.abc import Sized
|
||||
from contextlib import contextmanager
|
||||
from copy import deepcopy
|
||||
from itertools import chain
|
||||
from types import MappingProxyType
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Dict,
|
||||
Iterator,
|
||||
List,
|
||||
Mapping,
|
||||
Optional,
|
||||
Set,
|
||||
Sized,
|
||||
Tuple,
|
||||
Type,
|
||||
TypeVar,
|
||||
|
@ -61,6 +65,9 @@ class TelegramObject:
|
|||
* String representations objects of this type was overhauled. See :meth:`__repr__` for
|
||||
details. As this class doesn't implement :meth:`object.__str__`, the default
|
||||
implementation will be used, which is equivalent to :meth:`__repr__`.
|
||||
* Objects of this class (or subclasses) are now immutable. This means that you can't set
|
||||
or delete attributes anymore. Moreover, attributes that were formerly of type
|
||||
:obj:`list` are now of type :obj:`tuple`.
|
||||
|
||||
Arguments:
|
||||
api_kwargs (Dict[:obj:`str`, any], optional): |toapikwargsarg|
|
||||
|
@ -68,13 +75,13 @@ class TelegramObject:
|
|||
.. versionadded:: 20.0
|
||||
|
||||
Attributes:
|
||||
api_kwargs (Dict[:obj:`str`, any]): |toapikwargsattr|
|
||||
api_kwargs (:obj:`types.MappingProxyType` [:obj:`str`, any]): |toapikwargsattr|
|
||||
|
||||
.. versionadded:: 20.0
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("_id_attrs", "_bot", "api_kwargs")
|
||||
__slots__ = ("_id_attrs", "_bot", "_frozen", "api_kwargs")
|
||||
|
||||
# Used to cache the names of the parameters of the __init__ method of the class
|
||||
# Must be a private attribute to avoid name clashes between subclasses
|
||||
|
@ -85,14 +92,34 @@ class TelegramObject:
|
|||
__INIT_PARAMS_CHECK: Optional[Type["TelegramObject"]] = None
|
||||
|
||||
def __init__(self, *, api_kwargs: JSONDict = None) -> None:
|
||||
self._frozen: bool = False
|
||||
self._id_attrs: Tuple[object, ...] = ()
|
||||
self._bot: Optional["Bot"] = None
|
||||
# We don't do anything with api_kwargs here - see docstring of _apply_api_kwargs
|
||||
self.api_kwargs: JSONDict = api_kwargs or {}
|
||||
self.api_kwargs: Mapping[str, Any] = MappingProxyType(api_kwargs or {})
|
||||
|
||||
def _apply_api_kwargs(self) -> None:
|
||||
def _freeze(self) -> None:
|
||||
self._frozen = True
|
||||
|
||||
def _unfreeze(self) -> None:
|
||||
self._frozen = False
|
||||
|
||||
@contextmanager
|
||||
def _unfrozen(self: Tele_co) -> Iterator[Tele_co]:
|
||||
"""Context manager to temporarily unfreeze the object. For internal use only.
|
||||
|
||||
Note:
|
||||
with to._unfrozen() as other_to:
|
||||
assert to is other_to
|
||||
"""
|
||||
self._unfreeze()
|
||||
yield self
|
||||
self._freeze()
|
||||
|
||||
def _apply_api_kwargs(self, api_kwargs: JSONDict) -> None:
|
||||
"""Loops through the api kwargs and for every key that exists as attribute of the
|
||||
object (and is None), it moves the value from `api_kwargs` to the attribute.
|
||||
*Edits `api_kwargs` in place!*
|
||||
|
||||
This method is currently only called in the unpickling process, i.e. not on "normal" init.
|
||||
This is because
|
||||
|
@ -105,9 +132,39 @@ class TelegramObject:
|
|||
then you can pass everything as proper argument.
|
||||
"""
|
||||
# we convert to list to ensure that the list doesn't change length while we loop
|
||||
for key in list(self.api_kwargs.keys()):
|
||||
for key in list(api_kwargs.keys()):
|
||||
if getattr(self, key, True) is None:
|
||||
setattr(self, key, self.api_kwargs.pop(key))
|
||||
setattr(self, key, api_kwargs.pop(key))
|
||||
|
||||
def __setattr__(self, key: str, value: object) -> None:
|
||||
"""Overrides :meth:`object.__setattr__` to prevent the overriding of attributes.
|
||||
|
||||
Raises:
|
||||
:exc:`AttributeError`
|
||||
"""
|
||||
# protected attributes can always be set for convenient internal use
|
||||
if key[0] == "_" or not getattr(self, "_frozen", True):
|
||||
super().__setattr__(key, value)
|
||||
return
|
||||
|
||||
raise AttributeError(
|
||||
f"Attribute `{key}` of class `{self.__class__.__name__}` can't be set!"
|
||||
)
|
||||
|
||||
def __delattr__(self, key: str) -> None:
|
||||
"""Overrides :meth:`object.__delattr__` to prevent the deletion of attributes.
|
||||
|
||||
Raises:
|
||||
:exc:`AttributeError`
|
||||
"""
|
||||
# protected attributes can always be set for convenient internal use
|
||||
if key[0] == "_" or not getattr(self, "_frozen", True):
|
||||
super().__delattr__(key)
|
||||
return
|
||||
|
||||
raise AttributeError(
|
||||
f"Attribute `{key}` of class `{self.__class__.__name__}` can't be deleted!"
|
||||
)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""Gives a string representation of this object in the form
|
||||
|
@ -130,6 +187,9 @@ class TelegramObject:
|
|||
if not self.api_kwargs:
|
||||
# Drop api_kwargs from the representation, if empty
|
||||
as_dict.pop("api_kwargs", None)
|
||||
else:
|
||||
# Otherwise, we want to skip the "mappingproxy" part of the repr
|
||||
as_dict["api_kwargs"] = dict(self.api_kwargs)
|
||||
|
||||
contents = ", ".join(
|
||||
f"{k}={as_dict[k]!r}"
|
||||
|
@ -189,7 +249,11 @@ class TelegramObject:
|
|||
Returns:
|
||||
state (Dict[:obj:`str`, :obj:`object`]): The state of the object.
|
||||
"""
|
||||
return self._get_attrs(include_private=True, recursive=False, remove_bot=True)
|
||||
out = self._get_attrs(include_private=True, recursive=False, remove_bot=True)
|
||||
# MappingProxyType is not pickable, so we convert it to a dict and revert in
|
||||
# __setstate__
|
||||
out["api_kwargs"] = dict(self.api_kwargs)
|
||||
return out
|
||||
|
||||
def __setstate__(self, state: dict) -> None:
|
||||
"""
|
||||
|
@ -208,19 +272,36 @@ class TelegramObject:
|
|||
Args:
|
||||
state (:obj:`dict`): The data to set as attributes of this object.
|
||||
"""
|
||||
self._unfreeze()
|
||||
|
||||
# Make sure that we have a `_bot` attribute. This is necessary, since __getstate__ omits
|
||||
# this as Bots are not pickable.
|
||||
setattr(self, "_bot", None)
|
||||
|
||||
setattr(self, "api_kwargs", state.pop("api_kwargs", {})) # assign api_kwargs first
|
||||
# get api_kwargs first because we may need to add entries to it (see try-except below)
|
||||
api_kwargs = state.pop("api_kwargs", {})
|
||||
# get _frozen before the loop to avoid setting it to True in the loop
|
||||
frozen = state.pop("_frozen", False)
|
||||
|
||||
for key, val in state.items():
|
||||
|
||||
try:
|
||||
setattr(self, key, val)
|
||||
except AttributeError: # catch cases when old attributes are removed from new versions
|
||||
self.api_kwargs[key] = val # add it to api_kwargs as fallback
|
||||
except AttributeError:
|
||||
# catch cases when old attributes are removed from new versions
|
||||
api_kwargs[key] = val # add it to api_kwargs as fallback
|
||||
|
||||
self._apply_api_kwargs()
|
||||
# For api_kwargs we first apply any kwargs that are already attributes of the object
|
||||
# and then set the rest as MappingProxyType attribute. Converting to MappingProxyType
|
||||
# is necessary, since __getstate__ converts it to a dict as MPT is not pickable.
|
||||
self._apply_api_kwargs(api_kwargs)
|
||||
setattr(self, "api_kwargs", MappingProxyType(api_kwargs))
|
||||
|
||||
# Apply freezing if necessary
|
||||
# we .get(…) the setting for backwards compatibility with objects that were pickled
|
||||
# before the freeze feature was introduced
|
||||
if frozen:
|
||||
self._freeze()
|
||||
|
||||
def __deepcopy__(self: Tele_co, memodict: dict) -> Tele_co:
|
||||
"""
|
||||
|
@ -243,9 +324,19 @@ class TelegramObject:
|
|||
result = cls.__new__(cls) # create a new instance
|
||||
memodict[id(self)] = result # save the id of the object in the dict
|
||||
|
||||
for k in self._get_attrs_names(
|
||||
include_private=True
|
||||
): # now we set the attributes in the deepcopied object
|
||||
setattr(result, "_frozen", False) # unfreeze the new object for setting the attributes
|
||||
|
||||
# now we set the attributes in the deepcopied object
|
||||
for k in self._get_attrs_names(include_private=True):
|
||||
if k == "_frozen":
|
||||
# Setting the frozen status to True would prevent the attributes from being set
|
||||
continue
|
||||
if k == "api_kwargs":
|
||||
# Need to copy api_kwargs manually, since it's a MappingProxyType is not
|
||||
# pickable and deepcopy uses the pickle interface
|
||||
setattr(result, k, MappingProxyType(deepcopy(dict(self.api_kwargs), memodict)))
|
||||
continue
|
||||
|
||||
try:
|
||||
setattr(result, k, deepcopy(getattr(self, k), memodict))
|
||||
except AttributeError:
|
||||
|
@ -254,6 +345,10 @@ class TelegramObject:
|
|||
# did not have the attribute yet.
|
||||
continue
|
||||
|
||||
# Apply freezing if necessary
|
||||
if self._frozen:
|
||||
result._freeze()
|
||||
|
||||
result.set_bot(bot) # Assign the bots back
|
||||
self.set_bot(bot)
|
||||
return result
|
||||
|
@ -372,21 +467,26 @@ class TelegramObject:
|
|||
@classmethod
|
||||
def de_list(
|
||||
cls: Type[Tele_co], data: Optional[List[JSONDict]], bot: "Bot"
|
||||
) -> List[Optional[Tele_co]]:
|
||||
"""Converts JSON data to a list of Telegram objects.
|
||||
) -> Tuple[Tele_co, ...]:
|
||||
"""Converts a list of JSON objects to a tuple of Telegram objects.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|
||||
* Returns a tuple instead of a list.
|
||||
* Filters out any :obj:`None` values.
|
||||
|
||||
Args:
|
||||
data (Dict[:obj:`str`, ...]): The JSON data.
|
||||
data (List[Dict[:obj:`str`, ...]]): The JSON data.
|
||||
bot (:class:`telegram.Bot`): The bot associated with these objects.
|
||||
|
||||
Returns:
|
||||
A list of Telegram objects.
|
||||
A tuple of Telegram objects.
|
||||
|
||||
"""
|
||||
if not data:
|
||||
return []
|
||||
return ()
|
||||
|
||||
return [cls.de_json(d, bot) for d in data]
|
||||
return tuple(obj for obj in (cls.de_json(d, bot) for d in data) if obj is not None)
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Gives a JSON representation of object.
|
||||
|
@ -403,7 +503,9 @@ class TelegramObject:
|
|||
"""Gives representation of object as :obj:`dict`.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
Now includes all entries of :attr:`api_kwargs`.
|
||||
|
||||
* Now includes all entries of :attr:`api_kwargs`.
|
||||
* Attributes whose values are empty sequences are no longer included.
|
||||
|
||||
Args:
|
||||
recursive (:obj:`bool`, optional): If :obj:`True`, will convert any TelegramObjects
|
||||
|
@ -420,13 +522,19 @@ class TelegramObject:
|
|||
# Now we should convert TGObjects to dicts inside objects such as sequences, and convert
|
||||
# datetimes to timestamps. This mostly eliminates the need for subclasses to override
|
||||
# `to_dict`
|
||||
pop_keys: Set[str] = set()
|
||||
for key, value in out.items():
|
||||
if isinstance(value, (tuple, list)) and value:
|
||||
if isinstance(value, (tuple, list)):
|
||||
if not value:
|
||||
# not popping directly to avoid changing the dict size during iteration
|
||||
pop_keys.add(key)
|
||||
continue
|
||||
|
||||
val = [] # empty list to append our converted values to
|
||||
for item in value:
|
||||
if hasattr(item, "to_dict"):
|
||||
val.append(item.to_dict(recursive=recursive))
|
||||
# This branch is useful for e.g. List[List[PhotoSize|KeyboardButton]]
|
||||
# This branch is useful for e.g. Tuple[Tuple[PhotoSize|KeyboardButton]]
|
||||
elif isinstance(item, (tuple, list)):
|
||||
val.append(
|
||||
[
|
||||
|
@ -441,6 +549,9 @@ class TelegramObject:
|
|||
elif isinstance(value, datetime.datetime):
|
||||
out[key] = to_timestamp(value)
|
||||
|
||||
for key in pop_keys:
|
||||
out.pop(key)
|
||||
|
||||
# Effectively "unpack" api_kwargs into `out`:
|
||||
out.update(out.pop("api_kwargs", {})) # type: ignore[call-overload]
|
||||
return out
|
||||
|
|
|
@ -268,6 +268,8 @@ class Update(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.update_id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@property
|
||||
def effective_user(self) -> Optional["User"]:
|
||||
"""
|
||||
|
|
|
@ -158,6 +158,8 @@ class User(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.id,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
""":obj:`str`: Convenience property. If available, returns the user's :attr:`username`
|
||||
|
@ -482,7 +484,7 @@ class User(TelegramObject):
|
|||
caption: Optional[str] = None,
|
||||
parse_mode: ODVInput[str] = DEFAULT_NONE,
|
||||
caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
|
||||
) -> List["Message"]:
|
||||
) -> Tuple["Message", ...]:
|
||||
"""Shortcut for::
|
||||
|
||||
await bot.send_media_group(update.effective_user.id, *args, **kwargs)
|
||||
|
@ -490,7 +492,8 @@ class User(TelegramObject):
|
|||
For the documentation of the arguments, please see :meth:`telegram.Bot.send_media_group`.
|
||||
|
||||
Returns:
|
||||
List[:class:`telegram.Message`:] On success, instance representing the message posted.
|
||||
Tuple[:class:`telegram.Message`:] On success, a tuple of :class:`~telegram.Message`
|
||||
instances that were sent is returned.
|
||||
|
||||
"""
|
||||
return await self.get_bot().send_media_group(
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains an object that represents a Telegram UserProfilePhotos."""
|
||||
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
from typing import TYPE_CHECKING, Optional, Sequence
|
||||
|
||||
from telegram._files.photosize import PhotoSize
|
||||
from telegram._telegramobject import TelegramObject
|
||||
|
@ -36,27 +35,40 @@ class UserProfilePhotos(TelegramObject):
|
|||
|
||||
Args:
|
||||
total_count (:obj:`int`): Total number of profile pictures the target user has.
|
||||
photos (List[List[:class:`telegram.PhotoSize`]]): Requested profile pictures (in up to 4
|
||||
sizes each).
|
||||
photos (Sequence[Sequence[:class:`telegram.PhotoSize`]]): Requested profile pictures (in up
|
||||
to 4 sizes each).
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
Attributes:
|
||||
total_count (:obj:`int`): Total number of profile pictures.
|
||||
photos (List[List[:class:`telegram.PhotoSize`]]): Requested profile pictures.
|
||||
photos (Tuple[Tuple[:class:`telegram.PhotoSize`]]): Requested profile pictures (in up
|
||||
to 4 sizes each).
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ("photos", "total_count")
|
||||
|
||||
def __init__(
|
||||
self, total_count: int, photos: List[List[PhotoSize]], *, api_kwargs: JSONDict = None
|
||||
self,
|
||||
total_count: int,
|
||||
photos: Sequence[Sequence[PhotoSize]],
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
):
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
# Required
|
||||
self.total_count = total_count
|
||||
self.photos = photos
|
||||
self.photos = tuple(tuple(sizes) for sizes in photos)
|
||||
|
||||
self._id_attrs = (self.total_count, self.photos)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["UserProfilePhotos"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
@ -68,6 +80,3 @@ class UserProfilePhotos(TelegramObject):
|
|||
data["photos"] = [PhotoSize.de_list(photo, bot) for photo in data["photos"]]
|
||||
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(tuple(tuple(p for p in photo) for photo in self.photos))
|
||||
|
|
40
telegram/_utils/argumentparsing.py
Normal file
40
telegram/_utils/argumentparsing.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# A library that provides a Python interface to the Telegram Bot API
|
||||
# Copyright (C) 2015-2022
|
||||
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains helper functions related to parsing arguments for classes and methods.
|
||||
|
||||
Warning:
|
||||
Contents of this module are intended to be used internally by the library and *not* by the
|
||||
user. Changes to this module are not considered breaking changes and may not be documented in
|
||||
the changelog.
|
||||
"""
|
||||
from typing import Optional, Sequence, Tuple, TypeVar
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
def parse_sequence_arg(arg: Optional[Sequence[T]]) -> Tuple[T, ...]:
|
||||
"""Parses an optional sequence into a tuple
|
||||
|
||||
Args:
|
||||
arg (:obj:`Sequence`): The sequence to parse.
|
||||
|
||||
Returns:
|
||||
:obj:`Tuple`: The sequence converted to a tuple or an empty tuple.
|
||||
"""
|
||||
return tuple(arg) if arg else ()
|
|
@ -27,15 +27,19 @@ Warning:
|
|||
user. Changes to this module are not considered breaking changes and may not be documented in
|
||||
the changelog.
|
||||
"""
|
||||
from collections.abc import Sequence
|
||||
|
||||
|
||||
def check_keyboard_type(keyboard: object) -> bool:
|
||||
"""Checks if the keyboard provided is of the correct type - A list of lists.
|
||||
Implicitly tested in the init-tests of `{Inline, Reply}KeyboardMarkup`
|
||||
"""
|
||||
if not isinstance(keyboard, list):
|
||||
# string and bytes may actually be used for ReplyKeyboardMarkup in which case each button
|
||||
# would contain a single character. But that use case should be discouraged and we don't
|
||||
# allow it here.
|
||||
if not isinstance(keyboard, Sequence) or isinstance(keyboard, (str, bytes)):
|
||||
return False
|
||||
for row in keyboard:
|
||||
if not isinstance(row, list):
|
||||
if not isinstance(row, Sequence) or isinstance(row, (str, bytes)):
|
||||
return False
|
||||
return True
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# You should have received a copy of the GNU Lesser Public License
|
||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
"""This module contains objects related to Telegram video chats."""
|
||||
|
||||
import datetime as dtm
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
from typing import TYPE_CHECKING, Optional, Sequence
|
||||
|
||||
from telegram._telegramobject import TelegramObject
|
||||
from telegram._user import User
|
||||
from telegram._utils.argumentparsing import parse_sequence_arg
|
||||
from telegram._utils.datetime import from_timestamp
|
||||
from telegram._utils.types import JSONDict
|
||||
|
||||
|
@ -76,6 +76,8 @@ class VideoChatEnded(TelegramObject):
|
|||
self.duration = duration
|
||||
self._id_attrs = (self.duration,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
|
||||
class VideoChatParticipantsInvited(TelegramObject):
|
||||
"""
|
||||
|
@ -89,10 +91,16 @@ class VideoChatParticipantsInvited(TelegramObject):
|
|||
This class was renamed from ``VoiceChatParticipantsInvited`` in accordance to Bot API 6.0.
|
||||
|
||||
Args:
|
||||
users (List[:class:`telegram.User`]): New members that were invited to the video chat.
|
||||
users (Sequence[:class:`telegram.User`]): New members that were invited to the video chat.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|sequenceclassargs|
|
||||
|
||||
Attributes:
|
||||
users (List[:class:`telegram.User`]): New members that were invited to the video chat.
|
||||
users (Tuple[:class:`telegram.User`]): New members that were invited to the video chat.
|
||||
|
||||
.. versionchanged:: 20.0
|
||||
|tupleclassattrs|
|
||||
|
||||
"""
|
||||
|
||||
|
@ -100,14 +108,16 @@ class VideoChatParticipantsInvited(TelegramObject):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
users: List[User],
|
||||
users: Sequence[User],
|
||||
*,
|
||||
api_kwargs: JSONDict = None,
|
||||
) -> None:
|
||||
super().__init__(api_kwargs=api_kwargs)
|
||||
self.users = users
|
||||
self.users = parse_sequence_arg(users)
|
||||
self._id_attrs = (self.users,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(
|
||||
cls, data: Optional[JSONDict], bot: "Bot"
|
||||
|
@ -121,9 +131,6 @@ class VideoChatParticipantsInvited(TelegramObject):
|
|||
data["users"] = User.de_list(data.get("users", []), bot)
|
||||
return super().de_json(data=data, bot=bot)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash(None) if self.users is None else hash(tuple(self.users))
|
||||
|
||||
|
||||
class VideoChatScheduled(TelegramObject):
|
||||
"""This object represents a service message about a video chat scheduled in the chat.
|
||||
|
@ -156,6 +163,8 @@ class VideoChatScheduled(TelegramObject):
|
|||
|
||||
self._id_attrs = (self.start_date,)
|
||||
|
||||
self._freeze()
|
||||
|
||||
@classmethod
|
||||
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["VideoChatScheduled"]:
|
||||
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||
|
|
|
@ -58,3 +58,5 @@ class WebAppData(TelegramObject):
|
|||
self.button_text = button_text
|
||||
|
||||
self._id_attrs = (self.data, self.button_text)
|
||||
|
||||
self._freeze()
|
||||
|
|
|
@ -53,3 +53,5 @@ class WebAppInfo(TelegramObject):
|
|||
self.url = url
|
||||
|
||||
self._id_attrs = (self.url,)
|
||||
|
||||
self._freeze()
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue