Fix Handling of Parameters do_quote and allow_sending_without_reply in Message.reply_* (#4818)

This commit is contained in:
Bibo-Joshi
2025-06-19 20:56:43 +02:00
committed by GitHub
parent b15507fc22
commit d46ddf7318
5 changed files with 132 additions and 72 deletions
@@ -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"]
+1 -1
View File
@@ -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
View File
@@ -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,
+8 -11
View File
@@ -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
View File
@@ -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(