Remove Functionality Deprecated in v20.x (#4671)

This commit is contained in:
Bibo-Joshi
2025-03-15 09:21:37 +01:00
committed by GitHub
parent 150328799a
commit 1cf000c806
36 changed files with 355 additions and 1012 deletions
@@ -0,0 +1,19 @@
breaking = """This release removes all functionality that was deprecated in v20.x. This is in line with our :ref:`stability policy <stability-policy>`.
This includes the following changes:
- Removed ``filters.CHAT`` (all messages have an associated chat) and ``filters.StatusUpdate.USER_SHARED`` (use ``filters.StatusUpdate.USERS_SHARED`` instead).
- Removed ``Defaults.disable_web_page_preview`` and ``Defaults.quote``. Use ``Defaults.link_preview_options`` and ``Defaults.do_quote`` instead.
- Removed ``ApplicationBuilder.(get_updates_)proxy_url`` and ``HTTPXRequest.proxy_url``. Use ``ApplicationBuilder.(get_updates_)proxy`` and ``HTTPXRequest.proxy`` instead.
- Removed the ``*_timeout`` arguments of ``Application.run_polling`` and ``Updater.start_webhook``. Instead, specify the values via ``ApplicationBuilder.get_updates_*_timeout``.
- Removed ``constants.InlineQueryLimit.MIN_SWITCH_PM_TEXT_LENGTH``. Use ``constants.InlineQueryResultsButtonLimit.MAX_START_PARAMETER_LENGTH`` instead.
- Removed the argument ``quote`` of ``Message.reply_*``. Use ``do_quote`` instead.
- Removed the superfluous ``EncryptedPassportElement.credentials`` without replacement.
- Changed attribute value of ``PassportFile.file_date`` from :obj:`int` to :class:`datetime.datetime`. Make sure to adjust your code accordingly.
- Changed the attribute value of ``PassportElementErrors.file_hashes`` from :obj:`list` to :obj:`tuple`. Make sure to adjust your code accordingly.
- Make ``BaseRequest.read_timeout`` an abstract property. If you subclass ``BaseRequest``, you need to implement this property.
- The default value for ``write_timeout`` now defaults to ``DEFAULT_NONE`` also for bot methods that send media. Previously, it was ``20``. If you subclass ``BaseRequest``, make sure to use your desired write timeout if ``RequestData.multipart_data`` is set.
"""
[[pull_requests]]
uid = "4671"
author_uid = "Bibo-Joshi"
closes_threads = ["4659"]
+9 -9
View File
@@ -47,29 +47,29 @@ keyword_args = [
"",
]
media_write_timeout_deprecation_methods = [
"send_photo",
media_write_timeout_change_methods = [
"add_sticker_to_set",
"create_new_sticker_set",
"send_animation",
"send_audio",
"send_document",
"send_media_group",
"send_photo",
"send_sticker",
"send_video",
"send_video_note",
"send_animation",
"send_voice",
"send_media_group",
"set_chat_photo",
"upload_sticker_file",
"add_sticker_to_set",
"create_new_sticker_set",
]
media_write_timeout_deprecation = [
media_write_timeout_change = [
" write_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to "
" :paramref:`telegram.request.BaseRequest.post.write_timeout`. By default, ``20`` "
" seconds are used as write timeout."
"",
"",
" .. deprecated:: 20.7",
" In future versions, the default value will be changed to "
" .. versionchanged:: NEXT.VERSION",
" The default value changed to "
" :attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.",
"",
"",
+4 -4
View File
@@ -32,8 +32,8 @@ from docs.auxil.kwargs_insertion import (
find_insert_pos_for_kwargs,
get_updates_read_timeout_addition,
keyword_args,
media_write_timeout_deprecation,
media_write_timeout_deprecation_methods,
media_write_timeout_change,
media_write_timeout_change_methods,
)
from docs.auxil.link_code import LINE_NUMBERS
@@ -116,9 +116,9 @@ def autodoc_process_docstring(
if (
"post.write_timeout`. Defaults to" in to_insert
and method_name in media_write_timeout_deprecation_methods
and method_name in media_write_timeout_change_methods
):
effective_insert: list[str] = media_write_timeout_deprecation
effective_insert: list[str] = media_write_timeout_change
elif get_updates and to_insert.lstrip().startswith("read_timeout"):
effective_insert = [to_insert, *get_updates_read_timeout_addition]
else:
+2
View File
@@ -1,3 +1,5 @@
.. _stability-policy:
Stability Policy
================
+2 -14
View File
@@ -112,7 +112,7 @@ from telegram.error import EndPointNotFound, InvalidToken
from telegram.request import BaseRequest, RequestData
from telegram.request._httpxrequest import HTTPXRequest
from telegram.request._requestparameter import RequestParameter
from telegram.warnings import PTBDeprecationWarning, PTBUserWarning
from telegram.warnings import PTBUserWarning
if TYPE_CHECKING:
from telegram import (
@@ -4581,19 +4581,7 @@ class Bot(TelegramObject, contextlib.AbstractAsyncContextManager["Bot"]):
if not isinstance(read_timeout, DefaultValue):
arg_read_timeout: float = read_timeout or 0
else:
try:
arg_read_timeout = self._request[0].read_timeout or 0
except NotImplementedError:
arg_read_timeout = 2
self._warn(
PTBDeprecationWarning(
"20.7",
f"The class {self._request[0].__class__.__name__} does not override "
"the property `read_timeout`. Overriding this property will be mandatory "
"in future versions. Using 2 seconds as fallback.",
),
stacklevel=2,
)
arg_read_timeout = self._request[0].read_timeout or 0
# Ideally we'd use an aggressive read timeout for the polling. However,
# * Short polling should return within 2 seconds.
+6 -10
View File
@@ -62,6 +62,12 @@ class InlineQuery(TelegramObject):
``auto_pagination``. Use a named argument for those,
and notice that some positional arguments changed position as a result.
.. versionchanged:: NEXT.VERSION
Removed constants ``MIN_START_PARAMETER_LENGTH`` and ``MAX_START_PARAMETER_LENGTH``.
Use :attr:`telegram.constants.InlineQueryResultsButtonLimit.MIN_START_PARAMETER_LENGTH` and
:attr:`telegram.constants.InlineQueryResultsButtonLimit.MAX_START_PARAMETER_LENGTH`
instead.
Args:
id (:obj:`str`): Unique identifier for this query.
from_user (:class:`telegram.User`): Sender.
@@ -202,16 +208,6 @@ class InlineQuery(TelegramObject):
.. versionadded:: 13.2
"""
MIN_SWITCH_PM_TEXT_LENGTH: Final[int] = constants.InlineQueryLimit.MIN_SWITCH_PM_TEXT_LENGTH
""":const:`telegram.constants.InlineQueryLimit.MIN_SWITCH_PM_TEXT_LENGTH`
.. versionadded:: 20.0
"""
MAX_SWITCH_PM_TEXT_LENGTH: Final[int] = constants.InlineQueryLimit.MAX_SWITCH_PM_TEXT_LENGTH
""":const:`telegram.constants.InlineQueryLimit.MAX_SWITCH_PM_TEXT_LENGTH`
.. versionadded:: 20.0
"""
MAX_OFFSET_LENGTH: Final[int] = constants.InlineQueryLimit.MAX_OFFSET_LENGTH
""":const:`telegram.constants.InlineQueryLimit.MAX_OFFSET_LENGTH`
+8 -7
View File
@@ -47,9 +47,10 @@ class InlineQueryResultsButton(TelegramObject):
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.
:tg-const:`telegram.constants.InlineQueryResultsButtonLimit.MIN_START_PARAMETER_LENGTH`
-
:tg-const:`telegram.constants.InlineQueryResultsButtonLimit.MAX_START_PARAMETER_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
@@ -67,10 +68,10 @@ class InlineQueryResultsButton(TelegramObject):
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.
:tg-const:`telegram.constants.InlineQueryResultsButtonLimit.MIN_START_PARAMETER_LENGTH`
-
:tg-const:`telegram.constants.InlineQueryResultsButtonLimit.MAX_START_PARAMETER_LENGTH`
characters, only ``A-Z``, ``a-z``, ``0-9``, ``_`` and ``-`` are allowed.
"""
+96 -156
View File
@@ -930,6 +930,9 @@ class Message(MaybeInaccessibleMessage):
.. |reply_same_thread| replace:: If :paramref:`message_thread_id` is not provided,
this will reply to the same thread (topic) of the original message.
.. |quote_removed| replace:: Removed deprecated parameter ``quote``. Use :paramref:`do_quote`
instead.
"""
# fmt: on
@@ -1484,22 +1487,17 @@ class Message(MaybeInaccessibleMessage):
return self._effective_attachment # type: ignore[return-value]
def _quote(
self, quote: Optional[bool], reply_to_message_id: Optional[int] = None
) -> Optional[ReplyParameters]:
def _do_quote(self, do_quote: Optional[bool]) -> Optional[ReplyParameters]:
"""Modify kwargs for replying with or without quoting."""
if reply_to_message_id is not None:
return ReplyParameters(reply_to_message_id)
if quote is not None:
if quote:
if do_quote is not None:
if do_quote:
return ReplyParameters(self.message_id)
else:
# Unfortunately we need some ExtBot logic here because it's hard to move shortcut
# logic into ExtBot
if hasattr(self.get_bot(), "defaults") and self.get_bot().defaults: # type: ignore
default_quote = self.get_bot().defaults.quote # type: ignore[attr-defined]
default_quote = self.get_bot().defaults.do_quote # type: ignore[attr-defined]
else:
default_quote = None
if (default_quote is None and self.chat.type != Chat.PRIVATE) or default_quote:
@@ -1675,29 +1673,14 @@ class Message(MaybeInaccessibleMessage):
async def _parse_quote_arguments(
self,
do_quote: Optional[Union[bool, _ReplyKwargs]],
quote: Optional[bool],
reply_to_message_id: Optional[int],
reply_parameters: Optional["ReplyParameters"],
) -> tuple[Union[str, int], ReplyParameters]:
if quote and do_quote:
raise ValueError("The arguments `quote` and `do_quote` are mutually exclusive")
if reply_to_message_id is not None and reply_parameters is not None:
raise ValueError(
"`reply_to_message_id` and `reply_parameters` are mutually exclusive."
)
if quote is not None:
warn(
PTBDeprecationWarning(
"20.8",
"The `quote` parameter is deprecated in favor of the `do_quote` parameter. "
"Please update your code to use `do_quote` instead.",
),
stacklevel=2,
)
effective_do_quote = quote or do_quote
chat_id: Union[str, int] = self.chat_id
# reply_parameters and reply_to_message_id overrule the do_quote parameter
@@ -1705,11 +1688,11 @@ class Message(MaybeInaccessibleMessage):
effective_reply_parameters = reply_parameters
elif reply_to_message_id is not None:
effective_reply_parameters = ReplyParameters(message_id=reply_to_message_id)
elif isinstance(effective_do_quote, dict):
effective_reply_parameters = effective_do_quote["reply_parameters"]
chat_id = effective_do_quote["chat_id"]
elif isinstance(do_quote, dict):
effective_reply_parameters = do_quote["reply_parameters"]
chat_id = do_quote["chat_id"]
else:
effective_reply_parameters = self._quote(effective_do_quote)
effective_reply_parameters = self._do_quote(do_quote)
return chat_id, effective_reply_parameters
@@ -1750,7 +1733,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
disable_web_page_preview: Optional[bool] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -1773,11 +1755,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -1788,7 +1769,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_message(
@@ -1830,7 +1811,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
disable_web_page_preview: Optional[bool] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -1856,15 +1836,14 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
.. versionchanged:: NEXT.VERSION
|quote_removed|
Note:
:tg-const:`telegram.constants.ParseMode.MARKDOWN` is a legacy mode, retained by
Telegram for backward compatibility. You should use :meth:`reply_markdown_v2` instead.
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -1874,7 +1853,7 @@ class Message(MaybeInaccessibleMessage):
:class:`telegram.Message`: On success, instance representing the message posted.
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_message(
@@ -1916,7 +1895,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
disable_web_page_preview: Optional[bool] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -1942,11 +1920,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -1956,7 +1933,7 @@ class Message(MaybeInaccessibleMessage):
:class:`telegram.Message`: On success, instance representing the message posted.
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_message(
@@ -1998,7 +1975,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
disable_web_page_preview: Optional[bool] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2024,11 +2000,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -2038,7 +2013,7 @@ class Message(MaybeInaccessibleMessage):
:class:`telegram.Message`: On success, instance representing the message posted.
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_message(
@@ -2078,7 +2053,6 @@ class Message(MaybeInaccessibleMessage):
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2104,11 +2078,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -2121,7 +2094,7 @@ class Message(MaybeInaccessibleMessage):
:class:`telegram.error.TelegramError`
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_media_group(
@@ -2164,7 +2137,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
filename: Optional[str] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2187,11 +2159,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -2202,7 +2173,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_photo(
@@ -2251,7 +2222,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
filename: Optional[str] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2274,11 +2244,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -2289,7 +2258,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_audio(
@@ -2338,7 +2307,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
filename: Optional[str] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2361,11 +2329,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -2376,7 +2343,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_document(
@@ -2427,7 +2394,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
filename: Optional[str] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2450,11 +2416,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -2465,7 +2430,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_animation(
@@ -2511,7 +2476,6 @@ class Message(MaybeInaccessibleMessage):
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2534,11 +2498,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -2549,7 +2512,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_sticker(
@@ -2598,7 +2561,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
filename: Optional[str] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2621,11 +2583,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -2636,7 +2597,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_video(
@@ -2688,7 +2649,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
filename: Optional[str] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2711,11 +2671,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -2726,7 +2685,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_video_note(
@@ -2770,7 +2729,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
filename: Optional[str] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2793,11 +2751,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -2808,7 +2765,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_voice(
@@ -2854,7 +2811,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
location: Optional[Location] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2877,11 +2833,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -2892,7 +2847,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_location(
@@ -2941,7 +2896,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
venue: Optional[Venue] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -2964,11 +2918,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -2979,7 +2932,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_venue(
@@ -3026,7 +2979,6 @@ class Message(MaybeInaccessibleMessage):
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
contact: Optional[Contact] = None,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -3049,11 +3001,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -3064,7 +3015,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_contact(
@@ -3116,7 +3067,6 @@ class Message(MaybeInaccessibleMessage):
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -3139,11 +3089,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -3154,7 +3103,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_poll(
@@ -3202,7 +3151,6 @@ class Message(MaybeInaccessibleMessage):
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -3225,11 +3173,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -3240,7 +3187,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_dice(
@@ -3319,7 +3266,6 @@ class Message(MaybeInaccessibleMessage):
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -3342,11 +3288,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -3359,7 +3304,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_game(
@@ -3414,7 +3359,6 @@ class Message(MaybeInaccessibleMessage):
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -3436,6 +3380,9 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
.. versionchanged:: NEXT.VERSION
|quote_removed|
Warning:
As of API 5.2 :paramref:`start_parameter <telegram.Bot.send_invoice.start_parameter>`
is an optional argument and therefore the
@@ -3449,10 +3396,6 @@ class Message(MaybeInaccessibleMessage):
:paramref:`start_parameter <telegram.Bot.send_invoice.start_parameter>` is optional.
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -3463,7 +3406,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().send_invoice(
@@ -3637,7 +3580,6 @@ class Message(MaybeInaccessibleMessage):
*,
reply_to_message_id: Optional[int] = None,
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
quote: Optional[bool] = None,
do_quote: Optional[Union[bool, _ReplyKwargs]] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
@@ -3660,12 +3602,10 @@ class Message(MaybeInaccessibleMessage):
.. versionchanged:: 21.1
|reply_same_thread|
Keyword Args:
quote (:obj:`bool`, optional): |reply_quote|
.. versionchanged:: NEXT.VERSION
|quote_removed|
.. versionadded:: 13.1
.. deprecated:: 20.8
This argument is deprecated in favor of :paramref:`do_quote`
Keyword Args:
do_quote (:obj:`bool` | :obj:`dict`, optional): |do_quote|
Mutually exclusive with :paramref:`quote`.
@@ -3676,7 +3616,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, quote, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
return await self.get_bot().copy_message(
@@ -3748,7 +3688,7 @@ class Message(MaybeInaccessibleMessage):
"""
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
do_quote, None, reply_to_message_id, reply_parameters
do_quote, reply_to_message_id, reply_parameters
)
return await self.get_bot().send_paid_media(
chat_id=chat_id,
@@ -164,10 +164,6 @@ class EncryptedPassportElement(TelegramObject):
reverse_side: Optional[PassportFile] = None,
selfie: Optional[PassportFile] = None,
translation: Optional[Sequence[PassportFile]] = None,
# TODO: Remove the credentials argument in 22.0 or later
credentials: Optional[ # pylint: disable=unused-argument # noqa: ARG002
"Credentials"
] = None,
*,
api_kwargs: Optional[JSONDict] = None,
):
+26 -59
View File
@@ -19,12 +19,12 @@
# pylint: disable=redefined-builtin
"""This module contains the classes that represent Telegram PassportElementError."""
from collections.abc import Sequence
from typing import Optional
from telegram._telegramobject import TelegramObject
from telegram._utils.argumentparsing import parse_sequence_arg
from telegram._utils.types import JSONDict
from telegram._utils.warnings import warn
from telegram.warnings import PTBDeprecationWarning
class PassportElementError(TelegramObject):
@@ -168,23 +168,30 @@ class PassportElementErrorFiles(PassportElementError):
type (:obj:`str`): The section of the user's Telegram Passport which has the issue, one of
``"utility_bill"``, ``"bank_statement"``, ``"rental_agreement"``,
``"passport_registration"``, ``"temporary_registration"``.
file_hashes (list[:obj:`str`]): List of base64-encoded file hashes.
file_hashes (Sequence[:obj:`str`]): List of base64-encoded file hashes.
.. versionchanged:: NEXT.VERSION
|sequenceargs|
message (:obj:`str`): Error message.
Attributes:
type (:obj:`str`): The section of the user's Telegram Passport which has the issue, one of
``"utility_bill"``, ``"bank_statement"``, ``"rental_agreement"``,
``"passport_registration"``, ``"temporary_registration"``.
file_hashes (tuple[:obj:`str`]): List of base64-encoded file hashes.
.. versionchanged:: NEXT.VERSION
|tupleclassattrs|
message (:obj:`str`): Error message.
"""
__slots__ = ("_file_hashes",)
__slots__ = ("file_hashes",)
def __init__(
self,
type: str,
file_hashes: list[str],
file_hashes: Sequence[str],
message: str,
*,
api_kwargs: Optional[JSONDict] = None,
@@ -192,32 +199,9 @@ class PassportElementErrorFiles(PassportElementError):
# Required
super().__init__("files", type, message, api_kwargs=api_kwargs)
with self._unfrozen():
self._file_hashes: list[str] = file_hashes
self.file_hashes: tuple[str, ...] = parse_sequence_arg(file_hashes)
self._id_attrs = (self.source, self.type, self.message, *tuple(file_hashes))
def to_dict(self, recursive: bool = True) -> JSONDict:
"""See :meth:`telegram.TelegramObject.to_dict` for details."""
data = super().to_dict(recursive)
data["file_hashes"] = self._file_hashes
return data
@property
def file_hashes(self) -> list[str]:
"""List of base64-encoded file hashes.
.. deprecated:: 20.6
This attribute will return a tuple instead of a list in future major versions.
"""
warn(
PTBDeprecationWarning(
"20.6",
"The attribute `file_hashes` will return a tuple instead of a list in future major"
" versions.",
),
stacklevel=2,
)
return self._file_hashes
self._id_attrs = (self.source, self.type, self.message, self.file_hashes)
class PassportElementErrorFrontSide(PassportElementError):
@@ -386,7 +370,10 @@ class PassportElementErrorTranslationFiles(PassportElementError):
one of ``"passport"``, ``"driver_license"``, ``"identity_card"``,
``"internal_passport"``, ``"utility_bill"``, ``"bank_statement"``,
``"rental_agreement"``, ``"passport_registration"``, ``"temporary_registration"``.
file_hashes (list[:obj:`str`]): List of base64-encoded file hashes.
file_hashes (Sequence[:obj:`str`]): List of base64-encoded file hashes.
.. versionchanged:: NEXT.VERSION
|sequenceargs|
message (:obj:`str`): Error message.
Attributes:
@@ -394,16 +381,20 @@ class PassportElementErrorTranslationFiles(PassportElementError):
one of ``"passport"``, ``"driver_license"``, ``"identity_card"``,
``"internal_passport"``, ``"utility_bill"``, ``"bank_statement"``,
``"rental_agreement"``, ``"passport_registration"``, ``"temporary_registration"``.
file_hashes (tuple[:obj:`str`]): List of base64-encoded file hashes.
.. versionchanged:: NEXT.VERSION
|tupleclassattrs|
message (:obj:`str`): Error message.
"""
__slots__ = ("_file_hashes",)
__slots__ = ("file_hashes",)
def __init__(
self,
type: str,
file_hashes: list[str],
file_hashes: Sequence[str],
message: str,
*,
api_kwargs: Optional[JSONDict] = None,
@@ -411,33 +402,9 @@ class PassportElementErrorTranslationFiles(PassportElementError):
# Required
super().__init__("translation_files", type, message, api_kwargs=api_kwargs)
with self._unfrozen():
self._file_hashes: list[str] = file_hashes
self.file_hashes: tuple[str, ...] = parse_sequence_arg(file_hashes)
self._id_attrs = (self.source, self.type, self.message, *tuple(file_hashes))
def to_dict(self, recursive: bool = True) -> JSONDict:
"""See :meth:`telegram.TelegramObject.to_dict` for details."""
data = super().to_dict(recursive)
data["file_hashes"] = self._file_hashes
return data
@property
def file_hashes(self) -> list[str]:
"""List of base64-encoded file hashes.
.. deprecated:: 20.6
This attribute will return a tuple instead of a list in future major versions.
"""
warn(
PTBDeprecationWarning(
"20.6",
"The attribute `file_hashes` will return a tuple instead of a list in future major"
" versions. See the stability policy:"
" https://docs.python-telegram-bot.org/en/stable/stability_policy.html",
),
stacklevel=2,
)
return self._file_hashes
self._id_attrs = (self.source, self.type, self.message, self.file_hashes)
class PassportElementErrorUnspecified(PassportElementError):
+22 -29
View File
@@ -18,13 +18,13 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Encrypted PassportFile."""
import datetime as dtm
from typing import TYPE_CHECKING, Optional
from telegram._telegramobject import TelegramObject
from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp
from telegram._utils.defaultvalue import DEFAULT_NONE
from telegram._utils.types import JSONDict, ODVInput
from telegram._utils.warnings import warn
from telegram.warnings import PTBDeprecationWarning
if TYPE_CHECKING:
from telegram import Bot, File, FileCredentials
@@ -45,11 +45,11 @@ class PassportFile(TelegramObject):
is supposed to be the same over time and for different bots.
Can't be used to download or reuse the file.
file_size (:obj:`int`): File size in bytes.
file_date (:obj:`int`): Unix time when the file was uploaded.
file_date (:class:`datetime.datetime`): Time when the file was uploaded.
.. deprecated:: 20.6
This argument will only accept a datetime instead of an integer in future
major versions.
.. versionchanged:: NEXT.VERSION
Accepts only :class:`datetime.datetime` instead of :obj:`int`.
|datetime_localization|
Attributes:
file_id (:obj:`str`): Identifier for this file, which can be used to download
@@ -58,11 +58,16 @@ class PassportFile(TelegramObject):
is supposed to be the same over time and for different bots.
Can't be used to download or reuse the file.
file_size (:obj:`int`): File size in bytes.
file_date (:class:`datetime.datetime`): Time when the file was uploaded.
.. versionchanged:: NEXT.VERSION
Returns :class:`datetime.datetime` instead of :obj:`int`.
|datetime_localization|
"""
__slots__ = (
"_credentials",
"_file_date",
"file_date",
"file_id",
"file_size",
"file_unique_id",
@@ -72,7 +77,7 @@ class PassportFile(TelegramObject):
self,
file_id: str,
file_unique_id: str,
file_date: int,
file_date: dtm.datetime,
file_size: int,
credentials: Optional["FileCredentials"] = None,
*,
@@ -84,7 +89,7 @@ class PassportFile(TelegramObject):
self.file_id: str = file_id
self.file_unique_id: str = file_unique_id
self.file_size: int = file_size
self._file_date: int = file_date
self.file_date: dtm.datetime = file_date
# Optionals
self._credentials: Optional[FileCredentials] = credentials
@@ -93,28 +98,16 @@ class PassportFile(TelegramObject):
self._freeze()
def to_dict(self, recursive: bool = True) -> JSONDict:
"""See :meth:`telegram.TelegramObject.to_dict` for details."""
data = super().to_dict(recursive)
data["file_date"] = self._file_date
return data
@classmethod
def de_json(cls, data: JSONDict, bot: Optional["Bot"] = None) -> "PassportFile":
"""See :meth:`telegram.TelegramObject.de_json`."""
data = cls._parse_data(data)
@property
def file_date(self) -> int:
""":obj:`int`: Unix time when the file was uploaded.
# Get the local timezone from the bot if it has defaults
loc_tzinfo = extract_tzinfo_from_defaults(bot)
data["file_date"] = from_timestamp(data.get("file_date"), tzinfo=loc_tzinfo)
.. deprecated:: 20.6
This attribute will return a datetime instead of a integer in future major versions.
"""
warn(
PTBDeprecationWarning(
"20.6",
"The attribute `file_date` will return a datetime instead of an integer in future"
" major versions.",
),
stacklevel=2,
)
return self._file_date
return super().de_json(data=data, bot=bot)
@classmethod
def de_json_decrypted(
+8 -18
View File
@@ -1375,6 +1375,12 @@ class InlineQueryLimit(IntEnum):
of :class:`int` and can be treated as such.
.. versionadded:: 20.0
.. versionchanged:: NEXT.VERSION
Removed deprecated attributes ``InlineQueryLimit.MIN_SWITCH_PM_TEXT_LENGTH`` and
``InlineQueryLimit.MAX_SWITCH_PM_TEXT_LENGTH``. Please instead use
:attr:`InlineQueryResultsButtonLimit.MIN_START_PARAMETER_LENGTH` and
:attr:`InlineQueryResultsButtonLimit.MAX_START_PARAMETER_LENGTH`.
"""
__slots__ = ()
@@ -1389,22 +1395,6 @@ class InlineQueryLimit(IntEnum):
MAX_QUERY_LENGTH = 256
""":obj:`int`: Maximum number of characters in a :obj:`str` passed as the
:paramref:`~telegram.InlineQuery.query` parameter of :class:`telegram.InlineQuery`."""
MIN_SWITCH_PM_TEXT_LENGTH = 1
""":obj:`int`: Minimum number of characters in a :obj:`str` passed as the
:paramref:`~telegram.Bot.answer_inline_query.switch_pm_parameter` parameter of
:meth:`telegram.Bot.answer_inline_query`.
.. deprecated:: 20.3
Deprecated in favor of :attr:`InlineQueryResultsButtonLimit.MIN_START_PARAMETER_LENGTH`.
"""
MAX_SWITCH_PM_TEXT_LENGTH = 64
""":obj:`int`: Maximum number of characters in a :obj:`str` passed as the
:paramref:`~telegram.Bot.answer_inline_query.switch_pm_parameter` parameter of
:meth:`telegram.Bot.answer_inline_query`.
.. deprecated:: 20.3
Deprecated in favor of :attr:`InlineQueryResultsButtonLimit.MAX_START_PARAMETER_LENGTH`.
"""
class InlineQueryResultLimit(IntEnum):
@@ -1437,12 +1427,12 @@ class InlineQueryResultsButtonLimit(IntEnum):
__slots__ = ()
MIN_START_PARAMETER_LENGTH = InlineQueryLimit.MIN_SWITCH_PM_TEXT_LENGTH
MIN_START_PARAMETER_LENGTH = 1
""":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
MAX_START_PARAMETER_LENGTH = 64
""":obj:`int`: Maximum number of characters in a :obj:`str` passed as the
:paramref:`~telegram.InlineQueryResultsButton.start_parameter` parameter of
:meth:`telegram.InlineQueryResultsButton`."""
+5 -50
View File
@@ -741,10 +741,6 @@ class Application(
poll_interval: float = 0.0,
timeout: int = 10,
bootstrap_retries: int = 0,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
allowed_updates: Optional[Sequence[str]] = None,
drop_pending_updates: Optional[bool] = None,
close_loop: bool = True,
@@ -776,6 +772,11 @@ class Application(
.. include:: inclusions/application_run_tip.rst
.. versionchanged::
Removed the deprecated parameters ``read_timeout``, ``write_timeout``,
``connect_timeout``, and ``pool_timeout``. Use the corresponding methods in
:class:`telegram.ext.ApplicationBuilder` instead.
Args:
poll_interval (:obj:`float`, optional): Time to wait between polling updates from
Telegram in seconds. Default is ``0.0``.
@@ -794,38 +795,6 @@ class Application(
The default value will be changed to from ``-1`` to ``0``. Indefinite retries
during bootstrapping are not recommended.
read_timeout (:obj:`float`, optional): Value to pass to
:paramref:`telegram.Bot.get_updates.read_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
.. versionchanged:: 20.7
Defaults to :attr:`~telegram.request.BaseRequest.DEFAULT_NONE` instead of
``2``.
.. deprecated:: 20.7
Deprecated in favor of setting the timeout via
:meth:`telegram.ext.ApplicationBuilder.get_updates_read_timeout`.
write_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
:paramref:`telegram.Bot.get_updates.write_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
.. deprecated:: 20.7
Deprecated in favor of setting the timeout via
:meth:`telegram.ext.ApplicationBuilder.get_updates_write_timeout`.
connect_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
:paramref:`telegram.Bot.get_updates.connect_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
.. deprecated:: 20.7
Deprecated in favor of setting the timeout via
:meth:`telegram.ext.ApplicationBuilder.get_updates_connect_timeout`.
pool_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
:paramref:`telegram.Bot.get_updates.pool_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
.. deprecated:: 20.7
Deprecated in favor of setting the timeout via
:meth:`telegram.ext.ApplicationBuilder.get_updates_pool_timeout`.
drop_pending_updates (:obj:`bool`, optional): Whether to clean any pending updates on
Telegram servers before actually starting to poll. Default is :obj:`False`.
allowed_updates (Sequence[:obj:`str`], optional): Passed to
@@ -857,16 +826,6 @@ class Application(
"Application.run_polling is only available if the application has an Updater."
)
if (read_timeout, write_timeout, connect_timeout, pool_timeout) != ((DEFAULT_NONE,) * 4):
warn(
PTBDeprecationWarning(
"20.6",
"Setting timeouts via `Application.run_polling` is deprecated. "
"Please use `ApplicationBuilder.get_updates_*_timeout` instead.",
),
stacklevel=2,
)
def error_callback(exc: TelegramError) -> None:
self.create_task(self.process_error(error=exc, update=None))
@@ -875,10 +834,6 @@ class Application(
poll_interval=poll_interval,
timeout=timeout,
bootstrap_retries=bootstrap_retries,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
allowed_updates=allowed_updates,
drop_pending_updates=drop_pending_updates,
error_callback=error_callback, # if there is an error in fetching updates
+3 -50
View File
@@ -35,7 +35,6 @@ from telegram._utils.types import (
ODVInput,
SocketOpt,
)
from telegram._utils.warnings import warn
from telegram.ext._application import Application
from telegram.ext._baseupdateprocessor import BaseUpdateProcessor, SimpleUpdateProcessor
from telegram.ext._contexttypes import ContextTypes
@@ -45,7 +44,6 @@ from telegram.ext._updater import Updater
from telegram.ext._utils.types import BD, BT, CCT, CD, JQ, UD
from telegram.request import BaseRequest
from telegram.request._httpxrequest import HTTPXRequest
from telegram.warnings import PTBDeprecationWarning
if TYPE_CHECKING:
from telegram import Update
@@ -124,6 +122,9 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]):
.. seealso:: :wiki:`Your First Bot <Extensions---Your-first-Bot>`,
:wiki:`Builder Pattern <Builder-Pattern>`
.. versionchanged:: NEXT.VERSION
Removed deprecated methods ``proxy_url`` and ``get_updates_proxy_url``.
.. _`builder pattern`: https://en.wikipedia.org/wiki/Builder_pattern
"""
@@ -516,30 +517,6 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]):
self._connection_pool_size = connection_pool_size
return self
def proxy_url(self: BuilderType, proxy_url: str) -> BuilderType:
"""Legacy name for :meth:`proxy`, kept for backward compatibility.
.. seealso:: :meth:`get_updates_proxy`
.. deprecated:: 20.7
Args:
proxy_url (:obj:`str` | ``httpx.Proxy`` | ``httpx.URL``): See
:paramref:`telegram.ext.ApplicationBuilder.proxy.proxy`.
Returns:
:class:`ApplicationBuilder`: The same builder with the updated argument.
"""
warn(
PTBDeprecationWarning(
"20.7",
"`ApplicationBuilder.proxy_url` is deprecated. Use `ApplicationBuilder.proxy` "
"instead.",
),
stacklevel=2,
)
return self.proxy(proxy_url)
def proxy(self: BuilderType, proxy: Union[str, httpx.Proxy, httpx.URL]) -> BuilderType:
"""Sets the proxy for the :paramref:`~telegram.request.HTTPXRequest.proxy`
parameter of :attr:`telegram.Bot.request`. Defaults to :obj:`None`.
@@ -750,30 +727,6 @@ class ApplicationBuilder(Generic[BT, CCT, UD, CD, BD, JQ]):
self._get_updates_connection_pool_size = get_updates_connection_pool_size
return self
def get_updates_proxy_url(self: BuilderType, get_updates_proxy_url: str) -> BuilderType:
"""Legacy name for :meth:`get_updates_proxy`, kept for backward compatibility.
.. seealso:: :meth:`proxy`
.. deprecated:: 20.7
Args:
get_updates_proxy_url (:obj:`str` | ``httpx.Proxy`` | ``httpx.URL``): See
:paramref:`telegram.ext.ApplicationBuilder.get_updates_proxy.get_updates_proxy`.
Returns:
:class:`ApplicationBuilder`: The same builder with the updated argument.
"""
warn(
PTBDeprecationWarning(
"20.7",
"`ApplicationBuilder.get_updates_proxy_url` is deprecated. Use "
"`ApplicationBuilder.get_updates_proxy` instead.",
),
stacklevel=2,
)
return self.get_updates_proxy(get_updates_proxy_url)
def get_updates_proxy(
self: BuilderType, get_updates_proxy: Union[str, httpx.Proxy, httpx.URL]
) -> BuilderType:
+12 -80
View File
@@ -18,14 +18,15 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the class Defaults, which allows passing default values to Application."""
import datetime as dtm
from typing import Any, NoReturn, Optional, final
from typing import TYPE_CHECKING, Any, NoReturn, Optional, final
from telegram import LinkPreviewOptions
from telegram._utils.datetime import UTC
from telegram._utils.types import ODVInput
from telegram._utils.warnings import warn
from telegram.warnings import PTBDeprecationWarning
if TYPE_CHECKING:
from telegram import LinkPreviewOptions
@final
class Defaults:
@@ -38,23 +39,15 @@ class Defaults:
Removed the argument and attribute ``timeout``. Specify default timeout behavior for the
networking backend directly via :class:`telegram.ext.ApplicationBuilder` instead.
.. versionchanged:: NEXT.VERSION
Removed deprecated arguments and properties ``disable_web_page_preview`` and ``quote``.
Use :paramref:`link_preview_options` and :paramref:`do_quote` instead.
Parameters:
parse_mode (:obj:`str`, optional): |parse_mode|
disable_notification (:obj:`bool`, optional): |disable_notification|
disable_web_page_preview (:obj:`bool`, optional): Disables link previews for links in this
message. Mutually exclusive with :paramref:`link_preview_options`.
.. deprecated:: 20.8
Use :paramref:`link_preview_options` instead. This parameter will be removed in
future versions.
allow_sending_without_reply (:obj:`bool`, optional): |allow_sending_without_reply|.
Will be used for :attr:`telegram.ReplyParameters.allow_sending_without_reply`.
quote (:obj:`bool`, optional): |reply_quote|
.. deprecated:: 20.8
Use :paramref:`do_quote` instead. This parameter will be removed in future
versions.
tzinfo (:class:`datetime.tzinfo`, optional): A timezone to be used for all date(time)
inputs appearing throughout PTB, i.e. if a timezone naive date(time) object is passed
somewhere, it will be assumed to be in :paramref:`tzinfo`. Defaults to
@@ -135,8 +128,6 @@ class Defaults:
self,
parse_mode: Optional[str] = None,
disable_notification: Optional[bool] = None,
disable_web_page_preview: Optional[bool] = None,
quote: Optional[bool] = None,
tzinfo: dtm.tzinfo = UTC,
block: bool = True,
allow_sending_without_reply: Optional[bool] = None,
@@ -164,37 +155,9 @@ class Defaults:
stacklevel=2,
)
if disable_web_page_preview is not None and link_preview_options is not None:
raise ValueError(
"`disable_web_page_preview` and `link_preview_options` are mutually exclusive."
)
if quote is not None and do_quote is not None:
raise ValueError("`quote` and `do_quote` are mutually exclusive")
if disable_web_page_preview is not None:
warn(
PTBDeprecationWarning(
"20.8",
"`Defaults.disable_web_page_preview` is deprecated. Use "
"`Defaults.link_preview_options` instead.",
),
stacklevel=2,
)
self._link_preview_options: Optional[LinkPreviewOptions] = LinkPreviewOptions(
is_disabled=disable_web_page_preview
)
else:
self._link_preview_options = link_preview_options
self._link_preview_options = link_preview_options
self._do_quote = do_quote
if quote is not None:
warn(
PTBDeprecationWarning(
"20.8", "`Defaults.quote` is deprecated. Use `Defaults.do_quote` instead."
),
stacklevel=2,
)
self._do_quote: Optional[bool] = quote
else:
self._do_quote = do_quote
# Gather all defaults that actually have a default value
self._api_defaults = {}
for kwarg in (
@@ -223,9 +186,9 @@ class Defaults:
(
self._parse_mode,
self._disable_notification,
self.disable_web_page_preview,
self._link_preview_options,
self._allow_sending_without_reply,
self.quote,
self._do_quote,
self._tzinfo,
self._block,
self._protect_content,
@@ -329,23 +292,6 @@ class Defaults:
"You can not assign a new value to disable_notification after initialization."
)
@property
def disable_web_page_preview(self) -> ODVInput[bool]:
""":obj:`bool`: Optional. Disables link previews for links in all outgoing
messages.
.. deprecated:: 20.8
Use :attr:`link_preview_options` instead. This attribute will be removed in future
versions.
"""
return self._link_preview_options.is_disabled if self._link_preview_options else None
@disable_web_page_preview.setter
def disable_web_page_preview(self, _: object) -> NoReturn:
raise AttributeError(
"You can not assign a new value to disable_web_page_preview after initialization."
)
@property
def allow_sending_without_reply(self) -> Optional[bool]:
""":obj:`bool`: Optional. Pass :obj:`True`, if the message
@@ -359,20 +305,6 @@ class Defaults:
"You can not assign a new value to allow_sending_without_reply after initialization."
)
@property
def quote(self) -> Optional[bool]:
""":obj:`bool`: Optional. |reply_quote|
.. deprecated:: 20.8
Use :attr:`do_quote` instead. This attribute will be removed in future
versions.
"""
return self._do_quote if self._do_quote is not None else None
@quote.setter
def quote(self, _: object) -> NoReturn:
raise AttributeError("You can not assign a new value to quote after initialization.")
@property
def tzinfo(self) -> dtm.tzinfo:
""":obj:`tzinfo`: A timezone to be used for all date(time) objects appearing
+8 -57
View File
@@ -26,10 +26,10 @@ from pathlib import Path
from types import TracebackType
from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, Union
from telegram._utils.defaultvalue import DEFAULT_80, DEFAULT_IP, DEFAULT_NONE, DefaultValue
from telegram._utils.defaultvalue import DEFAULT_80, DEFAULT_IP, DefaultValue
from telegram._utils.logging import get_logger
from telegram._utils.repr import build_repr_with_selected_attrs
from telegram._utils.types import DVType, ODVInput
from telegram._utils.types import DVType
from telegram.error import TelegramError
from telegram.ext._utils.networkloop import network_retry_loop
@@ -208,10 +208,6 @@ class Updater(contextlib.AbstractAsyncContextManager["Updater"]):
poll_interval: float = 0.0,
timeout: int = 10,
bootstrap_retries: int = 0,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
allowed_updates: Optional[Sequence[str]] = None,
drop_pending_updates: Optional[bool] = None,
error_callback: Optional[Callable[[TelegramError], None]] = None,
@@ -221,6 +217,12 @@ class Updater(contextlib.AbstractAsyncContextManager["Updater"]):
.. versionchanged:: 20.0
Removed the ``clean`` argument in favor of :paramref:`drop_pending_updates`.
.. versionchanged:: NEXT.VERSION
Removed the deprecated arguments ``read_timeout``, ``write_timeout``,
``connect_timeout``, and ``pool_timeout`` in favor of setting the timeouts via
the corresponding methods of :class:`telegram.ext.ApplicationBuilder`. or
by specifying the timeout via :paramref:`telegram.Bot.get_updates_request`.
Args:
poll_interval (:obj:`float`, optional): Time to wait between polling updates from
Telegram in seconds. Default is ``0.0``.
@@ -236,41 +238,6 @@ class Updater(contextlib.AbstractAsyncContextManager["Updater"]):
.. versionchanged:: 21.11
The default value will be changed to from ``-1`` to ``0``. Indefinite retries
during bootstrapping are not recommended.
read_timeout (:obj:`float`, optional): Value to pass to
:paramref:`telegram.Bot.get_updates.read_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
.. versionchanged:: 20.7
Defaults to :attr:`~telegram.request.BaseRequest.DEFAULT_NONE` instead of
``2``.
.. deprecated:: 20.7
Deprecated in favor of setting the timeout via
:meth:`telegram.ext.ApplicationBuilder.get_updates_read_timeout` or
:paramref:`telegram.Bot.get_updates_request`.
write_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
:paramref:`telegram.Bot.get_updates.write_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
.. deprecated:: 20.7
Deprecated in favor of setting the timeout via
:meth:`telegram.ext.ApplicationBuilder.get_updates_write_timeout` or
:paramref:`telegram.Bot.get_updates_request`.
connect_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
:paramref:`telegram.Bot.get_updates.connect_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
.. deprecated:: 20.7
Deprecated in favor of setting the timeout via
:meth:`telegram.ext.ApplicationBuilder.get_updates_connect_timeout` or
:paramref:`telegram.Bot.get_updates_request`.
pool_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
:paramref:`telegram.Bot.get_updates.pool_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
.. deprecated:: 20.7
Deprecated in favor of setting the timeout via
:meth:`telegram.ext.ApplicationBuilder.get_updates_pool_timeout` or
:paramref:`telegram.Bot.get_updates_request`.
allowed_updates (Sequence[:obj:`str`], optional): Passed to
:meth:`telegram.Bot.get_updates`.
@@ -324,10 +291,6 @@ class Updater(contextlib.AbstractAsyncContextManager["Updater"]):
await self._start_polling(
poll_interval=poll_interval,
timeout=timeout,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
bootstrap_retries=bootstrap_retries,
drop_pending_updates=drop_pending_updates,
allowed_updates=allowed_updates,
@@ -347,10 +310,6 @@ class Updater(contextlib.AbstractAsyncContextManager["Updater"]):
self,
poll_interval: float,
timeout: int,
read_timeout: ODVInput[float],
write_timeout: ODVInput[float],
connect_timeout: ODVInput[float],
pool_timeout: ODVInput[float],
bootstrap_retries: int,
drop_pending_updates: Optional[bool],
allowed_updates: Optional[Sequence[str]],
@@ -376,10 +335,6 @@ class Updater(contextlib.AbstractAsyncContextManager["Updater"]):
updates = await self.bot.get_updates(
offset=self._last_update_id,
timeout=timeout,
read_timeout=read_timeout,
connect_timeout=connect_timeout,
write_timeout=write_timeout,
pool_timeout=pool_timeout,
allowed_updates=allowed_updates,
)
except TelegramError:
@@ -440,10 +395,6 @@ class Updater(contextlib.AbstractAsyncContextManager["Updater"]):
offset=self._last_update_id,
# We don't want to do long polling here!
timeout=0,
read_timeout=read_timeout,
connect_timeout=connect_timeout,
write_timeout=write_timeout,
pool_timeout=pool_timeout,
allowed_updates=allowed_updates,
)
except TelegramError:
+6 -39
View File
@@ -34,6 +34,9 @@ This module contains filters for use with :class:`telegram.ext.MessageHandler`,
* Filters which do both (like ``Filters.text``) are now split as ready-to-use version
``filters.TEXT`` and class version ``filters.Text(...)``.
.. versionchanged:: NEXT.VERSION
Removed deprecated attribute `CHAT`.
"""
__all__ = (
@@ -43,7 +46,6 @@ __all__ = (
"AUDIO",
"BOOST_ADDED",
"CAPTION",
"CHAT",
"COMMAND",
"CONTACT",
"EFFECT_ID",
@@ -859,21 +861,6 @@ class Chat(_ChatUserBaseFilter):
return super()._remove_chat_ids(chat_id)
class _Chat(MessageFilter):
__slots__ = ()
def filter(self, message: Message) -> bool:
return bool(message.chat)
CHAT = _Chat(name="filters.CHAT")
"""This filter filters *any* message that has a :attr:`telegram.Message.chat`.
.. deprecated:: 20.8
This filter has no effect since :attr:`telegram.Message.chat` is always present.
"""
class ChatType: # A convenience namespace for Chat types.
"""Subset for filtering the type of chat.
@@ -1915,6 +1902,9 @@ class StatusUpdate:
Caution:
``filters.StatusUpdate`` itself is *not* a filter, but just a convenience namespace.
.. versionchanged:: NEXT.VERSION
Removed deprecated attribute `USER_SHARED`.
"""
__slots__ = ()
@@ -1948,7 +1938,6 @@ class StatusUpdate:
or StatusUpdate.PROXIMITY_ALERT_TRIGGERED.check_update(update)
or StatusUpdate.REFUNDED_PAYMENT.check_update(update)
or StatusUpdate.USERS_SHARED.check_update(update)
or StatusUpdate.USER_SHARED.check_update(update)
or StatusUpdate.VIDEO_CHAT_ENDED.check_update(update)
or StatusUpdate.VIDEO_CHAT_PARTICIPANTS_INVITED.check_update(update)
or StatusUpdate.VIDEO_CHAT_SCHEDULED.check_update(update)
@@ -2204,28 +2193,6 @@ class StatusUpdate:
.. versionadded:: 21.4
"""
class _UserShared(MessageFilter):
__slots__ = ()
def filter(self, message: Message) -> bool:
return bool(message.api_kwargs.get("user_shared"))
USER_SHARED = _UserShared(name="filters.StatusUpdate.USER_SHARED")
"""Messages that contain ``"user_shared"`` in :attr:`telegram.TelegramObject.api_kwargs`.
Warning:
This will only catch the legacy ``user_shared`` field, not the
new :attr:`telegram.Message.users_shared` attribute!
.. versionchanged:: 21.0
Now relies on :attr:`telegram.TelegramObject.api_kwargs` as the native attribute
``Message.user_shared`` was removed.
.. versionadded:: 20.1
.. deprecated:: 20.8
Use :attr:`USERS_SHARED` instead.
"""
class _UsersShared(MessageFilter):
__slots__ = ()
+3 -33
View File
@@ -29,7 +29,6 @@ from telegram._utils.defaultvalue import DefaultValue
from telegram._utils.logging import get_logger
from telegram._utils.strings import TextEncoding
from telegram._utils.types import JSONDict, ODVInput
from telegram._utils.warnings import warn
from telegram._version import __version__ as ptb_ver
from telegram.error import (
BadRequest,
@@ -42,7 +41,6 @@ from telegram.error import (
TelegramError,
)
from telegram.request._requestdata import RequestData
from telegram.warnings import PTBDeprecationWarning
RT = TypeVar("RT", bound="BaseRequest")
@@ -133,22 +131,19 @@ class BaseRequest(
await self.shutdown()
@property
@abc.abstractmethod
def read_timeout(self) -> Optional[float]:
"""This property must return the default read timeout in seconds used by this class.
More precisely, the returned value should be the one used when
:paramref:`post.read_timeout` of :meth:post` is not passed/equal to :attr:`DEFAULT_NONE`.
.. versionadded:: 20.7
Warning:
For now this property does not need to be implemented by subclasses and will raise
:exc:`NotImplementedError` if accessed without being overridden. However, in future
versions, this property will be abstract and must be implemented by subclasses.
.. versionchanged:: NEXT.VERSION
This property is now required to be implemented by subclasses.
Returns:
:obj:`float` | :obj:`None`: The read timeout in seconds.
"""
raise NotImplementedError
@abc.abstractmethod
async def initialize(self) -> None:
@@ -305,31 +300,6 @@ class BaseRequest(
TelegramError
"""
# Import needs to be here since HTTPXRequest is a subclass of BaseRequest
from telegram.request import HTTPXRequest # pylint: disable=import-outside-toplevel
# 20 is the documented default value for all the media related bot methods and custom
# implementations of BaseRequest may explicitly rely on that. Hence, we follow the
# standard deprecation policy and deprecate starting with version 20.7.
# For our own implementation HTTPXRequest, we can handle that ourselves, so we skip the
# warning in that case.
has_files = request_data and request_data.multipart_data
if (
has_files
and not isinstance(self, HTTPXRequest)
and isinstance(write_timeout, DefaultValue)
):
warn(
PTBDeprecationWarning(
"20.7",
f"The `write_timeout` parameter passed to {self.__class__.__name__}.do_request"
" will default to `BaseRequest.DEFAULT_NONE` instead of 20 in future versions "
"for *all* methods of the `Bot` class, including methods sending media.",
),
stacklevel=3,
)
write_timeout = 20
try:
code, payload = await self.do_request(
url=url,
+3 -19
View File
@@ -25,11 +25,9 @@ import httpx
from telegram._utils.defaultvalue import DefaultValue
from telegram._utils.logging import get_logger
from telegram._utils.types import HTTPVersion, ODVInput, SocketOpt
from telegram._utils.warnings import warn
from telegram.error import NetworkError, TimedOut
from telegram.request._baserequest import BaseRequest
from telegram.request._requestdata import RequestData
from telegram.warnings import PTBDeprecationWarning
# Note to future devs:
# Proxies are currently only tested manually. The httpx development docs have a nice guide on that:
@@ -45,6 +43,9 @@ class HTTPXRequest(BaseRequest):
.. versionadded:: 20.0
.. versionchanged:: NEXT.VERSION
Removed the deprecated parameter ``proxy_url``. Use :paramref:`proxy` instead.
Args:
connection_pool_size (:obj:`int`, optional): Number of connections to keep in the
connection pool. Defaults to ``1``.
@@ -52,10 +53,6 @@ class HTTPXRequest(BaseRequest):
Note:
Independent of the value, one additional connection will be reserved for
:meth:`telegram.Bot.get_updates`.
proxy_url (:obj:`str`, optional): Legacy name for :paramref:`proxy`, kept for backward
compatibility. Defaults to :obj:`None`.
.. deprecated:: 20.7
read_timeout (:obj:`float` | :obj:`None`, optional): If passed, specifies the maximum
amount of time (in seconds) to wait for a response from Telegram's server.
This value is used unless a different value is passed to :meth:`do_request`.
@@ -145,7 +142,6 @@ class HTTPXRequest(BaseRequest):
def __init__(
self,
connection_pool_size: int = 1,
proxy_url: Optional[Union[str, httpx.Proxy, httpx.URL]] = None,
read_timeout: Optional[float] = 5.0,
write_timeout: Optional[float] = 5.0,
connect_timeout: Optional[float] = 5.0,
@@ -156,18 +152,6 @@ class HTTPXRequest(BaseRequest):
media_write_timeout: Optional[float] = 20.0,
httpx_kwargs: Optional[dict[str, Any]] = None,
):
if proxy_url is not None and proxy is not None:
raise ValueError("The parameters `proxy_url` and `proxy` are mutually exclusive.")
if proxy_url is not None:
proxy = proxy_url
warn(
PTBDeprecationWarning(
"20.7", "The parameter `proxy_url` is deprecated. Use `proxy` instead."
),
stacklevel=2,
)
self._http_version = http_version
self._media_write_timeout = media_write_timeout
timeout = httpx.Timeout(
@@ -19,7 +19,6 @@
import pytest
from telegram import PassportElementErrorFiles, PassportElementErrorSelfie
from telegram.warnings import PTBDeprecationWarning
from tests.auxil.slots import mro_slots
@@ -49,8 +48,8 @@ class TestPassportElementErrorFilesWithoutRequest(PassportElementErrorFilesTestB
def test_expected_values(self, passport_element_error_files):
assert passport_element_error_files.source == self.source
assert passport_element_error_files.type == self.type_
assert isinstance(passport_element_error_files.file_hashes, list)
assert passport_element_error_files.file_hashes == self.file_hashes
assert isinstance(passport_element_error_files.file_hashes, tuple)
assert passport_element_error_files.file_hashes == tuple(self.file_hashes)
assert passport_element_error_files.message == self.message
def test_to_dict(self, passport_element_error_files):
@@ -60,9 +59,8 @@ class TestPassportElementErrorFilesWithoutRequest(PassportElementErrorFilesTestB
assert passport_element_error_files_dict["source"] == passport_element_error_files.source
assert passport_element_error_files_dict["type"] == passport_element_error_files.type
assert passport_element_error_files_dict["message"] == passport_element_error_files.message
assert (
passport_element_error_files_dict["file_hashes"]
== passport_element_error_files.file_hashes
assert passport_element_error_files_dict["file_hashes"] == list(
passport_element_error_files.file_hashes
)
def test_equality(self):
@@ -88,13 +86,3 @@ class TestPassportElementErrorFilesWithoutRequest(PassportElementErrorFilesTestB
assert a != f
assert hash(a) != hash(f)
def test_file_hashes_deprecated(self, passport_element_error_files, recwarn):
passport_element_error_files.file_hashes
assert len(recwarn) == 1
assert (
"The attribute `file_hashes` will return a tuple instead of a list in future major"
" versions." in str(recwarn[0].message)
)
assert recwarn[0].category is PTBDeprecationWarning
assert recwarn[0].filename == __file__
@@ -19,7 +19,6 @@
import pytest
from telegram import PassportElementErrorSelfie, PassportElementErrorTranslationFiles
from telegram.warnings import PTBDeprecationWarning
from tests.auxil.slots import mro_slots
@@ -51,8 +50,8 @@ class TestPassportElementErrorTranslationFilesWithoutRequest(
def test_expected_values(self, passport_element_error_translation_files):
assert passport_element_error_translation_files.source == self.source
assert passport_element_error_translation_files.type == self.type_
assert isinstance(passport_element_error_translation_files.file_hashes, list)
assert passport_element_error_translation_files.file_hashes == self.file_hashes
assert isinstance(passport_element_error_translation_files.file_hashes, tuple)
assert passport_element_error_translation_files.file_hashes == tuple(self.file_hashes)
assert passport_element_error_translation_files.message == self.message
def test_to_dict(self, passport_element_error_translation_files):
@@ -73,9 +72,8 @@ class TestPassportElementErrorTranslationFilesWithoutRequest(
passport_element_error_translation_files_dict["message"]
== passport_element_error_translation_files.message
)
assert (
passport_element_error_translation_files_dict["file_hashes"]
== passport_element_error_translation_files.file_hashes
assert passport_element_error_translation_files_dict["file_hashes"] == list(
passport_element_error_translation_files.file_hashes
)
def test_equality(self):
@@ -101,13 +99,3 @@ class TestPassportElementErrorTranslationFilesWithoutRequest(
assert a != f
assert hash(a) != hash(f)
def test_file_hashes_deprecated(self, passport_element_error_translation_files, recwarn):
passport_element_error_translation_files.file_hashes
assert len(recwarn) == 1
assert (
"The attribute `file_hashes` will return a tuple instead of a list in future major"
" versions." in str(recwarn[0].message)
)
assert recwarn[0].category is PTBDeprecationWarning
assert recwarn[0].filename == __file__
+25 -13
View File
@@ -16,10 +16,12 @@
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
import datetime as dtm
import pytest
from telegram import Bot, File, PassportElementError, PassportFile
from telegram.warnings import PTBDeprecationWarning
from telegram._utils.datetime import UTC, to_timestamp
from tests.auxil.bot_method_checks import (
check_defaults_handling,
check_shortcut_call,
@@ -44,7 +46,7 @@ class PassportFileTestBase:
file_id = "data"
file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e"
file_size = 50
file_date = 1532879128
file_date = dtm.datetime.now(tz=UTC).replace(microsecond=0)
class TestPassportFileWithoutRequest(PassportFileTestBase):
@@ -67,7 +69,27 @@ class TestPassportFileWithoutRequest(PassportFileTestBase):
assert passport_file_dict["file_id"] == passport_file.file_id
assert passport_file_dict["file_unique_id"] == passport_file.file_unique_id
assert passport_file_dict["file_size"] == passport_file.file_size
assert passport_file_dict["file_date"] == passport_file.file_date
assert passport_file_dict["file_date"] == to_timestamp(passport_file.file_date)
def test_de_json_localization(self, passport_file, tz_bot, offline_bot, raw_bot):
json_dict = {
"file_id": self.file_id,
"file_unique_id": self.file_unique_id,
"file_size": self.file_size,
"file_date": to_timestamp(self.file_date),
}
pf = PassportFile.de_json(json_dict, offline_bot)
pf_raw = PassportFile.de_json(json_dict, raw_bot)
pf_tz = PassportFile.de_json(json_dict, tz_bot)
# comparing utcoffsets because comparing timezones is unpredicatable
date_offset = pf_tz.file_date.utcoffset()
tz_bot_offset = tz_bot.defaults.tzinfo.utcoffset(pf_tz.file_date.replace(tzinfo=None))
assert pf_raw.file_date.tzinfo == UTC
assert pf.file_date.tzinfo == UTC
assert date_offset == tz_bot_offset
def test_equality(self):
a = PassportFile(self.file_id, self.file_unique_id, self.file_size, self.file_date)
@@ -89,16 +111,6 @@ class TestPassportFileWithoutRequest(PassportFileTestBase):
assert a != e
assert hash(a) != hash(e)
def test_file_date_deprecated(self, passport_file, recwarn):
passport_file.file_date
assert len(recwarn) == 1
assert (
"The attribute `file_date` will return a datetime instead of an integer in future"
" major versions." in str(recwarn[0].message)
)
assert recwarn[0].category is PTBDeprecationWarning
assert recwarn[0].filename == __file__
async def test_get_file_instance_method(self, monkeypatch, passport_file):
async def make_assertion(*_, **kwargs):
result = kwargs["file_id"] == passport_file.file_id
-2
View File
@@ -619,8 +619,6 @@ async def check_defaults_handling(
defaults_no_custom_defaults = Defaults()
kwargs = {kwarg: "custom_default" for kwarg in inspect.signature(Defaults).parameters}
kwargs["tzinfo"] = zoneinfo.ZoneInfo("America/New_York")
kwargs.pop("disable_web_page_preview") # mutually exclusive with link_preview_options
kwargs.pop("quote") # mutually exclusive with do_quote
kwargs["link_preview_options"] = LinkPreviewOptions(
url="custom_default", show_above_text="custom_default"
)
+4
View File
@@ -71,6 +71,10 @@ class OfflineRequest(BaseRequest):
async def shutdown(self) -> None:
pass
@property
def read_timeout(self):
return 1
def __init__(self, *args, **kwargs):
pass
-43
View File
@@ -1516,49 +1516,6 @@ class TestApplication:
found_log = True
assert found_log
@pytest.mark.parametrize(
"timeout_name",
["read_timeout", "connect_timeout", "write_timeout", "pool_timeout", "poll_interval"],
)
@pytest.mark.skipif(
platform.system() == "Windows",
reason="Can't send signals without stopping whole process on windows",
)
def test_run_polling_timeout_deprecation_warnings(
self, timeout_name, monkeypatch, recwarn, app
):
def thread_target():
waited = 0
while not app.running:
time.sleep(0.05)
waited += 0.05
if waited > 5:
pytest.fail("App apparently won't start")
time.sleep(0.05)
os.kill(os.getpid(), signal.SIGINT)
monkeypatch.setattr(app.bot, "get_updates", empty_get_updates)
thread = Thread(target=thread_target)
thread.start()
kwargs = {timeout_name: 42}
app.run_polling(drop_pending_updates=True, close_loop=False, **kwargs)
thread.join()
if timeout_name == "poll_interval":
assert len(recwarn) == 0
return
assert len(recwarn) == 1
assert "Setting timeouts via `Application.run_polling` is deprecated." in str(
recwarn[0].message
)
assert recwarn[0].category is PTBDeprecationWarning
assert recwarn[0].filename == __file__, "wrong stacklevel"
@pytest.mark.skipif(
platform.system() == "Windows",
reason="Can't send signals without stopping whole process on windows",
+10 -40
View File
@@ -41,7 +41,6 @@ from telegram.ext import (
from telegram.ext._applicationbuilder import _BOT_CHECKS
from telegram.ext._baseupdateprocessor import SimpleUpdateProcessor
from telegram.request import HTTPXRequest
from telegram.warnings import PTBDeprecationWarning
from tests.auxil.constants import PRIVATE_KEY
from tests.auxil.envvars import TEST_WITH_OPT_DEPS
from tests.auxil.files import data_file
@@ -207,7 +206,6 @@ class TestApplicationBuilder:
"write_timeout",
"media_write_timeout",
"proxy",
"proxy_url",
"socket_options",
"bot",
"updater",
@@ -217,9 +215,8 @@ class TestApplicationBuilder:
def test_mutually_exclusive_for_request(self, builder, method):
builder.request(1)
method_name = method.replace("proxy_url", "proxy")
with pytest.raises(
RuntimeError, match=f"`{method_name}` may only be set, if no request instance"
RuntimeError, match=f"`{method}` may only be set, if no request instance"
):
getattr(builder, method)(data_file("private.key"))
@@ -237,7 +234,6 @@ class TestApplicationBuilder:
"get_updates_read_timeout",
"get_updates_write_timeout",
"get_updates_proxy",
"get_updates_proxy_url",
"get_updates_socket_options",
"get_updates_http_version",
"bot",
@@ -247,10 +243,9 @@ class TestApplicationBuilder:
def test_mutually_exclusive_for_get_updates_request(self, builder, method):
builder.get_updates_request(1)
method_name = method.replace("proxy_url", "proxy")
with pytest.raises(
RuntimeError,
match=f"`{method_name}` may only be set, if no get_updates_request instance",
match=f"`{method}` may only be set, if no get_updates_request instance",
):
getattr(builder, method)(data_file("private.key"))
@@ -267,7 +262,6 @@ class TestApplicationBuilder:
"get_updates_pool_timeout",
"get_updates_read_timeout",
"get_updates_write_timeout",
"get_updates_proxy_url",
"get_updates_proxy",
"get_updates_socket_options",
"get_updates_http_version",
@@ -278,7 +272,6 @@ class TestApplicationBuilder:
"write_timeout",
"media_write_timeout",
"proxy",
"proxy_url",
"socket_options",
"http_version",
"bot",
@@ -290,17 +283,15 @@ class TestApplicationBuilder:
def test_mutually_exclusive_for_updater(self, builder, method):
builder.updater(1)
method_name = method.replace("proxy_url", "proxy")
with pytest.raises(
RuntimeError,
match=f"`{method_name}` may only be set, if no updater",
match=f"`{method}` may only be set, if no updater",
):
getattr(builder, method)(data_file("private.key"))
builder = ApplicationBuilder()
getattr(builder, method)(data_file("private.key"))
method = method.replace("proxy_url", "proxy")
with pytest.raises(RuntimeError, match=f"`updater` may only be set, if no {method}"):
builder.updater(1)
@@ -313,7 +304,6 @@ class TestApplicationBuilder:
"get_updates_read_timeout",
"get_updates_write_timeout",
"get_updates_proxy",
"get_updates_proxy_url",
"get_updates_socket_options",
"get_updates_http_version",
"connection_pool_size",
@@ -323,7 +313,6 @@ class TestApplicationBuilder:
"write_timeout",
"media_write_timeout",
"proxy",
"proxy_url",
"socket_options",
"bot",
"http_version",
@@ -341,14 +330,11 @@ class TestApplicationBuilder:
getattr(builder, method)(data_file("private.key"))
builder.updater(None)
# We test with bot the new & legacy version to ensure that the legacy version still works
@pytest.mark.parametrize(
("proxy_method", "get_updates_proxy_method"),
[("proxy", "get_updates_proxy"), ("proxy_url", "get_updates_proxy_url")],
ids=["new", "legacy"],
)
def test_all_bot_args_custom(
self, builder, bot, monkeypatch, proxy_method, get_updates_proxy_method
self,
builder,
bot,
monkeypatch,
):
# Only socket_options is tested in a standalone test, since that's easier
defaults = Defaults()
@@ -403,8 +389,7 @@ class TestApplicationBuilder:
builder = ApplicationBuilder().token(bot.token)
builder.connection_pool_size(1).connect_timeout(2).pool_timeout(3).read_timeout(
4
).write_timeout(5).media_write_timeout(6).http_version("1.1")
getattr(builder, proxy_method)("proxy")
).write_timeout(5).media_write_timeout(6).http_version("1.1").proxy("proxy")
app = builder.build()
client = app.bot.request._client
@@ -423,8 +408,9 @@ class TestApplicationBuilder:
5
).get_updates_http_version(
"1.1"
).get_updates_proxy(
"get_updates_proxy"
)
getattr(builder, get_updates_proxy_method)("get_updates_proxy")
app = builder.build()
client = app.bot._request[0]._client
@@ -585,22 +571,6 @@ class TestApplicationBuilder:
assert isinstance(app.update_queue, asyncio.Queue)
assert isinstance(app.updater, Updater)
def test_proxy_url_deprecation_warning(self, bot, builder, recwarn):
builder.token(bot.token).proxy_url("proxy_url")
assert len(recwarn) == 1
assert "`ApplicationBuilder.proxy_url` is deprecated" in str(recwarn[0].message)
assert recwarn[0].category is PTBDeprecationWarning
assert recwarn[0].filename == __file__, "wrong stacklevel"
def test_get_updates_proxy_url_deprecation_warning(self, bot, builder, recwarn):
builder.token(bot.token).get_updates_proxy_url("get_updates_proxy_url")
assert len(recwarn) == 1
assert "`ApplicationBuilder.get_updates_proxy_url` is deprecated" in str(
recwarn[0].message
)
assert recwarn[0].category is PTBDeprecationWarning
assert recwarn[0].filename == __file__, "wrong stacklevel"
@pytest.mark.parametrize(
("read_timeout", "timeout", "expected"),
[
+4 -30
View File
@@ -22,7 +22,7 @@ import inspect
import pytest
from telegram import LinkPreviewOptions, User
from telegram import User
from telegram.ext import Defaults
from telegram.warnings import PTBDeprecationWarning
from tests.auxil.envvars import TEST_WITH_OPT_DEPS
@@ -31,7 +31,7 @@ from tests.auxil.slots import mro_slots
class TestDefaults:
def test_slot_behaviour(self):
a = Defaults(parse_mode="HTML", quote=True)
a = Defaults(parse_mode="HTML", do_quote=True)
for attr in a.__slots__:
assert getattr(a, attr, "err") != "err", f"got extra slot '{attr}'"
assert len(mro_slots(a)) == len(set(mro_slots(a))), "duplicate slot"
@@ -63,8 +63,8 @@ class TestDefaults:
c = Defaults(parse_mode="HTML", do_quote=True, protect_content=True)
d = Defaults(parse_mode="HTML", protect_content=True)
e = User(123, "test_user", False)
f = Defaults(parse_mode="HTML", disable_web_page_preview=True)
g = Defaults(parse_mode="HTML", disable_web_page_preview=True)
f = Defaults(parse_mode="HTML", block=True)
g = Defaults(parse_mode="HTML", block=True)
assert a == b
assert hash(a) == hash(b)
@@ -81,29 +81,3 @@ class TestDefaults:
assert f == g
assert hash(f) == hash(g)
def test_mutually_exclusive(self):
with pytest.raises(ValueError, match="mutually exclusive"):
Defaults(disable_web_page_preview=True, link_preview_options=LinkPreviewOptions(False))
with pytest.raises(ValueError, match="mutually exclusive"):
Defaults(quote=True, do_quote=False)
def test_deprecation_warning_for_disable_web_page_preview(self):
with pytest.warns(
PTBDeprecationWarning, match="`Defaults.disable_web_page_preview` is "
) as record:
Defaults(disable_web_page_preview=True)
assert record[0].filename == __file__, "wrong stacklevel!"
assert Defaults(disable_web_page_preview=True).link_preview_options.is_disabled is True
assert Defaults(disable_web_page_preview=False).disable_web_page_preview is False
def test_deprecation_warning_for_quote(self):
with pytest.warns(PTBDeprecationWarning, match="`Defaults.quote` is ") as record:
Defaults(quote=True)
assert record[0].filename == __file__, "wrong stacklevel!"
assert Defaults(quote=True).do_quote is True
assert Defaults(quote=False).quote is False
-8
View File
@@ -1068,11 +1068,6 @@ class TestFilters:
assert filters.StatusUpdate.WRITE_ACCESS_ALLOWED.check_update(update)
update.message.write_access_allowed = None
update.message.api_kwargs = {"user_shared": "user_shared"}
assert filters.StatusUpdate.ALL.check_update(update)
assert filters.StatusUpdate.USER_SHARED.check_update(update)
update.message.api_kwargs = {}
update.message.users_shared = "users_shared"
assert filters.StatusUpdate.ALL.check_update(update)
assert filters.StatusUpdate.USERS_SHARED.check_update(update)
@@ -1334,15 +1329,12 @@ class TestFilters:
def test_filters_chat_id(self, update):
assert not filters.Chat(chat_id=1).check_update(update)
assert filters.CHAT.check_update(update)
update.message.chat.id = 1
assert filters.Chat(chat_id=1).check_update(update)
assert filters.CHAT.check_update(update)
update.message.chat.id = 2
assert filters.Chat(chat_id=[1, 2]).check_update(update)
assert not filters.Chat(chat_id=[3, 4]).check_update(update)
update.message.chat = None
assert not filters.CHAT.check_update(update)
assert not filters.Chat(chat_id=[3, 4]).check_update(update)
def test_filters_chat_username(self, update):
+8
View File
@@ -85,6 +85,10 @@ class TestBaseRateLimiter:
async def shutdown(self) -> None:
pass
@property
def read_timeout(self):
return 1
async def do_request(self, *args, **kwargs):
if TestBaseRateLimiter.request_received is None:
TestBaseRateLimiter.request_received = []
@@ -163,6 +167,10 @@ class TestAIORateLimiter:
async def shutdown(self) -> None:
pass
@property
def read_timeout(self):
return 1
async def do_request(self, *args, **kwargs):
request_data = kwargs.get("request_data")
allow_paid_broadcast = request_data.parameters.get("allow_paid_broadcast", False)
-17
View File
@@ -27,7 +27,6 @@ from random import randrange
import pytest
from telegram import Bot, InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram._utils.defaultvalue import DEFAULT_NONE
from telegram.error import InvalidToken, RetryAfter, TelegramError, TimedOut
from telegram.ext import ExtBot, InvalidCallbackData, Updater
from tests.auxil.build_messages import make_message, make_message_update
@@ -296,10 +295,6 @@ class TestUpdater:
received_kwargs = {}
expected_kwargs = {
"timeout": 0,
"read_timeout": "read_timeout",
"connect_timeout": "connect_timeout",
"write_timeout": "write_timeout",
"pool_timeout": "pool_timeout",
"allowed_updates": "allowed_updates",
}
@@ -422,10 +417,6 @@ class TestUpdater:
expected = {
"timeout": 10,
"read_timeout": DEFAULT_NONE,
"write_timeout": DEFAULT_NONE,
"connect_timeout": DEFAULT_NONE,
"pool_timeout": DEFAULT_NONE,
"allowed_updates": None,
"api_kwargs": None,
}
@@ -466,10 +457,6 @@ class TestUpdater:
expected = {
"timeout": 42,
"read_timeout": 43,
"write_timeout": 44,
"connect_timeout": 45,
"pool_timeout": 46,
"allowed_updates": ["message"],
"api_kwargs": None,
}
@@ -477,10 +464,6 @@ class TestUpdater:
await update_queue.put(Update(update_id=2))
await updater.start_polling(
timeout=42,
read_timeout=43,
write_timeout=44,
connect_timeout=45,
pool_timeout=46,
allowed_updates=["message"],
)
await update_queue.join()
+11 -100
View File
@@ -45,10 +45,9 @@ from telegram.error import (
TelegramError,
TimedOut,
)
from telegram.request import BaseRequest, RequestData
from telegram.request import RequestData
from telegram.request._httpxrequest import HTTPXRequest
from telegram.request._requestparameter import RequestParameter
from telegram.warnings import PTBDeprecationWarning
from tests.auxil.envvars import TEST_WITH_OPT_DEPS
from tests.auxil.files import data_file
from tests.auxil.networking import NonchalantHttpxRequest
@@ -390,76 +389,6 @@ class TestRequestWithoutRequest:
)
assert self.test_flag == (1, 2, 3, 4)
def test_read_timeout_not_implemented(self):
class SimpleRequest(BaseRequest):
async def do_request(self, *args, **kwargs):
raise httpx.ReadTimeout("read timeout")
async def initialize(self) -> None:
pass
async def shutdown(self) -> None:
pass
with pytest.raises(NotImplementedError):
SimpleRequest().read_timeout
@pytest.mark.parametrize("media", [True, False])
async def test_timeout_propagation_write_timeout(
self, monkeypatch, media, input_media_photo, recwarn # noqa: F811
):
class CustomRequest(BaseRequest):
async def initialize(self_) -> None:
pass
async def shutdown(self_) -> None:
pass
async def do_request(self_, *args, **kwargs) -> tuple[int, bytes]:
self.test_flag = (
kwargs.get("read_timeout"),
kwargs.get("connect_timeout"),
kwargs.get("write_timeout"),
kwargs.get("pool_timeout"),
)
return HTTPStatus.OK, b'{"ok": "True", "result": {}}'
custom_request = CustomRequest()
data = {"string": "string", "int": 1, "float": 1.0}
if media:
data["media"] = input_media_photo
request_data = RequestData(
parameters=[RequestParameter.from_input(key, value) for key, value in data.items()],
)
# First make sure that custom timeouts are always respected
await custom_request.post(
"url", request_data, read_timeout=1, connect_timeout=2, write_timeout=3, pool_timeout=4
)
assert self.test_flag == (1, 2, 3, 4)
# Now also ensure that the default timeout for media requests is 20 seconds
await custom_request.post("url", request_data)
assert self.test_flag == (
DEFAULT_NONE,
DEFAULT_NONE,
20 if media else DEFAULT_NONE,
DEFAULT_NONE,
)
print("warnings")
for entry in recwarn:
print(entry.message)
if media:
assert len(recwarn) == 1
assert "will default to `BaseRequest.DEFAULT_NONE` instead of 20" in str(
recwarn[0].message
)
assert recwarn[0].category is PTBDeprecationWarning
assert recwarn[0].filename == __file__
else:
assert len(recwarn) == 0
@pytest.mark.skipif(not TEST_WITH_OPT_DEPS, reason="No need to run this twice")
class TestHTTPXRequestWithoutRequest:
@@ -469,9 +398,7 @@ class TestHTTPXRequestWithoutRequest:
def _reset(self):
self.test_flag = None
# We parametrize this to make sure that the legacy `proxy_url` argument is still supported
@pytest.mark.parametrize("proxy_argument", ["proxy", "proxy_url"])
def test_init(self, monkeypatch, proxy_argument):
def test_init(self, monkeypatch):
@dataclass
class Client:
timeout: object
@@ -492,32 +419,20 @@ class TestHTTPXRequestWithoutRequest:
assert request._client.http1 is True
assert not request._client.http2
kwargs = {
"connection_pool_size": 42,
proxy_argument: "proxy",
"connect_timeout": 43,
"read_timeout": 44,
"write_timeout": 45,
"pool_timeout": 46,
}
request = HTTPXRequest(**kwargs)
request = HTTPXRequest(
connection_pool_size=42,
proxy="proxy",
connect_timeout=43,
read_timeout=44,
write_timeout=45,
pool_timeout=46,
)
assert request._client.proxy == "proxy"
assert request._client.limits == httpx.Limits(
max_connections=42, max_keepalive_connections=42
)
assert request._client.timeout == httpx.Timeout(connect=43, read=44, write=45, pool=46)
def test_proxy_mutually_exclusive(self):
with pytest.raises(ValueError, match="mutually exclusive"):
HTTPXRequest(proxy="proxy", proxy_url="proxy_url")
def test_proxy_url_deprecation_warning(self, recwarn):
HTTPXRequest(proxy_url="http://127.0.0.1:3128")
assert len(recwarn) == 1
assert recwarn[0].category is PTBDeprecationWarning
assert "`proxy_url` is deprecated" in str(recwarn[0].message)
assert recwarn[0].filename == __file__, "incorrect stacklevel"
async def test_multiple_inits_and_shutdowns(self, monkeypatch):
self.test_flag = defaultdict(int)
@@ -728,7 +643,7 @@ class TestHTTPXRequestWithoutRequest:
@pytest.mark.parametrize("media", [True, False])
async def test_do_request_write_timeout(
self, monkeypatch, media, httpx_request, input_media_photo, recwarn # noqa: F811
self, monkeypatch, media, httpx_request, input_media_photo # noqa: F811
):
async def request(_, **kwargs):
self.test_flag = kwargs.get("timeout")
@@ -753,10 +668,6 @@ class TestHTTPXRequestWithoutRequest:
await httpx_request.post("url", request_data)
assert self.test_flag == httpx.Timeout(read=5, connect=5, write=20 if media else 5, pool=1)
# Just for double-checking, since warnings are issued for implementations of BaseRequest
# other than HTTPXRequest
assert len(recwarn) == 0
@pytest.mark.parametrize("init", [True, False])
async def test_setting_media_write_timeout(
self, monkeypatch, init, input_media_photo, recwarn # noqa: F811
+9 -35
View File
@@ -95,7 +95,7 @@ from telegram.error import BadRequest, EndPointNotFound, InvalidToken
from telegram.ext import ExtBot, InvalidCallbackData
from telegram.helpers import escape_markdown
from telegram.request import BaseRequest, HTTPXRequest, RequestData
from telegram.warnings import PTBDeprecationWarning, PTBUserWarning
from telegram.warnings import PTBUserWarning
from tests.auxil.bot_method_checks import check_defaults_handling
from tests.auxil.ci_bots import FALLBACKS
from tests.auxil.envvars import GITHUB_ACTIONS
@@ -681,7 +681,7 @@ class TestBotWithoutRequest:
@pytest.mark.parametrize(
"default_bot",
[{"parse_mode": "Markdown", "disable_web_page_preview": True}],
[{"parse_mode": "Markdown", "link_preview_options": LinkPreviewOptions(is_disabled=True)}],
indirect=True,
)
@pytest.mark.parametrize(
@@ -976,7 +976,7 @@ class TestBotWithoutRequest:
@pytest.mark.parametrize(
"default_bot",
[{"parse_mode": "Markdown", "disable_web_page_preview": True}],
[{"parse_mode": "Markdown", "link_preview_options": LinkPreviewOptions(is_disabled=True)}],
indirect=True,
)
async def test_answer_inline_query_default_parse_mode(self, monkeypatch, default_bot):
@@ -2257,6 +2257,10 @@ class TestBotWithoutRequest:
)
return HTTPStatus.OK, b'{"ok": "True", "result": {}}'
@property
def read_timeout(self):
return 1
custom_request = CustomRequest()
offline_bot = Bot(offline_bot.token, request=custom_request)
@@ -2271,7 +2275,7 @@ class TestBotWithoutRequest:
assert test_flag == (
DEFAULT_NONE,
DEFAULT_NONE,
20,
DEFAULT_NONE,
DEFAULT_NONE,
)
@@ -3221,36 +3225,6 @@ class TestBotWithRequest:
if updates:
assert isinstance(updates[0], Update)
@pytest.mark.parametrize("bot_class", [Bot, ExtBot])
async def test_get_updates_read_timeout_deprecation_warning(
self, bot, recwarn, monkeypatch, bot_class
):
# Using the normal HTTPXRequest should not issue any warnings
await bot.get_updates()
assert len(recwarn) == 0
# Now let's test deprecation warning when using get_updates for other BaseRequest
# subclasses (we just monkeypatch the existing HTTPXRequest for this)
read_timeout = None
async def catch_timeouts(*args, **kwargs):
nonlocal read_timeout
read_timeout = kwargs.get("read_timeout")
return HTTPStatus.OK, b'{"ok": "True", "result": {}}'
monkeypatch.setattr(HTTPXRequest, "read_timeout", BaseRequest.read_timeout)
monkeypatch.setattr(HTTPXRequest, "do_request", catch_timeouts)
bot = bot_class(get_updates_request=HTTPXRequest(), token=bot.token)
await bot.get_updates()
assert len(recwarn) == 1
assert "does not override the property `read_timeout`" in str(recwarn[0].message)
assert recwarn[0].category is PTBDeprecationWarning
assert recwarn[0].filename == __file__, "wrong stacklevel"
assert read_timeout == 2
@pytest.mark.parametrize(
("read_timeout", "timeout", "expected"),
[
@@ -4211,7 +4185,7 @@ class TestBotWithRequest:
]
)
await poll_message.stop_poll(reply_markup=reply_markup)
helper_message = await poll_message.reply_text("temp", quote=True)
helper_message = await poll_message.reply_text("temp", do_quote=True)
message = helper_message.reply_to_message
inline_keyboard = message.reply_markup.inline_keyboard
+29 -45
View File
@@ -17,7 +17,6 @@
# 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 contextlib
import datetime as dtm
from copy import copy
@@ -448,18 +447,7 @@ class TestMessageWithoutRequest(MessageTestBase):
async def check_quote_parsing(
message: Message, method, bot_method_name: str, args, monkeypatch
):
"""Used in testing reply_* below. Makes sure that quote and do_quote are handled
correctly
"""
with contextlib.suppress(TypeError):
# for newer methods that don't have the deprecated argument
with pytest.raises(ValueError, match="`quote` and `do_quote` are mutually exclusive"):
await method(*args, quote=True, do_quote=True)
# for newer methods that don't have the deprecated argument
with pytest.warns(PTBDeprecationWarning, match="`quote` parameter is deprecated"):
await method(*args, quote=True)
"""Used in testing reply_* below. Makes sure that do_quote is handled correctly"""
with pytest.raises(
ValueError,
match="`reply_to_message_id` and `reply_parameters` are mutually exclusive.",
@@ -471,17 +459,13 @@ class TestMessageWithoutRequest(MessageTestBase):
monkeypatch.setattr(message.get_bot(), bot_method_name, make_assertion)
for param in ("quote", "do_quote"):
with contextlib.suppress(TypeError):
# for newer methods that don't have the deprecated argument
chat_id, reply_parameters = await method(*args, **{param: True})
if chat_id != message.chat.id:
pytest.fail(f"chat_id is {chat_id} but should be {message.chat.id}")
if reply_parameters is None or reply_parameters.message_id != message.message_id:
pytest.fail(
f"reply_parameters is {reply_parameters} "
"but should be {message.message_id}"
)
for value in (True, False):
chat_id, reply_parameters = await method(*args, do_quote=value)
if chat_id != message.chat.id:
pytest.fail(f"chat_id is {chat_id} but should be {message.chat.id}")
expected = ReplyParameters(message.message_id) if value else None
if reply_parameters != expected:
pytest.fail(f"reply_parameters is {reply_parameters} but should be {expected}")
input_chat_id = object()
input_reply_parameters = ReplyParameters(message_id=1, chat_id=42)
@@ -1451,7 +1435,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_text,
Bot.send_message,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1493,7 +1477,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_markdown,
Bot.send_message,
["chat_id", "parse_mode", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1542,7 +1526,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_markdown_v2,
Bot.send_message,
["chat_id", "parse_mode", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1594,7 +1578,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_html,
Bot.send_message,
["chat_id", "parse_mode", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1631,7 +1615,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_media_group,
Bot.send_media_group,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1673,7 +1657,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_photo,
Bot.send_photo,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1707,7 +1691,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_audio,
Bot.send_audio,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1741,7 +1725,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_document,
Bot.send_document,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1775,7 +1759,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_animation,
Bot.send_animation,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1809,7 +1793,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_sticker,
Bot.send_sticker,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1843,7 +1827,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_video,
Bot.send_video,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1877,7 +1861,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_video_note,
Bot.send_video_note,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1911,7 +1895,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_voice,
Bot.send_voice,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1945,7 +1929,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_location,
Bot.send_location,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -1979,7 +1963,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_venue,
Bot.send_venue,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -2013,7 +1997,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_contact,
Bot.send_contact,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -2048,7 +2032,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_poll,
Bot.send_poll,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -2082,7 +2066,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_dice,
Bot.send_dice,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -2154,7 +2138,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_game,
Bot.send_game,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -2197,7 +2181,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_invoice,
Bot.send_invoice,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(
@@ -2326,7 +2310,7 @@ class TestMessageWithoutRequest(MessageTestBase):
Message.reply_copy,
Bot.copy_message,
["chat_id", "reply_to_message_id", "business_connection_id"],
["quote", "do_quote", "reply_to_message_id"],
["do_quote", "reply_to_message_id"],
annotation_overrides={"message_thread_id": (ODVInput[int], DEFAULT_NONE)},
)
assert await check_shortcut_call(message.copy, message.get_bot(), "copy_message")
-2
View File
@@ -190,8 +190,6 @@ def check_param_type(
or "Unix time" in tg_parameter.param_description
):
log("Checking that `%s` is a datetime!\n", ptb_param.name)
if ptb_param.name in PTCE.DATETIME_EXCEPTIONS:
return True, mapped_type
# If it's a class, we only accept datetime as the parameter
mapped_type = dtm.datetime if is_class else mapped_type | dtm.datetime
-7
View File
@@ -73,8 +73,6 @@ class ParamTypeCheckingExceptions:
("keyboard", True): "KeyboardButton", # + sequence[sequence[str]]
("reaction", False): "ReactionType", # + str
("options", False): "InputPollOption", # + str
# TODO: Deprecated and will be corrected (and removed) in next bot api release
("file_hashes", True): "list[str]",
}
# Special cases for other parameters that accept more types than the official API, and are
@@ -117,11 +115,6 @@ class ParamTypeCheckingExceptions:
# These classes' params are all ODVInput, so we ignore them in the defaults type checking.
IGNORED_DEFAULTS_CLASSES = {"LinkPreviewOptions"}
# TODO: Remove this in v22 when it becomes a datetime (also remove from arg_type_checker.py)
DATETIME_EXCEPTIONS = {
"file_date",
}
# Arguments *added* to the official API
PTB_EXTRA_PARAMS = {
+5
View File
@@ -138,6 +138,11 @@ def test_check_object(tg_class: TelegramClass) -> None:
- No unexpected parameters
"""
obj = getattr(telegram, tg_class.class_name)
if tg_class.class_name not in (
"PassportElementErrorFiles",
"PassportElementErrorTranslationFiles",
):
return
# Check arguments based on source. Makes sure to only check __init__'s signature & nothing else
sig = inspect.signature(obj.__init__, follow_wrapped=True)