Improve Test Instability Caused by `Message` Fixtures by Bibo-Joshi · Pull Request #4507 · python-telegram-bot/python-telegram-bot
self = <tests.test_bot.TestBotWithRequest object at 0x108edc430>
default_bot = PytestExtBot[token=691423554:AAF8WkjCZbnHqP_i6GhTYirFElZrGaYOhX0]
chat_id = '675666224'
one_time_message = Message(channel_chat_created=False, chat=Chat(first_name='PTB', id=675666224, last_name='Test user', type=<ChatType.PR...me='ptb_travis_pypy_27_bot'), group_chat_created=False, message_id=3235779, supergroup_chat_created=False, text='Text')
@pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True)
async def test_edit_message_text_default_parse_mode(
self, default_bot, chat_id, one_time_message
):
test_string = "Italic Bold Code"
test_markdown_string = "_Italic_ *Bold* `Code`"
message = await default_bot.edit_message_text(
text=test_markdown_string,
chat_id=one_time_message.chat_id,
message_id=one_time_message.message_id,
disable_web_page_preview=True,
)
assert message.text_markdown == test_markdown_string
assert message.text == test_string
message = await default_bot.edit_message_text(
text=test_markdown_string,
chat_id=message.chat_id,
message_id=message.message_id,
parse_mode=None,
disable_web_page_preview=True,
)
assert message.text == test_markdown_string
assert message.text_markdown == escape_markdown(test_markdown_string)
> message = await default_bot.edit_message_text(
text=test_markdown_string,
chat_id=message.chat_id,
message_id=message.message_id,
parse_mode="HTML",
disable_web_page_preview=True,
)
tests/test_bot.py:2895:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
telegram/ext/_extbot.py:1664: in edit_message_text
return await super().edit_message_text(
telegram/_bot.py:4047: in edit_message_text
return await self._send_message(
telegram/ext/_extbot.py:610: in _send_message
result = await super()._send_message(
telegram/_bot.py:745: in _send_message
result = await self._post(
telegram/_bot.py:623: in _post
return await self._do_post(
telegram/ext/_extbot.py:355: in _do_post
return await super()._do_post(
telegram/_bot.py:652: in _do_post
result = await request.post(
telegram/request/_baserequest.py:201: in post
result = await self._request_wrapper(
tests/auxil/networking.py:48: in _request_wrapper
return await super()._request_wrapper(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <tests.auxil.networking.NonchalantHttpxRequest object at 0x109aa4400>
url = 'https://api.telegram.org/bot691423554:AAF8WkjCZbnHqP_i6GhTYirFElZrGaYOhX0/editMessageText'
method = 'POST'
request_data = <telegram.request._requestdata.RequestData object at 0x109d60d00>
read_timeout = None, write_timeout = None, connect_timeout = None
pool_timeout = None
async def _request_wrapper(
self,
url: str,
method: str,
request_data: Optional[RequestData] = None,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
) -> bytes:
"""Wraps the real implementation request method.
Performs the following tasks:
* Handle the various HTTP response codes.
* Parse the Telegram server response.
Args:
url (:obj:`str`): The URL to request.
method (:obj:`str`): HTTP method (i.e. 'POST', 'GET', etc.).
request_data (:class:`telegram.request.RequestData`, optional): An object containing
information about parameters and files to upload for the request.
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 instead
of the time specified during creating of this object. Defaults to
:attr:`DEFAULT_NONE`.
write_timeout (:obj:`float` | :obj:`None`, optional): If passed, specifies the maximum
amount of time (in seconds) to wait for a write operation to complete (in terms of
a network socket; i.e. POSTing a request or uploading a file) instead of the time
specified during creating of this object. Defaults to :attr:`DEFAULT_NONE`.
connect_timeout (:obj:`float` | :obj:`None`, optional): If passed, specifies the
maximum amount of time (in seconds) to wait for a connection attempt to a server
to succeed instead of the time specified during creating of this object. Defaults
to :attr:`DEFAULT_NONE`.
pool_timeout (:obj:`float` | :obj:`None`, optional): If passed, specifies the maximum
amount of time (in seconds) to wait for a connection to become available instead
of the time specified during creating of this object. Defaults to
:attr:`DEFAULT_NONE`.
Returns:
bytes: The payload part of the HTTP server response.
Raises:
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,
method=method,
request_data=request_data,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
)
except TelegramError:
raise
except Exception as exc:
raise NetworkError(f"Unknown error in HTTP implementation: {exc!r}") from exc
if HTTPStatus.OK <= code <= 299:
# 200-299 range are HTTP success statuses
return payload
response_data = self.parse_json_payload(payload)
description = response_data.get("description")
message = description if description else "Unknown HTTPError"
# In some special cases, we can raise more informative exceptions:
# see https://core.telegram.org/bots/api#responseparameters and
# https://core.telegram.org/bots/api#making-requests
# TGs response also has the fields 'ok' and 'error_code'.
# However, we rather rely on the HTTP status code for now.
parameters = response_data.get("parameters")
if parameters:
migrate_to_chat_id = parameters.get("migrate_to_chat_id")
if migrate_to_chat_id:
raise ChatMigrated(migrate_to_chat_id)
retry_after = parameters.get("retry_after")
if retry_after:
raise RetryAfter(retry_after)
message += f"\nThe server response contained unknown parameters: {parameters}"
if code == HTTPStatus.FORBIDDEN: # 403
raise Forbidden(message)
if code in (HTTPStatus.NOT_FOUND, HTTPStatus.UNAUTHORIZED): # 404 and 401
# TG returns 404 Not found for
# 1) malformed tokens
# 2) correct tokens but non-existing method, e.g. api.tg.org/botTOKEN/unkonwnMethod
# 2) is relevant only for Bot.do_api_request, where we have special handing for it.
# TG returns 401 Unauthorized for correctly formatted tokens that are not valid
raise InvalidToken(message)
if code == HTTPStatus.BAD_REQUEST: # 400
> raise BadRequest(message)
E telegram.error.BadRequest: Message is not modified: specified new message content and reply markup are exactly the same as a current content and reply markup of the message
telegram/request/_baserequest.py:382: BadRequest