mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2026-06-19 07:35:19 +00:00
Fix Handling of Parameters do_quote and allow_sending_without_reply in Message.reply_* (#4818)
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
bugfixes = """
|
||||
Correctly parse parameter ``allow_sending_without_reply`` in ``Message.reply_*`` when used in combination with ``do_quote=True``.
|
||||
|
||||
.. hint::
|
||||
|
||||
Using ``dict`` valued input for ``do_quote`` along with passing ``allow_sending_without_reply`` is not supported and will raise an error.
|
||||
"""
|
||||
|
||||
[[pull_requests]]
|
||||
uid = "4818"
|
||||
author_uid = "Bibo-Joshi"
|
||||
closes_threads = ["4807"]
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
.. |reply_quote| replace:: If set to :obj:`True`, the reply is sent as an actual reply to this message. If ``reply_to_message_id`` is passed, this parameter will be ignored. Default: :obj:`True` in group chats and :obj:`False` in private chats.
|
||||
|
||||
.. |do_quote| replace:: If set to :obj:`True`, the replied message is quoted. For a dict, it must be the output of :meth:`~telegram.Message.build_reply_arguments` to specify exact ``reply_parameters``. If ``reply_to_message_id`` or ``reply_parameters`` are passed, this parameter will be ignored. Default: :obj:`True` in group chats and :obj:`False` in private chats.
|
||||
.. |do_quote| replace:: If set to :obj:`True`, the replied message is quoted. For a dict, it must be the output of :meth:`~telegram.Message.build_reply_arguments` to specify exact ``reply_parameters``. If ``reply_to_message_id`` or ``reply_parameters`` are passed, this parameter will be ignored. When passing dict-valued input, ``do_quote`` is mutually exclusive with ``allow_sending_without_reply``. Default: :obj:`True` in group chats and :obj:`False` in private chats.
|
||||
|
||||
.. |non_optional_story_argument| replace:: As of this version, this argument is now required. In accordance with our `stability policy <https://docs.python-telegram-bot.org/en/stable/stability_policy.html>`__, the signature will be kept as optional for now, though they are mandatory and an error will be raised if you don't pass it.
|
||||
|
||||
|
||||
+50
-49
@@ -1541,11 +1541,17 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
return self._effective_attachment # type: ignore[return-value]
|
||||
|
||||
def _do_quote(self, do_quote: Optional[bool]) -> Optional[ReplyParameters]:
|
||||
def _do_quote(
|
||||
self, do_quote: Optional[bool], allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE
|
||||
) -> Optional[ReplyParameters]:
|
||||
"""Modify kwargs for replying with or without quoting."""
|
||||
# `Defaults` handling for allow_sending_without_reply is not necessary, as
|
||||
# `ReplyParameters` have special defaults handling in (ExtBot)._insert_defaults
|
||||
if do_quote is not None:
|
||||
if do_quote:
|
||||
return ReplyParameters(self.message_id)
|
||||
return ReplyParameters(
|
||||
self.message_id, allow_sending_without_reply=allow_sending_without_reply
|
||||
)
|
||||
|
||||
else:
|
||||
# Unfortunately we need some ExtBot logic here because it's hard to move shortcut
|
||||
@@ -1555,7 +1561,9 @@ class Message(MaybeInaccessibleMessage):
|
||||
else:
|
||||
default_quote = None
|
||||
if (default_quote is None and self.chat.type != Chat.PRIVATE) or default_quote:
|
||||
return ReplyParameters(self.message_id)
|
||||
return ReplyParameters(
|
||||
self.message_id, allow_sending_without_reply=allow_sending_without_reply
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
@@ -1729,7 +1737,13 @@ class Message(MaybeInaccessibleMessage):
|
||||
do_quote: Optional[Union[bool, _ReplyKwargs]],
|
||||
reply_to_message_id: Optional[int],
|
||||
reply_parameters: Optional["ReplyParameters"],
|
||||
allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE,
|
||||
) -> tuple[Union[str, int], ReplyParameters]:
|
||||
if allow_sending_without_reply is not DEFAULT_NONE and reply_parameters is not None:
|
||||
raise ValueError(
|
||||
"`allow_sending_without_reply` and `reply_parameters` 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."
|
||||
@@ -1741,12 +1755,21 @@ class Message(MaybeInaccessibleMessage):
|
||||
if reply_parameters is not None:
|
||||
effective_reply_parameters = reply_parameters
|
||||
elif reply_to_message_id is not None:
|
||||
effective_reply_parameters = ReplyParameters(message_id=reply_to_message_id)
|
||||
effective_reply_parameters = ReplyParameters(
|
||||
message_id=reply_to_message_id,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
)
|
||||
elif isinstance(do_quote, dict):
|
||||
if allow_sending_without_reply is not DEFAULT_NONE:
|
||||
raise ValueError(
|
||||
"`allow_sending_without_reply` and `dict`-value input for `do_quote` are "
|
||||
"mutually exclusive."
|
||||
)
|
||||
|
||||
effective_reply_parameters = do_quote["reply_parameters"]
|
||||
chat_id = do_quote["chat_id"]
|
||||
else:
|
||||
effective_reply_parameters = self._do_quote(do_quote)
|
||||
effective_reply_parameters = self._do_quote(do_quote, allow_sending_without_reply)
|
||||
|
||||
return chat_id, effective_reply_parameters
|
||||
|
||||
@@ -1823,7 +1846,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_message(
|
||||
@@ -1835,7 +1858,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
disable_notification=disable_notification,
|
||||
reply_parameters=effective_reply_parameters,
|
||||
reply_markup=reply_markup,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
entities=entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
@@ -1907,7 +1929,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, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_message(
|
||||
@@ -1919,7 +1941,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
disable_notification=disable_notification,
|
||||
reply_parameters=effective_reply_parameters,
|
||||
reply_markup=reply_markup,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
entities=entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
@@ -1987,7 +2008,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, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_message(
|
||||
@@ -1999,7 +2020,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
disable_notification=disable_notification,
|
||||
reply_parameters=effective_reply_parameters,
|
||||
reply_markup=reply_markup,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
entities=entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
@@ -2067,7 +2087,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, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_message(
|
||||
@@ -2079,7 +2099,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
disable_notification=disable_notification,
|
||||
reply_parameters=effective_reply_parameters,
|
||||
reply_markup=reply_markup,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
entities=entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
@@ -2148,7 +2167,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
:class:`telegram.error.TelegramError`
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_media_group(
|
||||
@@ -2161,7 +2180,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
caption=caption,
|
||||
@@ -2227,7 +2245,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_photo(
|
||||
@@ -2238,7 +2256,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
reply_parameters=effective_reply_parameters,
|
||||
reply_markup=reply_markup,
|
||||
parse_mode=parse_mode,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
@@ -2312,7 +2329,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_audio(
|
||||
@@ -2326,7 +2343,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
reply_parameters=effective_reply_parameters,
|
||||
reply_markup=reply_markup,
|
||||
parse_mode=parse_mode,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
@@ -2397,7 +2413,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_document(
|
||||
@@ -2415,7 +2431,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
parse_mode=parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
disable_content_type_detection=disable_content_type_detection,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
caption_entities=caption_entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
@@ -2484,7 +2499,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_animation(
|
||||
@@ -2503,7 +2518,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
@@ -2566,7 +2580,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_sticker(
|
||||
@@ -2580,7 +2594,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
emoji=emoji,
|
||||
@@ -2651,7 +2664,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_video(
|
||||
@@ -2671,7 +2684,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
parse_mode=parse_mode,
|
||||
supports_streaming=supports_streaming,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
@@ -2739,7 +2751,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_video_note(
|
||||
@@ -2755,7 +2767,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
@@ -2819,7 +2830,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_voice(
|
||||
@@ -2836,7 +2847,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
pool_timeout=pool_timeout,
|
||||
parse_mode=parse_mode,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
caption_entities=caption_entities,
|
||||
filename=filename,
|
||||
protect_content=protect_content,
|
||||
@@ -2901,7 +2911,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_location(
|
||||
@@ -2921,7 +2931,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
horizontal_accuracy=horizontal_accuracy,
|
||||
heading=heading,
|
||||
proximity_alert_radius=proximity_alert_radius,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
@@ -2986,7 +2995,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_venue(
|
||||
@@ -3008,7 +3017,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
api_kwargs=api_kwargs,
|
||||
google_place_id=google_place_id,
|
||||
google_place_type=google_place_type,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
@@ -3069,7 +3077,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_contact(
|
||||
@@ -3087,7 +3095,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
contact=contact,
|
||||
vcard=vcard,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
@@ -3157,7 +3164,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_poll(
|
||||
@@ -3181,7 +3188,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
open_period=open_period,
|
||||
close_date=close_date,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
explanation_entities=explanation_entities,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
@@ -3241,7 +3247,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_dice(
|
||||
@@ -3255,7 +3261,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
pool_timeout=pool_timeout,
|
||||
emoji=emoji,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
@@ -3358,7 +3363,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_game(
|
||||
@@ -3372,7 +3377,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
protect_content=protect_content,
|
||||
message_thread_id=message_thread_id,
|
||||
business_connection_id=self.business_connection_id,
|
||||
@@ -3460,7 +3464,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().send_invoice(
|
||||
@@ -3492,7 +3496,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
connect_timeout=connect_timeout,
|
||||
pool_timeout=pool_timeout,
|
||||
api_kwargs=api_kwargs,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
max_tip_amount=max_tip_amount,
|
||||
suggested_tip_amounts=suggested_tip_amounts,
|
||||
protect_content=protect_content,
|
||||
@@ -3670,7 +3673,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
message_thread_id = self._parse_message_thread_id(chat_id, message_thread_id)
|
||||
return await self.get_bot().copy_message(
|
||||
@@ -3683,7 +3686,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
caption_entities=caption_entities,
|
||||
disable_notification=disable_notification,
|
||||
reply_parameters=effective_reply_parameters,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
reply_markup=reply_markup,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
@@ -3742,7 +3744,7 @@ class Message(MaybeInaccessibleMessage):
|
||||
|
||||
"""
|
||||
chat_id, effective_reply_parameters = await self._parse_quote_arguments(
|
||||
do_quote, reply_to_message_id, reply_parameters
|
||||
do_quote, reply_to_message_id, reply_parameters, allow_sending_without_reply
|
||||
)
|
||||
return await self.get_bot().send_paid_media(
|
||||
chat_id=chat_id,
|
||||
@@ -3755,7 +3757,6 @@ class Message(MaybeInaccessibleMessage):
|
||||
caption_entities=caption_entities,
|
||||
disable_notification=disable_notification,
|
||||
reply_parameters=effective_reply_parameters,
|
||||
allow_sending_without_reply=allow_sending_without_reply,
|
||||
reply_markup=reply_markup,
|
||||
read_timeout=read_timeout,
|
||||
write_timeout=write_timeout,
|
||||
|
||||
@@ -70,7 +70,7 @@ def check_shortcut_signature(
|
||||
bot_method: The bot method, e.g. :meth:`telegram.Bot.send_message`
|
||||
shortcut_kwargs: The kwargs passed by the shortcut directly, e.g. ``chat_id``
|
||||
additional_kwargs: Additional kwargs of the shortcut that the bot method doesn't have, e.g.
|
||||
``quote``.
|
||||
``do_quote``.
|
||||
annotation_overrides: A dictionary of exceptions for the annotation comparison. The key is
|
||||
the name of the argument, the value is a tuple of the expected annotation and
|
||||
the default value. E.g. ``{'parse_mode': (str, 'None')}``.
|
||||
@@ -228,21 +228,18 @@ async def check_shortcut_call(
|
||||
|
||||
shortcut_signature = inspect.signature(shortcut_method)
|
||||
# auto_pagination: Special casing for InlineQuery.answer
|
||||
# quote: Don't test deprecated "quote" parameter of Message.reply_*
|
||||
kwargs = {
|
||||
name: name
|
||||
for name in shortcut_signature.parameters
|
||||
if name not in ["auto_pagination", "quote"]
|
||||
name: name for name in shortcut_signature.parameters if name not in ["auto_pagination"]
|
||||
}
|
||||
if "reply_parameters" in kwargs:
|
||||
kwargs["reply_parameters"] = ReplyParameters(message_id=1)
|
||||
|
||||
# We tested this for a long time, but Bot API 7.0 deprecated it in favor of
|
||||
# reply_parameters. In the transition phase, both exist in a mutually exclusive
|
||||
# way. Testing both cases would require a lot of additional code, so we just
|
||||
# ignore this parameter here until it is removed.
|
||||
kwargs.pop("reply_to_message_id", None)
|
||||
expected_args.discard("reply_to_message_id")
|
||||
# reply_parameters. Testing both cases would require a lot of additional code, so we just
|
||||
# ignore these parameters here.
|
||||
for arg in ["reply_to_message_id", "allow_sending_without_reply"]:
|
||||
kwargs.pop(arg, None)
|
||||
expected_args.discard(arg)
|
||||
|
||||
async def make_assertion(**kw):
|
||||
# name == value makes sure that
|
||||
@@ -254,7 +251,7 @@ async def check_shortcut_call(
|
||||
if name in ignored_args
|
||||
or (value == name or (name == "reply_parameters" and value.message_id == 1))
|
||||
}
|
||||
if not received_kwargs == expected_args:
|
||||
if received_kwargs != expected_args:
|
||||
raise Exception(
|
||||
f"{orig_bot_method.__name__} did not receive correct value for the parameters "
|
||||
f"{expected_args - received_kwargs}"
|
||||
|
||||
+61
-11
@@ -495,9 +495,8 @@ class MessageTestBase:
|
||||
|
||||
|
||||
class TestMessageWithoutRequest(MessageTestBase):
|
||||
@staticmethod
|
||||
async def check_quote_parsing(
|
||||
message: Message, method, bot_method_name: str, args, monkeypatch
|
||||
self, message: Message, method, bot_method_name: str, args, monkeypatch
|
||||
):
|
||||
"""Used in testing reply_* below. Makes sure that do_quote is handled correctly"""
|
||||
with pytest.raises(
|
||||
@@ -506,30 +505,74 @@ class TestMessageWithoutRequest(MessageTestBase):
|
||||
):
|
||||
await method(*args, reply_to_message_id=42, reply_parameters=42)
|
||||
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match="`allow_sending_without_reply` and `reply_parameters` are mutually exclusive.",
|
||||
):
|
||||
await method(*args, allow_sending_without_reply=True, reply_parameters=42)
|
||||
|
||||
async def make_assertion(*args, **kwargs):
|
||||
return kwargs.get("chat_id"), kwargs.get("reply_parameters")
|
||||
|
||||
monkeypatch.setattr(message.get_bot(), bot_method_name, make_assertion)
|
||||
|
||||
for aswr in (DEFAULT_NONE, True):
|
||||
await self._check_quote_parsing(
|
||||
message=message,
|
||||
method=method,
|
||||
bot_method_name=bot_method_name,
|
||||
args=args,
|
||||
monkeypatch=monkeypatch,
|
||||
aswr=aswr,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
async def _check_quote_parsing(
|
||||
message: Message, method, bot_method_name: str, args, monkeypatch, aswr
|
||||
):
|
||||
# test that boolean input for do_quote is parse correctly
|
||||
for value in (True, False):
|
||||
chat_id, reply_parameters = await method(*args, do_quote=value)
|
||||
chat_id, reply_parameters = await method(
|
||||
*args, do_quote=value, allow_sending_without_reply=aswr
|
||||
)
|
||||
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
|
||||
expected = (
|
||||
ReplyParameters(message.message_id, allow_sending_without_reply=aswr)
|
||||
if value
|
||||
else None
|
||||
)
|
||||
if reply_parameters != expected:
|
||||
pytest.fail(f"reply_parameters is {reply_parameters} but should be {expected}")
|
||||
|
||||
# test that dict input for do_quote is parsed correctly
|
||||
input_chat_id = object()
|
||||
input_reply_parameters = ReplyParameters(message_id=1, chat_id=42)
|
||||
chat_id, reply_parameters = await method(
|
||||
*args, do_quote={"chat_id": input_chat_id, "reply_parameters": input_reply_parameters}
|
||||
coro = method(
|
||||
*args,
|
||||
do_quote={"chat_id": input_chat_id, "reply_parameters": input_reply_parameters},
|
||||
allow_sending_without_reply=aswr,
|
||||
)
|
||||
if chat_id is not input_chat_id:
|
||||
pytest.fail(f"chat_id is {chat_id} but should be {chat_id}")
|
||||
if reply_parameters is not input_reply_parameters:
|
||||
pytest.fail(f"reply_parameters is {reply_parameters} but should be {reply_parameters}")
|
||||
if aswr is True:
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match="`allow_sending_without_reply` and `dict`-value input",
|
||||
):
|
||||
await coro
|
||||
else:
|
||||
chat_id, reply_parameters = await coro
|
||||
if chat_id is not input_chat_id:
|
||||
pytest.fail(f"chat_id is {chat_id} but should be {input_chat_id}")
|
||||
if reply_parameters is not input_reply_parameters:
|
||||
pytest.fail(
|
||||
f"reply_parameters is {reply_parameters} "
|
||||
f"but should be {input_reply_parameters}"
|
||||
)
|
||||
|
||||
input_parameters_2 = ReplyParameters(message_id=2, chat_id=43)
|
||||
# test that do_quote input is overridden by reply_parameters
|
||||
input_parameters_2 = ReplyParameters(
|
||||
message_id=message.message_id + 1, chat_id=message.chat_id + 1
|
||||
)
|
||||
chat_id, reply_parameters = await method(
|
||||
*args,
|
||||
reply_parameters=input_parameters_2,
|
||||
@@ -543,16 +586,23 @@ class TestMessageWithoutRequest(MessageTestBase):
|
||||
f"reply_parameters is {reply_parameters} but should be {input_parameters_2}"
|
||||
)
|
||||
|
||||
# test that do_quote input is overridden by reply_to_message_id
|
||||
chat_id, reply_parameters = await method(
|
||||
*args,
|
||||
reply_to_message_id=42,
|
||||
# passing these here to make sure that `reply_to_message_id` has higher priority
|
||||
do_quote={"chat_id": input_chat_id, "reply_parameters": input_reply_parameters},
|
||||
allow_sending_without_reply=aswr,
|
||||
)
|
||||
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 != 42:
|
||||
pytest.fail(f"reply_parameters is {reply_parameters} but should be 42")
|
||||
if reply_parameters is None or reply_parameters.allow_sending_without_reply != aswr:
|
||||
pytest.fail(
|
||||
f"reply_parameters.allow_sending_without_reply is "
|
||||
f"{reply_parameters.allow_sending_without_reply} it should be {aswr}"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
async def check_thread_id_parsing(
|
||||
|
||||
Reference in New Issue
Block a user