8000 Improve Warning Categories & Stacklevels by Bibo-Joshi · Pull Request #3674 · python-telegram-bot/python-telegram-bot · GitHub
[go: up one dir, main page]

Skip to content

Improve Warning Categories & Stacklevels #3674

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 38 additions & 12 deletions telegram/_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def __init__(
warning_string = "request"

if warning_string:
warn(
self._warn(
f"You set the HTTP version for the {warning_string} HTTPXRequest instance to "
f"HTTP/2. The self hosted bot api instances only support HTTP/1.1. You should "
f"either run a HTTP proxy in front of it which supports HTTP/2 or use HTTP/1.1.",
Expand Down Expand Up @@ -338,6 +338,15 @@ def private_key(self) -> Optional[Any]:
"""
return self._private_key

@classmethod
def _warn(
cls, message: str, category: Type[Warning] = PTBUserWarning, stacklevel: int = 0
) -> None:
"""Convenience method to issue a warning. This method is here mostly to make it easier
for ExtBot to add 1 level to all warning calls.
"""
warn(message=message, category=category, stacklevel=stacklevel + 1)

def __reduce__(self) -> NoReturn:
"""Customizes how :func:`copy.deepcopy` processes objects of this type. Bots can not
be pickled and this method will always raise an exception.
Expand Down Expand Up @@ -1157,7 +1166,10 @@ async def send_audio(

"""
thumbnail_or_thumb: FileInput = warn_about_thumb_return_thumbnail(
deprecated_arg=thumb, new_arg=thumbnail
deprecated_arg=thumb,
new_arg=thumbnail,
warn_callback=self._warn,
stacklevel=3,
)
data: JSONDict = {
"chat_id": chat_id,
Expand Down Expand Up @@ -1294,7 +1306,10 @@ async def send_document(

"""
thumbnail_or_thumb: FileInput = warn_about_thumb_return_thumbnail(
deprecated_arg=thumb, new_arg=thumbnail
deprecated_arg=thumb,
new_arg=thumbnail,
warn_callback=self._warn,
stacklevel=3,
)

data: JSONDict = {
Expand Down Expand Up @@ -1531,7 +1546,10 @@ async def send_video(

"""
thumbnail_or_thumb: FileInput = warn_about_thumb_return_thumbnail(
deprecated_arg=thumb, new_arg=thumbnail
deprecated_arg=thumb,
new_arg=thumbnail,
warn_callback=self._warn,
stacklevel=3,
)
data: JSONDict = {
"chat_id": chat_id,
Expand Down Expand Up @@ -1664,7 +1682,10 @@ async def send_video_note(

"""
thumbnail_or_thumb: FileInput = warn_about_thumb_return_thumbnail(
deprecated_arg=thumb, new_arg=thumbnail
deprecated_arg=thumb,
new_arg=thumbnail,
warn_callback=self._warn,
stacklevel=3,
)
data: JSONDict = {
"chat_id": chat_id,
Expand Down Expand Up @@ -1807,6 +1828,8 @@ async def send_animation(
thumbnail_or_thumb: FileInput = warn_about_thumb_return_thumbnail(
deprecated_arg=thumb,
new_arg=thumbnail,
warn_callback=self._warn,
stacklevel=3,
)
data: JSONDict = {
"chat_id": chat_id,
Expand Down Expand Up @@ -5614,11 +5637,12 @@ async def upload_sticker_file(
# only, which would have been confusing.

if png_sticker:
warn(
self._warn(
"Since Bot API 6.6, the parameter `png_sticker` for "
"`upload_sticker_file` is deprecated. Please use the new parameters "
"`sticker` and `sticker_format` instead.",
stacklevel=4,
stacklevel=3,
category=PTBDeprecationWarning,
)

data: JSONDict = {
Expand Down Expand Up @@ -5813,11 +5837,12 @@ async def create_new_sticker_set(
# only, which would have been confusing.

if any(pre_api_6_6_params.values()):
warn(
self._warn(
f"Since Bot API 6.6, the parameters {set(pre_api_6_6_params)} for "
"`create_new_sticker_set` are deprecated. Please use the new parameter "
"`stickers` and `sticker_format` instead.",
stacklevel=4,
stacklevel=3,
category=PTBDeprecationWarning,
)

data: JSONDict = {
Expand Down Expand Up @@ -5984,11 +6009,12 @@ async def add_sticker_to_set(
)

if any(pre_api_6_6_params.values()):
warn(
self._warn(
f"Since Bot API 6.6, the parameters {set(pre_api_6_6_params)} for "
"`add_sticker_to_set` are deprecated. Please use the new parameter `sticker` "
"instead.",
stacklevel=4,
stacklevel=3,
category=PTBDeprecationWarning,
)

data: JSONDict = {
Expand Down Expand Up @@ -6224,7 +6250,7 @@ async def set_sticker_set_thumb(
:class:`telegram.error.TelegramError`

"""
warn(
self._warn(
message=(
"Bot API 6.6 renamed the method 'setStickerSetThumb' to 'setStickerSetThumbnail', "
"hence method 'set_sticker_set_thumb' was renamed to 'set_sticker_set_thumbnail' "
Expand Down
2 changes: 1 addition & 1 deletion telegram/_files/_basethumbedmedium.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def __init__(
deprecated_arg_name="thumb",
new_arg_name="thumbnail",
bot_api_version="6.6",
stacklevel=4,
stacklevel=3,
)

@property
Expand Down
41 changes: 25 additions & 16 deletions telegram/_utils/warnings_transition.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@

.. versionadded:: 20.2
"""
import functools
from typing import Any
from typing import Any, Callable, Type

from telegram._utils.warnings import warn
from telegram.warnings import PTBDeprecationWarning
Expand All @@ -38,7 +37,8 @@ def warn_about_deprecated_arg_return_new_arg(
deprecated_arg_name: str,
new_arg_name: str,
bot_api_version: str,
stacklevel: int = 3,
stacklevel: int = 2,
warn_callback: Callable[[str, Type[Warning], int], None] = warn,
) -> Any:
"""A helper f F438 unction for the transition in API when argument is renamed.

Expand All @@ -58,11 +58,11 @@ def warn_about_deprecated_arg_return_new_arg(
)

if deprecated_arg:
warn(
warn_callback(
f"Bot API {bot_api_version} renamed the argument '{deprecated_arg_name}' to "
f"'{new_arg_name}'.",
PTBDeprecationWarning,
stacklevel=stacklevel,
stacklevel + 1,
)
return deprecated_arg

Expand All @@ -73,7 +73,7 @@ def warn_about_deprecated_attr_in_property(
deprecated_attr_name: str,
new_attr_name: str,
bot_api_version: str,
stacklevel: int = 3,
stacklevel: int = 2,
) -> None:
"""A helper function for the transition in API when attribute is renamed. Call from properties.

Expand All @@ -83,16 +83,25 @@ def warn_about_deprecated_attr_in_property(
f"Bot API {bot_api_version} renamed the attribute '{deprecated_attr_name}' to "
f"'{new_attr_name}'.",
PTBDeprecationWarning,
stacklevel=stacklevel,
stacklevel=stacklevel + 1,
)


warn_about_thumb_return_thumbnail = functools.partial(
warn_about_deprecated_arg_return_new_arg,
deprecated_arg_name="thumb",
new_arg_name="thumbnail",
bot_api_version="6.6",
)
"""A helper function to warn about using a deprecated 'thumb' argument and return it or the new
'thumbnail' argument, introduced in API 6.6.
"""
def warn_about_thumb_return_thumbnail(
deprecated_arg: Any,
new_arg: Any,
stacklevel: int = 2,
warn_callback: Callable[[str, Type[Warning], int], None] = warn,
) -> Any:
"""A helper function to warn about using a deprecated 'thumb' argument and return it or the
new 'thumbnail' argument, introduced in API 6.6.
"""
return warn_about_deprecated_arg_return_new_arg(
deprecated_arg=deprecated_arg,
new_arg=new_arg,
warn_callback=warn_callback,
deprecated_arg_name="thumb",
new_arg_name="thumbnail",
bot_api_version="6.6",
stacklevel=stacklevel + 1,
)
3 changes: 3 additions & 0 deletions telegram/ext/_conversationhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -840,11 +840,13 @@ async def handle_update( # type: ignore[override]
if application.job_queue is None:
warn(
"Ignoring `conversation_timeout` because the Application has no JobQueue.",
stacklevel=1,
)
elif not application.job_queue.scheduler.running:
warn(
"Ignoring `conversation_timeout` because the Applications JobQueue is "
"not running.",
stacklevel=1,
)
elif isinstance(new_state, asyncio.Task):
# Add the new timeout job
Expand Down Expand Up @@ -931,6 +933,7 @@ async def _trigger_timeout(self, context: CCT) -> None:
warn(
"ApplicationHandlerStop in TIMEOUT state of "
"ConversationHandler has no effect. Ignoring.",
stacklevel=2,
)

self._update_state(self.END, ctxt.conversation_key)
48 changes: 21 additions & 27 deletions telegram/ext/_extbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,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/].
"""This module contains an object that represents a Telegram Bot with convenience extensions."""
import warnings
from copy import copy
from datetime import datetime
from typing import (
Expand All @@ -31,6 +30,7 @@
Optional,
Sequence,
Tuple,
Type,
TypeVar,
Union,
cast,
Expand Down Expand Up @@ -87,11 +87,10 @@
from telegram._utils.defaultvalue import DEFAULT_NONE, DefaultValue
from telegram._utils.logging import get_logger
from telegram._utils.types import DVInput, FileInput, JSONDict, ODVInput, ReplyMarkup
from telegram._utils.warnings import warn
from telegram.ext._callbackdatacache import CallbackDataCache
from telegram.ext._utils.types import RLARGS
from telegram.request import BaseRequest
from telegram.warnings import PTBDeprecationWarning
from telegram.warnings import PTBUserWarning

if TYPE_CHECKING:
from telegram import (
Expand Down Expand Up @@ -235,6 +234,15 @@ def __init__(

self._callback_data_cache = CallbackDataCache(bot=self, maxsize=maxsize)

@classmethod
def _warn(
cls, message: str, category: Type[Warning] = PTBUserWarning, stacklevel: int = 0
) -> None:
"""We override this method to add one more level to the stacklevel, so that the warning
points to the user's code, not to the PTB code.
"""
super()._warn(message=message, category=category, stacklevel=stacklevel + 2)

@property
def callback_data_cache(self) -> Optional[CallbackDataCache]:
""":class:`telegram.ext.CallbackDataCache`: Optional. The cache for
Expand Down Expand Up @@ -3284,30 +3292,16 @@ async def set_sticker_set_thumb(
api_kwargs: JSONDict = None,
rate_limit_args: RLARGS = None,
) -> bool:
# Manually issue deprecation here to get the stacklevel right
# Suppress the warning issued by super().set_sticker_set_thumb just in case
# the user explicitly enables deprecation warnings
# Unfortunately this is not entirely reliable (see tests), but it's a best effort solution
warn(
message=(
"Bot API 6.6 renamed the method 'setStickerSetThumb' to 'setStickerSetThumbnail', "
"hence method 'set_sticker_set_thumb' was renamed to 'set_sticker_set_thumbnail' "
"in PTB."
),
category=PTBDeprecationWarning,
stacklevel=2,
)
with warnings.catch_warnings():
return await super().set_sticker_set_thumb(
name=name,
user_id=user_id,
thumb=thumb,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
)
return await super().set_sticker_set_thumb(
name=name,
user_id=user_id,
thumb=thumb,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args),
)

async def set_webhook(
self,
Expand Down
5 changes: 4 additions & 1 deletion telegram/ext/_picklepersistence.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ def persistent_id(self, obj: object) -> Optional[str]:
if obj is self._bot:
return _REPLACED_KNOWN_BOT
if isinstance(obj, Bot):
warn("Unknown bot instance found. Will be replaced by `None` during unpickling")
warn(
"Unknown bot instance found. Will be replaced by `None` during unpickling",
stacklevel=2,
)
return _REPLACED_UNKNOWN_BOT
return None # pickles as usual

Expand Down
18 changes: 17 additions & 1 deletion tests/_files/test_animation.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@
check_shortcut_call,
check_shortcut_signature,
)
from tests.auxil.deprecations import check_thumb_deprecation_warnings_for_args_and_attrs
from tests.auxil.deprecations import (
check_thumb_deprecation_warning_for_method_args,
check_thumb_deprecation_warnings_for_args_and_attrs,
)
from tests.auxil.files import data_file
from tests.auxil.slots import mro_slots

Expand Down Expand Up @@ -191,6 +194,19 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs):
monkeypatch.setattr(bot.request, "post", make_assertion)
assert await bot.send_animation(animation=animation, chat_id=chat_id)

@pytest.mark.parametrize("bot_class", ["Bot", "ExtBot"])
async def test_send_animation_thumb_deprecation_warning(
self, recwarn, monkeypatch, bot_class, bot, raw_bot, chat_id, animation
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
return True

bot = raw_bot if bot_class == "Bot" else bot

monkeypatch.setattr(bot.request, "post", make_assertion)
await bot.send_animation(chat_id, animation, thumb="thumb")
check_thumb_deprecation_warning_for_method_args(recwarn, __file__)

async def test_send_animation_with_local_files_throws_error_with_different_thumb_and_thumbnail(
self, bot, chat_id
):
Expand Down
Loading
0