mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2024-12-31 16:40:53 +01:00
API 6.7 (#3673)
Co-authored-by: Dmitry Kolomatskiy <58207913+lemontree210@users.noreply.github.com> Co-authored-by: Harshil Mehta <37377066+harshil21@users.noreply.github.com> Co-authored-by: poolitzer <github@poolitzer.eu> Co-authored-by: Aditya <clot27@apx_managed.vanilla>
This commit is contained in:
parent
450dc2115c
commit
8c252c9822
30 changed files with 1236 additions and 91 deletions
|
@ -14,7 +14,7 @@
|
||||||
:target: https://pypi.org/project/python-telegram-bot/
|
:target: https://pypi.org/project/python-telegram-bot/
|
||||||
:alt: Supported Python versions
|
:alt: Supported Python versions
|
||||||
|
|
||||||
.. image:: https://img.shields.io/badge/Bot%20API-6.6-blue?logo=telegram
|
.. image:: https://img.shields.io/badge/Bot%20API-6.7-blue?logo=telegram
|
||||||
:target: https://core.telegram.org/bots/api-changelog
|
:target: https://core.telegram.org/bots/api-changelog
|
||||||
:alt: Supported Bot API versions
|
:alt: Supported Bot API versions
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
|
||||||
Telegram API support
|
Telegram API support
|
||||||
====================
|
====================
|
||||||
|
|
||||||
All types and methods of the Telegram Bot API **6.6** are supported.
|
All types and methods of the Telegram Bot API **6.7** are supported.
|
||||||
|
|
||||||
Installing
|
Installing
|
||||||
==========
|
==========
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
:target: https://pypi.org/project/python-telegram-bot-raw/
|
:target: https://pypi.org/project/python-telegram-bot-raw/
|
||||||
:alt: Supported Python versions
|
:alt: Supported Python versions
|
||||||
|
|
||||||
.. image:: https://img.shields.io/badge/Bot%20API-6.6-blue?logo=telegram
|
.. image:: https://img.shields.io/badge/Bot%20API-6.7-blue?logo=telegram
|
||||||
:target: https://core.telegram.org/bots/api-changelog
|
:target: https://core.telegram.org/bots/api-changelog
|
||||||
:alt: Supported Bot API versions
|
:alt: Supported Bot API versions
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ Installing both ``python-telegram-bot`` and ``python-telegram-bot-raw`` in conju
|
||||||
Telegram API support
|
Telegram API support
|
||||||
====================
|
====================
|
||||||
|
|
||||||
All types and methods of the Telegram Bot API **6.6** are supported.
|
All types and methods of the Telegram Bot API **6.7** are supported.
|
||||||
|
|
||||||
Installing
|
Installing
|
||||||
==========
|
==========
|
||||||
|
|
|
@ -196,6 +196,10 @@
|
||||||
- Used for setting the short description of the bot
|
- Used for setting the short description of the bot
|
||||||
* - :meth:`~telegram.Bot.get_my_short_description`
|
* - :meth:`~telegram.Bot.get_my_short_description`
|
||||||
- Used for obtaining the short description of the bot
|
- Used for obtaining the short description of the bot
|
||||||
|
* - :meth:`~telegram.Bot.set_my_name`
|
||||||
|
- Used for setting the name of the bot
|
||||||
|
* - :meth:`~telegram.Bot.get_my_name`
|
||||||
|
- Used for obtaining the name of the bot
|
||||||
|
|
||||||
.. raw:: html
|
.. raw:: html
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ Available Types
|
||||||
telegram.botcommandscopechatmember
|
telegram.botcommandscopechatmember
|
||||||
telegram.botcommandscopedefault
|
telegram.botcommandscopedefault
|
||||||
telegram.botdescription
|
telegram.botdescription
|
||||||
|
telegram.botname
|
||||||
telegram.botshortdescription
|
telegram.botshortdescription
|
||||||
telegram.callbackquery
|
telegram.callbackquery
|
||||||
telegram.chat
|
telegram.chat
|
||||||
|
@ -78,6 +79,7 @@ Available Types
|
||||||
telegram.replykeyboardmarkup
|
telegram.replykeyboardmarkup
|
||||||
telegram.replykeyboardremove
|
telegram.replykeyboardremove
|
||||||
telegram.sentwebappmessage
|
telegram.sentwebappmessage
|
||||||
|
telegram.switchinlinequerychosenchat
|
||||||
telegram.telegramobject
|
telegram.telegramobject
|
||||||
telegram.update
|
telegram.update
|
||||||
telegram.user
|
telegram.user
|
||||||
|
|
6
docs/source/telegram.botname.rst
Normal file
6
docs/source/telegram.botname.rst
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
BotName
|
||||||
|
=======
|
||||||
|
|
||||||
|
.. autoclass:: telegram.BotName
|
||||||
|
:members:
|
||||||
|
:show-inheritance:
|
|
@ -24,6 +24,7 @@ Inline Mode
|
||||||
telegram.inlinequeryresultlocation
|
telegram.inlinequeryresultlocation
|
||||||
telegram.inlinequeryresultmpeg4gif
|
telegram.inlinequeryresultmpeg4gif
|
||||||
telegram.inlinequeryresultphoto
|
telegram.inlinequeryresultphoto
|
||||||
|
telegram.inlinequeryresultsbutton
|
||||||
telegram.inlinequeryresultvenue
|
telegram.inlinequeryresultvenue
|
||||||
telegram.inlinequeryresultvideo
|
telegram.inlinequeryresultvideo
|
||||||
telegram.inlinequeryresultvoice
|
telegram.inlinequeryresultvoice
|
||||||
|
|
6
docs/source/telegram.inlinequeryresultsbutton.rst
Normal file
6
docs/source/telegram.inlinequeryresultsbutton.rst
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
InlineQueryResultsButton
|
||||||
|
========================
|
||||||
|
|
||||||
|
.. autoclass:: telegram.InlineQueryResultsButton
|
||||||
|
:members:
|
||||||
|
:show-inheritance:
|
6
docs/source/telegram.switchinlinequerychosenchat.rst
Normal file
6
docs/source/telegram.switchinlinequerychosenchat.rst
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
SwitchInlineQueryChosenChat
|
||||||
|
===========================
|
||||||
|
|
||||||
|
.. autoclass:: telegram.SwitchInlineQueryChosenChat
|
||||||
|
:members:
|
||||||
|
:show-inheritance:
|
|
@ -38,6 +38,7 @@ __all__ = ( # Keep this alphabetically ordered
|
||||||
"BotCommandScopeChatMember",
|
"BotCommandScopeChatMember",
|
||||||
"BotCommandScopeDefault",
|
"BotCommandScopeDefault",
|
||||||
"BotDescription",
|
"BotDescription",
|
||||||
|
"BotName",
|
||||||
"BotShortDescription",
|
"BotShortDescription",
|
||||||
"CallbackGame",
|
"CallbackGame",
|
||||||
"CallbackQuery",
|
"CallbackQuery",
|
||||||
|
@ -102,6 +103,7 @@ __all__ = ( # Keep this alphabetically ordered
|
||||||
"InlineQueryResultLocation",
|
"InlineQueryResultLocation",
|
||||||
"InlineQueryResultMpeg4Gif",
|
"InlineQueryResultMpeg4Gif",
|
||||||
"InlineQueryResultPhoto",
|
"InlineQueryResultPhoto",
|
||||||
|
"InlineQueryResultsButton",
|
||||||
"InlineQueryResultVenue",
|
"InlineQueryResultVenue",
|
||||||
"InlineQueryResultVideo",
|
"InlineQueryResultVideo",
|
||||||
"InlineQueryResultVoice",
|
"InlineQueryResultVoice",
|
||||||
|
@ -169,6 +171,7 @@ __all__ = ( # Keep this alphabetically ordered
|
||||||
"Sticker",
|
"Sticker",
|
||||||
"StickerSet",
|
"StickerSet",
|
||||||
"SuccessfulPayment",
|
"SuccessfulPayment",
|
||||||
|
"SwitchInlineQueryChosenChat",
|
||||||
"TelegramObject",
|
"TelegramObject",
|
||||||
"Update",
|
"Update",
|
||||||
"User",
|
"User",
|
||||||
|
@ -204,6 +207,7 @@ from ._botcommandscope import (
|
||||||
BotCommandScopeDefault,
|
BotCommandScopeDefault,
|
||||||
)
|
)
|
||||||
from ._botdescription import BotDescription, BotShortDescription
|
from ._botdescription import BotDescription, BotShortDescription
|
||||||
|
from ._botname import BotName
|
||||||
from ._callbackquery import CallbackQuery
|
from ._callbackquery import CallbackQuery
|
||||||
from ._chat import Chat
|
from ._chat import Chat
|
||||||
from ._chatadministratorrights import ChatAdministratorRights
|
from ._chatadministratorrights import ChatAdministratorRights
|
||||||
|
@ -280,6 +284,7 @@ from ._inline.inlinequeryresultgif import InlineQueryResultGif
|
||||||
from ._inline.inlinequeryresultlocation import InlineQueryResultLocation
|
from ._inline.inlinequeryresultlocation import InlineQueryResultLocation
|
||||||
from ._inline.inlinequeryresultmpeg4gif import InlineQueryResultMpeg4Gif
|
from ._inline.inlinequeryresultmpeg4gif import InlineQueryResultMpeg4Gif
|
||||||
from ._inline.inlinequeryresultphoto import InlineQueryResultPhoto
|
from ._inline.inlinequeryresultphoto import InlineQueryResultPhoto
|
||||||
|
from ._inline.inlinequeryresultsbutton import InlineQueryResultsButton
|
||||||
from ._inline.inlinequeryresultvenue import InlineQueryResultVenue
|
from ._inline.inlinequeryresultvenue import InlineQueryResultVenue
|
||||||
from ._inline.inlinequeryresultvideo import InlineQueryResultVideo
|
from ._inline.inlinequeryresultvideo import InlineQueryResultVideo
|
||||||
from ._inline.inlinequeryresultvoice import InlineQueryResultVoice
|
from ._inline.inlinequeryresultvoice import InlineQueryResultVoice
|
||||||
|
@ -336,6 +341,7 @@ from ._replykeyboardmarkup import ReplyKeyboardMarkup
|
||||||
from ._replykeyboardremove import ReplyKeyboardRemove
|
from ._replykeyboardremove import ReplyKeyboardRemove
|
||||||
from ._sentwebappmessage import SentWebAppMessage
|
from ._sentwebappmessage import SentWebAppMessage
|
||||||
from ._shared import ChatShared, UserShared
|
from ._shared import ChatShared, UserShared
|
||||||
|
from ._switchinlinequerychosenchat import SwitchInlineQueryChosenChat
|
||||||
from ._telegramobject import TelegramObject
|
from ._telegramobject import TelegramObject
|
||||||
from ._update import Update
|
from ._update import Update
|
||||||
from ._user import User
|
from ._user import User
|
||||||
|
|
146
telegram/_bot.py
146
telegram/_bot.py
|
@ -56,6 +56,7 @@ except ImportError:
|
||||||
from telegram._botcommand import BotCommand
|
from telegram._botcommand import BotCommand
|
||||||
from telegram._botcommandscope import BotCommandScope
|
from telegram._botcommandscope import BotCommandScope
|
||||||
from telegram._botdescription import BotDescription, BotShortDescription
|
from telegram._botdescription import BotDescription, BotShortDescription
|
||||||
|
from telegram._botname import BotName
|
||||||
from telegram._chat import Chat
|
from telegram._chat import Chat
|
||||||
from telegram._chatadministratorrights import ChatAdministratorRights
|
from telegram._chatadministratorrights import ChatAdministratorRights
|
||||||
from telegram._chatinvitelink import ChatInviteLink
|
from telegram._chatinvitelink import ChatInviteLink
|
||||||
|
@ -79,6 +80,7 @@ from telegram._files.voice import Voice
|
||||||
from telegram._forumtopic import ForumTopic
|
from telegram._forumtopic import ForumTopic
|
||||||
from telegram._games.gamehighscore import GameHighScore
|
from telegram._games.gamehighscore import GameHighScore
|
||||||
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
from telegram._inline.inlinekeyboardmarkup import InlineKeyboardMarkup
|
||||||
|
from telegram._inline.inlinequeryresultsbutton import InlineQueryResultsButton
|
||||||
from telegram._menubutton import MenuButton
|
from telegram._menubutton import MenuButton
|
||||||
from telegram._message import Message
|
from telegram._message import Message
|
||||||
from telegram._messageid import MessageId
|
from telegram._messageid import MessageId
|
||||||
|
@ -2811,8 +2813,15 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||||
cache_time: int = None,
|
cache_time: int = None,
|
||||||
is_personal: bool = None,
|
is_personal: bool = None,
|
||||||
next_offset: str = None,
|
next_offset: str = None,
|
||||||
|
# Deprecated params since bot api 6.7
|
||||||
|
# <----
|
||||||
switch_pm_text: str = None,
|
switch_pm_text: str = None,
|
||||||
switch_pm_parameter: str = None,
|
switch_pm_parameter: str = None,
|
||||||
|
# --->
|
||||||
|
# New params since bot api 6.7
|
||||||
|
# <----
|
||||||
|
button: InlineQueryResultsButton = None,
|
||||||
|
# --->
|
||||||
*,
|
*,
|
||||||
current_offset: str = None,
|
current_offset: str = None,
|
||||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
@ -2825,15 +2834,6 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||||
Use this method to send answers to an inline query. No more than
|
Use this method to send answers to an inline query. No more than
|
||||||
:tg-const:`telegram.InlineQuery.MAX_RESULTS` results per query are allowed.
|
:tg-const:`telegram.InlineQuery.MAX_RESULTS` results per query are allowed.
|
||||||
|
|
||||||
Example:
|
|
||||||
An inline bot that sends YouTube videos can ask the user to connect the bot to their
|
|
||||||
YouTube account to adapt search results accordingly. To do this, it displays a
|
|
||||||
'Connect your YouTube account' button above the results, or even before showing any.
|
|
||||||
The user presses the button, switches to a private chat with the bot and, in doing so,
|
|
||||||
passes a start parameter that instructs the bot to return an OAuth link. Once done, the
|
|
||||||
bot can offer a switch_inline button so that the user can easily return to the chat
|
|
||||||
where they wanted to use the bot's inline capabilities.
|
|
||||||
|
|
||||||
Warning:
|
Warning:
|
||||||
In most use cases :paramref:`current_offset` should not be passed manually. Instead of
|
In most use cases :paramref:`current_offset` should not be passed manually. Instead of
|
||||||
calling this method directly, use the shortcut :meth:`telegram.InlineQuery.answer` with
|
calling this method directly, use the shortcut :meth:`telegram.InlineQuery.answer` with
|
||||||
|
@ -2842,6 +2842,9 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||||
|
|
||||||
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
.. seealso:: :wiki:`Working with Files and Media <Working-with-Files-and-Media>`
|
||||||
|
|
||||||
|
.. |api6_7_depr| replace:: Since Bot API 6.7, this argument is deprecated in favour of
|
||||||
|
:paramref:`button`.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
inline_query_id (:obj:`str`): Unique identifier for the answered query.
|
inline_query_id (:obj:`str`): Unique identifier for the answered query.
|
||||||
results (List[:class:`telegram.InlineQueryResult`] | Callable): A list of results for
|
results (List[:class:`telegram.InlineQueryResult`] | Callable): A list of results for
|
||||||
|
@ -2862,12 +2865,22 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||||
switch_pm_text (:obj:`str`, optional): If passed, clients will display a button with
|
switch_pm_text (:obj:`str`, optional): If passed, clients will display a button with
|
||||||
specified text that switches the user to a private chat with the bot and sends the
|
specified text that switches the user to a private chat with the bot and sends the
|
||||||
bot a start message with the parameter :paramref:`switch_pm_parameter`.
|
bot a start message with the parameter :paramref:`switch_pm_parameter`.
|
||||||
|
|
||||||
|
.. deprecated:: NEXT.VERSION
|
||||||
|
|api6_7_depr|
|
||||||
switch_pm_parameter (:obj:`str`, optional): Deep-linking parameter for the
|
switch_pm_parameter (:obj:`str`, optional): Deep-linking parameter for the
|
||||||
:guilabel:`/start` message sent to the bot when user presses the switch button.
|
:guilabel:`/start` message sent to the bot when user presses the switch button.
|
||||||
:tg-const:`telegram.InlineQuery.MIN_SWITCH_PM_TEXT_LENGTH`-
|
:tg-const:`telegram.InlineQuery.MIN_SWITCH_PM_TEXT_LENGTH`-
|
||||||
:tg-const:`telegram.InlineQuery.MAX_SWITCH_PM_TEXT_LENGTH` characters,
|
:tg-const:`telegram.InlineQuery.MAX_SWITCH_PM_TEXT_LENGTH` characters,
|
||||||
only ``A-Z``, ``a-z``, ``0-9``, ``_`` and ``-`` are allowed.
|
only ``A-Z``, ``a-z``, ``0-9``, ``_`` and ``-`` are allowed.
|
||||||
|
|
||||||
|
.. deprecated:: NEXT.VERSION
|
||||||
|
|api6_7_depr|
|
||||||
|
button (:class:`telegram.InlineQueryResultsButton`, optional): A button to be shown
|
||||||
|
above the inline query results.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
Keyword Args:
|
Keyword Args:
|
||||||
current_offset (:obj:`str`, optional): The :attr:`telegram.InlineQuery.offset` of
|
current_offset (:obj:`str`, optional): The :attr:`telegram.InlineQuery.offset` of
|
||||||
the inline query to answer. If passed, PTB will automatically take care of
|
the inline query to answer. If passed, PTB will automatically take care of
|
||||||
|
@ -2881,6 +2894,26 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||||
:class:`telegram.error.TelegramError`
|
:class:`telegram.error.TelegramError`
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
if (switch_pm_text or switch_pm_parameter) and button:
|
||||||
|
raise TypeError(
|
||||||
|
"Since Bot API 6.7, the parameter `button is mutually exclusive to the deprecated "
|
||||||
|
"parameters `switch_pm_text` and `switch_pm_parameter`. Please use the new "
|
||||||
|
"parameter `button`."
|
||||||
|
)
|
||||||
|
|
||||||
|
if switch_pm_text and switch_pm_parameter:
|
||||||
|
self._warn(
|
||||||
|
"Since Bot API 6.7, the parameters `switch_pm_text` and `switch_pm_parameter` are "
|
||||||
|
"deprecated in favour of the new parameter `button`. Please use the new parameter "
|
||||||
|
"`button` instead.",
|
||||||
|
category=PTBDeprecationWarning,
|
||||||
|
stacklevel=3,
|
||||||
|
)
|
||||||
|
button = InlineQueryResultsButton(
|
||||||
|
text=switch_pm_text,
|
||||||
|
start_parameter=switch_pm_parameter,
|
||||||
|
)
|
||||||
|
|
||||||
effective_results, next_offset = self._effective_inline_results(
|
effective_results, next_offset = self._effective_inline_results(
|
||||||
results=results, next_offset=next_offset, current_offset=current_offset
|
results=results, next_offset=next_offset, current_offset=current_offset
|
||||||
)
|
)
|
||||||
|
@ -2896,8 +2929,7 @@ class Bot(TelegramObject, AsyncContextManager["Bot"]):
|
||||||
"next_offset": next_offset,
|
"next_offset": next_offset,
|
||||||
"cache_time": cache_time,
|
"cache_time": cache_time,
|
||||||
"is_personal": is_personal,
|
"is_personal": is_personal,
|
||||||
"switch_pm_text": switch_pm_text,
|
"button": button,
|
||||||
"switch_pm_parameter": switch_pm_parameter,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return await self._post(
|
return await self._post(
|
||||||
|
@ -8138,6 +8170,94 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||||
bot=self,
|
bot=self,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@_log
|
||||||
|
async def set_my_name(
|
||||||
|
self,
|
||||||
|
name: str = None,
|
||||||
|
language_code: str = None,
|
||||||
|
*,
|
||||||
|
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
api_kwargs: JSONDict = None,
|
||||||
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Use this method to change the bot's name.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (:obj:`str`, optional): New bot name;
|
||||||
|
0-:tg-const:`telegram.constants.BotNameLimit.MAX_NAME_LENGTH`
|
||||||
|
characters. Pass an empty string to remove the dedicated name for the given
|
||||||
|
language.
|
||||||
|
|
||||||
|
Caution:
|
||||||
|
If :paramref:`language_code` is not specified, a :paramref:`name` *must*
|
||||||
|
be specified.
|
||||||
|
language_code (:obj:`str`, optional): A two-letter ISO 639-1 language code. If empty,
|
||||||
|
the name will be applied to all users for whose language there is no
|
||||||
|
dedicated name.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
:obj:`bool`: On success, :obj:`True` is returned.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
:class:`telegram.error.TelegramError`
|
||||||
|
|
||||||
|
"""
|
||||||
|
data: JSONDict = {"name": name, "language_code": language_code}
|
||||||
|
|
||||||
|
return await self._post(
|
||||||
|
"setMyName",
|
||||||
|
data,
|
||||||
|
read_timeout=read_timeout,
|
||||||
|
write_timeout=write_timeout,
|
||||||
|
connect_timeout=connect_timeout,
|
||||||
|
pool_timeout=pool_timeout,
|
||||||
|
api_kwargs=api_kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
@_log
|
||||||
|
async def get_my_name(
|
||||||
|
self,
|
||||||
|
language_code: str = None,
|
||||||
|
*,
|
||||||
|
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
api_kwargs: JSONDict = None,
|
||||||
|
) -> BotName:
|
||||||
|
"""
|
||||||
|
Use this method to get the current bot name for the given user language.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
language_code (:obj:`str`, optional): A two-letter ISO 639-1 language code or an empty
|
||||||
|
string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
:class:`telegram.BotName`: On success, the bot name is returned.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
:class:`telegram.error.TelegramError`
|
||||||
|
|
||||||
|
"""
|
||||||
|
data = {"language_code": language_code}
|
||||||
|
return BotName.de_json( # type: ignore[return-value]
|
||||||
|
await self._post(
|
||||||
|
"getMyName",
|
||||||
|
data,
|
||||||
|
read_timeout=read_timeout,
|
||||||
|
write_timeout=write_timeout,
|
||||||
|
connect_timeout=connect_timeout,
|
||||||
|
pool_timeout=pool_timeout,
|
||||||
|
api_kwargs=api_kwargs,
|
||||||
|
),
|
||||||
|
bot=self,
|
||||||
|
)
|
||||||
|
|
||||||
def to_dict(self, recursive: bool = True) -> JSONDict: # skipcq: PYL-W0613
|
def to_dict(self, recursive: bool = True) -> JSONDict: # skipcq: PYL-W0613
|
||||||
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
"""See :meth:`telegram.TelegramObject.to_dict`."""
|
||||||
data: JSONDict = {"id": self.id, "username": self.username, "first_name": self.first_name}
|
data: JSONDict = {"id": self.id, "username": self.username, "first_name": self.first_name}
|
||||||
|
@ -8382,3 +8502,7 @@ CUSTOM_EMOJI_IDENTIFIER_LIMIT` custom emoji identifiers can be specified.
|
||||||
"""Alias for :meth:`set_sticker_keywords`"""
|
"""Alias for :meth:`set_sticker_keywords`"""
|
||||||
setStickerMaskPosition = set_sticker_mask_position
|
setStickerMaskPosition = set_sticker_mask_position
|
||||||
"""Alias for :meth:`set_sticker_mask_position`"""
|
"""Alias for :meth:`set_sticker_mask_position`"""
|
||||||
|
setMyName = set_my_name
|
||||||
|
"""Alias for :meth:`set_my_name`"""
|
||||||
|
getMyName = get_my_name
|
||||||
|
"""Alias for :meth:`get_my_name`"""
|
||||||
|
|
54
telegram/_botname.py
Normal file
54
telegram/_botname.py
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# A library that provides a Python interface to the Telegram Bot API
|
||||||
|
# Copyright (C) 2015-2023
|
||||||
|
# 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 an object that represent a Telegram bots name."""
|
||||||
|
from typing import ClassVar
|
||||||
|
|
||||||
|
from telegram import constants
|
||||||
|
from telegram._telegramobject import TelegramObject
|
||||||
|
from telegram._utils.types import JSONDict
|
||||||
|
|
||||||
|
|
||||||
|
class BotName(TelegramObject):
|
||||||
|
"""This object represents the bot's name.
|
||||||
|
|
||||||
|
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||||
|
considered equal, if their :attr:`name` is equal.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (:obj:`str`): The bot's name.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
name (:obj:`str`): The bot's name.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("name",)
|
||||||
|
|
||||||
|
def __init__(self, name: str, *, api_kwargs: JSONDict = None):
|
||||||
|
super().__init__(api_kwargs=api_kwargs)
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
self._id_attrs = (self.name,)
|
||||||
|
|
||||||
|
self._freeze()
|
||||||
|
|
||||||
|
MAX_LENGTH: ClassVar[int] = constants.BotNameLimit.MAX_NAME_LENGTH
|
||||||
|
""":const:`telegram.constants.BotNameLimit.MAX_NAME_LENGTH`"""
|
|
@ -59,6 +59,10 @@ class ChatMemberUpdated(TelegramObject):
|
||||||
new_chat_member (:class:`telegram.ChatMember`): New information about the chat member.
|
new_chat_member (:class:`telegram.ChatMember`): New information about the chat member.
|
||||||
invite_link (:class:`telegram.ChatInviteLink`, optional): Chat invite link, which was used
|
invite_link (:class:`telegram.ChatInviteLink`, optional): Chat invite link, which was used
|
||||||
by the user to join the chat. For joining by invite link events only.
|
by the user to join the chat. For joining by invite link events only.
|
||||||
|
via_chat_folder_invite_link (:obj:`bool`, optional): :obj:`True`, if the user joined the
|
||||||
|
chat via a chat folder invite link
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
chat (:class:`telegram.Chat`): Chat the user belongs to.
|
chat (:class:`telegram.Chat`): Chat the user belongs to.
|
||||||
|
@ -72,6 +76,10 @@ class ChatMemberUpdated(TelegramObject):
|
||||||
new_chat_member (:class:`telegram.ChatMember`): New information about the chat member.
|
new_chat_member (:class:`telegram.ChatMember`): New information about the chat member.
|
||||||
invite_link (:class:`telegram.ChatInviteLink`): Optional. Chat invite link, which was used
|
invite_link (:class:`telegram.ChatInviteLink`): Optional. Chat invite link, which was used
|
||||||
by the user to join the chat. For joining by invite link events only.
|
by the user to join the chat. For joining by invite link events only.
|
||||||
|
via_chat_folder_invite_link (:obj:`bool`): Optional. :obj:`True`, if the user joined the
|
||||||
|
chat via a chat folder invite link
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -82,6 +90,7 @@ class ChatMemberUpdated(TelegramObject):
|
||||||
"old_chat_member",
|
"old_chat_member",
|
||||||
"new_chat_member",
|
"new_chat_member",
|
||||||
"invite_link",
|
"invite_link",
|
||||||
|
"via_chat_folder_invite_link",
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -92,6 +101,7 @@ class ChatMemberUpdated(TelegramObject):
|
||||||
old_chat_member: ChatMember,
|
old_chat_member: ChatMember,
|
||||||
new_chat_member: ChatMember,
|
new_chat_member: ChatMember,
|
||||||
invite_link: ChatInviteLink = None,
|
invite_link: ChatInviteLink = None,
|
||||||
|
via_chat_folder_invite_link: bool = None,
|
||||||
*,
|
*,
|
||||||
api_kwargs: JSONDict = None,
|
api_kwargs: JSONDict = None,
|
||||||
):
|
):
|
||||||
|
@ -102,6 +112,7 @@ class ChatMemberUpdated(TelegramObject):
|
||||||
self.date: datetime.datetime = date
|
self.date: datetime.datetime = date
|
||||||
self.old_chat_member: ChatMember = old_chat_member
|
self.old_chat_member: ChatMember = old_chat_member
|
||||||
self.new_chat_member: ChatMember = new_chat_member
|
self.new_chat_member: ChatMember = new_chat_member
|
||||||
|
self.via_chat_folder_invite_link: Optional[bool] = via_chat_folder_invite_link
|
||||||
|
|
||||||
# Optionals
|
# Optionals
|
||||||
self.invite_link: Optional[ChatInviteLink] = invite_link
|
self.invite_link: Optional[ChatInviteLink] = invite_link
|
||||||
|
|
|
@ -23,6 +23,7 @@ from typing import TYPE_CHECKING, ClassVar, Optional, Union
|
||||||
from telegram import constants
|
from telegram import constants
|
||||||
from telegram._games.callbackgame import CallbackGame
|
from telegram._games.callbackgame import CallbackGame
|
||||||
from telegram._loginurl import LoginUrl
|
from telegram._loginurl import LoginUrl
|
||||||
|
from telegram._switchinlinequerychosenchat import SwitchInlineQueryChosenChat
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
from telegram._utils.types import JSONDict
|
from telegram._utils.types import JSONDict
|
||||||
from telegram._webappinfo import WebAppInfo
|
from telegram._webappinfo import WebAppInfo
|
||||||
|
@ -111,6 +112,10 @@ class InlineKeyboardButton(TelegramObject):
|
||||||
in inline mode when they are currently in a private chat with it. Especially useful
|
in inline mode when they are currently in a private chat with it. Especially useful
|
||||||
when combined with ``switch_pm*`` actions - in this case the user will be automatically
|
when combined with ``switch_pm*`` actions - in this case the user will be automatically
|
||||||
returned to the chat they switched from, skipping the chat selection screen.
|
returned to the chat they switched from, skipping the chat selection screen.
|
||||||
|
|
||||||
|
Tip:
|
||||||
|
This is similar to the new parameter :paramref:`switch_inline_query_chosen_chat`,
|
||||||
|
but gives no control over which chats can be selected.
|
||||||
switch_inline_query_current_chat (:obj:`str`, optional): If set, pressing the button will
|
switch_inline_query_current_chat (:obj:`str`, optional): If set, pressing the button will
|
||||||
insert the bot's username and the specified inline query in the current chat's input
|
insert the bot's username and the specified inline query in the current chat's input
|
||||||
field. Can be empty, in which case only the bot's username will be inserted. This
|
field. Can be empty, in which case only the bot's username will be inserted. This
|
||||||
|
@ -122,6 +127,20 @@ class InlineKeyboardButton(TelegramObject):
|
||||||
pay (:obj:`bool`, optional): Specify :obj:`True`, to send a Pay button. This type of button
|
pay (:obj:`bool`, optional): Specify :obj:`True`, to send a Pay button. This type of button
|
||||||
**must** always be the **first** button in the first row and can only be used in
|
**must** always be the **first** button in the first row and can only be used in
|
||||||
invoice messages.
|
invoice messages.
|
||||||
|
switch_inline_query_chosen_chat (:obj:`telegram.SwitchInlineQueryChosenChat`, optional):
|
||||||
|
If set, pressing the button will prompt the user to select one of their chats of the
|
||||||
|
specified type, open that chat and insert the bot's username and the specified inline
|
||||||
|
query in the input field.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
|
Tip:
|
||||||
|
This is similar to :paramref:`switch_inline_query`, but gives more control on
|
||||||
|
which chats can be selected.
|
||||||
|
|
||||||
|
Caution:
|
||||||
|
The PTB team has discovered that this field works correctly only if your Telegram
|
||||||
|
client is released after April 20th 2023.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
text (:obj:`str`): Label text on the button.
|
text (:obj:`str`): Label text on the button.
|
||||||
|
@ -154,6 +173,10 @@ class InlineKeyboardButton(TelegramObject):
|
||||||
in inline mode when they are currently in a private chat with it. Especially useful
|
in inline mode when they are currently in a private chat with it. Especially useful
|
||||||
when combined with ``switch_pm*`` actions - in this case the user will be automatically
|
when combined with ``switch_pm*`` actions - in this case the user will be automatically
|
||||||
returned to the chat they switched from, skipping the chat selection screen.
|
returned to the chat they switched from, skipping the chat selection screen.
|
||||||
|
|
||||||
|
Tip:
|
||||||
|
This is similar to the new parameter :paramref:`switch_inline_query_chosen_chat`,
|
||||||
|
but gives no control over which chats can be selected.
|
||||||
switch_inline_query_current_chat (:obj:`str`): Optional. If set, pressing the button will
|
switch_inline_query_current_chat (:obj:`str`): Optional. If set, pressing the button will
|
||||||
insert the bot's username and the specified inline query in the current chat's input
|
insert the bot's username and the specified inline query in the current chat's input
|
||||||
field. Can be empty, in which case only the bot's username will be inserted. This
|
field. Can be empty, in which case only the bot's username will be inserted. This
|
||||||
|
@ -165,7 +188,20 @@ class InlineKeyboardButton(TelegramObject):
|
||||||
pay (:obj:`bool`): Optional. Specify :obj:`True`, to send a Pay button. This type of button
|
pay (:obj:`bool`): Optional. Specify :obj:`True`, to send a Pay button. This type of button
|
||||||
**must** always be the **first** button in the first row and can only be used in
|
**must** always be the **first** button in the first row and can only be used in
|
||||||
invoice messages.
|
invoice messages.
|
||||||
|
switch_inline_query_chosen_chat (:obj:`telegram.SwitchInlineQueryChosenChat`): Optional.
|
||||||
|
If set, pressing the button will prompt the user to select one of their chats of the
|
||||||
|
specified type, open that chat and insert the bot's username and the specified inline
|
||||||
|
query in the input field.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
|
Tip:
|
||||||
|
This is similar to :attr:`switch_inline_query`, but gives more control on
|
||||||
|
which chats can be selected.
|
||||||
|
|
||||||
|
Caution:
|
||||||
|
The PTB team has discovered that this field works correctly only if your Telegram
|
||||||
|
client is released after April 20th 2023.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
|
@ -178,6 +214,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||||
"text",
|
"text",
|
||||||
"login_url",
|
"login_url",
|
||||||
"web_app",
|
"web_app",
|
||||||
|
"switch_inline_query_chosen_chat",
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -191,6 +228,7 @@ class InlineKeyboardButton(TelegramObject):
|
||||||
pay: bool = None,
|
pay: bool = None,
|
||||||
login_url: LoginUrl = None,
|
login_url: LoginUrl = None,
|
||||||
web_app: WebAppInfo = None,
|
web_app: WebAppInfo = None,
|
||||||
|
switch_inline_query_chosen_chat: SwitchInlineQueryChosenChat = None,
|
||||||
*,
|
*,
|
||||||
api_kwargs: JSONDict = None,
|
api_kwargs: JSONDict = None,
|
||||||
):
|
):
|
||||||
|
@ -207,6 +245,9 @@ class InlineKeyboardButton(TelegramObject):
|
||||||
self.callback_game: Optional[CallbackGame] = callback_game
|
self.callback_game: Optional[CallbackGame] = callback_game
|
||||||
self.pay: Optional[bool] = pay
|
self.pay: Optional[bool] = pay
|
||||||
self.web_app: Optional[WebAppInfo] = web_app
|
self.web_app: Optional[WebAppInfo] = web_app
|
||||||
|
self.switch_inline_query_chosen_chat: Optional[
|
||||||
|
SwitchInlineQueryChosenChat
|
||||||
|
] = switch_inline_query_chosen_chat
|
||||||
self._id_attrs = ()
|
self._id_attrs = ()
|
||||||
self._set_id_attrs()
|
self._set_id_attrs()
|
||||||
|
|
||||||
|
@ -236,6 +277,9 @@ class InlineKeyboardButton(TelegramObject):
|
||||||
data["login_url"] = LoginUrl.de_json(data.get("login_url"), bot)
|
data["login_url"] = LoginUrl.de_json(data.get("login_url"), bot)
|
||||||
data["web_app"] = WebAppInfo.de_json(data.get("web_app"), bot)
|
data["web_app"] = WebAppInfo.de_json(data.get("web_app"), bot)
|
||||||
data["callback_game"] = CallbackGame.de_json(data.get("callback_game"), bot)
|
data["callback_game"] = CallbackGame.de_json(data.get("callback_game"), bot)
|
||||||
|
data["switch_inline_query_chosen_chat"] = SwitchInlineQueryChosenChat.de_json(
|
||||||
|
data.get("switch_inline_query_chosen_chat"), bot
|
||||||
|
)
|
||||||
|
|
||||||
return super().de_json(data=data, bot=bot)
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ from typing import TYPE_CHECKING, Callable, ClassVar, Optional, Sequence, Union
|
||||||
|
|
||||||
from telegram import constants
|
from telegram import constants
|
||||||
from telegram._files.location import Location
|
from telegram._files.location import Location
|
||||||
|
from telegram._inline.inlinequeryresultsbutton import InlineQueryResultsButton
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
from telegram._user import User
|
from telegram._user import User
|
||||||
from telegram._utils.defaultvalue import DEFAULT_NONE
|
from telegram._utils.defaultvalue import DEFAULT_NONE
|
||||||
|
@ -146,6 +147,7 @@ class InlineQuery(TelegramObject):
|
||||||
next_offset: str = None,
|
next_offset: str = None,
|
||||||
switch_pm_text: str = None,
|
switch_pm_text: str = None,
|
||||||
switch_pm_parameter: str = None,
|
switch_pm_parameter: str = None,
|
||||||
|
button: InlineQueryResultsButton = None,
|
||||||
*,
|
*,
|
||||||
current_offset: str = None,
|
current_offset: str = None,
|
||||||
auto_pagination: bool = False,
|
auto_pagination: bool = False,
|
||||||
|
@ -192,6 +194,7 @@ class InlineQuery(TelegramObject):
|
||||||
next_offset=next_offset,
|
next_offset=next_offset,
|
||||||
switch_pm_text=switch_pm_text,
|
switch_pm_text=switch_pm_text,
|
||||||
switch_pm_parameter=switch_pm_parameter,
|
switch_pm_parameter=switch_pm_parameter,
|
||||||
|
button=button,
|
||||||
read_timeout=read_timeout,
|
read_timeout=read_timeout,
|
||||||
write_timeout=write_timeout,
|
write_timeout=write_timeout,
|
||||||
connect_timeout=connect_timeout,
|
connect_timeout=connect_timeout,
|
||||||
|
|
117
telegram/_inline/inlinequeryresultsbutton.py
Normal file
117
telegram/_inline/inlinequeryresultsbutton.py
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# A library that provides a Python interface to the Telegram Bot API
|
||||||
|
# Copyright (C) 2015-2023
|
||||||
|
# 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/].
|
||||||
|
# pylint: disable=redefined-builtin
|
||||||
|
"""This module contains the class that represent a Telegram InlineQueryResultsButton."""
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, ClassVar, Optional
|
||||||
|
|
||||||
|
from telegram import constants
|
||||||
|
from telegram._telegramobject import TelegramObject
|
||||||
|
from telegram._utils.types import JSONDict
|
||||||
|
from telegram._webappinfo import WebAppInfo
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from telegram import Bot
|
||||||
|
|
||||||
|
|
||||||
|
class InlineQueryResultsButton(TelegramObject):
|
||||||
|
"""This object represents a button to be shown above inline query results. You **must** use
|
||||||
|
exactly one of the optional fields.
|
||||||
|
|
||||||
|
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||||
|
considered equal, if their :attr:`text`, :attr:`web_app` and :attr:`start_parameter` are equal.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
text (:obj:`str`): Label text on the button.
|
||||||
|
web_app (:class:`telegram.WebAppInfo`, optional): Description of the
|
||||||
|
`Web App <https://core.telegram.org/bots/webapps>`_ that will be launched when the
|
||||||
|
user presses the button. The Web App will be able to switch back to the inline mode
|
||||||
|
using the method
|
||||||
|
`switchInlineQuery <https://core.telegram.org/bots/webapps#initializing-web-apps>`_
|
||||||
|
inside the Web App.
|
||||||
|
start_parameter (:obj:`str`, optional): Deep-linking parameter for the
|
||||||
|
:guilabel:`/start` message sent to the bot when user presses the switch button.
|
||||||
|
:tg-const:`telegram.InlineQuery.MIN_SWITCH_PM_TEXT_LENGTH`-
|
||||||
|
:tg-const:`telegram.InlineQuery.MAX_SWITCH_PM_TEXT_LENGTH` characters,
|
||||||
|
only ``A-Z``, ``a-z``, ``0-9``, ``_`` and ``-`` are allowed.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
An inline bot that sends YouTube videos can ask the user to connect the bot to
|
||||||
|
their YouTube account to adapt search results accordingly. To do this, it displays
|
||||||
|
a 'Connect your YouTube account' button above the results, or even before showing
|
||||||
|
any. The user presses the button, switches to a private chat with the bot and, in
|
||||||
|
doing so, passes a start parameter that instructs the bot to return an OAuth link.
|
||||||
|
Once done, the bot can offer a switch_inline button so that the user can easily
|
||||||
|
return to the chat where they wanted to use the bot's inline capabilities.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
text (:obj:`str`): Label text on the button.
|
||||||
|
web_app (:class:`telegram.WebAppInfo`): Optional. Description of the
|
||||||
|
`Web App <https://core.telegram.org/bots/webapps>`_ that will be launched when the
|
||||||
|
user presses the button. The Web App will be able to switch back to the inline mode
|
||||||
|
using the method ``web_app_switch_inline_query`` inside the Web App.
|
||||||
|
start_parameter (:obj:`str`): Optional. Deep-linking parameter for the
|
||||||
|
:guilabel:`/start` message sent to the bot when user presses the switch button.
|
||||||
|
:tg-const:`telegram.InlineQuery.MIN_SWITCH_PM_TEXT_LENGTH`-
|
||||||
|
:tg-const:`telegram.InlineQuery.MAX_SWITCH_PM_TEXT_LENGTH` characters,
|
||||||
|
only ``A-Z``, ``a-z``, ``0-9``, ``_`` and ``-`` are allowed.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("text", "web_app", "start_parameter")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
text: str,
|
||||||
|
web_app: WebAppInfo = None,
|
||||||
|
start_parameter: str = None,
|
||||||
|
*,
|
||||||
|
api_kwargs: JSONDict = None,
|
||||||
|
):
|
||||||
|
super().__init__(api_kwargs=api_kwargs)
|
||||||
|
|
||||||
|
# Required
|
||||||
|
self.text: str = text
|
||||||
|
|
||||||
|
# Optional
|
||||||
|
self.web_app: Optional[WebAppInfo] = web_app
|
||||||
|
self.start_parameter: Optional[str] = start_parameter
|
||||||
|
|
||||||
|
self._id_attrs = (self.text, self.web_app, self.start_parameter)
|
||||||
|
|
||||||
|
self._freeze()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def de_json(cls, data: Optional[JSONDict], bot: "Bot") -> Optional["InlineQueryResultsButton"]:
|
||||||
|
"""See :meth:`telegram.TelegramObject.de_json`."""
|
||||||
|
if not data:
|
||||||
|
return None
|
||||||
|
|
||||||
|
data["web_app"] = WebAppInfo.de_json(data.get("web_app"), bot)
|
||||||
|
|
||||||
|
return super().de_json(data=data, bot=bot)
|
||||||
|
|
||||||
|
MIN_START_PARAMETER_LENGTH: ClassVar[
|
||||||
|
int
|
||||||
|
] = constants.InlineQueryResultsButtonLimit.MIN_START_PARAMETER_LENGTH
|
||||||
|
""":const:`telegram.constants.InlineQueryResultsButtonLimit.MIN_START_PARAMETER_LENGTH`"""
|
||||||
|
MAX_START_PARAMETER_LENGTH: ClassVar[
|
||||||
|
int
|
||||||
|
] = constants.InlineQueryResultsButtonLimit.MAX_START_PARAMETER_LENGTH
|
||||||
|
""":const:`telegram.constants.InlineQueryResultsButtonLimit.MAX_START_PARAMETER_LENGTH`"""
|
|
@ -59,6 +59,7 @@ from telegram._utils.argumentparsing import parse_sequence_arg
|
||||||
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
|
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
|
||||||
from telegram._utils.defaultvalue import DEFAULT_NONE, DefaultValue
|
from telegram._utils.defaultvalue import DEFAULT_NONE, DefaultValue
|
||||||
from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup
|
from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup
|
||||||
|
from telegram._utils.warnings import warn
|
||||||
from telegram._videochat import (
|
from telegram._videochat import (
|
||||||
VideoChatEnded,
|
VideoChatEnded,
|
||||||
VideoChatParticipantsInvited,
|
VideoChatParticipantsInvited,
|
||||||
|
@ -69,6 +70,7 @@ from telegram._webappdata import WebAppData
|
||||||
from telegram._writeaccessallowed import WriteAccessAllowed
|
from telegram._writeaccessallowed import WriteAccessAllowed
|
||||||
from telegram.constants import MessageAttachmentType, ParseMode
|
from telegram.constants import MessageAttachmentType, ParseMode
|
||||||
from telegram.helpers import escape_markdown
|
from telegram.helpers import escape_markdown
|
||||||
|
from telegram.warnings import PTBDeprecationWarning
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from telegram import (
|
from telegram import (
|
||||||
|
@ -578,8 +580,13 @@ class Message(TelegramObject):
|
||||||
|
|
||||||
.. versionadded:: 20.1
|
.. versionadded:: 20.1
|
||||||
|
|
||||||
.. |custom_emoji_formatting_note| replace:: Custom emoji entities will currently be ignored
|
.. |custom_emoji_formatting_note| replace:: Custom emoji entities will be ignored by this
|
||||||
by this function. Instead, the supplied replacement for the emoji will be used.
|
function. Instead, the supplied replacement for the emoji will be used.
|
||||||
|
|
||||||
|
.. |custom_emoji_md1_deprecation| replace:: Since custom emoji entities are not supported by
|
||||||
|
:attr:`~telegram.constants.ParseMode.MARKDOWN`, this method will raise a
|
||||||
|
:exc:`ValueError` in future versions instead of falling back to the supplied replacement
|
||||||
|
for the emoji.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
@ -3317,6 +3324,10 @@ class Message(TelegramObject):
|
||||||
insert = f"<s>{escaped_text}</s>"
|
insert = f"<s>{escaped_text}</s>"
|
||||||
elif entity.type == MessageEntity.SPOILER:
|
elif entity.type == MessageEntity.SPOILER:
|
||||||
insert = f'<span class="tg-spoiler">{escaped_text}</span>'
|
insert = f'<span class="tg-spoiler">{escaped_text}</span>'
|
||||||
|
elif entity.type == MessageEntity.CUSTOM_EMOJI:
|
||||||
|
insert = (
|
||||||
|
f'<tg-emoji emoji-id="{entity.custom_emoji_id}">{escaped_text}</tg-emoji>'
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
insert = escaped_text
|
insert = escaped_text
|
||||||
|
|
||||||
|
@ -3355,12 +3366,12 @@ class Message(TelegramObject):
|
||||||
Use this if you want to retrieve the message text with the entities formatted as HTML in
|
Use this if you want to retrieve the message text with the entities formatted as HTML in
|
||||||
the same way the original message was formatted.
|
the same way the original message was formatted.
|
||||||
|
|
||||||
Note:
|
|
||||||
|custom_emoji_formatting_note|
|
|
||||||
|
|
||||||
.. versionchanged:: 13.10
|
.. versionchanged:: 13.10
|
||||||
Spoiler entities are now formatted as HTML.
|
Spoiler entities are now formatted as HTML.
|
||||||
|
|
||||||
|
.. versionchanged:: NEXT.VERSION
|
||||||
|
Custom emoji entities are now supported.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`str`: Message text with entities formatted as HTML.
|
:obj:`str`: Message text with entities formatted as HTML.
|
||||||
|
|
||||||
|
@ -3374,12 +3385,12 @@ class Message(TelegramObject):
|
||||||
Use this if you want to retrieve the message text with the entities formatted as HTML.
|
Use this if you want to retrieve the message text with the entities formatted as HTML.
|
||||||
This also formats :attr:`telegram.MessageEntity.URL` as a hyperlink.
|
This also formats :attr:`telegram.MessageEntity.URL` as a hyperlink.
|
||||||
|
|
||||||
Note:
|
|
||||||
|custom_emoji_formatting_note|
|
|
||||||
|
|
||||||
.. versionchanged:: 13.10
|
.. versionchanged:: 13.10
|
||||||
Spoiler entities are now formatted as HTML.
|
Spoiler entities are now formatted as HTML.
|
||||||
|
|
||||||
|
.. versionchanged:: NEXT.VERSION
|
||||||
|
Custom emoji entities are now supported.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`str`: Message text with entities formatted as HTML.
|
:obj:`str`: Message text with entities formatted as HTML.
|
||||||
|
|
||||||
|
@ -3394,12 +3405,12 @@ class Message(TelegramObject):
|
||||||
Use this if you want to retrieve the message caption with the caption entities formatted as
|
Use this if you want to retrieve the message caption with the caption entities formatted as
|
||||||
HTML in the same way the original message was formatted.
|
HTML in the same way the original message was formatted.
|
||||||
|
|
||||||
Note:
|
|
||||||
|custom_emoji_formatting_note|
|
|
||||||
|
|
||||||
.. versionchanged:: 13.10
|
.. versionchanged:: 13.10
|
||||||
Spoiler entities are now formatted as HTML.
|
Spoiler entities are now formatted as HTML.
|
||||||
|
|
||||||
|
.. versionchanged:: NEXT.VERSION
|
||||||
|
Custom emoji entities are now supported.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`str`: Message caption with caption entities formatted as HTML.
|
:obj:`str`: Message caption with caption entities formatted as HTML.
|
||||||
"""
|
"""
|
||||||
|
@ -3413,12 +3424,12 @@ class Message(TelegramObject):
|
||||||
Use this if you want to retrieve the message caption with the caption entities formatted as
|
Use this if you want to retrieve the message caption with the caption entities formatted as
|
||||||
HTML. This also formats :attr:`telegram.MessageEntity.URL` as a hyperlink.
|
HTML. This also formats :attr:`telegram.MessageEntity.URL` as a hyperlink.
|
||||||
|
|
||||||
Note:
|
|
||||||
|custom_emoji_formatting_note|
|
|
||||||
|
|
||||||
.. versionchanged:: 13.10
|
.. versionchanged:: 13.10
|
||||||
Spoiler entities are now formatted as HTML.
|
Spoiler entities are now formatted as HTML.
|
||||||
|
|
||||||
|
.. versionchanged:: NEXT.VERSION
|
||||||
|
Custom emoji entities are now supported.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`str`: Message caption with caption entities formatted as HTML.
|
:obj:`str`: Message caption with caption entities formatted as HTML.
|
||||||
"""
|
"""
|
||||||
|
@ -3522,6 +3533,26 @@ class Message(TelegramObject):
|
||||||
"Spoiler entities are not supported for Markdown version 1"
|
"Spoiler entities are not supported for Markdown version 1"
|
||||||
)
|
)
|
||||||
insert = f"||{escaped_text}||"
|
insert = f"||{escaped_text}||"
|
||||||
|
elif entity.type == MessageEntity.CUSTOM_EMOJI:
|
||||||
|
if version == 1:
|
||||||
|
# this ensures compatibility to previous PTB versions
|
||||||
|
insert = escaped_text
|
||||||
|
warn(
|
||||||
|
"Custom emoji entities are not supported for Markdown version 1. "
|
||||||
|
"Future version of PTB will raise a ValueError instead of falling "
|
||||||
|
"back to the alternative standard emoji.",
|
||||||
|
stacklevel=3,
|
||||||
|
category=PTBDeprecationWarning,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# This should never be needed because ids are numeric but the documentation
|
||||||
|
# specifically mentions it so here we are
|
||||||
|
custom_emoji_id = escape_markdown(
|
||||||
|
entity.custom_emoji_id,
|
||||||
|
version=version,
|
||||||
|
entity_type=MessageEntity.CUSTOM_EMOJI,
|
||||||
|
)
|
||||||
|
insert = f"![{escaped_text}](tg://emoji?id={custom_emoji_id})"
|
||||||
else:
|
else:
|
||||||
insert = escaped_text
|
insert = escaped_text
|
||||||
|
|
||||||
|
@ -3570,6 +3601,9 @@ class Message(TelegramObject):
|
||||||
|
|
||||||
* |custom_emoji_formatting_note|
|
* |custom_emoji_formatting_note|
|
||||||
|
|
||||||
|
.. deprecated:: NEXT.VERSION
|
||||||
|
|custom_emoji_md1_deprecation|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`str`: Message text with entities formatted as Markdown.
|
:obj:`str`: Message text with entities formatted as Markdown.
|
||||||
|
|
||||||
|
@ -3588,12 +3622,12 @@ class Message(TelegramObject):
|
||||||
Use this if you want to retrieve the message text with the entities formatted as Markdown
|
Use this if you want to retrieve the message text with the entities formatted as Markdown
|
||||||
in the same way the original message was formatted.
|
in the same way the original message was formatted.
|
||||||
|
|
||||||
Note:
|
|
||||||
|custom_emoji_formatting_note|
|
|
||||||
|
|
||||||
.. versionchanged:: 13.10
|
.. versionchanged:: 13.10
|
||||||
Spoiler entities are now formatted as Markdown V2.
|
Spoiler entities are now formatted as Markdown V2.
|
||||||
|
|
||||||
|
.. versionchanged:: NEXT.VERSION
|
||||||
|
Custom emoji entities are now supported.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`str`: Message text with entities formatted as Markdown.
|
:obj:`str`: Message text with entities formatted as Markdown.
|
||||||
"""
|
"""
|
||||||
|
@ -3614,6 +3648,9 @@ class Message(TelegramObject):
|
||||||
|
|
||||||
* |custom_emoji_formatting_note|
|
* |custom_emoji_formatting_note|
|
||||||
|
|
||||||
|
.. deprecated:: NEXT.VERSION
|
||||||
|
|custom_emoji_md1_deprecation|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`str`: Message text with entities formatted as Markdown.
|
:obj:`str`: Message text with entities formatted as Markdown.
|
||||||
|
|
||||||
|
@ -3632,12 +3669,12 @@ class Message(TelegramObject):
|
||||||
Use this if you want to retrieve the message text with the entities formatted as Markdown.
|
Use this if you want to retrieve the message text with the entities formatted as Markdown.
|
||||||
This also formats :attr:`telegram.MessageEntity.URL` as a hyperlink.
|
This also formats :attr:`telegram.MessageEntity.URL` as a hyperlink.
|
||||||
|
|
||||||
Note:
|
|
||||||
|custom_emoji_formatting_note|
|
|
||||||
|
|
||||||
.. versionchanged:: 13.10
|
.. versionchanged:: 13.10
|
||||||
Spoiler entities are now formatted as Markdown V2.
|
Spoiler entities are now formatted as Markdown V2.
|
||||||
|
|
||||||
|
.. versionchanged:: NEXT.VERSION
|
||||||
|
Custom emoji entities are now supported.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`str`: Message text with entities formatted as Markdown.
|
:obj:`str`: Message text with entities formatted as Markdown.
|
||||||
"""
|
"""
|
||||||
|
@ -3658,6 +3695,9 @@ class Message(TelegramObject):
|
||||||
|
|
||||||
* |custom_emoji_formatting_note|
|
* |custom_emoji_formatting_note|
|
||||||
|
|
||||||
|
.. deprecated:: NEXT.VERSION
|
||||||
|
|custom_emoji_md1_deprecation|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`str`: Message caption with caption entities formatted as Markdown.
|
:obj:`str`: Message caption with caption entities formatted as Markdown.
|
||||||
|
|
||||||
|
@ -3676,12 +3716,12 @@ class Message(TelegramObject):
|
||||||
Use this if you want to retrieve the message caption with the caption entities formatted as
|
Use this if you want to retrieve the message caption with the caption entities formatted as
|
||||||
Markdown in the same way the original message was formatted.
|
Markdown in the same way the original message was formatted.
|
||||||
|
|
||||||
Note:
|
|
||||||
|custom_emoji_formatting_note|
|
|
||||||
|
|
||||||
.. versionchanged:: 13.10
|
.. versionchanged:: 13.10
|
||||||
Spoiler entities are now formatted as Markdown V2.
|
Spoiler entities are now formatted as Markdown V2.
|
||||||
|
|
||||||
|
.. versionchanged:: NEXT.VERSION
|
||||||
|
Custom emoji entities are now supported.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`str`: Message caption with caption entities formatted as Markdown.
|
:obj:`str`: Message caption with caption entities formatted as Markdown.
|
||||||
"""
|
"""
|
||||||
|
@ -3704,6 +3744,9 @@ class Message(TelegramObject):
|
||||||
|
|
||||||
* |custom_emoji_formatting_note|
|
* |custom_emoji_formatting_note|
|
||||||
|
|
||||||
|
.. deprecated:: NEXT.VERSION
|
||||||
|
|custom_emoji_md1_deprecation|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`str`: Message caption with caption entities formatted as Markdown.
|
:obj:`str`: Message caption with caption entities formatted as Markdown.
|
||||||
|
|
||||||
|
@ -3722,12 +3765,12 @@ class Message(TelegramObject):
|
||||||
Use this if you want to retrieve the message caption with the caption entities formatted as
|
Use this if you want to retrieve the message caption with the caption entities formatted as
|
||||||
Markdown. This also formats :attr:`telegram.MessageEntity.URL` as a hyperlink.
|
Markdown. This also formats :attr:`telegram.MessageEntity.URL` as a hyperlink.
|
||||||
|
|
||||||
Note:
|
|
||||||
|custom_emoji_formatting_note|
|
|
||||||
|
|
||||||
.. versionchanged:: 13.10
|
.. versionchanged:: 13.10
|
||||||
Spoiler entities are now formatted as Markdown V2.
|
Spoiler entities are now formatted as Markdown V2.
|
||||||
|
|
||||||
|
.. versionchanged:: NEXT.VERSION
|
||||||
|
Custom emoji entities are now supported.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`str`: Message caption with caption entities formatted as Markdown.
|
:obj:`str`: Message caption with caption entities formatted as Markdown.
|
||||||
"""
|
"""
|
||||||
|
|
99
telegram/_switchinlinequerychosenchat.py
Normal file
99
telegram/_switchinlinequerychosenchat.py
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# A library that provides a Python interface to the Telegram Bot API
|
||||||
|
# Copyright (C) 2015-2023
|
||||||
|
# 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
|
||||||
|
"""This module contains a class that represents a Telegram SwitchInlineQueryChosenChat."""
|
||||||
|
|
||||||
|
from telegram._telegramobject import TelegramObject
|
||||||
|
from telegram._utils.types import JSONDict
|
||||||
|
|
||||||
|
|
||||||
|
class SwitchInlineQueryChosenChat(TelegramObject):
|
||||||
|
"""
|
||||||
|
This object represents an inline button that switches the current user to inline mode in a
|
||||||
|
chosen chat, with an optional default inline query.
|
||||||
|
|
||||||
|
Objects of this class are comparable in terms of equality. Two objects of this class are
|
||||||
|
considered equal, if their :attr:`query`, :attr:`allow_user_chats`, :attr:`allow_bot_chats`,
|
||||||
|
:attr:`allow_group_chats`, and :attr:`allow_channel_chats` are equal.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
|
Caution:
|
||||||
|
The PTB team has discovered that you must pass at least one of
|
||||||
|
:paramref:`allow_user_chats`, :paramref:`allow_bot_chats`, :paramref:`allow_group_chats`,
|
||||||
|
or :paramref:`allow_channel_chats` to Telegram. Otherwise, an error will be raised.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
query (:obj:`str`, optional): The default inline query to be inserted in the input field.
|
||||||
|
If left empty, only the bot's username will be inserted.
|
||||||
|
allow_user_chats (:obj:`bool`, optional): Pass :obj:`True`, if private chats with users
|
||||||
|
can be chosen.
|
||||||
|
allow_bot_chats (:obj:`bool`, optional): Pass :obj:`True`, if private chats with bots can
|
||||||
|
be chosen.
|
||||||
|
allow_group_chats (:obj:`bool`, optional): Pass :obj:`True`, if group and supergroup chats
|
||||||
|
can be chosen.
|
||||||
|
allow_channel_chats (:obj:`bool`, optional): Pass :obj:`True`, if channel chats can be
|
||||||
|
chosen.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
query (:obj:`str`): Optional. The default inline query to be inserted in the input field.
|
||||||
|
If left empty, only the bot's username will be inserted.
|
||||||
|
allow_user_chats (:obj:`bool`): Optional. :obj:`True`, if private chats with users can be
|
||||||
|
chosen.
|
||||||
|
allow_bot_chats (:obj:`bool`): Optional. :obj:`True`, if private chats with bots can be
|
||||||
|
chosen.
|
||||||
|
allow_group_chats (:obj:`bool`): Optional. :obj:`True`, if group and supergroup chats can
|
||||||
|
be chosen.
|
||||||
|
allow_channel_chats (:obj:`bool`): Optional. :obj:`True`, if channel chats can be chosen.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"query",
|
||||||
|
"allow_user_chats",
|
||||||
|
"allow_bot_chats",
|
||||||
|
"allow_group_chats",
|
||||||
|
"allow_channel_chats",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
query: str = None,
|
||||||
|
allow_user_chats: bool = None,
|
||||||
|
allow_bot_chats: bool = None,
|
||||||
|
allow_group_chats: bool = None,
|
||||||
|
allow_channel_chats: bool = None,
|
||||||
|
*,
|
||||||
|
api_kwargs: JSONDict = None,
|
||||||
|
):
|
||||||
|
super().__init__(api_kwargs=api_kwargs)
|
||||||
|
# Optional
|
||||||
|
self.query = query
|
||||||
|
self.allow_user_chats = allow_user_chats
|
||||||
|
self.allow_bot_chats = allow_bot_chats
|
||||||
|
self.allow_group_chats = allow_group_chats
|
||||||
|
self.allow_channel_chats = allow_channel_chats
|
||||||
|
|
||||||
|
self._id_attrs = (
|
||||||
|
self.query,
|
||||||
|
self.allow_user_chats,
|
||||||
|
self.allow_bot_chats,
|
||||||
|
self.allow_group_chats,
|
||||||
|
self.allow_channel_chats,
|
||||||
|
)
|
||||||
|
|
||||||
|
self._freeze()
|
|
@ -17,21 +17,35 @@
|
||||||
# You should have received a copy of the GNU Lesser Public License
|
# You should have received a copy of the GNU Lesser Public License
|
||||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||||
"""This module contains objects related to the write access allowed service message."""
|
"""This module contains objects related to the write access allowed service message."""
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from telegram._telegramobject import TelegramObject
|
from telegram._telegramobject import TelegramObject
|
||||||
from telegram._utils.types import JSONDict
|
from telegram._utils.types import JSONDict
|
||||||
|
|
||||||
|
|
||||||
class WriteAccessAllowed(TelegramObject):
|
class WriteAccessAllowed(TelegramObject):
|
||||||
"""
|
"""
|
||||||
This object represents a service message about a user allowing a bot added to the attachment
|
This object represents a service message about a user allowing a bot to write messages after
|
||||||
menu to write messages. Currently holds no information.
|
adding the bot to the attachment menu or launching a Web App from a link.
|
||||||
|
|
||||||
.. versionadded:: 20.0
|
.. versionadded:: 20.0
|
||||||
|
|
||||||
|
Args:
|
||||||
|
web_app_name (:obj:`str`, optional): Name of the Web App which was launched from a link.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
web_app_name (:obj:`str`): Optional. Name of the Web App which was launched from a link.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ("web_app_name",)
|
||||||
|
|
||||||
def __init__(self, *, api_kwargs: JSONDict = None):
|
def __init__(self, web_app_name: str = None, *, api_kwargs: JSONDict = None):
|
||||||
super().__init__(api_kwargs=api_kwargs)
|
super().__init__(api_kwargs=api_kwargs)
|
||||||
|
self.web_app_name: Optional[str] = web_app_name
|
||||||
|
|
||||||
self._freeze()
|
self._freeze()
|
||||||
|
|
|
@ -37,6 +37,7 @@ __all__ = [
|
||||||
"BotCommandLimit",
|
"BotCommandLimit",
|
||||||
"BotCommandScopeType",
|
"BotCommandScopeType",
|
||||||
"BotDescriptionLimit",
|
"BotDescriptionLimit",
|
||||||
|
"BotNameLimit",
|
||||||
"CallbackQueryLimit",
|
"CallbackQueryLimit",
|
||||||
"ChatAction",
|
"ChatAction",
|
||||||
"ChatID",
|
"ChatID",
|
||||||
|
@ -57,6 +58,7 @@ __all__ = [
|
||||||
"InlineKeyboardMarkupLimit",
|
"InlineKeyboardMarkupLimit",
|
||||||
"InlineQueryLimit",
|
"InlineQueryLimit",
|
||||||
"InlineQueryResultLimit",
|
"InlineQueryResultLimit",
|
||||||
|
"InlineQueryResultsButtonLimit",
|
||||||
"InlineQueryResultType",
|
"InlineQueryResultType",
|
||||||
"InputMediaType",
|
"InputMediaType",
|
||||||
"InvoiceLimit",
|
"InvoiceLimit",
|
||||||
|
@ -114,7 +116,7 @@ class _BotAPIVersion(NamedTuple):
|
||||||
#: :data:`telegram.__bot_api_version_info__`.
|
#: :data:`telegram.__bot_api_version_info__`.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 20.0
|
#: .. versionadded:: 20.0
|
||||||
BOT_API_VERSION_INFO = _BotAPIVersion(major=6, minor=6)
|
BOT_API_VERSION_INFO = _BotAPIVersion(major=6, minor=7)
|
||||||
#: :obj:`str`: Telegram Bot API
|
#: :obj:`str`: Telegram Bot API
|
||||||
#: version supported by this version of `python-telegram-bot`. Also available as
|
#: version supported by this version of `python-telegram-bot`. Also available as
|
||||||
#: :data:`telegram.__bot_api_version__`.
|
#: :data:`telegram.__bot_api_version__`.
|
||||||
|
@ -209,6 +211,21 @@ class BotDescriptionLimit(IntEnum):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class BotNameLimit(IntEnum):
|
||||||
|
"""This enum contains limitations for the methods :meth:`telegram.Bot.set_my_name`.
|
||||||
|
The enum members of this enumeration are instances of :class:`int` and can be treated as such.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
|
MAX_NAME_LENGTH = 64
|
||||||
|
""":obj:`int`: Maximum length for the parameter :paramref:`~telegram.Bot.set_my_name.name` of
|
||||||
|
:meth:`telegram.Bot.set_my_name`
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class CallbackQueryLimit(IntEnum):
|
class CallbackQueryLimit(IntEnum):
|
||||||
"""This enum contains limitations for :class:`telegram.CallbackQuery`/
|
"""This enum contains limitations for :class:`telegram.CallbackQuery`/
|
||||||
:meth:`telegram.Bot.answer_callback_query`. The enum members of this enumeration are instances
|
:meth:`telegram.Bot.answer_callback_query`. The enum members of this enumeration are instances
|
||||||
|
@ -735,11 +752,19 @@ class InlineQueryLimit(IntEnum):
|
||||||
MIN_SWITCH_PM_TEXT_LENGTH = 1
|
MIN_SWITCH_PM_TEXT_LENGTH = 1
|
||||||
""":obj:`int`: Minimum number of characters in a :obj:`str` passed as the
|
""":obj:`int`: Minimum number of characters in a :obj:`str` passed as the
|
||||||
:paramref:`~telegram.Bot.answer_inline_query.switch_pm_parameter` parameter of
|
:paramref:`~telegram.Bot.answer_inline_query.switch_pm_parameter` parameter of
|
||||||
:meth:`telegram.Bot.answer_inline_query`."""
|
:meth:`telegram.Bot.answer_inline_query`.
|
||||||
|
|
||||||
|
.. deprecated:: NEXT.VERSION
|
||||||
|
Deprecated in favor of :attr:`InlineQueryResultsButtonLimit.MIN_START_PARAMETER_LENGTH`.
|
||||||
|
"""
|
||||||
MAX_SWITCH_PM_TEXT_LENGTH = 64
|
MAX_SWITCH_PM_TEXT_LENGTH = 64
|
||||||
""":obj:`int`: Maximum number of characters in a :obj:`str` passed as the
|
""":obj:`int`: Maximum number of characters in a :obj:`str` passed as the
|
||||||
:paramref:`~telegram.Bot.answer_inline_query.switch_pm_parameter` parameter of
|
:paramref:`~telegram.Bot.answer_inline_query.switch_pm_parameter` parameter of
|
||||||
:meth:`telegram.Bot.answer_inline_query`."""
|
:meth:`telegram.Bot.answer_inline_query`.
|
||||||
|
|
||||||
|
.. deprecated:: NEXT.VERSION
|
||||||
|
Deprecated in favor of :attr:`InlineQueryResultsButtonLimit.MAX_START_PARAMETER_LENGTH`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class InlineQueryResultLimit(IntEnum):
|
class InlineQueryResultLimit(IntEnum):
|
||||||
|
@ -763,6 +788,26 @@ class InlineQueryResultLimit(IntEnum):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class InlineQueryResultsButtonLimit(IntEnum):
|
||||||
|
"""This enum contains limitations for :class:`telegram.InlineQueryResultsButton`.
|
||||||
|
The enum members of this enumeration are instances of :class:`int` and can be treated as such.
|
||||||
|
|
||||||
|
.. versionadded:: NEXT.VERSION
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
|
MIN_START_PARAMETER_LENGTH = InlineQueryLimit.MIN_SWITCH_PM_TEXT_LENGTH
|
||||||
|
""":obj:`int`: Minimum number of characters in a :obj:`str` passed as the
|
||||||
|
:paramref:`~telegram.InlineQueryResultsButton.start_parameter` parameter of
|
||||||
|
:meth:`telegram.InlineQueryResultsButton`."""
|
||||||
|
|
||||||
|
MAX_START_PARAMETER_LENGTH = InlineQueryLimit.MAX_SWITCH_PM_TEXT_LENGTH
|
||||||
|
""":obj:`int`: Maximum number of characters in a :obj:`str` passed as the
|
||||||
|
:paramref:`~telegram.InlineQueryResultsButton.start_parameter` parameter of
|
||||||
|
:meth:`telegram.InlineQueryResultsButton`."""
|
||||||
|
|
||||||
|
|
||||||
class InlineQueryResultType(StringEnum):
|
class InlineQueryResultType(StringEnum):
|
||||||
"""This enum contains the available types of :class:`telegram.InlineQueryResult`. The enum
|
"""This enum contains the available types of :class:`telegram.InlineQueryResult`. The enum
|
||||||
members of this enumeration are instances of :class:`str` and can be treated as such.
|
members of this enumeration are instances of :class:`str` and can be treated as such.
|
||||||
|
|
|
@ -46,6 +46,7 @@ from telegram import (
|
||||||
BotCommand,
|
BotCommand,
|
||||||
BotCommandScope,
|
BotCommandScope,
|
||||||
BotDescription,
|
BotDescription,
|
||||||
|
BotName,
|
||||||
BotShortDescription,
|
BotShortDescription,
|
||||||
CallbackQuery,
|
CallbackQuery,
|
||||||
Chat,
|
Chat,
|
||||||
|
@ -60,6 +61,7 @@ from telegram import (
|
||||||
ForumTopic,
|
ForumTopic,
|
||||||
GameHighScore,
|
GameHighScore,
|
||||||
InlineKeyboardMarkup,
|
InlineKeyboardMarkup,
|
||||||
|
InlineQueryResultsButton,
|
||||||
InputMedia,
|
InputMedia,
|
||||||
InputSticker,
|
InputSticker,
|
||||||
Location,
|
Location,
|
||||||
|
@ -792,6 +794,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||||
next_offset: str = None,
|
next_offset: str = None,
|
||||||
switch_pm_text: str = None,
|
switch_pm_text: str = None,
|
||||||
switch_pm_parameter: str = None,
|
switch_pm_parameter: str = None,
|
||||||
|
button: InlineQueryResultsButton = None,
|
||||||
*,
|
*,
|
||||||
current_offset: str = None,
|
current_offset: str = None,
|
||||||
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
@ -814,6 +817,7 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||||
write_timeout=write_timeout,
|
write_timeout=write_timeout,
|
||||||
connect_timeout=connect_timeout,
|
connect_timeout=connect_timeout,
|
||||||
pool_timeout=pool_timeout,
|
pool_timeout=pool_timeout,
|
||||||
|
button=button,
|
||||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3581,6 +3585,48 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||||
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def set_my_name(
|
||||||
|
self,
|
||||||
|
name: str = None,
|
||||||
|
language_code: str = None,
|
||||||
|
*,
|
||||||
|
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
api_kwargs: JSONDict = None,
|
||||||
|
rate_limit_args: RLARGS = None,
|
||||||
|
) -> bool:
|
||||||
|
return await super().set_my_name(
|
||||||
|
name=name,
|
||||||
|
language_code=language_code,
|
||||||
|
read_timeout=read_timeout,
|
||||||
|
write_timeout=write_timeout,
|
||||||
|
connect_timeout=connect_timeout,
|
||||||
|
pool_timeout=pool_timeout,
|
||||||
|
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||||
|
)
|
||||||
|
|
||||||
|
async def get_my_name(
|
||||||
|
self,
|
||||||
|
language_code: str = None,
|
||||||
|
*,
|
||||||
|
read_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
write_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
connect_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
pool_timeout: ODVInput[float] = DEFAULT_NONE,
|
||||||
|
api_kwargs: JSONDict = None,
|
||||||
|
rate_limit_args: RLARGS = None,
|
||||||
|
) -> BotName:
|
||||||
|
return await super().get_my_name(
|
||||||
|
language_code=language_code,
|
||||||
|
read_timeout=read_timeout,
|
||||||
|
write_timeout=write_timeout,
|
||||||
|
connect_timeout=connect_timeout,
|
||||||
|
pool_timeout=pool_timeout,
|
||||||
|
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
|
||||||
|
)
|
||||||
|
|
||||||
async def set_custom_emoji_sticker_set_thumbnail(
|
async def set_custom_emoji_sticker_set_thumbnail(
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
|
@ -3823,3 +3869,5 @@ class ExtBot(Bot, Generic[RLARGS]):
|
||||||
setStickerEmojiList = set_sticker_emoji_list
|
setStickerEmojiList = set_sticker_emoji_list
|
||||||
setStickerKeywords = set_sticker_keywords
|
setStickerKeywords = set_sticker_keywords
|
||||||
setStickerMaskPosition = set_sticker_mask_position
|
setStickerMaskPosition = set_sticker_mask_position
|
||||||
|
setMyName = set_my_name
|
||||||
|
getMyName = get_my_name
|
||||||
|
|
|
@ -44,23 +44,27 @@ if TYPE_CHECKING:
|
||||||
def escape_markdown(text: str, version: int = 1, entity_type: str = None) -> str:
|
def escape_markdown(text: str, version: int = 1, entity_type: str = None) -> str:
|
||||||
"""Helper function to escape telegram markup symbols.
|
"""Helper function to escape telegram markup symbols.
|
||||||
|
|
||||||
|
.. versionchanged:: NEXT.VERSION
|
||||||
|
Custom emoji entity escaping is now supported.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
text (:obj:`str`): The text.
|
text (:obj:`str`): The text.
|
||||||
version (:obj:`int` | :obj:`str`): Use to specify the version of telegrams Markdown.
|
version (:obj:`int` | :obj:`str`): Use to specify the version of telegrams Markdown.
|
||||||
Either ``1`` or ``2``. Defaults to ``1``.
|
Either ``1`` or ``2``. Defaults to ``1``.
|
||||||
entity_type (:obj:`str`, optional): For the entity types
|
entity_type (:obj:`str`, optional): For the entity types
|
||||||
:tg-const:`telegram.MessageEntity.PRE`, :tg-const:`telegram.MessageEntity.CODE` and
|
:tg-const:`telegram.MessageEntity.PRE`, :tg-const:`telegram.MessageEntity.CODE` and
|
||||||
the link part of :tg-const:`telegram.MessageEntity.TEXT_LINK`, only certain characters
|
the link part of :tg-const:`telegram.MessageEntity.TEXT_LINK` and
|
||||||
need to be escaped in :tg-const:`telegram.constants.ParseMode.MARKDOWN_V2`.
|
:tg-const:`telegram.MessageEntity.CUSTOM_EMOJI`, only certain characters need to be
|
||||||
See the official API documentation for details. Only valid in combination with
|
escaped in :tg-const:`telegram.constants.ParseMode.MARKDOWN_V2`. See the `official API
|
||||||
``version=2``, will be ignored else.
|
documentation <https://core.telegram.org/bots/api#formatting-options>`_ for details.
|
||||||
|
Only valid in combination with ``version=2``, will be ignored else.
|
||||||
"""
|
"""
|
||||||
if int(version) == 1:
|
if int(version) == 1:
|
||||||
escape_chars = r"_*`["
|
escape_chars = r"_*`["
|
||||||
elif int(version) == 2:
|
elif int(version) == 2:
|
||||||
if entity_type in ["pre", "code"]:
|
if entity_type in ["pre", "code"]:
|
||||||
escape_chars = r"\`"
|
escape_chars = r"\`"
|
||||||
elif entity_type == "text_link":
|
elif entity_type in ["text_link", "custom_emoji"]:
|
||||||
escape_chars = r"\)"
|
escape_chars = r"\)"
|
||||||
else:
|
else:
|
||||||
escape_chars = r"\_*[]()~`>#+-=|{}.!"
|
escape_chars = r"\_*[]()~`>#+-=|{}.!"
|
||||||
|
|
|
@ -19,7 +19,13 @@
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from telegram import CallbackGame, InlineKeyboardButton, LoginUrl, WebAppInfo
|
from telegram import (
|
||||||
|
CallbackGame,
|
||||||
|
InlineKeyboardButton,
|
||||||
|
LoginUrl,
|
||||||
|
SwitchInlineQueryChosenChat,
|
||||||
|
WebAppInfo,
|
||||||
|
)
|
||||||
from tests.auxil.slots import mro_slots
|
from tests.auxil.slots import mro_slots
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,6 +41,7 @@ def inline_keyboard_button():
|
||||||
pay=TestInlineKeyboardButtonBase.pay,
|
pay=TestInlineKeyboardButtonBase.pay,
|
||||||
login_url=TestInlineKeyboardButtonBase.login_url,
|
login_url=TestInlineKeyboardButtonBase.login_url,
|
||||||
web_app=TestInlineKeyboardButtonBase.web_app,
|
web_app=TestInlineKeyboardButtonBase.web_app,
|
||||||
|
switch_inline_query_chosen_chat=TestInlineKeyboardButtonBase.switch_inline_query_chosen_chat, # noqa: E501
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,6 +55,7 @@ class TestInlineKeyboardButtonBase:
|
||||||
pay = True
|
pay = True
|
||||||
login_url = LoginUrl("http://google.com")
|
login_url = LoginUrl("http://google.com")
|
||||||
web_app = WebAppInfo(url="https://example.com")
|
web_app = WebAppInfo(url="https://example.com")
|
||||||
|
switch_inline_query_chosen_chat = SwitchInlineQueryChosenChat("a_bot", True, False, True, True)
|
||||||
|
|
||||||
|
|
||||||
class TestInlineKeyboardButtonWithoutRequest(TestInlineKeyboardButtonBase):
|
class TestInlineKeyboardButtonWithoutRequest(TestInlineKeyboardButtonBase):
|
||||||
|
@ -70,6 +78,10 @@ class TestInlineKeyboardButtonWithoutRequest(TestInlineKeyboardButtonBase):
|
||||||
assert inline_keyboard_button.pay == self.pay
|
assert inline_keyboard_button.pay == self.pay
|
||||||
assert inline_keyboard_button.login_url == self.login_url
|
assert inline_keyboard_button.login_url == self.login_url
|
||||||
assert inline_keyboard_button.web_app == self.web_app
|
assert inline_keyboard_button.web_app == self.web_app
|
||||||
|
assert (
|
||||||
|
inline_keyboard_button.switch_inline_query_chosen_chat
|
||||||
|
== self.switch_inline_query_chosen_chat
|
||||||
|
)
|
||||||
|
|
||||||
def test_to_dict(self, inline_keyboard_button):
|
def test_to_dict(self, inline_keyboard_button):
|
||||||
inline_keyboard_button_dict = inline_keyboard_button.to_dict()
|
inline_keyboard_button_dict = inline_keyboard_button.to_dict()
|
||||||
|
@ -95,6 +107,10 @@ class TestInlineKeyboardButtonWithoutRequest(TestInlineKeyboardButtonBase):
|
||||||
inline_keyboard_button_dict["login_url"] == inline_keyboard_button.login_url.to_dict()
|
inline_keyboard_button_dict["login_url"] == inline_keyboard_button.login_url.to_dict()
|
||||||
)
|
)
|
||||||
assert inline_keyboard_button_dict["web_app"] == inline_keyboard_button.web_app.to_dict()
|
assert inline_keyboard_button_dict["web_app"] == inline_keyboard_button.web_app.to_dict()
|
||||||
|
assert (
|
||||||
|
inline_keyboard_button_dict["switch_inline_query_chosen_chat"]
|
||||||
|
== inline_keyboard_button.switch_inline_query_chosen_chat.to_dict()
|
||||||
|
)
|
||||||
|
|
||||||
def test_de_json(self, bot):
|
def test_de_json(self, bot):
|
||||||
json_dict = {
|
json_dict = {
|
||||||
|
@ -107,6 +123,7 @@ class TestInlineKeyboardButtonWithoutRequest(TestInlineKeyboardButtonBase):
|
||||||
"web_app": self.web_app.to_dict(),
|
"web_app": self.web_app.to_dict(),
|
||||||
"login_url": self.login_url.to_dict(),
|
"login_url": self.login_url.to_dict(),
|
||||||
"pay": self.pay,
|
"pay": self.pay,
|
||||||
|
"switch_inline_query_chosen_chat": self.switch_inline_query_chosen_chat.to_dict(),
|
||||||
}
|
}
|
||||||
|
|
||||||
inline_keyboard_button = InlineKeyboardButton.de_json(json_dict, None)
|
inline_keyboard_button = InlineKeyboardButton.de_json(json_dict, None)
|
||||||
|
@ -124,6 +141,10 @@ class TestInlineKeyboardButtonWithoutRequest(TestInlineKeyboardButtonBase):
|
||||||
assert inline_keyboard_button.pay == self.pay
|
assert inline_keyboard_button.pay == self.pay
|
||||||
assert inline_keyboard_button.login_url == self.login_url
|
assert inline_keyboard_button.login_url == self.login_url
|
||||||
assert inline_keyboard_button.web_app == self.web_app
|
assert inline_keyboard_button.web_app == self.web_app
|
||||||
|
assert (
|
||||||
|
inline_keyboard_button.switch_inline_query_chosen_chat
|
||||||
|
== self.switch_inline_query_chosen_chat
|
||||||
|
)
|
||||||
|
|
||||||
none = InlineKeyboardButton.de_json({}, bot)
|
none = InlineKeyboardButton.de_json({}, bot)
|
||||||
assert none is None
|
assert none is None
|
||||||
|
|
|
@ -34,6 +34,7 @@ from telegram import (
|
||||||
BotCommand,
|
BotCommand,
|
||||||
BotCommandScopeChat,
|
BotCommandScopeChat,
|
||||||
BotDescription,
|
BotDescription,
|
||||||
|
BotName,
|
||||||
BotShortDescription,
|
BotShortDescription,
|
||||||
CallbackQuery,
|
CallbackQuery,
|
||||||
Chat,
|
Chat,
|
||||||
|
@ -44,6 +45,7 @@ from telegram import (
|
||||||
InlineKeyboardMarkup,
|
InlineKeyboardMarkup,
|
||||||
InlineQueryResultArticle,
|
InlineQueryResultArticle,
|
||||||
InlineQueryResultDocument,
|
InlineQueryResultDocument,
|
||||||
|
InlineQueryResultsButton,
|
||||||
InlineQueryResultVoice,
|
InlineQueryResultVoice,
|
||||||
InputFile,
|
InputFile,
|
||||||
InputMessageContent,
|
InputMessageContent,
|
||||||
|
@ -76,7 +78,7 @@ from telegram.error import BadRequest, InvalidToken, NetworkError
|
||||||
from telegram.ext import ExtBot, InvalidCallbackData
|
from telegram.ext import ExtBot, InvalidCallbackData
|
||||||
from telegram.helpers import escape_markdown
|
from telegram.helpers import escape_markdown
|
||||||
from telegram.request import BaseRequest, HTTPXRequest, RequestData
|
from telegram.request import BaseRequest, HTTPXRequest, RequestData
|
||||||
from telegram.warnings import PTBUserWarning
|
from telegram.warnings import PTBDeprecationWarning, PTBUserWarning
|
||||||
from tests.auxil.bot_method_checks import check_defaults_handling
|
from tests.auxil.bot_method_checks import check_defaults_handling
|
||||||
from tests.auxil.ci_bots import FALLBACKS
|
from tests.auxil.ci_bots import FALLBACKS
|
||||||
from tests.auxil.envvars import GITHUB_ACTION, TEST_WITH_OPT_DEPS
|
from tests.auxil.envvars import GITHUB_ACTION, TEST_WITH_OPT_DEPS
|
||||||
|
@ -655,10 +657,11 @@ class TestBotWithoutRequest:
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: Needs improvement. We need incoming inline query to test answer.
|
# TODO: Needs improvement. We need incoming inline query to test answer.
|
||||||
async def test_answer_inline_query(self, monkeypatch, bot, raw_bot):
|
@pytest.mark.parametrize("button_type", ["start", "web_app", "backward_compat"])
|
||||||
|
async def test_answer_inline_query(self, monkeypatch, bot, raw_bot, button_type):
|
||||||
# For now just test that our internals pass the correct data
|
# For now just test that our internals pass the correct data
|
||||||
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||||
return request_data.parameters == {
|
expected = {
|
||||||
"cache_time": 300,
|
"cache_time": 300,
|
||||||
"results": [
|
"results": [
|
||||||
{
|
{
|
||||||
|
@ -685,12 +688,22 @@ class TestBotWithoutRequest:
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"next_offset": "42",
|
"next_offset": "42",
|
||||||
"switch_pm_parameter": "start_pm",
|
|
||||||
"inline_query_id": 1234,
|
"inline_query_id": 1234,
|
||||||
"is_personal": True,
|
"is_personal": True,
|
||||||
"switch_pm_text": "switch pm",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if button_type in ["start", "backward_compat"]:
|
||||||
|
button_dict = {"text": "button_text", "start_parameter": "start_parameter"}
|
||||||
|
else:
|
||||||
|
button_dict = {
|
||||||
|
"text": "button_text",
|
||||||
|
"web_app": {"url": "https://python-telegram-bot.org"},
|
||||||
|
}
|
||||||
|
|
||||||
|
expected["button"] = button_dict
|
||||||
|
|
||||||
|
return request_data.parameters == expected
|
||||||
|
|
||||||
results = [
|
results = [
|
||||||
InlineQueryResultArticle("11", "first", InputTextMessageContent("first")),
|
InlineQueryResultArticle("11", "first", InputTextMessageContent("first")),
|
||||||
InlineQueryResultArticle("12", "second", InputMessageContentDWPP("second")),
|
InlineQueryResultArticle("12", "second", InputMessageContentDWPP("second")),
|
||||||
|
@ -705,6 +718,17 @@ class TestBotWithoutRequest:
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if button_type == "start":
|
||||||
|
button = InlineQueryResultsButton(
|
||||||
|
text="button_text", start_parameter="start_parameter"
|
||||||
|
)
|
||||||
|
elif button_type == "web_app":
|
||||||
|
button = InlineQueryResultsButton(
|
||||||
|
text="button_text", web_app=WebAppInfo("https://python-telegram-bot.org")
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
button = None
|
||||||
|
|
||||||
copied_results = copy.copy(results)
|
copied_results = copy.copy(results)
|
||||||
ext_bot = bot
|
ext_bot = bot
|
||||||
for bot in (ext_bot, raw_bot):
|
for bot in (ext_bot, raw_bot):
|
||||||
|
@ -717,8 +741,11 @@ class TestBotWithoutRequest:
|
||||||
cache_time=300,
|
cache_time=300,
|
||||||
is_personal=True,
|
is_personal=True,
|
||||||
next_offset="42",
|
next_offset="42",
|
||||||
switch_pm_text="switch pm",
|
switch_pm_text="button_text" if button_type == "backward_compat" else None,
|
||||||
switch_pm_parameter="start_pm",
|
switch_pm_parameter="start_parameter"
|
||||||
|
if button_type == "backward_compat"
|
||||||
|
else None,
|
||||||
|
button=button,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 1)
|
# 1)
|
||||||
|
@ -739,6 +766,43 @@ class TestBotWithoutRequest:
|
||||||
|
|
||||||
monkeypatch.delattr(bot.request, "post")
|
monkeypatch.delattr(bot.request, "post")
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("bot_class", ["Bot", "ExtBot"])
|
||||||
|
async def test_answer_inline_query_deprecated_args(
|
||||||
|
self, monkeypatch, recwarn, bot_class, bot, raw_bot
|
||||||
|
):
|
||||||
|
async def mock_post(*args, **kwargs):
|
||||||
|
return True
|
||||||
|
|
||||||
|
bot = raw_bot if bot_class == "Bot" else bot
|
||||||
|
|
||||||
|
monkeypatch.setattr(bot.request, "post", mock_post)
|
||||||
|
|
||||||
|
with pytest.raises(
|
||||||
|
TypeError, match="6.7, the parameter `button is mutually exclusive to the deprecated"
|
||||||
|
):
|
||||||
|
await bot.answer_inline_query(
|
||||||
|
inline_query_id="123",
|
||||||
|
results=[],
|
||||||
|
button=True,
|
||||||
|
switch_pm_text="text",
|
||||||
|
switch_pm_parameter="param",
|
||||||
|
)
|
||||||
|
|
||||||
|
recwarn.clear()
|
||||||
|
assert await bot.answer_inline_query(
|
||||||
|
inline_query_id="123",
|
||||||
|
results=[],
|
||||||
|
switch_pm_text="text",
|
||||||
|
switch_pm_parameter="parameter",
|
||||||
|
)
|
||||||
|
assert len(recwarn) == 1
|
||||||
|
assert recwarn[-1].category is PTBDeprecationWarning
|
||||||
|
assert str(recwarn[-1].message).startswith(
|
||||||
|
"Since Bot API 6.7, the parameters `switch_pm_text` and `switch_pm_parameter` are "
|
||||||
|
"deprecated"
|
||||||
|
)
|
||||||
|
assert recwarn[-1].filename == __file__, "stacklevel is incorrect!"
|
||||||
|
|
||||||
async def test_answer_inline_query_no_default_parse_mode(self, monkeypatch, bot):
|
async def test_answer_inline_query_no_default_parse_mode(self, monkeypatch, bot):
|
||||||
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
|
||||||
return request_data.parameters == {
|
return request_data.parameters == {
|
||||||
|
@ -769,10 +833,8 @@ class TestBotWithoutRequest:
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"next_offset": "42",
|
"next_offset": "42",
|
||||||
"switch_pm_parameter": "start_pm",
|
|
||||||
"inline_query_id": 1234,
|
"inline_query_id": 1234,
|
||||||
"is_personal": True,
|
"is_personal": True,
|
||||||
"switch_pm_text": "switch pm",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
monkeypatch.setattr(bot.request, "post", make_assertion)
|
monkeypatch.setattr(bot.request, "post", make_assertion)
|
||||||
|
@ -797,8 +859,6 @@ class TestBotWithoutRequest:
|
||||||
cache_time=300,
|
cache_time=300,
|
||||||
is_personal=True,
|
is_personal=True,
|
||||||
next_offset="42",
|
next_offset="42",
|
||||||
switch_pm_text="switch pm",
|
|
||||||
switch_pm_parameter="start_pm",
|
|
||||||
)
|
)
|
||||||
# make sure that the results were not edited in-place
|
# make sure that the results were not edited in-place
|
||||||
assert results == copied_results
|
assert results == copied_results
|
||||||
|
@ -862,10 +922,8 @@ class TestBotWithoutRequest:
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"next_offset": "42",
|
"next_offset": "42",
|
||||||
"switch_pm_parameter": "start_pm",
|
|
||||||
"inline_query_id": 1234,
|
"inline_query_id": 1234,
|
||||||
"is_personal": True,
|
"is_personal": True,
|
||||||
"switch_pm_text": "switch pm",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
monkeypatch.setattr(default_bot.request, "post", make_assertion)
|
monkeypatch.setattr(default_bot.request, "post", make_assertion)
|
||||||
|
@ -890,8 +948,6 @@ class TestBotWithoutRequest:
|
||||||
cache_time=300,
|
cache_time=300,
|
||||||
is_personal=True,
|
is_personal=True,
|
||||||
next_offset="42",
|
next_offset="42",
|
||||||
switch_pm_text="switch pm",
|
|
||||||
switch_pm_parameter="start_pm",
|
|
||||||
)
|
)
|
||||||
# make sure that the results were not edited in-place
|
# make sure that the results were not edited in-place
|
||||||
assert results == copied_results
|
assert results == copied_results
|
||||||
|
@ -1680,6 +1736,80 @@ class TestBotWithoutRequest:
|
||||||
assert warning.filename == __file__, "wrong stacklevel!"
|
assert warning.filename == __file__, "wrong stacklevel!"
|
||||||
assert warning.category is PTBUserWarning
|
assert warning.category is PTBUserWarning
|
||||||
|
|
||||||
|
async def test_set_get_my_name(self, bot, monkeypatch):
|
||||||
|
"""We only test that we pass the correct values to TG since this endpoint is heavily
|
||||||
|
rate limited which makes automated tests rather infeasible."""
|
||||||
|
default_name = "default_bot_name"
|
||||||
|
en_name = "en_bot_name"
|
||||||
|
de_name = "de_bot_name"
|
||||||
|
|
||||||
|
# We predefine the responses that we would TG expect to send us
|
||||||
|
set_stack = asyncio.Queue()
|
||||||
|
get_stack = asyncio.Queue()
|
||||||
|
await set_stack.put({"name": default_name})
|
||||||
|
await set_stack.put({"name": en_name, "language_code": "en"})
|
||||||
|
await set_stack.put({"name": de_name, "language_code": "de"})
|
||||||
|
await get_stack.put({"name": default_name, "language_code": None})
|
||||||
|
await get_stack.put({"name": en_name, "language_code": "en"})
|
||||||
|
await get_stack.put({"name": de_name, "language_code": "de"})
|
||||||
|
|
||||||
|
await set_stack.put({"name": default_name})
|
||||||
|
await set_stack.put({"language_code": "en"})
|
||||||
|
await set_stack.put({"language_code": "de"})
|
||||||
|
await get_stack.put({"name": default_name, "language_code": None})
|
||||||
|
await get_stack.put({"name": default_name, "language_code": "en"})
|
||||||
|
await get_stack.put({"name": default_name, "language_code": "de"})
|
||||||
|
|
||||||
|
async def post(url, request_data: RequestData, *args, **kwargs):
|
||||||
|
# The mock-post now just fetches the predefined responses from the queues
|
||||||
|
if "setMyName" in url:
|
||||||
|
expected = await set_stack.get()
|
||||||
|
assert request_data.json_parameters == expected
|
||||||
|
set_stack.task_done()
|
||||||
|
return True
|
||||||
|
|
||||||
|
bot_name = await get_stack.get()
|
||||||
|
if "language_code" in request_data.json_parameters:
|
||||||
|
assert request_data.json_parameters == {"language_code": bot_name["language_code"]}
|
||||||
|
else:
|
||||||
|
assert request_data.json_parameters == {}
|
||||||
|
get_stack.task_done()
|
||||||
|
return bot_name
|
||||||
|
|
||||||
|
monkeypatch.setattr(bot.request, "post", post)
|
||||||
|
|
||||||
|
# Set the names
|
||||||
|
assert all(
|
||||||
|
await asyncio.gather(
|
||||||
|
bot.set_my_name(default_name),
|
||||||
|
bot.set_my_name(en_name, language_code="en"),
|
||||||
|
bot.set_my_name(de_name, language_code="de"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check that they were set correctly
|
||||||
|
assert await asyncio.gather(
|
||||||
|
bot.get_my_name(), bot.get_my_name("en"), bot.get_my_name("de")
|
||||||
|
) == [
|
||||||
|
BotName(default_name),
|
||||||
|
BotName(en_name),
|
||||||
|
BotName(de_name),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Delete the names
|
||||||
|
assert all(
|
||||||
|
await asyncio.gather(
|
||||||
|
bot.set_my_name(default_name),
|
||||||
|
bot.set_my_name(None, language_code="en"),
|
||||||
|
bot.set_my_name(None, language_code="de"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check that they were deleted correctly
|
||||||
|
assert await asyncio.gather(
|
||||||
|
bot.get_my_name(), bot.get_my_name("en"), bot.get_my_name("de")
|
||||||
|
) == 3 * [BotName(default_name)]
|
||||||
|
|
||||||
|
|
||||||
class TestBotWithRequest:
|
class TestBotWithRequest:
|
||||||
"""
|
"""
|
||||||
|
|
56
tests/test_botname.py
Normal file
56
tests/test_botname.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# A library that provides a Python interface to the Telegram Bot API
|
||||||
|
# Copyright (C) 2015-2023
|
||||||
|
# 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/].
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from telegram import BotName
|
||||||
|
from tests.auxil.slots import mro_slots
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def bot_name(bot):
|
||||||
|
return BotName(TestBotNameBase.name)
|
||||||
|
|
||||||
|
|
||||||
|
class TestBotNameBase:
|
||||||
|
name = "This is a test name"
|
||||||
|
|
||||||
|
|
||||||
|
class TestBotNameWithoutRequest(TestBotNameBase):
|
||||||
|
def test_slot_behaviour(self, bot_name):
|
||||||
|
for attr in bot_name.__slots__:
|
||||||
|
assert getattr(bot_name, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||||
|
assert len(mro_slots(bot_name)) == len(set(mro_slots(bot_name))), "duplicate slot"
|
||||||
|
|
||||||
|
def test_to_dict(self, bot_name):
|
||||||
|
bot_name_dict = bot_name.to_dict()
|
||||||
|
|
||||||
|
assert isinstance(bot_name_dict, dict)
|
||||||
|
assert bot_name_dict["name"] == self.name
|
||||||
|
|
||||||
|
def test_equality(self):
|
||||||
|
a = BotName(self.name)
|
||||||
|
b = BotName(self.name)
|
||||||
|
c = BotName("text.com")
|
||||||
|
|
||||||
|
assert a == b
|
||||||
|
assert hash(a) == hash(b)
|
||||||
|
assert a is not b
|
||||||
|
|
||||||
|
assert a != c
|
||||||
|
assert hash(a) != hash(c)
|
|
@ -79,7 +79,7 @@ def invite_link(user):
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def chat_member_updated(user, chat, old_chat_member, new_chat_member, invite_link, time):
|
def chat_member_updated(user, chat, old_chat_member, new_chat_member, invite_link, time):
|
||||||
return ChatMemberUpdated(chat, user, time, old_chat_member, new_chat_member, invite_link)
|
return ChatMemberUpdated(chat, user, time, old_chat_member, new_chat_member, invite_link, True)
|
||||||
|
|
||||||
|
|
||||||
class TestChatMemberUpdatedBase:
|
class TestChatMemberUpdatedBase:
|
||||||
|
@ -113,6 +113,7 @@ class TestChatMemberUpdatedWithoutRequest(TestChatMemberUpdatedBase):
|
||||||
assert chat_member_updated.old_chat_member == old_chat_member
|
assert chat_member_updated.old_chat_member == old_chat_member
|
||||||
assert chat_member_updated.new_chat_member == new_chat_member
|
assert chat_member_updated.new_chat_member == new_chat_member
|
||||||
assert chat_member_updated.invite_link is None
|
assert chat_member_updated.invite_link is None
|
||||||
|
assert chat_member_updated.via_chat_folder_invite_link is None
|
||||||
|
|
||||||
def test_de_json_all_args(
|
def test_de_json_all_args(
|
||||||
self, bot, user, time, invite_link, chat, old_chat_member, new_chat_member
|
self, bot, user, time, invite_link, chat, old_chat_member, new_chat_member
|
||||||
|
@ -124,6 +125,7 @@ class TestChatMemberUpdatedWithoutRequest(TestChatMemberUpdatedBase):
|
||||||
"old_chat_member": old_chat_member.to_dict(),
|
"old_chat_member": old_chat_member.to_dict(),
|
||||||
"new_chat_member": new_chat_member.to_dict(),
|
"new_chat_member": new_chat_member.to_dict(),
|
||||||
"invite_link": invite_link.to_dict(),
|
"invite_link": invite_link.to_dict(),
|
||||||
|
"via_chat_folder_invite_link": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
chat_member_updated = ChatMemberUpdated.de_json(json_dict, bot)
|
chat_member_updated = ChatMemberUpdated.de_json(json_dict, bot)
|
||||||
|
@ -136,6 +138,7 @@ class TestChatMemberUpdatedWithoutRequest(TestChatMemberUpdatedBase):
|
||||||
assert chat_member_updated.old_chat_member == old_chat_member
|
assert chat_member_updated.old_chat_member == old_chat_member
|
||||||
assert chat_member_updated.new_chat_member == new_chat_member
|
assert chat_member_updated.new_chat_member == new_chat_member
|
||||||
assert chat_member_updated.invite_link == invite_link
|
assert chat_member_updated.invite_link == invite_link
|
||||||
|
assert chat_member_updated.via_chat_folder_invite_link is True
|
||||||
|
|
||||||
def test_de_json_localization(
|
def test_de_json_localization(
|
||||||
self, bot, raw_bot, tz_bot, user, chat, old_chat_member, new_chat_member, time, invite_link
|
self, bot, raw_bot, tz_bot, user, chat, old_chat_member, new_chat_member, time, invite_link
|
||||||
|
@ -178,6 +181,10 @@ class TestChatMemberUpdatedWithoutRequest(TestChatMemberUpdatedBase):
|
||||||
== chat_member_updated.new_chat_member.to_dict()
|
== chat_member_updated.new_chat_member.to_dict()
|
||||||
)
|
)
|
||||||
assert chat_member_updated_dict["invite_link"] == chat_member_updated.invite_link.to_dict()
|
assert chat_member_updated_dict["invite_link"] == chat_member_updated.invite_link.to_dict()
|
||||||
|
assert (
|
||||||
|
chat_member_updated_dict["via_chat_folder_invite_link"]
|
||||||
|
== chat_member_updated.via_chat_folder_invite_link
|
||||||
|
)
|
||||||
|
|
||||||
def test_equality(self, time, old_chat_member, new_chat_member, invite_link):
|
def test_equality(self, time, old_chat_member, new_chat_member, invite_link):
|
||||||
a = ChatMemberUpdated(
|
a = ChatMemberUpdated(
|
||||||
|
|
|
@ -32,8 +32,9 @@ class TestHelpers:
|
||||||
("_italic_", r"\_italic\_"),
|
("_italic_", r"\_italic\_"),
|
||||||
("`code`", r"\`code\`"),
|
("`code`", r"\`code\`"),
|
||||||
("[text_link](https://github.com/)", r"\[text\_link](https://github.com/)"),
|
("[text_link](https://github.com/)", r"\[text\_link](https://github.com/)"),
|
||||||
|
("![👍](tg://emoji?id=1)", r"!\[👍](tg://emoji?id=1)"),
|
||||||
],
|
],
|
||||||
ids=["bold", "italic", "code", "text_link"],
|
ids=["bold", "italic", "code", "text_link", "custom_emoji_id"],
|
||||||
)
|
)
|
||||||
def test_escape_markdown(self, test_str, expected):
|
def test_escape_markdown(self, test_str, expected):
|
||||||
assert expected == helpers.escape_markdown(test_str)
|
assert expected == helpers.escape_markdown(test_str)
|
||||||
|
@ -68,13 +69,16 @@ class TestHelpers:
|
||||||
test_str, version=2, entity_type=MessageEntity.CODE
|
test_str, version=2, entity_type=MessageEntity.CODE
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_escape_markdown_v2_text_link(self):
|
def test_escape_markdown_v2_links(self):
|
||||||
test_str = "https://url.containing/funny)cha)\\ra\\)cter\\s"
|
test_str = "https://url.containing/funny)cha)\\ra\\)cter\\s"
|
||||||
expected_str = "https://url.containing/funny\\)cha\\)\\\\ra\\\\\\)cter\\\\s"
|
expected_str = "https://url.containing/funny\\)cha\\)\\\\ra\\\\\\)cter\\\\s"
|
||||||
|
|
||||||
assert expected_str == helpers.escape_markdown(
|
assert expected_str == helpers.escape_markdown(
|
||||||
test_str, version=2, entity_type=MessageEntity.TEXT_LINK
|
test_str, version=2, entity_type=MessageEntity.TEXT_LINK
|
||||||
)
|
)
|
||||||
|
assert expected_str == helpers.escape_markdown(
|
||||||
|
test_str, version=2, entity_type=MessageEntity.CUSTOM_EMOJI
|
||||||
|
)
|
||||||
|
|
||||||
def test_markdown_invalid_version(self):
|
def test_markdown_invalid_version(self):
|
||||||
with pytest.raises(ValueError, match="Markdown version must be either"):
|
with pytest.raises(ValueError, match="Markdown version must be either"):
|
||||||
|
|
83
tests/test_inlinequeryresultsbutton.py
Normal file
83
tests/test_inlinequeryresultsbutton.py
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# A library that provides a Python interface to the Telegram Bot API
|
||||||
|
# Copyright (C) 2015-2023
|
||||||
|
# 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/].
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from telegram import InlineQueryResultsButton, WebAppInfo
|
||||||
|
from tests.auxil.slots import mro_slots
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def inline_query_results_button():
|
||||||
|
return InlineQueryResultsButton(
|
||||||
|
text=TestInlineQueryResultsButtonBase.text,
|
||||||
|
start_parameter=TestInlineQueryResultsButtonBase.start_parameter,
|
||||||
|
web_app=TestInlineQueryResultsButtonBase.web_app,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestInlineQueryResultsButtonBase:
|
||||||
|
text = "text"
|
||||||
|
start_parameter = "start_parameter"
|
||||||
|
web_app = WebAppInfo(url="https://python-telegram-bot.org")
|
||||||
|
|
||||||
|
|
||||||
|
class TestInlineQueryResultsButtonWithoutRequest(TestInlineQueryResultsButtonBase):
|
||||||
|
def test_slot_behaviour(self, inline_query_results_button):
|
||||||
|
inst = inline_query_results_button
|
||||||
|
for attr in inst.__slots__:
|
||||||
|
assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||||
|
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||||
|
|
||||||
|
def test_to_dict(self, inline_query_results_button):
|
||||||
|
inline_query_results_button_dict = inline_query_results_button.to_dict()
|
||||||
|
assert isinstance(inline_query_results_button_dict, dict)
|
||||||
|
assert inline_query_results_button_dict["text"] == self.text
|
||||||
|
assert inline_query_results_button_dict["start_parameter"] == self.start_parameter
|
||||||
|
assert inline_query_results_button_dict["web_app"] == self.web_app.to_dict()
|
||||||
|
|
||||||
|
def test_de_json(self, bot):
|
||||||
|
assert InlineQueryResultsButton.de_json(None, bot) is None
|
||||||
|
assert InlineQueryResultsButton.de_json({}, bot) is None
|
||||||
|
|
||||||
|
json_dict = {
|
||||||
|
"text": self.text,
|
||||||
|
"start_parameter": self.start_parameter,
|
||||||
|
"web_app": self.web_app.to_dict(),
|
||||||
|
}
|
||||||
|
inline_query_results_button = InlineQueryResultsButton.de_json(json_dict, bot)
|
||||||
|
|
||||||
|
assert inline_query_results_button.text == self.text
|
||||||
|
assert inline_query_results_button.start_parameter == self.start_parameter
|
||||||
|
assert inline_query_results_button.web_app == self.web_app
|
||||||
|
|
||||||
|
def test_equality(self):
|
||||||
|
a = InlineQueryResultsButton(self.text, self.start_parameter, self.web_app)
|
||||||
|
b = InlineQueryResultsButton(self.text, self.start_parameter, self.web_app)
|
||||||
|
c = InlineQueryResultsButton(self.text, "", self.web_app)
|
||||||
|
d = InlineQueryResultsButton(self.text, self.start_parameter, None)
|
||||||
|
|
||||||
|
assert a == b
|
||||||
|
assert hash(a) == hash(b)
|
||||||
|
assert a is not b
|
||||||
|
|
||||||
|
assert a != c
|
||||||
|
assert hash(a) != hash(c)
|
||||||
|
|
||||||
|
assert a != d
|
||||||
|
assert hash(a) != hash(d)
|
|
@ -59,6 +59,7 @@ from telegram import (
|
||||||
from telegram._utils.datetime import UTC
|
from telegram._utils.datetime import UTC
|
||||||
from telegram.constants import ChatAction, ParseMode
|
from telegram.constants import ChatAction, ParseMode
|
||||||
from telegram.ext import Defaults
|
from telegram.ext import Defaults
|
||||||
|
from telegram.warnings import PTBDeprecationWarning
|
||||||
from tests._passport.test_passport import RAW_PASSPORT_DATA
|
from tests._passport.test_passport import RAW_PASSPORT_DATA
|
||||||
from tests.auxil.bot_method_checks import (
|
from tests.auxil.bot_method_checks import (
|
||||||
check_defaults_handling,
|
check_defaults_handling,
|
||||||
|
@ -322,10 +323,11 @@ class TestMessageBase:
|
||||||
{"length": 9, "offset": 101, "type": "strikethrough"},
|
{"length": 9, "offset": 101, "type": "strikethrough"},
|
||||||
{"length": 10, "offset": 129, "type": "pre", "language": "python"},
|
{"length": 10, "offset": 129, "type": "pre", "language": "python"},
|
||||||
{"length": 7, "offset": 141, "type": "spoiler"},
|
{"length": 7, "offset": 141, "type": "spoiler"},
|
||||||
|
{"length": 2, "offset": 150, "type": "custom_emoji", "custom_emoji_id": "1"},
|
||||||
]
|
]
|
||||||
test_text_v2 = (
|
test_text_v2 = (
|
||||||
r"Test for <bold, ita_lic, \`code, links, text-mention and `\pre. "
|
r"Test for <bold, ita_lic, \`code, links, text-mention and `\pre. "
|
||||||
"http://google.com and bold nested in strk>trgh nested in italic. Python pre. Spoiled."
|
"http://google.com and bold nested in strk>trgh nested in italic. Python pre. Spoiled. 👍."
|
||||||
)
|
)
|
||||||
test_message = Message(
|
test_message = Message(
|
||||||
message_id=1,
|
message_id=1,
|
||||||
|
@ -513,7 +515,8 @@ class TestMessageWithoutRequest(TestMessageBase):
|
||||||
r"<pre>`\pre</pre>. http://google.com "
|
r"<pre>`\pre</pre>. http://google.com "
|
||||||
"and <i>bold <b>nested in <s>strk>trgh</s> nested in</b> italic</i>. "
|
"and <i>bold <b>nested in <s>strk>trgh</s> nested in</b> italic</i>. "
|
||||||
'<pre><code class="python">Python pre</code></pre>. '
|
'<pre><code class="python">Python pre</code></pre>. '
|
||||||
'<span class="tg-spoiler">Spoiled</span>.'
|
'<span class="tg-spoiler">Spoiled</span>. '
|
||||||
|
'<tg-emoji emoji-id="1">👍</tg-emoji>.'
|
||||||
)
|
)
|
||||||
text_html = self.test_message_v2.text_html
|
text_html = self.test_message_v2.text_html
|
||||||
assert text_html == test_html_string
|
assert text_html == test_html_string
|
||||||
|
@ -532,7 +535,8 @@ class TestMessageWithoutRequest(TestMessageBase):
|
||||||
r'<pre>`\pre</pre>. <a href="http://google.com">http://google.com</a> '
|
r'<pre>`\pre</pre>. <a href="http://google.com">http://google.com</a> '
|
||||||
"and <i>bold <b>nested in <s>strk>trgh</s> nested in</b> italic</i>. "
|
"and <i>bold <b>nested in <s>strk>trgh</s> nested in</b> italic</i>. "
|
||||||
'<pre><code class="python">Python pre</code></pre>. '
|
'<pre><code class="python">Python pre</code></pre>. '
|
||||||
'<span class="tg-spoiler">Spoiled</span>.'
|
'<span class="tg-spoiler">Spoiled</span>. '
|
||||||
|
'<tg-emoji emoji-id="1">👍</tg-emoji>.'
|
||||||
)
|
)
|
||||||
text_html = self.test_message_v2.text_html_urled
|
text_html = self.test_message_v2.text_html_urled
|
||||||
assert text_html == test_html_string
|
assert text_html == test_html_string
|
||||||
|
@ -553,7 +557,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
||||||
"[links](http://github.com/abc\\\\\\)def), "
|
"[links](http://github.com/abc\\\\\\)def), "
|
||||||
"[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. "
|
"[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. "
|
||||||
r"http://google\.com and _bold *nested in ~strk\>trgh~ nested in* italic_\. "
|
r"http://google\.com and _bold *nested in ~strk\>trgh~ nested in* italic_\. "
|
||||||
"```python\nPython pre```\\. ||Spoiled||\\."
|
"```python\nPython pre```\\. ||Spoiled||\\. ![👍](tg://emoji?id=1)\\."
|
||||||
)
|
)
|
||||||
text_markdown = self.test_message_v2.text_markdown_v2
|
text_markdown = self.test_message_v2.text_markdown_v2
|
||||||
assert text_markdown == test_md_string
|
assert text_markdown == test_md_string
|
||||||
|
@ -603,7 +607,8 @@ class TestMessageWithoutRequest(TestMessageBase):
|
||||||
"[links](http://github.com/abc\\\\\\)def), "
|
"[links](http://github.com/abc\\\\\\)def), "
|
||||||
"[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. "
|
"[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. "
|
||||||
r"[http://google\.com](http://google.com) and _bold *nested in ~strk\>trgh~ "
|
r"[http://google\.com](http://google.com) and _bold *nested in ~strk\>trgh~ "
|
||||||
"nested in* italic_\\. ```python\nPython pre```\\. ||Spoiled||\\."
|
"nested in* italic_\\. ```python\nPython pre```\\. ||Spoiled||\\. "
|
||||||
|
"![👍](tg://emoji?id=1)\\."
|
||||||
)
|
)
|
||||||
text_markdown = self.test_message_v2.text_markdown_v2_urled
|
text_markdown = self.test_message_v2.text_markdown_v2_urled
|
||||||
assert text_markdown == test_md_string
|
assert text_markdown == test_md_string
|
||||||
|
@ -634,17 +639,72 @@ class TestMessageWithoutRequest(TestMessageBase):
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"type_",
|
"type_",
|
||||||
argvalues=[
|
argvalues=[
|
||||||
"text_html",
|
|
||||||
"text_html_urled",
|
|
||||||
"text_markdown",
|
"text_markdown",
|
||||||
"text_markdown_urled",
|
"text_markdown_urled",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_text_custom_emoji_md_v1(self, type_, recwarn):
|
||||||
|
text = "Look a custom emoji: 😎"
|
||||||
|
expected = "Look a custom emoji: 😎"
|
||||||
|
emoji_entity = MessageEntity(
|
||||||
|
type=MessageEntity.CUSTOM_EMOJI,
|
||||||
|
offset=21,
|
||||||
|
length=2,
|
||||||
|
custom_emoji_id="5472409228461217725",
|
||||||
|
)
|
||||||
|
message = Message(
|
||||||
|
1,
|
||||||
|
from_user=self.from_user,
|
||||||
|
date=self.date,
|
||||||
|
chat=self.chat,
|
||||||
|
text=text,
|
||||||
|
entities=[emoji_entity],
|
||||||
|
)
|
||||||
|
assert expected == getattr(message, type_)
|
||||||
|
|
||||||
|
assert len(recwarn) == 1
|
||||||
|
assert recwarn[0].category is PTBDeprecationWarning
|
||||||
|
assert str(recwarn[0].message).startswith(
|
||||||
|
"Custom emoji entities are not supported for Markdown version 1"
|
||||||
|
)
|
||||||
|
assert recwarn[0].filename == __file__
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"type_",
|
||||||
|
argvalues=[
|
||||||
"text_markdown_v2",
|
"text_markdown_v2",
|
||||||
"text_markdown_v2_urled",
|
"text_markdown_v2_urled",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_text_custom_emoji(self, type_):
|
def test_text_custom_emoji_md_v2(self, type_):
|
||||||
text = "Look a custom emoji: 😎"
|
text = "Look a custom emoji: 😎"
|
||||||
expected = "Look a custom emoji: 😎"
|
expected = "Look a custom emoji: ![😎](tg://emoji?id=5472409228461217725)"
|
||||||
|
emoji_entity = MessageEntity(
|
||||||
|
type=MessageEntity.CUSTOM_EMOJI,
|
||||||
|
offset=21,
|
||||||
|
length=2,
|
||||||
|
custom_emoji_id="5472409228461217725",
|
||||||
|
)
|
||||||
|
message = Message(
|
||||||
|
1,
|
||||||
|
from_user=self.from_user,
|
||||||
|
date=self.date,
|
||||||
|
chat=self.chat,
|
||||||
|
text=text,
|
||||||
|
entities=[emoji_entity],
|
||||||
|
)
|
||||||
|
assert expected == message[type_]
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"type_",
|
||||||
|
argvalues=[
|
||||||
|
"text_html",
|
||||||
|
"text_html_urled",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_text_custom_emoji_html(self, type_):
|
||||||
|
text = "Look a custom emoji: 😎"
|
||||||
|
expected = 'Look a custom emoji: <tg-emoji emoji-id="5472409228461217725">😎</tg-emoji>'
|
||||||
emoji_entity = MessageEntity(
|
emoji_entity = MessageEntity(
|
||||||
type=MessageEntity.CUSTOM_EMOJI,
|
type=MessageEntity.CUSTOM_EMOJI,
|
||||||
offset=21,
|
offset=21,
|
||||||
|
@ -670,7 +730,8 @@ class TestMessageWithoutRequest(TestMessageBase):
|
||||||
r"<pre>`\pre</pre>. http://google.com "
|
r"<pre>`\pre</pre>. http://google.com "
|
||||||
"and <i>bold <b>nested in <s>strk>trgh</s> nested in</b> italic</i>. "
|
"and <i>bold <b>nested in <s>strk>trgh</s> nested in</b> italic</i>. "
|
||||||
'<pre><code class="python">Python pre</code></pre>. '
|
'<pre><code class="python">Python pre</code></pre>. '
|
||||||
'<span class="tg-spoiler">Spoiled</span>.'
|
'<span class="tg-spoiler">Spoiled</span>. '
|
||||||
|
'<tg-emoji emoji-id="1">👍</tg-emoji>.'
|
||||||
)
|
)
|
||||||
caption_html = self.test_message_v2.caption_html
|
caption_html = self.test_message_v2.caption_html
|
||||||
assert caption_html == test_html_string
|
assert caption_html == test_html_string
|
||||||
|
@ -689,7 +750,8 @@ class TestMessageWithoutRequest(TestMessageBase):
|
||||||
r'<pre>`\pre</pre>. <a href="http://google.com">http://google.com</a> '
|
r'<pre>`\pre</pre>. <a href="http://google.com">http://google.com</a> '
|
||||||
"and <i>bold <b>nested in <s>strk>trgh</s> nested in</b> italic</i>. "
|
"and <i>bold <b>nested in <s>strk>trgh</s> nested in</b> italic</i>. "
|
||||||
'<pre><code class="python">Python pre</code></pre>. '
|
'<pre><code class="python">Python pre</code></pre>. '
|
||||||
'<span class="tg-spoiler">Spoiled</span>.'
|
'<span class="tg-spoiler">Spoiled</span>. '
|
||||||
|
'<tg-emoji emoji-id="1">👍</tg-emoji>.'
|
||||||
)
|
)
|
||||||
caption_html = self.test_message_v2.caption_html_urled
|
caption_html = self.test_message_v2.caption_html_urled
|
||||||
assert caption_html == test_html_string
|
assert caption_html == test_html_string
|
||||||
|
@ -710,7 +772,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
||||||
"[links](http://github.com/abc\\\\\\)def), "
|
"[links](http://github.com/abc\\\\\\)def), "
|
||||||
"[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. "
|
"[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. "
|
||||||
r"http://google\.com and _bold *nested in ~strk\>trgh~ nested in* italic_\. "
|
r"http://google\.com and _bold *nested in ~strk\>trgh~ nested in* italic_\. "
|
||||||
"```python\nPython pre```\\. ||Spoiled||\\."
|
"```python\nPython pre```\\. ||Spoiled||\\. ![👍](tg://emoji?id=1)\\."
|
||||||
)
|
)
|
||||||
caption_markdown = self.test_message_v2.caption_markdown_v2
|
caption_markdown = self.test_message_v2.caption_markdown_v2
|
||||||
assert caption_markdown == test_md_string
|
assert caption_markdown == test_md_string
|
||||||
|
@ -737,7 +799,8 @@ class TestMessageWithoutRequest(TestMessageBase):
|
||||||
"[links](http://github.com/abc\\\\\\)def), "
|
"[links](http://github.com/abc\\\\\\)def), "
|
||||||
"[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. "
|
"[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. "
|
||||||
r"[http://google\.com](http://google.com) and _bold *nested in ~strk\>trgh~ "
|
r"[http://google\.com](http://google.com) and _bold *nested in ~strk\>trgh~ "
|
||||||
"nested in* italic_\\. ```python\nPython pre```\\. ||Spoiled||\\."
|
"nested in* italic_\\. ```python\nPython pre```\\. ||Spoiled||\\. "
|
||||||
|
"![👍](tg://emoji?id=1)\\."
|
||||||
)
|
)
|
||||||
caption_markdown = self.test_message_v2.caption_markdown_v2_urled
|
caption_markdown = self.test_message_v2.caption_markdown_v2_urled
|
||||||
assert caption_markdown == test_md_string
|
assert caption_markdown == test_md_string
|
||||||
|
@ -773,17 +836,72 @@ class TestMessageWithoutRequest(TestMessageBase):
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"type_",
|
"type_",
|
||||||
argvalues=[
|
argvalues=[
|
||||||
"caption_html",
|
|
||||||
"caption_html_urled",
|
|
||||||
"caption_markdown",
|
"caption_markdown",
|
||||||
"caption_markdown_urled",
|
"caption_markdown_urled",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_caption_custom_emoji_md_v1(self, type_, recwarn):
|
||||||
|
caption = "Look a custom emoji: 😎"
|
||||||
|
expected = "Look a custom emoji: 😎"
|
||||||
|
emoji_entity = MessageEntity(
|
||||||
|
type=MessageEntity.CUSTOM_EMOJI,
|
||||||
|
offset=21,
|
||||||
|
length=2,
|
||||||
|
custom_emoji_id="5472409228461217725",
|
||||||
|
)
|
||||||
|
message = Message(
|
||||||
|
1,
|
||||||
|
from_user=self.from_user,
|
||||||
|
date=self.date,
|
||||||
|
chat=self.chat,
|
||||||
|
caption=caption,
|
||||||
|
caption_entities=[emoji_entity],
|
||||||
|
)
|
||||||
|
assert expected == getattr(message, type_)
|
||||||
|
|
||||||
|
assert len(recwarn) == 1
|
||||||
|
assert recwarn[0].category is PTBDeprecationWarning
|
||||||
|
assert str(recwarn[0].message).startswith(
|
||||||
|
"Custom emoji entities are not supported for Markdown version 1"
|
||||||
|
)
|
||||||
|
assert recwarn[0].filename == __file__
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"type_",
|
||||||
|
argvalues=[
|
||||||
"caption_markdown_v2",
|
"caption_markdown_v2",
|
||||||
"caption_markdown_v2_urled",
|
"caption_markdown_v2_urled",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_caption_custom_emoji(self, type_):
|
def test_caption_custom_emoji_md_v2(self, type_):
|
||||||
caption = "Look a custom emoji: 😎"
|
caption = "Look a custom emoji: 😎"
|
||||||
expected = "Look a custom emoji: 😎"
|
expected = "Look a custom emoji: ![😎](tg://emoji?id=5472409228461217725)"
|
||||||
|
emoji_entity = MessageEntity(
|
||||||
|
type=MessageEntity.CUSTOM_EMOJI,
|
||||||
|
offset=21,
|
||||||
|
length=2,
|
||||||
|
custom_emoji_id="5472409228461217725",
|
||||||
|
)
|
||||||
|
message = Message(
|
||||||
|
1,
|
||||||
|
from_user=self.from_user,
|
||||||
|
date=self.date,
|
||||||
|
chat=self.chat,
|
||||||
|
caption=caption,
|
||||||
|
caption_entities=[emoji_entity],
|
||||||
|
)
|
||||||
|
assert expected == message[type_]
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"type_",
|
||||||
|
argvalues=[
|
||||||
|
"caption_html",
|
||||||
|
"caption_html_urled",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_caption_custom_emoji_html(self, type_):
|
||||||
|
caption = "Look a custom emoji: 😎"
|
||||||
|
expected = 'Look a custom emoji: <tg-emoji emoji-id="5472409228461217725">😎</tg-emoji>'
|
||||||
emoji_entity = MessageEntity(
|
emoji_entity = MessageEntity(
|
||||||
type=MessageEntity.CUSTOM_EMOJI,
|
type=MessageEntity.CUSTOM_EMOJI,
|
||||||
offset=21,
|
offset=21,
|
||||||
|
@ -955,7 +1073,7 @@ class TestMessageWithoutRequest(TestMessageBase):
|
||||||
"[links](http://github.com/abc\\\\\\)def), "
|
"[links](http://github.com/abc\\\\\\)def), "
|
||||||
"[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. "
|
"[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. "
|
||||||
r"http://google\.com and _bold *nested in ~strk\>trgh~ nested in* italic_\. "
|
r"http://google\.com and _bold *nested in ~strk\>trgh~ nested in* italic_\. "
|
||||||
"```python\nPython pre```\\. ||Spoiled||\\."
|
"```python\nPython pre```\\. ||Spoiled||\\. ![👍](tg://emoji?id=1)\\."
|
||||||
)
|
)
|
||||||
|
|
||||||
async def make_assertion(*_, **kwargs):
|
async def make_assertion(*_, **kwargs):
|
||||||
|
@ -995,7 +1113,8 @@ class TestMessageWithoutRequest(TestMessageBase):
|
||||||
r"<pre>`\pre</pre>. http://google.com "
|
r"<pre>`\pre</pre>. http://google.com "
|
||||||
"and <i>bold <b>nested in <s>strk>trgh</s> nested in</b> italic</i>. "
|
"and <i>bold <b>nested in <s>strk>trgh</s> nested in</b> italic</i>. "
|
||||||
'<pre><code class="python">Python pre</code></pre>. '
|
'<pre><code class="python">Python pre</code></pre>. '
|
||||||
'<span class="tg-spoiler">Spoiled</span>.'
|
'<span class="tg-spoiler">Spoiled</span>. '
|
||||||
|
'<tg-emoji emoji-id="1">👍</tg-emoji>.'
|
||||||
)
|
)
|
||||||
|
|
||||||
async def make_assertion(*_, **kwargs):
|
async def make_assertion(*_, **kwargs):
|
||||||
|
|
|
@ -154,6 +154,7 @@ BACKWARDS_COMPAT_KWARGS = {
|
||||||
"thumb_url",
|
"thumb_url",
|
||||||
},
|
},
|
||||||
"InlineQueryResult(Game|Gif|Mpeg4Gif)": {"thumb_mime_type"},
|
"InlineQueryResult(Game|Gif|Mpeg4Gif)": {"thumb_mime_type"},
|
||||||
|
"answer_inline_query": {"switch_pm_text", "switch_pm_parameter"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
87
tests/test_switchinlinequerychosenchat.py
Normal file
87
tests/test_switchinlinequerychosenchat.py
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# A library that provides a Python interface to the Telegram Bot API
|
||||||
|
# Copyright (C) 2015-2023
|
||||||
|
# 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/].
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from telegram import SwitchInlineQueryChosenChat
|
||||||
|
from tests.auxil.slots import mro_slots
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def switch_inline_query_chosen_chat():
|
||||||
|
return SwitchInlineQueryChosenChat(
|
||||||
|
query=TestSwitchInlineQueryChosenChatBase.query,
|
||||||
|
allow_user_chats=TestSwitchInlineQueryChosenChatBase.allow_user_chats,
|
||||||
|
allow_bot_chats=TestSwitchInlineQueryChosenChatBase.allow_bot_chats,
|
||||||
|
allow_channel_chats=TestSwitchInlineQueryChosenChatBase.allow_channel_chats,
|
||||||
|
allow_group_chats=TestSwitchInlineQueryChosenChatBase.allow_group_chats,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestSwitchInlineQueryChosenChatBase:
|
||||||
|
query = "query"
|
||||||
|
allow_user_chats = True
|
||||||
|
allow_bot_chats = True
|
||||||
|
allow_channel_chats = False
|
||||||
|
allow_group_chats = True
|
||||||
|
|
||||||
|
|
||||||
|
class TestSwitchInlineQueryChosenChat(TestSwitchInlineQueryChosenChatBase):
|
||||||
|
def test_slot_behaviour(self, switch_inline_query_chosen_chat):
|
||||||
|
inst = switch_inline_query_chosen_chat
|
||||||
|
for attr in inst.__slots__:
|
||||||
|
assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'"
|
||||||
|
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||||
|
|
||||||
|
def test_expected_values(self, switch_inline_query_chosen_chat):
|
||||||
|
assert switch_inline_query_chosen_chat.query == self.query
|
||||||
|
assert switch_inline_query_chosen_chat.allow_user_chats == self.allow_user_chats
|
||||||
|
assert switch_inline_query_chosen_chat.allow_bot_chats == self.allow_bot_chats
|
||||||
|
assert switch_inline_query_chosen_chat.allow_channel_chats == self.allow_channel_chats
|
||||||
|
assert switch_inline_query_chosen_chat.allow_group_chats == self.allow_group_chats
|
||||||
|
|
||||||
|
def test_to_dict(self, switch_inline_query_chosen_chat):
|
||||||
|
siqcc = switch_inline_query_chosen_chat.to_dict()
|
||||||
|
|
||||||
|
assert isinstance(siqcc, dict)
|
||||||
|
assert siqcc["query"] == switch_inline_query_chosen_chat.query
|
||||||
|
assert siqcc["allow_user_chats"] == switch_inline_query_chosen_chat.allow_user_chats
|
||||||
|
assert siqcc["allow_bot_chats"] == switch_inline_query_chosen_chat.allow_bot_chats
|
||||||
|
assert siqcc["allow_channel_chats"] == switch_inline_query_chosen_chat.allow_channel_chats
|
||||||
|
assert siqcc["allow_group_chats"] == switch_inline_query_chosen_chat.allow_group_chats
|
||||||
|
|
||||||
|
def test_equality(self):
|
||||||
|
siqcc = SwitchInlineQueryChosenChat
|
||||||
|
a = siqcc(self.query, self.allow_user_chats, self.allow_bot_chats)
|
||||||
|
b = siqcc(self.query, self.allow_user_chats, self.allow_bot_chats)
|
||||||
|
c = siqcc(self.query, self.allow_user_chats)
|
||||||
|
d = siqcc("", self.allow_user_chats, self.allow_bot_chats)
|
||||||
|
e = siqcc(self.query, self.allow_user_chats, self.allow_bot_chats, self.allow_group_chats)
|
||||||
|
|
||||||
|
assert a == b
|
||||||
|
assert hash(a) == hash(b)
|
||||||
|
|
||||||
|
assert a != c
|
||||||
|
assert hash(a) != hash(c)
|
||||||
|
|
||||||
|
assert a != d
|
||||||
|
assert hash(a) != hash(d)
|
||||||
|
|
||||||
|
assert a != e
|
||||||
|
assert hash(a) != hash(e)
|
Loading…
Reference in a new issue