Skip to content

Commit

Permalink
Allow Sequence Input for Bot Methods (#3412)
Browse files Browse the repository at this point in the history
Co-authored-by: Dmitry Kolomatskiy <58207913+lemontree210@users.noreply.github.com>
Co-authored-by: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com>
  • Loading branch information
3 people committed Jan 1, 2023
1 parent cb90814 commit 456b81d
Show file tree
Hide file tree
Showing 30 changed files with 352 additions and 184 deletions.
8 changes: 6 additions & 2 deletions docs/substitutions/global.rst
Expand Up @@ -34,16 +34,20 @@

.. |allow_sending_without_reply| replace:: Pass :obj:`True`, if the message should be sent even if the specified replied-to message is not found.

.. |caption_entities| replace:: List of special entities that appear in the caption, which can be specified instead of ``parse_mode``.
.. |caption_entities| replace:: Sequence of special entities that appear in the caption, which can be specified instead of ``parse_mode``.

.. |protect_content| replace:: Protects the contents of the sent message from forwarding and saving.

.. |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.

.. |sequenceclassargs| replace:: Accepts any :class:`collections.abc.Sequence` as input instead of just a list. The input is converted to a tuple.
.. |sequenceclassargs| replace:: |sequenceargs| 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.

.. |sequenceargs| replace:: Accepts any :class:`collections.abc.Sequence` as input instead of just a list.

.. |captionentitiesattr| replace:: Tuple of special entities that appear in the caption, which can be specified instead of ``parse_mode``.
196 changes: 137 additions & 59 deletions telegram/_bot.py

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions telegram/_callbackquery.py
Expand Up @@ -18,7 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
# pylint: disable=redefined-builtin
"""This module contains an object that represents a Telegram CallbackQuery"""
from typing import TYPE_CHECKING, ClassVar, List, Optional, Tuple, Union
from typing import TYPE_CHECKING, ClassVar, Optional, Sequence, Tuple, Union

from telegram import constants
from telegram._files.location import Location
Expand Down Expand Up @@ -192,7 +192,7 @@ async def edit_message_text(
parse_mode: ODVInput[str] = DEFAULT_NONE,
disable_web_page_preview: ODVInput[bool] = DEFAULT_NONE,
reply_markup: "InlineKeyboardMarkup" = None,
entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
entities: Sequence["MessageEntity"] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
Expand Down Expand Up @@ -252,7 +252,7 @@ async def edit_message_caption(
caption: str = None,
reply_markup: "InlineKeyboardMarkup" = None,
parse_mode: ODVInput[str] = DEFAULT_NONE,
caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
caption_entities: Sequence["MessageEntity"] = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
Expand Down Expand Up @@ -720,7 +720,7 @@ async def copy_message(
chat_id: Union[int, str],
caption: str = None,
parse_mode: ODVInput[str] = DEFAULT_NONE,
caption_entities: Union[Tuple["MessageEntity", ...], List["MessageEntity"]] = None,
caption_entities: Sequence["MessageEntity"] = None,
disable_notification: DVInput[bool] = DEFAULT_NONE,
reply_to_message_id: int = None,
allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE,
Expand Down
32 changes: 16 additions & 16 deletions telegram/_chat.py
Expand Up @@ -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, Sequence, Tuple, Union
from typing import TYPE_CHECKING, ClassVar, Optional, Sequence, Tuple, Union

from telegram import constants
from telegram._chatlocation import ChatLocation
Expand Down Expand Up @@ -1239,7 +1239,7 @@ async def send_message(
reply_to_message_id: int = None,
reply_markup: ReplyMarkup = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
entities: Sequence["MessageEntity"] = None,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: int = None,
*,
Expand Down Expand Up @@ -1280,7 +1280,7 @@ async def send_message(

async def send_media_group(
self,
media: List[
media: Sequence[
Union["InputMediaAudio", "InputMediaDocument", "InputMediaPhoto", "InputMediaVideo"]
],
disable_notification: ODVInput[bool] = DEFAULT_NONE,
Expand All @@ -1296,7 +1296,7 @@ async def send_media_group(
api_kwargs: JSONDict = None,
caption: Optional[str] = None,
parse_mode: ODVInput[str] = DEFAULT_NONE,
caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
caption_entities: Sequence["MessageEntity"] = None,
) -> Tuple["Message", ...]:
"""Shortcut for::
Expand Down Expand Up @@ -1369,7 +1369,7 @@ async def send_photo(
reply_markup: ReplyMarkup = None,
parse_mode: ODVInput[str] = DEFAULT_NONE,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
caption_entities: Sequence["MessageEntity"] = None,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: int = None,
*,
Expand Down Expand Up @@ -1473,7 +1473,7 @@ async def send_audio(
parse_mode: ODVInput[str] = DEFAULT_NONE,
thumb: FileInput = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
caption_entities: Sequence["MessageEntity"] = None,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: int = None,
*,
Expand Down Expand Up @@ -1529,7 +1529,7 @@ async def send_document(
thumb: FileInput = None,
disable_content_type_detection: bool = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
caption_entities: Sequence["MessageEntity"] = None,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: int = None,
*,
Expand Down Expand Up @@ -1663,7 +1663,7 @@ async def send_invoice(
payload: str,
provider_token: str,
currency: str,
prices: List["LabeledPrice"],
prices: Sequence["LabeledPrice"],
start_parameter: str = None,
photo_url: str = None,
photo_size: int = None,
Expand All @@ -1682,7 +1682,7 @@ async def send_invoice(
send_email_to_provider: bool = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
max_tip_amount: int = None,
suggested_tip_amounts: List[int] = None,
suggested_tip_amounts: Sequence[int] = None,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: int = None,
*,
Expand Down Expand Up @@ -1815,7 +1815,7 @@ async def send_animation(
reply_to_message_id: int = None,
reply_markup: ReplyMarkup = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
caption_entities: Sequence["MessageEntity"] = None,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: int = None,
*,
Expand Down Expand Up @@ -1974,7 +1974,7 @@ async def send_video(
supports_streaming: bool = None,
thumb: FileInput = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
caption_entities: Sequence["MessageEntity"] = None,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: int = None,
*,
Expand Down Expand Up @@ -2080,7 +2080,7 @@ async def send_voice(
reply_markup: ReplyMarkup = None,
parse_mode: ODVInput[str] = DEFAULT_NONE,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
caption_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
caption_entities: Sequence["MessageEntity"] = None,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: int = None,
*,
Expand Down Expand Up @@ -2125,7 +2125,7 @@ async def send_voice(
async def send_poll(
self,
question: str,
options: List[str],
options: Sequence[str],
is_anonymous: bool = None,
type: str = None,
allows_multiple_answers: bool = None,
Expand All @@ -2139,7 +2139,7 @@ async def send_poll(
open_period: int = None,
close_date: Union[int, datetime] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
explanation_entities: Union[List["MessageEntity"], Tuple["MessageEntity", ...]] = None,
explanation_entities: Sequence["MessageEntity"] = None,
protect_content: ODVInput[bool] = DEFAULT_NONE,
message_thread_id: int = None,
*,
Expand Down Expand Up @@ -2192,7 +2192,7 @@ async def send_copy(
message_id: int,
caption: str = None,
parse_mode: ODVInput[str] = DEFAULT_NONE,
caption_entities: Union[Tuple["MessageEntity", ...], List["MessageEntity"]] = None,
caption_entities: Sequence["MessageEntity"] = None,
disable_notification: DVInput[bool] = DEFAULT_NONE,
reply_to_message_id: int = None,
allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE,
Expand Down Expand Up @@ -2242,7 +2242,7 @@ async def copy_message(
message_id: int,
caption: str = None,
parse_mode: ODVInput[str] = DEFAULT_NONE,
caption_entities: Union[Tuple["MessageEntity", ...], List["MessageEntity"]] = None,
caption_entities: Sequence["MessageEntity"] = None,
disable_notification: DVInput[bool] = DEFAULT_NONE,
reply_to_message_id: int = None,
allow_sending_without_reply: DVInput[bool] = DEFAULT_NONE,
Expand Down
12 changes: 6 additions & 6 deletions telegram/_files/inputmedia.py
Expand Up @@ -68,7 +68,7 @@ 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 (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0
Expand Down Expand Up @@ -150,7 +150,7 @@ 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 (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0
Expand Down Expand Up @@ -234,7 +234,7 @@ class InputMediaPhoto(InputMedia):
media (:obj:`str` | :class:`telegram.InputFile`): Photo to send.
caption (:obj:`str`): Optional. Caption of the document to be sent.
parse_mode (:obj:`str`): Optional. The parse mode to use for text formatting.
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0
Expand Down Expand Up @@ -318,7 +318,7 @@ 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 (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0
Expand Down Expand Up @@ -421,7 +421,7 @@ 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 (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0
Expand Down Expand Up @@ -514,7 +514,7 @@ 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 (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0
Expand Down
2 changes: 1 addition & 1 deletion telegram/_games/game.py
Expand Up @@ -77,7 +77,7 @@ class Game(TelegramObject):
using :meth:`telegram.Bot.edit_message_text`.
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.
This tuple is empty if the message does not contain text entities.
.. versionchanged:: 20.0
|tupleclassattrs|
Expand Down
20 changes: 13 additions & 7 deletions telegram/_inline/inlinekeyboardmarkup.py
Expand Up @@ -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/].
"""This module contains an object that represents a Telegram InlineKeyboardMarkup."""
from typing import TYPE_CHECKING, List, Optional, Sequence
from typing import TYPE_CHECKING, Optional, Sequence

from telegram._inline.inlinekeyboardbutton import InlineKeyboardButton
from telegram._telegramobject import TelegramObject
Expand Down Expand Up @@ -111,7 +111,7 @@ def from_button(cls, button: InlineKeyboardButton, **kwargs: object) -> "InlineK

@classmethod
def from_row(
cls, button_row: List[InlineKeyboardButton], **kwargs: object
cls, button_row: Sequence[InlineKeyboardButton], **kwargs: object
) -> "InlineKeyboardMarkup":
"""Shortcut for::
Expand All @@ -120,15 +120,18 @@ def from_row(
Return an InlineKeyboardMarkup from a single row of InlineKeyboardButtons
Args:
button_row (List[:class:`telegram.InlineKeyboardButton`]): The button to use in the
markup
button_row (Sequence[:class:`telegram.InlineKeyboardButton`]): The button to use
in the markup
.. versionchanged:: 20.0
|sequenceargs|
"""
return cls([button_row], **kwargs) # type: ignore[arg-type]

@classmethod
def from_column(
cls, button_column: List[InlineKeyboardButton], **kwargs: object
cls, button_column: Sequence[InlineKeyboardButton], **kwargs: object
) -> "InlineKeyboardMarkup":
"""Shortcut for::
Expand All @@ -137,8 +140,11 @@ def from_column(
Return an InlineKeyboardMarkup from a single column of InlineKeyboardButtons
Args:
button_column (List[:class:`telegram.InlineKeyboardButton`]): The button to use in the
markup
button_column (Sequence[:class:`telegram.InlineKeyboardButton`]): The button to use
in the markup
.. versionchanged:: 20.0
|sequenceargs|
"""
button_grid = [[button] for button in button_column]
Expand Down
2 changes: 1 addition & 1 deletion telegram/_inline/inlinequeryresultaudio.py
Expand Up @@ -71,7 +71,7 @@ class InlineQueryResultAudio(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
parsing.
parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0
Expand Down
2 changes: 1 addition & 1 deletion telegram/_inline/inlinequeryresultcachedaudio.py
Expand Up @@ -66,7 +66,7 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
parsing.
parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0
Expand Down
2 changes: 1 addition & 1 deletion telegram/_inline/inlinequeryresultcacheddocument.py
Expand Up @@ -70,7 +70,7 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0
Expand Down
2 changes: 1 addition & 1 deletion telegram/_inline/inlinequeryresultcachedgif.py
Expand Up @@ -69,7 +69,7 @@ class InlineQueryResultCachedGif(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0
Expand Down
2 changes: 1 addition & 1 deletion telegram/_inline/inlinequeryresultcachedmpeg4gif.py
Expand Up @@ -69,7 +69,7 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters
after entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0
Expand Down
2 changes: 1 addition & 1 deletion telegram/_inline/inlinequeryresultcachedphoto.py
Expand Up @@ -71,7 +71,7 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after
entities parsing.
parse_mode (:obj:`str`): Optional. |parse_mode|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0
Expand Down
2 changes: 1 addition & 1 deletion telegram/_inline/inlinequeryresultcachedvideo.py
Expand Up @@ -67,7 +67,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 (Tuple[:class:`telegram.MessageEntity`]): Optional. |caption_entities|
caption_entities (Tuple[:class:`telegram.MessageEntity`]): Optional. |captionentitiesattr|
.. versionchanged:: 20.0
Expand Down
3 changes: 2 additions & 1 deletion telegram/_inline/inlinequeryresultcachedvoice.py
Expand Up @@ -47,7 +47,8 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters after entities
parsing.
parse_mode (:obj:`str`, optional): |parse_mode|
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional): |caption_entities|
caption_entities (Sequence[:class:`telegram.MessageEntity`], optional):
|captionentitiesattr|
.. versionchanged:: 20.0
|sequenceclassargs|
Expand Down

0 comments on commit 456b81d

Please sign in to comment.