From b4ea5557ac0f2463c875efabf98ca46ff8edf119 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 20 Aug 2021 01:31:10 +0530 Subject: [PATCH] Remove `__dict__` from `__slots__` and drop Python 3.6 (#2619, #2636) --- .github/workflows/test.yml | 2 +- .pre-commit-config.yaml | 2 +- README.rst | 2 +- README_RAW.rst | 2 +- pyproject.toml | 2 +- setup.py | 3 +- telegram/base.py | 31 +++++++----- telegram/bot.py | 8 ---- telegram/botcommand.py | 2 +- telegram/botcommandscope.py | 2 +- telegram/callbackquery.py | 1 - telegram/chat.py | 1 - telegram/chataction.py | 6 +-- telegram/chatinvitelink.py | 1 - telegram/chatjoinrequest.py | 1 - telegram/chatlocation.py | 2 +- telegram/chatmember.py | 1 - telegram/chatmemberupdated.py | 1 - telegram/chatpermissions.py | 1 - telegram/choseninlineresult.py | 2 +- telegram/dice.py | 2 +- telegram/error.py | 1 - telegram/ext/__init__.py | 12 ----- telegram/ext/basepersistence.py | 48 ++++++------------- telegram/ext/conversationhandler.py | 1 - telegram/ext/defaults.py | 5 -- telegram/ext/dispatcher.py | 13 +---- telegram/ext/extbot.py | 10 +--- telegram/ext/filters.py | 26 ++-------- telegram/ext/handler.py | 42 ++++------------ telegram/ext/jobqueue.py | 10 +--- telegram/ext/updater.py | 11 +---- telegram/ext/utils/promise.py | 5 -- telegram/ext/utils/webhookhandler.py | 5 -- telegram/files/animation.py | 1 - telegram/files/audio.py | 1 - telegram/files/chatphoto.py | 1 - telegram/files/contact.py | 2 +- telegram/files/document.py | 3 -- telegram/files/file.py | 1 - telegram/files/inputfile.py | 7 +-- telegram/files/location.py | 1 - telegram/files/photosize.py | 2 +- telegram/files/sticker.py | 4 +- telegram/files/venue.py | 1 - telegram/files/video.py | 1 - telegram/files/videonote.py | 1 - telegram/files/voice.py | 1 - telegram/forcereply.py | 2 +- telegram/games/game.py | 1 - telegram/games/gamehighscore.py | 2 +- telegram/inline/inlinekeyboardbutton.py | 1 - telegram/inline/inlinekeyboardmarkup.py | 2 +- telegram/inline/inlinequery.py | 2 +- telegram/inline/inlinequeryresult.py | 2 +- telegram/inline/inputcontactmessagecontent.py | 2 +- telegram/inline/inputinvoicemessagecontent.py | 1 - .../inline/inputlocationmessagecontent.py | 2 +- telegram/inline/inputtextmessagecontent.py | 2 +- telegram/inline/inputvenuemessagecontent.py | 1 - telegram/keyboardbutton.py | 2 +- telegram/keyboardbuttonpolltype.py | 2 +- telegram/loginurl.py | 2 +- telegram/message.py | 1 - telegram/messageautodeletetimerchanged.py | 2 +- telegram/messageentity.py | 2 +- telegram/messageid.py | 2 +- telegram/parsemode.py | 6 +-- telegram/passport/credentials.py | 1 - telegram/passport/encryptedpassportelement.py | 1 - telegram/passport/passportdata.py | 2 +- telegram/passport/passportelementerrors.py | 2 +- telegram/passport/passportfile.py | 1 - telegram/payment/invoice.py | 1 - telegram/payment/labeledprice.py | 2 +- telegram/payment/orderinfo.py | 2 +- telegram/payment/precheckoutquery.py | 1 - telegram/payment/shippingaddress.py | 1 - telegram/payment/shippingoption.py | 2 +- telegram/payment/shippingquery.py | 2 +- telegram/payment/successfulpayment.py | 1 - telegram/poll.py | 5 +- telegram/proximityalerttriggered.py | 2 +- telegram/replykeyboardmarkup.py | 1 - telegram/update.py | 1 - telegram/user.py | 1 - telegram/userprofilephotos.py | 2 +- telegram/utils/deprecate.py | 21 +------- telegram/utils/helpers.py | 2 +- telegram/utils/request.py | 6 +-- telegram/voicechat.py | 6 +-- telegram/webhookinfo.py | 1 - tests/conftest.py | 28 +++++++---- tests/test_animation.py | 5 +- tests/test_audio.py | 5 +- tests/test_bot.py | 12 +---- tests/test_botcommand.py | 5 +- tests/test_botcommandscope.py | 5 +- tests/test_callbackcontext.py | 2 +- tests/test_callbackdatacache.py | 8 +--- tests/test_callbackquery.py | 5 +- tests/test_callbackqueryhandler.py | 7 +-- tests/test_chat.py | 5 +- tests/test_chataction.py | 5 +- tests/test_chatinvitelink.py | 5 +- tests/test_chatjoinrequest.py | 3 -- tests/test_chatjoinrequesthandler.py | 3 -- tests/test_chatlocation.py | 5 +- tests/test_chatmember.py | 5 +- tests/test_chatmemberhandler.py | 5 +- tests/test_chatmemberupdated.py | 5 +- tests/test_chatpermissions.py | 5 +- tests/test_chatphoto.py | 5 +- tests/test_choseninlineresult.py | 5 +- tests/test_choseninlineresulthandler.py | 5 +- tests/test_commandhandler.py | 10 +--- tests/test_contact.py | 5 +- tests/test_contexttypes.py | 2 - tests/test_conversationhandler.py | 11 ++--- tests/test_defaults.py | 5 +- tests/test_dice.py | 5 +- tests/test_dispatcher.py | 15 +----- tests/test_document.py | 5 +- tests/test_encryptedcredentials.py | 5 +- tests/test_encryptedpassportelement.py | 5 +- tests/test_file.py | 5 +- tests/test_filters.py | 18 ++----- tests/test_forcereply.py | 5 +- tests/test_game.py | 5 +- tests/test_gamehighscore.py | 5 +- tests/test_handler.py | 8 +--- tests/test_inlinekeyboardbutton.py | 5 +- tests/test_inlinekeyboardmarkup.py | 5 +- tests/test_inlinequery.py | 5 +- tests/test_inlinequeryhandler.py | 7 +-- tests/test_inlinequeryresultarticle.py | 3 -- tests/test_inlinequeryresultaudio.py | 5 +- tests/test_inlinequeryresultcachedaudio.py | 5 +- tests/test_inlinequeryresultcacheddocument.py | 5 +- tests/test_inlinequeryresultcachedgif.py | 5 +- tests/test_inlinequeryresultcachedmpeg4gif.py | 5 +- tests/test_inlinequeryresultcachedphoto.py | 5 +- tests/test_inlinequeryresultcachedsticker.py | 5 +- tests/test_inlinequeryresultcachedvideo.py | 5 +- tests/test_inlinequeryresultcachedvoice.py | 5 +- tests/test_inlinequeryresultcontact.py | 5 +- tests/test_inlinequeryresultdocument.py | 5 +- tests/test_inlinequeryresultgame.py | 5 +- tests/test_inlinequeryresultgif.py | 5 +- tests/test_inlinequeryresultlocation.py | 5 +- tests/test_inlinequeryresultmpeg4gif.py | 5 +- tests/test_inlinequeryresultphoto.py | 5 +- tests/test_inlinequeryresultvenue.py | 5 +- tests/test_inlinequeryresultvideo.py | 5 +- tests/test_inlinequeryresultvoice.py | 5 +- tests/test_inputcontactmessagecontent.py | 5 +- tests/test_inputfile.py | 5 +- tests/test_inputinvoicemessagecontent.py | 5 +- tests/test_inputlocationmessagecontent.py | 5 +- tests/test_inputmedia.py | 25 ++-------- tests/test_inputtextmessagecontent.py | 5 +- tests/test_inputvenuemessagecontent.py | 5 +- tests/test_invoice.py | 5 +- tests/test_jobqueue.py | 5 +- tests/test_keyboardbutton.py | 5 +- tests/test_keyboardbuttonpolltype.py | 5 +- tests/test_labeledprice.py | 5 +- tests/test_location.py | 5 +- tests/test_loginurl.py | 5 +- tests/test_message.py | 5 +- tests/test_messageautodeletetimerchanged.py | 5 +- tests/test_messageentity.py | 5 +- tests/test_messagehandler.py | 5 +- tests/test_messageid.py | 5 +- tests/test_official.py | 5 +- tests/test_orderinfo.py | 5 +- tests/test_parsemode.py | 5 +- tests/test_passport.py | 5 +- tests/test_passportelementerrordatafield.py | 5 +- tests/test_passportelementerrorfile.py | 5 +- tests/test_passportelementerrorfiles.py | 5 +- tests/test_passportelementerrorfrontside.py | 5 +- tests/test_passportelementerrorreverseside.py | 5 +- tests/test_passportelementerrorselfie.py | 5 +- ...est_passportelementerrortranslationfile.py | 5 +- ...st_passportelementerrortranslationfiles.py | 5 +- tests/test_passportelementerrorunspecified.py | 5 +- tests/test_passportfile.py | 5 +- tests/test_persistence.py | 14 +----- tests/test_photo.py | 5 +- tests/test_poll.py | 5 +- tests/test_pollanswerhandler.py | 5 +- tests/test_pollhandler.py | 5 +- tests/test_precheckoutquery.py | 5 +- tests/test_precheckoutqueryhandler.py | 5 +- tests/test_promise.py | 5 +- tests/test_proximityalerttriggered.py | 5 +- tests/test_regexhandler.py | 5 +- tests/test_replykeyboardmarkup.py | 5 +- tests/test_replykeyboardremove.py | 5 +- tests/test_request.py | 5 +- tests/test_shippingaddress.py | 5 +- tests/test_shippingoption.py | 5 +- tests/test_shippingquery.py | 5 +- tests/test_shippingqueryhandler.py | 5 +- tests/test_slots.py | 46 ++++++------------ tests/test_sticker.py | 3 -- tests/test_stringcommandhandler.py | 5 +- tests/test_stringregexhandler.py | 5 +- tests/test_successfulpayment.py | 5 +- tests/test_telegramobject.py | 8 ++-- tests/test_typehandler.py | 5 +- tests/test_update.py | 5 +- tests/test_updater.py | 18 ++----- tests/test_user.py | 5 +- tests/test_userprofilephotos.py | 5 +- tests/test_venue.py | 5 +- tests/test_video.py | 5 +- tests/test_videonote.py | 5 +- tests/test_voice.py | 5 +- tests/test_voicechat.py | 20 ++------ tests/test_webhookinfo.py | 5 +- 222 files changed, 277 insertions(+), 931 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f9dbe6885..3a8695095 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: runs-on: ${{matrix.os}} strategy: matrix: - python-version: [3.6, 3.7, 3.8, 3.9] + python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest, windows-latest, macos-latest] fail-fast: False steps: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 66f5b9b11..d3056152e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -56,4 +56,4 @@ repos: - id: pyupgrade files: ^(telegram|examples|tests)/.*\.py$ args: - - --py36-plus + - --py37-plus diff --git a/README.rst b/README.rst index 9839d10c1..f14d8942c 100644 --- a/README.rst +++ b/README.rst @@ -93,7 +93,7 @@ Introduction This library provides a pure Python interface for the `Telegram Bot API `_. -It's compatible with Python versions 3.6.8+. PTB might also work on `PyPy `_, though there have been a lot of issues before. Hence, PyPy is not officially supported. +It's compatible with Python versions **3.7+**. PTB might also work on `PyPy `_, though there have been a lot of issues before. Hence, PyPy is not officially supported. In addition to the pure API implementation, this library features a number of high-level classes to make the development of bots easy and straightforward. These classes are contained in the diff --git a/README_RAW.rst b/README_RAW.rst index d7b2fa37e..33cfcfbd4 100644 --- a/README_RAW.rst +++ b/README_RAW.rst @@ -91,7 +91,7 @@ Introduction This library provides a pure Python, lightweight interface for the `Telegram Bot API `_. -It's compatible with Python versions 3.6.8+. PTB-Raw might also work on `PyPy `_, though there have been a lot of issues before. Hence, PyPy is not officially supported. +It's compatible with Python versions **3.7+**. PTB-Raw might also work on `PyPy `_, though there have been a lot of issues before. Hence, PyPy is not officially supported. ``python-telegram-bot-raw`` is part of the `python-telegram-bot `_ ecosystem and provides the pure API functionality extracted from PTB. It therefore does *not* have independent release schedules, changelogs or documentation. Please consult the PTB resources. diff --git a/pyproject.toml b/pyproject.toml index 956c60623..38ece5d5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.black] line-length = 99 -target-version = ['py36'] +target-version = ['py37'] skip-string-normalization = true # We need to force-exclude the negated include pattern diff --git a/setup.py b/setup.py index acffecc18..63a786a32 100644 --- a/setup.py +++ b/setup.py @@ -98,12 +98,11 @@ def get_setup_kwargs(raw=False): 'Topic :: Internet', 'Programming Language :: Python', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', ], - python_requires='>=3.6' + python_requires='>=3.7' ) return kwargs diff --git a/telegram/base.py b/telegram/base.py index f119d9624..3cb51785d 100644 --- a/telegram/base.py +++ b/telegram/base.py @@ -23,10 +23,9 @@ except ImportError: import json # type: ignore[no-redef] import warnings -from typing import TYPE_CHECKING, List, Optional, Tuple, Type, TypeVar +from typing import TYPE_CHECKING, List, Optional, Type, TypeVar, Tuple from telegram.utils.types import JSONDict -from telegram.utils.deprecate import set_new_attribute_deprecated if TYPE_CHECKING: from telegram import Bot @@ -37,12 +36,21 @@ TO = TypeVar('TO', bound='TelegramObject', covariant=True) class TelegramObject: """Base class for most Telegram objects.""" - _id_attrs: Tuple[object, ...] = () - + # type hints in __new__ are not read by mypy (https://github.com/python/mypy/issues/1021). As a + # workaround we can type hint instance variables in __new__ using a syntax defined in PEP 526 - + # https://www.python.org/dev/peps/pep-0526/#class-and-instance-variable-annotations + if TYPE_CHECKING: + _id_attrs: Tuple[object, ...] # Adding slots reduces memory usage & allows for faster attribute access. # Only instance variables should be added to __slots__. - # We add __dict__ here for backward compatibility & also to avoid repetition for subclasses. - __slots__ = ('__dict__',) + __slots__ = ('_id_attrs',) + + def __new__(cls, *args: object, **kwargs: object) -> 'TelegramObject': # pylint: disable=W0613 + # We add _id_attrs in __new__ instead of __init__ since we want to add this to the slots + # w/o calling __init__ in all of the subclasses. This is what we also do in BaseFilter. + instance = super().__new__(cls) + instance._id_attrs = () + return instance def __str__(self) -> str: return str(self.to_dict()) @@ -50,9 +58,6 @@ class TelegramObject: def __getitem__(self, item: str) -> object: return getattr(self, item, None) - def __setattr__(self, key: str, value: object) -> None: - set_new_attribute_deprecated(self, key, value) - @staticmethod def _parse_data(data: Optional[JSONDict]) -> Optional[JSONDict]: return None if data is None else data.copy() @@ -76,7 +81,7 @@ class TelegramObject: if cls == TelegramObject: return cls() - return cls(bot=bot, **data) # type: ignore[call-arg] + return cls(bot=bot, **data) @classmethod def de_list(cls: Type[TO], data: Optional[List[JSONDict]], bot: 'Bot') -> List[Optional[TO]]: @@ -132,6 +137,7 @@ class TelegramObject: return data def __eq__(self, other: object) -> bool: + # pylint: disable=no-member if isinstance(other, self.__class__): if self._id_attrs == (): warnings.warn( @@ -144,9 +150,10 @@ class TelegramObject: " for equivalence." ) return self._id_attrs == other._id_attrs - return super().__eq__(other) # pylint: disable=no-member + return super().__eq__(other) def __hash__(self) -> int: + # pylint: disable=no-member if self._id_attrs: - return hash((self.__class__, self._id_attrs)) # pylint: disable=no-member + return hash((self.__class__, self._id_attrs)) return super().__hash__() diff --git a/telegram/bot.py b/telegram/bot.py index cc983d561..867958f58 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -224,14 +224,6 @@ class Bot(TelegramObject): private_key, password=private_key_password, backend=default_backend() ) - # The ext_bot argument is a little hack to get warnings handled correctly. - # It's not very clean, but the warnings will be dropped at some point anyway. - def __setattr__(self, key: str, value: object, ext_bot: bool = False) -> None: - if issubclass(self.__class__, Bot) and self.__class__ is not Bot and not ext_bot: - object.__setattr__(self, key, value) - return - super().__setattr__(key, value) - def _insert_defaults( self, data: Dict[str, object], timeout: ODVInput[float] ) -> Optional[float]: diff --git a/telegram/botcommand.py b/telegram/botcommand.py index 7d0f2da30..cf919c038 100644 --- a/telegram/botcommand.py +++ b/telegram/botcommand.py @@ -41,7 +41,7 @@ class BotCommand(TelegramObject): """ - __slots__ = ('description', '_id_attrs', 'command') + __slots__ = ('description', 'command') def __init__(self, command: str, description: str, **_kwargs: Any): self.command = command diff --git a/telegram/botcommandscope.py b/telegram/botcommandscope.py index 283f7682b..8ae36cf55 100644 --- a/telegram/botcommandscope.py +++ b/telegram/botcommandscope.py @@ -57,7 +57,7 @@ class BotCommandScope(TelegramObject): type (:obj:`str`): Scope type. """ - __slots__ = ('type', '_id_attrs') + __slots__ = ('type',) DEFAULT = constants.BOT_COMMAND_SCOPE_DEFAULT """:const:`telegram.constants.BOT_COMMAND_SCOPE_DEFAULT`""" diff --git a/telegram/callbackquery.py b/telegram/callbackquery.py index b78363604..b1b2e2321 100644 --- a/telegram/callbackquery.py +++ b/telegram/callbackquery.py @@ -101,7 +101,6 @@ class CallbackQuery(TelegramObject): 'from_user', 'inline_message_id', 'data', - '_id_attrs', ) def __init__( diff --git a/telegram/chat.py b/telegram/chat.py index b5dbfe452..20c56c0b0 100644 --- a/telegram/chat.py +++ b/telegram/chat.py @@ -186,7 +186,6 @@ class Chat(TelegramObject): 'message_auto_delete_time', 'has_protected_content', 'has_private_forwards', - '_id_attrs', ) SENDER: ClassVar[str] = constants.CHAT_SENDER diff --git a/telegram/chataction.py b/telegram/chataction.py index 335ab39ac..d6d1bdb77 100644 --- a/telegram/chataction.py +++ b/telegram/chataction.py @@ -20,13 +20,12 @@ """This module contains an object that represents a Telegram ChatAction.""" from typing import ClassVar from telegram import constants -from telegram.utils.deprecate import set_new_attribute_deprecated class ChatAction: """Helper class to provide constants for different chat actions.""" - __slots__ = ('__dict__',) # Adding __dict__ here since it doesn't subclass TGObject + __slots__ = () FIND_LOCATION: ClassVar[str] = constants.CHATACTION_FIND_LOCATION """:const:`telegram.constants.CHATACTION_FIND_LOCATION`""" RECORD_AUDIO: ClassVar[str] = constants.CHATACTION_RECORD_AUDIO @@ -69,6 +68,3 @@ class ChatAction: """:const:`telegram.constants.CHATACTION_UPLOAD_VIDEO`""" UPLOAD_VIDEO_NOTE: ClassVar[str] = constants.CHATACTION_UPLOAD_VIDEO_NOTE """:const:`telegram.constants.CHATACTION_UPLOAD_VIDEO_NOTE`""" - - def __setattr__(self, key: str, value: object) -> None: - set_new_attribute_deprecated(self, key, value) diff --git a/telegram/chatinvitelink.py b/telegram/chatinvitelink.py index 6852b5599..d6f378a21 100644 --- a/telegram/chatinvitelink.py +++ b/telegram/chatinvitelink.py @@ -92,7 +92,6 @@ class ChatInviteLink(TelegramObject): 'name', 'creates_join_request', 'pending_join_request_count', - '_id_attrs', ) def __init__( diff --git a/telegram/chatjoinrequest.py b/telegram/chatjoinrequest.py index ec89c6614..096873cf0 100644 --- a/telegram/chatjoinrequest.py +++ b/telegram/chatjoinrequest.py @@ -68,7 +68,6 @@ class ChatJoinRequest(TelegramObject): 'bio', 'invite_link', 'bot', - '_id_attrs', ) def __init__( diff --git a/telegram/chatlocation.py b/telegram/chatlocation.py index f88c70808..9ac3e1a04 100644 --- a/telegram/chatlocation.py +++ b/telegram/chatlocation.py @@ -47,7 +47,7 @@ class ChatLocation(TelegramObject): """ - __slots__ = ('location', '_id_attrs', 'address') + __slots__ = ('location', 'address') def __init__( self, diff --git a/telegram/chatmember.py b/telegram/chatmember.py index 06968d4d6..d6de0a145 100644 --- a/telegram/chatmember.py +++ b/telegram/chatmember.py @@ -287,7 +287,6 @@ class ChatMember(TelegramObject): 'can_manage_chat', 'can_manage_voice_chats', 'until_date', - '_id_attrs', ) ADMINISTRATOR: ClassVar[str] = constants.CHATMEMBER_ADMINISTRATOR diff --git a/telegram/chatmemberupdated.py b/telegram/chatmemberupdated.py index cd6c76e3e..f6fe789b7 100644 --- a/telegram/chatmemberupdated.py +++ b/telegram/chatmemberupdated.py @@ -69,7 +69,6 @@ class ChatMemberUpdated(TelegramObject): 'old_chat_member', 'new_chat_member', 'invite_link', - '_id_attrs', ) def __init__( diff --git a/telegram/chatpermissions.py b/telegram/chatpermissions.py index 44b989a00..c7b076c51 100644 --- a/telegram/chatpermissions.py +++ b/telegram/chatpermissions.py @@ -82,7 +82,6 @@ class ChatPermissions(TelegramObject): 'can_send_other_messages', 'can_invite_users', 'can_send_polls', - '_id_attrs', 'can_send_messages', 'can_send_media_messages', 'can_change_info', diff --git a/telegram/choseninlineresult.py b/telegram/choseninlineresult.py index b931553eb..9f9134676 100644 --- a/telegram/choseninlineresult.py +++ b/telegram/choseninlineresult.py @@ -61,7 +61,7 @@ class ChosenInlineResult(TelegramObject): """ - __slots__ = ('location', 'result_id', 'from_user', 'inline_message_id', '_id_attrs', 'query') + __slots__ = ('location', 'result_id', 'from_user', 'inline_message_id', 'query') def __init__( self, diff --git a/telegram/dice.py b/telegram/dice.py index 8836529b1..b71e153b2 100644 --- a/telegram/dice.py +++ b/telegram/dice.py @@ -64,7 +64,7 @@ class Dice(TelegramObject): """ - __slots__ = ('emoji', 'value', '_id_attrs') + __slots__ = ('emoji', 'value') def __init__(self, value: int, emoji: str, **_kwargs: Any): self.value = value diff --git a/telegram/error.py b/telegram/error.py index 6a801a541..92682e5d9 100644 --- a/telegram/error.py +++ b/telegram/error.py @@ -41,7 +41,6 @@ def _lstrip_str(in_s: str, lstr: str) -> str: class TelegramError(Exception): """Base class for Telegram errors.""" - # Apparently the base class Exception already has __dict__ in it, so its not included here __slots__ = ('message',) def __init__(self, message: str): diff --git a/telegram/ext/__init__.py b/telegram/ext/__init__.py index 660aae3ec..b94440fa9 100644 --- a/telegram/ext/__init__.py +++ b/telegram/ext/__init__.py @@ -16,7 +16,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/]. -# pylint: disable=C0413 """Extensions over the Telegram Bot API to facilitate bot making""" from .extbot import ExtBot @@ -28,17 +27,6 @@ from .callbackcontext import CallbackContext from .contexttypes import ContextTypes from .dispatcher import Dispatcher, DispatcherHandlerStop, run_async -# https://bugs.python.org/issue41451, fixed on 3.7+, doesn't actually remove slots -# try-except is just here in case the __init__ is called twice (like in the tests) -# this block is also the reason for the pylint-ignore at the top of the file -try: - del Dispatcher.__slots__ -except AttributeError as exc: - if str(exc) == '__slots__': - pass - else: - raise exc - from .jobqueue import JobQueue, Job from .updater import Updater from .callbackqueryhandler import CallbackQueryHandler diff --git a/telegram/ext/basepersistence.py b/telegram/ext/basepersistence.py index c167a9993..764d27136 100644 --- a/telegram/ext/basepersistence.py +++ b/telegram/ext/basepersistence.py @@ -18,13 +18,10 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the BasePersistence class.""" import warnings -from sys import version_info as py_ver from abc import ABC, abstractmethod from copy import copy from typing import Dict, Optional, Tuple, cast, ClassVar, Generic, DefaultDict, NamedTuple -from telegram.utils.deprecate import set_new_attribute_deprecated - from telegram import Bot import telegram.ext.extbot @@ -108,18 +105,11 @@ class BasePersistence(Generic[UD, CD, BD], ABC): persistence instance. """ - # Apparently Py 3.7 and below have '__dict__' in ABC - if py_ver < (3, 7): - __slots__ = ( - 'store_data', - 'bot', - ) - else: - __slots__ = ( - 'store_data', # type: ignore[assignment] - 'bot', - '__dict__', - ) + __slots__ = ( + 'bot', + 'store_data', + '__dict__', # __dict__ is included because we replace methods in the __new__ + ) def __new__( cls, *args: object, **kwargs: object # pylint: disable=W0613 @@ -169,15 +159,15 @@ class BasePersistence(Generic[UD, CD, BD], ABC): obj_data, queue = data return update_callback_data((instance.replace_bot(obj_data), queue)) - # We want to ignore TGDeprecation warnings so we use obj.__setattr__. Adds to __dict__ - object.__setattr__(instance, 'get_user_data', get_user_data_insert_bot) - object.__setattr__(instance, 'get_chat_data', get_chat_data_insert_bot) - object.__setattr__(instance, 'get_bot_data', get_bot_data_insert_bot) - object.__setattr__(instance, 'get_callback_data', get_callback_data_insert_bot) - object.__setattr__(instance, 'update_user_data', update_user_data_replace_bot) - object.__setattr__(instance, 'update_chat_data', update_chat_data_replace_bot) - object.__setattr__(instance, 'update_bot_data', update_bot_data_replace_bot) - object.__setattr__(instance, 'update_callback_data', update_callback_data_replace_bot) + # Adds to __dict__ + setattr(instance, 'get_user_data', get_user_data_insert_bot) + setattr(instance, 'get_chat_data', get_chat_data_insert_bot) + setattr(instance, 'get_bot_data', get_bot_data_insert_bot) + setattr(instance, 'get_callback_data', get_callback_data_insert_bot) + setattr(instance, 'update_user_data', update_user_data_replace_bot) + setattr(instance, 'update_chat_data', update_chat_data_replace_bot) + setattr(instance, 'update_bot_data', update_bot_data_replace_bot) + setattr(instance, 'update_callback_data', update_callback_data_replace_bot) return instance def __init__( @@ -188,16 +178,6 @@ class BasePersistence(Generic[UD, CD, BD], ABC): self.bot: Bot = None # type: ignore[assignment] - def __setattr__(self, key: str, value: object) -> None: - # Allow user defined subclasses to have custom attributes. - if issubclass(self.__class__, BasePersistence) and self.__class__.__name__ not in { - 'DictPersistence', - 'PicklePersistence', - }: - object.__setattr__(self, key, value) - return - set_new_attribute_deprecated(self, key, value) - def set_bot(self, bot: Bot) -> None: """Set the Bot to be used by this persistence instance. diff --git a/telegram/ext/conversationhandler.py b/telegram/ext/conversationhandler.py index 23edf2f75..98b7ccfe0 100644 --- a/telegram/ext/conversationhandler.py +++ b/telegram/ext/conversationhandler.py @@ -46,7 +46,6 @@ CheckUpdateType = Optional[Tuple[Tuple[int, ...], Handler, object]] class _ConversationTimeoutContext: - # '__dict__' is not included since this a private class __slots__ = ('conversation_key', 'update', 'dispatcher', 'callback_context') def __init__( diff --git a/telegram/ext/defaults.py b/telegram/ext/defaults.py index 1e08255dd..148bd0751 100644 --- a/telegram/ext/defaults.py +++ b/telegram/ext/defaults.py @@ -22,7 +22,6 @@ from typing import NoReturn, Optional, Dict, Any import pytz -from telegram.utils.deprecate import set_new_attribute_deprecated from telegram.utils.helpers import DEFAULT_NONE from telegram.utils.types import ODVInput @@ -67,7 +66,6 @@ class Defaults: '_allow_sending_without_reply', '_parse_mode', '_api_defaults', - '__dict__', ) def __init__( @@ -108,9 +106,6 @@ class Defaults: if self._timeout != DEFAULT_NONE: self._api_defaults['timeout'] = self._timeout - def __setattr__(self, key: str, value: object) -> None: - set_new_attribute_deprecated(self, key, value) - @property def api_defaults(self) -> Dict[str, Any]: # skip-cq: PY-D0003 return self._api_defaults diff --git a/telegram/ext/dispatcher.py b/telegram/ext/dispatcher.py index 42a180c71..c74ba9038 100644 --- a/telegram/ext/dispatcher.py +++ b/telegram/ext/dispatcher.py @@ -48,7 +48,7 @@ from telegram.ext.callbackcontext import CallbackContext from telegram.ext.handler import Handler import telegram.ext.extbot from telegram.ext.callbackdatacache import CallbackDataCache -from telegram.utils.deprecate import TelegramDeprecationWarning, set_new_attribute_deprecated +from telegram.utils.deprecate import TelegramDeprecationWarning from telegram.ext.utils.promise import Promise from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE from telegram.ext.utils.types import CCT, UD, CD, BD @@ -312,17 +312,6 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): else: self._set_singleton(None) - def __setattr__(self, key: str, value: object) -> None: - # Mangled names don't automatically apply in __setattr__ (see - # https://docs.python.org/3/tutorial/classes.html#private-variables), so we have to make - # it mangled so they don't raise TelegramDeprecationWarning unnecessarily - if key.startswith('__'): - key = f"_{self.__class__.__name__}{key}" - if issubclass(self.__class__, Dispatcher) and self.__class__ is not Dispatcher: - object.__setattr__(self, key, value) - return - set_new_attribute_deprecated(self, key, value) - @property def exception_event(self) -> Event: # skipcq: PY-D0003 return self.__exception_event diff --git a/telegram/ext/extbot.py b/telegram/ext/extbot.py index f026191ee..3735ecb08 100644 --- a/telegram/ext/extbot.py +++ b/telegram/ext/extbot.py @@ -75,14 +75,6 @@ class ExtBot(telegram.bot.Bot): __slots__ = ('arbitrary_callback_data', 'callback_data_cache') - # The ext_bot argument is a little hack to get warnings handled correctly. - # It's not very clean, but the warnings will be dropped at some point anyway. - def __setattr__(self, key: str, value: object, ext_bot: bool = True) -> None: - if issubclass(self.__class__, ExtBot) and self.__class__ is not ExtBot: - object.__setattr__(self, key, value) - return - super().__setattr__(key, value, ext_bot=ext_bot) # type: ignore[call-arg] - def __init__( self, token: str, @@ -265,7 +257,7 @@ class ExtBot(telegram.bot.Bot): # different places new_result = copy(result) markup = self._replace_keyboard(result.reply_markup) # type: ignore[attr-defined] - new_result.reply_markup = markup + new_result.reply_markup = markup # type: ignore[attr-defined] results.append(new_result) return results, next_offset diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index 519c73a30..abfdd9694 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -23,7 +23,6 @@ import re import warnings from abc import ABC, abstractmethod -from sys import version_info as py_ver from threading import Lock from typing import ( Dict, @@ -51,7 +50,7 @@ __all__ = [ 'XORFilter', ] -from telegram.utils.deprecate import TelegramDeprecationWarning, set_new_attribute_deprecated +from telegram.utils.deprecate import TelegramDeprecationWarning from telegram.utils.types import SLT DataDict = Dict[str, list] @@ -113,12 +112,10 @@ class BaseFilter(ABC): (depends on the handler). """ - if py_ver < (3, 7): - __slots__ = ('_name', '_data_filter') - else: - __slots__ = ('_name', '_data_filter', '__dict__') # type: ignore[assignment] + __slots__ = ('_name', '_data_filter') def __new__(cls, *args: object, **kwargs: object) -> 'BaseFilter': # pylint: disable=W0613 + # We do this here instead of in a __init__ so filter don't have to call __init__ or super() instance = super().__new__(cls) instance._name = None instance._data_filter = False @@ -141,18 +138,6 @@ class BaseFilter(ABC): def __invert__(self) -> 'BaseFilter': return InvertedFilter(self) - def __setattr__(self, key: str, value: object) -> None: - # Allow setting custom attributes w/o warning for user defined custom filters. - # To differentiate between a custom and a PTB filter, we use this hacky but - # simple way of checking the module name where the class is defined from. - if ( - issubclass(self.__class__, (UpdateFilter, MessageFilter)) - and self.__class__.__module__ != __name__ - ): # __name__ is telegram.ext.filters - object.__setattr__(self, key, value) - return - set_new_attribute_deprecated(self, key, value) - @property def data_filter(self) -> bool: return self._data_filter @@ -437,10 +422,7 @@ class Filters: """ - __slots__ = ('__dict__',) - - def __setattr__(self, key: str, value: object) -> None: - set_new_attribute_deprecated(self, key, value) + __slots__ = () class _All(MessageFilter): __slots__ = () diff --git a/telegram/ext/handler.py b/telegram/ext/handler.py index b6e3a636d..aa106e929 100644 --- a/telegram/ext/handler.py +++ b/telegram/ext/handler.py @@ -19,9 +19,6 @@ """This module contains the base class for handlers as used by the Dispatcher.""" from abc import ABC, abstractmethod from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, TypeVar, Union, Generic -from sys import version_info as py_ver - -from telegram.utils.deprecate import set_new_attribute_deprecated from telegram import Update from telegram.ext.utils.promise import Promise @@ -93,26 +90,14 @@ class Handler(Generic[UT, CCT], ABC): """ - # Apparently Py 3.7 and below have '__dict__' in ABC - if py_ver < (3, 7): - __slots__ = ( - 'callback', - 'pass_update_queue', - 'pass_job_queue', - 'pass_user_data', - 'pass_chat_data', - 'run_async', - ) - else: - __slots__ = ( - 'callback', # type: ignore[assignment] - 'pass_update_queue', - 'pass_job_queue', - 'pass_user_data', - 'pass_chat_data', - 'run_async', - '__dict__', - ) + __slots__ = ( + 'callback', + 'pass_update_queue', + 'pass_job_queue', + 'pass_user_data', + 'pass_chat_data', + 'run_async', + ) def __init__( self, @@ -130,17 +115,6 @@ class Handler(Generic[UT, CCT], ABC): self.pass_chat_data = pass_chat_data self.run_async = run_async - def __setattr__(self, key: str, value: object) -> None: - # See comment on BaseFilter to know why this was done. - if key.startswith('__'): - key = f"_{self.__class__.__name__}{key}" - if issubclass(self.__class__, Handler) and not self.__class__.__module__.startswith( - 'telegram.ext.' - ): - object.__setattr__(self, key, value) - return - set_new_attribute_deprecated(self, key, value) - @abstractmethod def check_update(self, update: object) -> Optional[Union[bool, object]]: """ diff --git a/telegram/ext/jobqueue.py b/telegram/ext/jobqueue.py index f0c1fba02..b27f2c327 100644 --- a/telegram/ext/jobqueue.py +++ b/telegram/ext/jobqueue.py @@ -31,7 +31,6 @@ from apscheduler.job import Job as APSJob from telegram.ext.callbackcontext import CallbackContext from telegram.utils.types import JSONDict -from telegram.utils.deprecate import set_new_attribute_deprecated if TYPE_CHECKING: from telegram import Bot @@ -50,7 +49,7 @@ class JobQueue: """ - __slots__ = ('_dispatcher', 'logger', 'scheduler', '__dict__') + __slots__ = ('_dispatcher', 'logger', 'scheduler') def __init__(self) -> None: self._dispatcher: 'Dispatcher' = None # type: ignore[assignment] @@ -67,9 +66,6 @@ class JobQueue: logging.getLogger('apscheduler.executors.default').addFilter(aps_log_filter) self.scheduler.add_listener(self._dispatch_error, EVENT_JOB_ERROR) - def __setattr__(self, key: str, value: object) -> None: - set_new_attribute_deprecated(self, key, value) - def _build_args(self, job: 'Job') -> List[Union[CallbackContext, 'Bot', 'Job']]: if self._dispatcher.use_context: return [self._dispatcher.context_types.context.from_job(job, self._dispatcher)] @@ -560,7 +556,6 @@ class Job: '_removed', '_enabled', 'job', - '__dict__', ) def __init__( @@ -582,9 +577,6 @@ class Job: self.job = cast(APSJob, job) # skipcq: PTC-W0052 - def __setattr__(self, key: str, value: object) -> None: - set_new_attribute_deprecated(self, key, value) - def run(self, dispatcher: 'Dispatcher') -> None: """Executes the callback function independently of the jobs schedule.""" try: diff --git a/telegram/ext/updater.py b/telegram/ext/updater.py index b2c051256..74c167d9e 100644 --- a/telegram/ext/updater.py +++ b/telegram/ext/updater.py @@ -42,7 +42,7 @@ from typing import ( from telegram import Bot, TelegramError from telegram.error import InvalidToken, RetryAfter, TimedOut, Unauthorized from telegram.ext import Dispatcher, JobQueue, ContextTypes, ExtBot -from telegram.utils.deprecate import TelegramDeprecationWarning, set_new_attribute_deprecated +from telegram.utils.deprecate import TelegramDeprecationWarning from telegram.utils.helpers import get_signal_name, DEFAULT_FALSE, DefaultValue from telegram.utils.request import Request from telegram.ext.utils.types import CCT, UD, CD, BD @@ -149,7 +149,6 @@ class Updater(Generic[CCT, UD, CD, BD]): 'httpd', '__lock', '__threads', - '__dict__', ) @overload @@ -328,14 +327,6 @@ class Updater(Generic[CCT, UD, CD, BD]): self.__lock = Lock() self.__threads: List[Thread] = [] - def __setattr__(self, key: str, value: object) -> None: - if key.startswith('__'): - key = f"_{self.__class__.__name__}{key}" - if issubclass(self.__class__, Updater) and self.__class__ is not Updater: - object.__setattr__(self, key, value) - return - set_new_attribute_deprecated(self, key, value) - def _init_thread(self, target: Callable, name: str, *args: object, **kwargs: object) -> None: thr = Thread( target=self._thread_wrapper, diff --git a/telegram/ext/utils/promise.py b/telegram/ext/utils/promise.py index 86b3981c1..66ac30db4 100644 --- a/telegram/ext/utils/promise.py +++ b/telegram/ext/utils/promise.py @@ -22,7 +22,6 @@ import logging from threading import Event from typing import Callable, List, Optional, Tuple, TypeVar, Union -from telegram.utils.deprecate import set_new_attribute_deprecated from telegram.utils.types import JSONDict RT = TypeVar('RT') @@ -65,7 +64,6 @@ class Promise: '_done_callback', '_result', '_exception', - '__dict__', ) # TODO: Remove error_handling parameter once we drop the @run_async decorator @@ -87,9 +85,6 @@ class Promise: self._result: Optional[RT] = None self._exception: Optional[Exception] = None - def __setattr__(self, key: str, value: object) -> None: - set_new_attribute_deprecated(self, key, value) - def run(self) -> None: """Calls the :attr:`pooled_function` callable.""" try: diff --git a/telegram/ext/utils/webhookhandler.py b/telegram/ext/utils/webhookhandler.py index 64e639b12..fb69856b8 100644 --- a/telegram/ext/utils/webhookhandler.py +++ b/telegram/ext/utils/webhookhandler.py @@ -31,7 +31,6 @@ from tornado.ioloop import IOLoop from telegram import Update from telegram.ext import ExtBot -from telegram.utils.deprecate import set_new_attribute_deprecated from telegram.utils.types import JSONDict if TYPE_CHECKING: @@ -53,7 +52,6 @@ class WebhookServer: 'is_running', 'server_lock', 'shutdown_lock', - '__dict__', ) def __init__( @@ -68,9 +66,6 @@ class WebhookServer: self.server_lock = Lock() self.shutdown_lock = Lock() - def __setattr__(self, key: str, value: object) -> None: - set_new_attribute_deprecated(self, key, value) - def serve_forever(self, ready: Event = None) -> None: with self.server_lock: IOLoop().make_current() diff --git a/telegram/files/animation.py b/telegram/files/animation.py index a9f2ab5e3..05d11ca9c 100644 --- a/telegram/files/animation.py +++ b/telegram/files/animation.py @@ -76,7 +76,6 @@ class Animation(TelegramObject): 'mime_type', 'height', 'file_unique_id', - '_id_attrs', ) def __init__( diff --git a/telegram/files/audio.py b/telegram/files/audio.py index af6683cd0..970a9d7d9 100644 --- a/telegram/files/audio.py +++ b/telegram/files/audio.py @@ -80,7 +80,6 @@ class Audio(TelegramObject): 'performer', 'mime_type', 'file_unique_id', - '_id_attrs', ) def __init__( diff --git a/telegram/files/chatphoto.py b/telegram/files/chatphoto.py index 2f55bf9a9..a818b8efe 100644 --- a/telegram/files/chatphoto.py +++ b/telegram/files/chatphoto.py @@ -71,7 +71,6 @@ class ChatPhoto(TelegramObject): 'small_file_id', 'small_file_unique_id', 'big_file_id', - '_id_attrs', ) def __init__( diff --git a/telegram/files/contact.py b/telegram/files/contact.py index cee769f28..79b4dfa2a 100644 --- a/telegram/files/contact.py +++ b/telegram/files/contact.py @@ -46,7 +46,7 @@ class Contact(TelegramObject): """ - __slots__ = ('vcard', 'user_id', 'first_name', 'last_name', 'phone_number', '_id_attrs') + __slots__ = ('vcard', 'user_id', 'first_name', 'last_name', 'phone_number') def __init__( self, diff --git a/telegram/files/document.py b/telegram/files/document.py index a0ffcefb4..41252c670 100644 --- a/telegram/files/document.py +++ b/telegram/files/document.py @@ -68,11 +68,8 @@ class Document(TelegramObject): 'thumb', 'mime_type', 'file_unique_id', - '_id_attrs', ) - _id_keys = ('file_id',) - def __init__( self, file_id: str, diff --git a/telegram/files/file.py b/telegram/files/file.py index ca77f9d1e..5a86da62d 100644 --- a/telegram/files/file.py +++ b/telegram/files/file.py @@ -74,7 +74,6 @@ class File(TelegramObject): 'file_unique_id', 'file_path', '_credentials', - '_id_attrs', ) def __init__( diff --git a/telegram/files/inputfile.py b/telegram/files/inputfile.py index 2c3196fc1..76d0b037f 100644 --- a/telegram/files/inputfile.py +++ b/telegram/files/inputfile.py @@ -26,8 +26,6 @@ import os from typing import IO, Optional, Tuple, Union from uuid import uuid4 -from telegram.utils.deprecate import set_new_attribute_deprecated - DEFAULT_MIME_TYPE = 'application/octet-stream' logger = logging.getLogger(__name__) @@ -52,7 +50,7 @@ class InputFile: """ - __slots__ = ('filename', 'attach', 'input_file_content', 'mimetype', '__dict__') + __slots__ = ('filename', 'attach', 'input_file_content', 'mimetype') def __init__(self, obj: Union[IO, bytes], filename: str = None, attach: bool = None): self.filename = None @@ -78,9 +76,6 @@ class InputFile: if not self.filename: self.filename = self.mimetype.replace('/', '.') - def __setattr__(self, key: str, value: object) -> None: - set_new_attribute_deprecated(self, key, value) - @property def field_tuple(self) -> Tuple[str, bytes, str]: # skipcq: PY-D0003 return self.filename, self.input_file_content, self.mimetype diff --git a/telegram/files/location.py b/telegram/files/location.py index a5f5065a7..b8fdaebad 100644 --- a/telegram/files/location.py +++ b/telegram/files/location.py @@ -63,7 +63,6 @@ class Location(TelegramObject): 'live_period', 'latitude', 'heading', - '_id_attrs', ) def __init__( diff --git a/telegram/files/photosize.py b/telegram/files/photosize.py index 9a7988bb8..e920ba4f2 100644 --- a/telegram/files/photosize.py +++ b/telegram/files/photosize.py @@ -58,7 +58,7 @@ class PhotoSize(TelegramObject): """ - __slots__ = ('bot', 'width', 'file_id', 'file_size', 'height', 'file_unique_id', '_id_attrs') + __slots__ = ('bot', 'width', 'file_id', 'file_size', 'height', 'file_unique_id') def __init__( self, diff --git a/telegram/files/sticker.py b/telegram/files/sticker.py index e3f22a997..a911b82ac 100644 --- a/telegram/files/sticker.py +++ b/telegram/files/sticker.py @@ -97,7 +97,6 @@ class Sticker(TelegramObject): 'height', 'file_unique_id', 'emoji', - '_id_attrs', ) def __init__( @@ -208,7 +207,6 @@ class StickerSet(TelegramObject): 'title', 'stickers', 'name', - '_id_attrs', ) def __init__( @@ -286,7 +284,7 @@ class MaskPosition(TelegramObject): """ - __slots__ = ('point', 'scale', 'x_shift', 'y_shift', '_id_attrs') + __slots__ = ('point', 'scale', 'x_shift', 'y_shift') FOREHEAD: ClassVar[str] = constants.STICKER_FOREHEAD """:const:`telegram.constants.STICKER_FOREHEAD`""" diff --git a/telegram/files/venue.py b/telegram/files/venue.py index aad46db9d..481a8fbfe 100644 --- a/telegram/files/venue.py +++ b/telegram/files/venue.py @@ -68,7 +68,6 @@ class Venue(TelegramObject): 'foursquare_type', 'foursquare_id', 'google_place_id', - '_id_attrs', ) def __init__( diff --git a/telegram/files/video.py b/telegram/files/video.py index 92e7c5ea3..602001391 100644 --- a/telegram/files/video.py +++ b/telegram/files/video.py @@ -77,7 +77,6 @@ class Video(TelegramObject): 'mime_type', 'height', 'file_unique_id', - '_id_attrs', ) def __init__( diff --git a/telegram/files/videonote.py b/telegram/files/videonote.py index 17d6207ea..9daf2e0f6 100644 --- a/telegram/files/videonote.py +++ b/telegram/files/videonote.py @@ -69,7 +69,6 @@ class VideoNote(TelegramObject): 'thumb', 'duration', 'file_unique_id', - '_id_attrs', ) def __init__( diff --git a/telegram/files/voice.py b/telegram/files/voice.py index c8782821f..d90248d61 100644 --- a/telegram/files/voice.py +++ b/telegram/files/voice.py @@ -65,7 +65,6 @@ class Voice(TelegramObject): 'duration', 'mime_type', 'file_unique_id', - '_id_attrs', ) def __init__( diff --git a/telegram/forcereply.py b/telegram/forcereply.py index 792b211ac..a45bd8e83 100644 --- a/telegram/forcereply.py +++ b/telegram/forcereply.py @@ -60,7 +60,7 @@ class ForceReply(ReplyMarkup): """ - __slots__ = ('selective', 'force_reply', 'input_field_placeholder', '_id_attrs') + __slots__ = ('selective', 'force_reply', 'input_field_placeholder') def __init__( self, diff --git a/telegram/games/game.py b/telegram/games/game.py index 86eb2ab83..1b9146d8e 100644 --- a/telegram/games/game.py +++ b/telegram/games/game.py @@ -74,7 +74,6 @@ class Game(TelegramObject): 'text_entities', 'text', 'animation', - '_id_attrs', ) def __init__( diff --git a/telegram/games/gamehighscore.py b/telegram/games/gamehighscore.py index 5967ddaf1..d109d84c3 100644 --- a/telegram/games/gamehighscore.py +++ b/telegram/games/gamehighscore.py @@ -45,7 +45,7 @@ class GameHighScore(TelegramObject): """ - __slots__ = ('position', 'user', 'score', '_id_attrs') + __slots__ = ('position', 'user', 'score') def __init__(self, position: int, user: User, score: int): self.position = position diff --git a/telegram/inline/inlinekeyboardbutton.py b/telegram/inline/inlinekeyboardbutton.py index 49b6e071c..0d7be562f 100644 --- a/telegram/inline/inlinekeyboardbutton.py +++ b/telegram/inline/inlinekeyboardbutton.py @@ -121,7 +121,6 @@ class InlineKeyboardButton(TelegramObject): 'pay', 'switch_inline_query', 'text', - '_id_attrs', 'login_url', ) diff --git a/telegram/inline/inlinekeyboardmarkup.py b/telegram/inline/inlinekeyboardmarkup.py index 61724f089..eff0e0f11 100644 --- a/telegram/inline/inlinekeyboardmarkup.py +++ b/telegram/inline/inlinekeyboardmarkup.py @@ -45,7 +45,7 @@ class InlineKeyboardMarkup(ReplyMarkup): """ - __slots__ = ('inline_keyboard', '_id_attrs') + __slots__ = ('inline_keyboard',) def __init__(self, inline_keyboard: List[List[InlineKeyboardButton]], **_kwargs: Any): # Required diff --git a/telegram/inline/inlinequery.py b/telegram/inline/inlinequery.py index 12301512b..777cf81f1 100644 --- a/telegram/inline/inlinequery.py +++ b/telegram/inline/inlinequery.py @@ -71,7 +71,7 @@ class InlineQuery(TelegramObject): """ - __slots__ = ('bot', 'location', 'chat_type', 'id', 'offset', 'from_user', 'query', '_id_attrs') + __slots__ = ('bot', 'location', 'chat_type', 'id', 'offset', 'from_user', 'query') def __init__( self, diff --git a/telegram/inline/inlinequeryresult.py b/telegram/inline/inlinequeryresult.py index f3227d485..9566f707a 100644 --- a/telegram/inline/inlinequeryresult.py +++ b/telegram/inline/inlinequeryresult.py @@ -46,7 +46,7 @@ class InlineQueryResult(TelegramObject): """ - __slots__ = ('type', 'id', '_id_attrs') + __slots__ = ('type', 'id') def __init__(self, type: str, id: str, **_kwargs: Any): # Required diff --git a/telegram/inline/inputcontactmessagecontent.py b/telegram/inline/inputcontactmessagecontent.py index fe7b9d7dd..3d3a9d414 100644 --- a/telegram/inline/inputcontactmessagecontent.py +++ b/telegram/inline/inputcontactmessagecontent.py @@ -46,7 +46,7 @@ class InputContactMessageContent(InputMessageContent): """ - __slots__ = ('vcard', 'first_name', 'last_name', 'phone_number', '_id_attrs') + __slots__ = ('vcard', 'first_name', 'last_name', 'phone_number') def __init__( self, diff --git a/telegram/inline/inputinvoicemessagecontent.py b/telegram/inline/inputinvoicemessagecontent.py index 622f0ed36..a53abb306 100644 --- a/telegram/inline/inputinvoicemessagecontent.py +++ b/telegram/inline/inputinvoicemessagecontent.py @@ -144,7 +144,6 @@ class InputInvoiceMessageContent(InputMessageContent): 'send_phone_number_to_provider', 'send_email_to_provider', 'is_flexible', - '_id_attrs', ) def __init__( diff --git a/telegram/inline/inputlocationmessagecontent.py b/telegram/inline/inputlocationmessagecontent.py index 22760bfb3..e376227e4 100644 --- a/telegram/inline/inputlocationmessagecontent.py +++ b/telegram/inline/inputlocationmessagecontent.py @@ -60,7 +60,7 @@ class InputLocationMessageContent(InputMessageContent): """ __slots__ = ('longitude', 'horizontal_accuracy', 'proximity_alert_radius', 'live_period', - 'latitude', 'heading', '_id_attrs') + 'latitude', 'heading') # fmt: on def __init__( diff --git a/telegram/inline/inputtextmessagecontent.py b/telegram/inline/inputtextmessagecontent.py index c068aa77d..0be79137e 100644 --- a/telegram/inline/inputtextmessagecontent.py +++ b/telegram/inline/inputtextmessagecontent.py @@ -59,7 +59,7 @@ class InputTextMessageContent(InputMessageContent): """ - __slots__ = ('disable_web_page_preview', 'parse_mode', 'entities', 'message_text', '_id_attrs') + __slots__ = ('disable_web_page_preview', 'parse_mode', 'entities', 'message_text') def __init__( self, diff --git a/telegram/inline/inputvenuemessagecontent.py b/telegram/inline/inputvenuemessagecontent.py index c13107d5b..d26b07a31 100644 --- a/telegram/inline/inputvenuemessagecontent.py +++ b/telegram/inline/inputvenuemessagecontent.py @@ -69,7 +69,6 @@ class InputVenueMessageContent(InputMessageContent): 'foursquare_type', 'google_place_id', 'latitude', - '_id_attrs', ) def __init__( diff --git a/telegram/keyboardbutton.py b/telegram/keyboardbutton.py index fe2bd8704..1cc792f95 100644 --- a/telegram/keyboardbutton.py +++ b/telegram/keyboardbutton.py @@ -58,7 +58,7 @@ class KeyboardButton(TelegramObject): """ - __slots__ = ('request_location', 'request_contact', 'request_poll', 'text', '_id_attrs') + __slots__ = ('request_location', 'request_contact', 'request_poll', 'text') def __init__( self, diff --git a/telegram/keyboardbuttonpolltype.py b/telegram/keyboardbuttonpolltype.py index 813ce97a1..ca6c503ae 100644 --- a/telegram/keyboardbuttonpolltype.py +++ b/telegram/keyboardbuttonpolltype.py @@ -37,7 +37,7 @@ class KeyboardButtonPollType(TelegramObject): create a poll of any type. """ - __slots__ = ('type', '_id_attrs') + __slots__ = ('type',) def __init__(self, type: str = None, **_kwargs: Any): # pylint: disable=W0622 self.type = type diff --git a/telegram/loginurl.py b/telegram/loginurl.py index 7d6dc561e..d014f2674 100644 --- a/telegram/loginurl.py +++ b/telegram/loginurl.py @@ -69,7 +69,7 @@ class LoginUrl(TelegramObject): """ - __slots__ = ('bot_username', 'request_write_access', 'url', 'forward_text', '_id_attrs') + __slots__ = ('bot_username', 'request_write_access', 'url', 'forward_text') def __init__( self, diff --git a/telegram/message.py b/telegram/message.py index 74d750f28..b890ca81b 100644 --- a/telegram/message.py +++ b/telegram/message.py @@ -412,7 +412,6 @@ class Message(TelegramObject): 'voice_chat_scheduled', 'is_automatic_forward', 'has_protected_content', - '_id_attrs', ) ATTACHMENT_TYPES: ClassVar[List[str]] = [ diff --git a/telegram/messageautodeletetimerchanged.py b/telegram/messageautodeletetimerchanged.py index 21af1fb8e..5bafd4b65 100644 --- a/telegram/messageautodeletetimerchanged.py +++ b/telegram/messageautodeletetimerchanged.py @@ -44,7 +44,7 @@ class MessageAutoDeleteTimerChanged(TelegramObject): """ - __slots__ = ('message_auto_delete_time', '_id_attrs') + __slots__ = ('message_auto_delete_time',) def __init__( self, diff --git a/telegram/messageentity.py b/telegram/messageentity.py index d4e162044..b96a2726d 100644 --- a/telegram/messageentity.py +++ b/telegram/messageentity.py @@ -60,7 +60,7 @@ class MessageEntity(TelegramObject): """ - __slots__ = ('length', 'url', 'user', 'type', 'language', 'offset', '_id_attrs') + __slots__ = ('length', 'url', 'user', 'type', 'language', 'offset') def __init__( self, diff --git a/telegram/messageid.py b/telegram/messageid.py index df7f47c3d..cbe7082a5 100644 --- a/telegram/messageid.py +++ b/telegram/messageid.py @@ -32,7 +32,7 @@ class MessageId(TelegramObject): message_id (:obj:`int`): Unique message identifier """ - __slots__ = ('message_id', '_id_attrs') + __slots__ = ('message_id',) def __init__(self, message_id: int, **_kwargs: Any): self.message_id = int(message_id) diff --git a/telegram/parsemode.py b/telegram/parsemode.py index 38cf051fd..1047a0a01 100644 --- a/telegram/parsemode.py +++ b/telegram/parsemode.py @@ -21,13 +21,12 @@ from typing import ClassVar from telegram import constants -from telegram.utils.deprecate import set_new_attribute_deprecated class ParseMode: """This object represents a Telegram Message Parse Modes.""" - __slots__ = ('__dict__',) + __slots__ = () MARKDOWN: ClassVar[str] = constants.PARSEMODE_MARKDOWN """:const:`telegram.constants.PARSEMODE_MARKDOWN`\n @@ -40,6 +39,3 @@ class ParseMode: """:const:`telegram.constants.PARSEMODE_MARKDOWN_V2`""" HTML: ClassVar[str] = constants.PARSEMODE_HTML """:const:`telegram.constants.PARSEMODE_HTML`""" - - def __setattr__(self, key: str, value: object) -> None: - set_new_attribute_deprecated(self, key, value) diff --git a/telegram/passport/credentials.py b/telegram/passport/credentials.py index 94c602384..6b28a70fa 100644 --- a/telegram/passport/credentials.py +++ b/telegram/passport/credentials.py @@ -137,7 +137,6 @@ class EncryptedCredentials(TelegramObject): 'secret', 'bot', 'data', - '_id_attrs', '_decrypted_secret', '_decrypted_data', ) diff --git a/telegram/passport/encryptedpassportelement.py b/telegram/passport/encryptedpassportelement.py index 78b69720c..43e8e485f 100644 --- a/telegram/passport/encryptedpassportelement.py +++ b/telegram/passport/encryptedpassportelement.py @@ -130,7 +130,6 @@ class EncryptedPassportElement(TelegramObject): 'reverse_side', 'front_side', 'data', - '_id_attrs', ) def __init__( diff --git a/telegram/passport/passportdata.py b/telegram/passport/passportdata.py index 9d9595bad..80cf768e3 100644 --- a/telegram/passport/passportdata.py +++ b/telegram/passport/passportdata.py @@ -51,7 +51,7 @@ class PassportData(TelegramObject): """ - __slots__ = ('bot', 'credentials', 'data', '_decrypted_data', '_id_attrs') + __slots__ = ('bot', 'credentials', 'data', '_decrypted_data') def __init__( self, diff --git a/telegram/passport/passportelementerrors.py b/telegram/passport/passportelementerrors.py index fd38ff369..c03d06416 100644 --- a/telegram/passport/passportelementerrors.py +++ b/telegram/passport/passportelementerrors.py @@ -46,7 +46,7 @@ class PassportElementError(TelegramObject): """ # All subclasses of this class won't have _id_attrs in slots since it's added here. - __slots__ = ('message', 'source', 'type', '_id_attrs') + __slots__ = ('message', 'source', 'type') def __init__(self, source: str, type: str, message: str, **_kwargs: Any): # Required diff --git a/telegram/passport/passportfile.py b/telegram/passport/passportfile.py index 59f60c8e4..abfd76189 100644 --- a/telegram/passport/passportfile.py +++ b/telegram/passport/passportfile.py @@ -65,7 +65,6 @@ class PassportFile(TelegramObject): 'file_size', '_credentials', 'file_unique_id', - '_id_attrs', ) def __init__( diff --git a/telegram/payment/invoice.py b/telegram/payment/invoice.py index 18fda43a2..3032c2c76 100644 --- a/telegram/payment/invoice.py +++ b/telegram/payment/invoice.py @@ -59,7 +59,6 @@ class Invoice(TelegramObject): 'title', 'description', 'total_amount', - '_id_attrs', ) def __init__( diff --git a/telegram/payment/labeledprice.py b/telegram/payment/labeledprice.py index 37b58e304..cbba92e6c 100644 --- a/telegram/payment/labeledprice.py +++ b/telegram/payment/labeledprice.py @@ -45,7 +45,7 @@ class LabeledPrice(TelegramObject): """ - __slots__ = ('label', '_id_attrs', 'amount') + __slots__ = ('label', 'amount') def __init__(self, label: str, amount: int, **_kwargs: Any): self.label = label diff --git a/telegram/payment/orderinfo.py b/telegram/payment/orderinfo.py index 902b324d0..c222a216e 100644 --- a/telegram/payment/orderinfo.py +++ b/telegram/payment/orderinfo.py @@ -49,7 +49,7 @@ class OrderInfo(TelegramObject): """ - __slots__ = ('email', 'shipping_address', 'phone_number', 'name', '_id_attrs') + __slots__ = ('email', 'shipping_address', 'phone_number', 'name') def __init__( self, diff --git a/telegram/payment/precheckoutquery.py b/telegram/payment/precheckoutquery.py index 65b5e3004..9c62b5c82 100644 --- a/telegram/payment/precheckoutquery.py +++ b/telegram/payment/precheckoutquery.py @@ -76,7 +76,6 @@ class PreCheckoutQuery(TelegramObject): 'total_amount', 'id', 'from_user', - '_id_attrs', ) def __init__( diff --git a/telegram/payment/shippingaddress.py b/telegram/payment/shippingaddress.py index ae16d9fdc..b1d20615f 100644 --- a/telegram/payment/shippingaddress.py +++ b/telegram/payment/shippingaddress.py @@ -52,7 +52,6 @@ class ShippingAddress(TelegramObject): __slots__ = ( 'post_code', 'city', - '_id_attrs', 'country_code', 'street_line2', 'street_line1', diff --git a/telegram/payment/shippingoption.py b/telegram/payment/shippingoption.py index 5bca48a37..b0a9ccef5 100644 --- a/telegram/payment/shippingoption.py +++ b/telegram/payment/shippingoption.py @@ -46,7 +46,7 @@ class ShippingOption(TelegramObject): """ - __slots__ = ('prices', 'title', 'id', '_id_attrs') + __slots__ = ('prices', 'title', 'id') def __init__( self, diff --git a/telegram/payment/shippingquery.py b/telegram/payment/shippingquery.py index 2a0d1403a..fd92a902b 100644 --- a/telegram/payment/shippingquery.py +++ b/telegram/payment/shippingquery.py @@ -54,7 +54,7 @@ class ShippingQuery(TelegramObject): """ - __slots__ = ('bot', 'invoice_payload', 'shipping_address', 'id', 'from_user', '_id_attrs') + __slots__ = ('bot', 'invoice_payload', 'shipping_address', 'id', 'from_user') def __init__( self, diff --git a/telegram/payment/successfulpayment.py b/telegram/payment/successfulpayment.py index 7240fb8e5..f76e12f97 100644 --- a/telegram/payment/successfulpayment.py +++ b/telegram/payment/successfulpayment.py @@ -70,7 +70,6 @@ class SuccessfulPayment(TelegramObject): 'telegram_payment_charge_id', 'provider_payment_charge_id', 'total_amount', - '_id_attrs', ) def __init__( diff --git a/telegram/poll.py b/telegram/poll.py index a7c51b2f6..781358484 100644 --- a/telegram/poll.py +++ b/telegram/poll.py @@ -48,7 +48,7 @@ class PollOption(TelegramObject): """ - __slots__ = ('voter_count', 'text', '_id_attrs') + __slots__ = ('voter_count', 'text') def __init__(self, text: str, voter_count: int, **_kwargs: Any): self.text = text @@ -80,7 +80,7 @@ class PollAnswer(TelegramObject): """ - __slots__ = ('option_ids', 'user', 'poll_id', '_id_attrs') + __slots__ = ('option_ids', 'user', 'poll_id') def __init__(self, poll_id: str, user: User, option_ids: List[int], **_kwargs: Any): self.poll_id = poll_id @@ -164,7 +164,6 @@ class Poll(TelegramObject): 'explanation', 'question', 'correct_option_id', - '_id_attrs', ) def __init__( diff --git a/telegram/proximityalerttriggered.py b/telegram/proximityalerttriggered.py index df4cb557f..4423819b4 100644 --- a/telegram/proximityalerttriggered.py +++ b/telegram/proximityalerttriggered.py @@ -46,7 +46,7 @@ class ProximityAlertTriggered(TelegramObject): """ - __slots__ = ('traveler', 'distance', 'watcher', '_id_attrs') + __slots__ = ('traveler', 'distance', 'watcher') def __init__(self, traveler: User, watcher: User, distance: int, **_kwargs: Any): self.traveler = traveler diff --git a/telegram/replykeyboardmarkup.py b/telegram/replykeyboardmarkup.py index cc6f98590..9895d9874 100644 --- a/telegram/replykeyboardmarkup.py +++ b/telegram/replykeyboardmarkup.py @@ -81,7 +81,6 @@ class ReplyKeyboardMarkup(ReplyMarkup): 'resize_keyboard', 'one_time_keyboard', 'input_field_placeholder', - '_id_attrs', ) def __init__( diff --git a/telegram/update.py b/telegram/update.py index 7c7b21039..483b7ec86 100644 --- a/telegram/update.py +++ b/telegram/update.py @@ -156,7 +156,6 @@ class Update(TelegramObject): 'my_chat_member', 'chat_member', 'chat_join_request', - '_id_attrs', ) MESSAGE = constants.UPDATE_MESSAGE diff --git a/telegram/user.py b/telegram/user.py index 0a50895d0..395ff0b59 100644 --- a/telegram/user.py +++ b/telegram/user.py @@ -108,7 +108,6 @@ class User(TelegramObject): 'id', 'bot', 'language_code', - '_id_attrs', ) def __init__( diff --git a/telegram/userprofilephotos.py b/telegram/userprofilephotos.py index aa3e6ec74..0d157391e 100644 --- a/telegram/userprofilephotos.py +++ b/telegram/userprofilephotos.py @@ -44,7 +44,7 @@ class UserProfilePhotos(TelegramObject): """ - __slots__ = ('photos', 'total_count', '_id_attrs') + __slots__ = ('photos', 'total_count') def __init__(self, total_count: int, photos: List[List[PhotoSize]], **_kwargs: Any): # Required diff --git a/telegram/utils/deprecate.py b/telegram/utils/deprecate.py index bc9f5199b..d08a9ec75 100644 --- a/telegram/utils/deprecate.py +++ b/telegram/utils/deprecate.py @@ -16,9 +16,7 @@ # # 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 facilitates the deprecation of functions.""" - -import warnings +"""This module contains a class which is used for deprecation warnings.""" # We use our own DeprecationWarning since they are muted by default and "UserWarning" makes it @@ -28,20 +26,3 @@ class TelegramDeprecationWarning(Warning): """Custom warning class for deprecations in this library.""" __slots__ = () - - -# Function to warn users that setting custom attributes is deprecated (Use only in __setattr__!) -# Checks if a custom attribute is added by checking length of dictionary before & after -# assigning attribute. This is the fastest way to do it (I hope!). -def set_new_attribute_deprecated(self: object, key: str, value: object) -> None: - """Warns the user if they set custom attributes on PTB objects.""" - org = len(self.__dict__) - object.__setattr__(self, key, value) - new = len(self.__dict__) - if new > org: - warnings.warn( - f"Setting custom attributes such as {key!r} on objects such as " - f"{self.__class__.__name__!r} of the PTB library is deprecated.", - TelegramDeprecationWarning, - stacklevel=3, - ) diff --git a/telegram/utils/helpers.py b/telegram/utils/helpers.py index 194a46175..331b45c98 100644 --- a/telegram/utils/helpers.py +++ b/telegram/utils/helpers.py @@ -544,7 +544,7 @@ class DefaultValue(Generic[DVType]): """ - __slots__ = ('value', '__dict__') + __slots__ = ('value',) def __init__(self, value: DVType = None): self.value = value diff --git a/telegram/utils/request.py b/telegram/utils/request.py index 4b8de7b4e..4283265ed 100644 --- a/telegram/utils/request.py +++ b/telegram/utils/request.py @@ -70,7 +70,6 @@ from telegram.error import ( Unauthorized, ) from telegram.utils.types import JSONDict -from telegram.utils.deprecate import set_new_attribute_deprecated def _render_part(self: RequestField, name: str, value: str) -> str: # pylint: disable=W0613 @@ -112,7 +111,7 @@ class Request: """ - __slots__ = ('_connect_timeout', '_con_pool_size', '_con_pool', '__dict__') + __slots__ = ('_connect_timeout', '_con_pool_size', '_con_pool') def __init__( self, @@ -192,9 +191,6 @@ class Request: self._con_pool = mgr - def __setattr__(self, key: str, value: object) -> None: - set_new_attribute_deprecated(self, key, value) - @property def con_pool_size(self) -> int: """The size of the connection pool used.""" diff --git a/telegram/voicechat.py b/telegram/voicechat.py index 1430f5d2c..f2c439fac 100644 --- a/telegram/voicechat.py +++ b/telegram/voicechat.py @@ -64,7 +64,7 @@ class VoiceChatEnded(TelegramObject): """ - __slots__ = ('duration', '_id_attrs') + __slots__ = ('duration',) def __init__(self, duration: int, **_kwargs: Any) -> None: self.duration = int(duration) if duration is not None else None @@ -93,7 +93,7 @@ class VoiceChatParticipantsInvited(TelegramObject): """ - __slots__ = ('users', '_id_attrs') + __slots__ = ('users',) def __init__(self, users: List[User], **_kwargs: Any) -> None: self.users = users @@ -140,7 +140,7 @@ class VoiceChatScheduled(TelegramObject): """ - __slots__ = ('start_date', '_id_attrs') + __slots__ = ('start_date',) def __init__(self, start_date: dtm.datetime, **_kwargs: Any) -> None: self.start_date = start_date diff --git a/telegram/webhookinfo.py b/telegram/webhookinfo.py index 1611d6c20..21859a777 100644 --- a/telegram/webhookinfo.py +++ b/telegram/webhookinfo.py @@ -71,7 +71,6 @@ class WebhookInfo(TelegramObject): 'last_error_message', 'pending_update_count', 'has_custom_certificate', - '_id_attrs', ) def __init__( diff --git a/tests/conftest.py b/tests/conftest.py index 641430b56..255f6b764 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -44,6 +44,7 @@ from telegram import ( ChosenInlineResult, File, ChatPermissions, + Bot, ) from telegram.ext import ( Dispatcher, @@ -56,6 +57,7 @@ from telegram.ext import ( ) from telegram.error import BadRequest from telegram.utils.helpers import DefaultValue, DEFAULT_NONE +from telegram.utils.request import Request from tests.bots import get_bot @@ -89,14 +91,22 @@ def bot_info(): return get_bot() +# Below Dict* classes are used to monkeypatch attributes since parent classes don't have __dict__ +class DictRequest(Request): + pass + + +class DictExtBot(ExtBot): + pass + + +class DictBot(Bot): + pass + + @pytest.fixture(scope='session') def bot(bot_info): - class DictExtBot( - ExtBot - ): # Subclass Bot to allow monkey patching of attributes and functions, would - pass # come into effect when we __dict__ is dropped from slots - - return DictExtBot(bot_info['token'], private_key=PRIVATE_KEY) + return DictExtBot(bot_info['token'], private_key=PRIVATE_KEY, request=DictRequest()) DEFAULT_BOTS = {} @@ -230,7 +240,7 @@ def make_bot(bot_info, **kwargs): """ Tests are executed on tg.ext.ExtBot, as that class only extends the functionality of tg.bot """ - return ExtBot(bot_info['token'], private_key=PRIVATE_KEY, **kwargs) + return ExtBot(bot_info['token'], private_key=PRIVATE_KEY, request=DictRequest(), **kwargs) CMD_PATTERN = re.compile(r'/[\da-z_]{1,32}(?:@\w{1,32})?') @@ -361,9 +371,9 @@ def mro_slots(): return [ attr for cls in _class.__class__.__mro__[:-1] - if hasattr(cls, '__slots__') # ABC doesn't have slots in py 3.7 and below + if hasattr(cls, '__slots__') # The Exception class doesn't have slots for attr in cls.__slots__ - if attr != '__dict__' + if attr != '__dict__' # left here for classes which still has __dict__ ] return _mro_slots diff --git a/tests/test_animation.py b/tests/test_animation.py index ef046b862..c90a0ba24 100644 --- a/tests/test_animation.py +++ b/tests/test_animation.py @@ -57,13 +57,10 @@ class TestAnimation: file_size = 4127 caption = "Test *animation*" - def test_slot_behaviour(self, animation, recwarn, mro_slots): + def test_slot_behaviour(self, animation, mro_slots): for attr in animation.__slots__: assert getattr(animation, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not animation.__dict__, f"got missing slot(s): {animation.__dict__}" assert len(mro_slots(animation)) == len(set(mro_slots(animation))), "duplicate slot" - animation.custom, animation.file_name = 'should give warning', self.file_name - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_creation(self, animation): assert isinstance(animation, Animation) diff --git a/tests/test_audio.py b/tests/test_audio.py index e42974455..fa68f04d3 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -59,13 +59,10 @@ class TestAudio: audio_file_id = '5a3128a4d2a04750b5b58397f3b5e812' audio_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e' - def test_slot_behaviour(self, audio, recwarn, mro_slots): + def test_slot_behaviour(self, audio, mro_slots): for attr in audio.__slots__: assert getattr(audio, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not audio.__dict__, f"got missing slot(s): {audio.__dict__}" assert len(mro_slots(audio)) == len(set(mro_slots(audio))), "duplicate slot" - audio.custom, audio.file_name = 'should give warning', self.file_name - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_creation(self, audio): # Make sure file has been uploaded. diff --git a/tests/test_bot.py b/tests/test_bot.py index ceb371b45..6aff16609 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -145,20 +145,10 @@ class TestBot: """ @pytest.mark.parametrize('inst', ['bot', "default_bot"], indirect=True) - def test_slot_behaviour(self, inst, recwarn, mro_slots): + def test_slot_behaviour(self, inst, mro_slots): for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slots: {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.base_url = 'should give warning', inst.base_url - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list - - class CustomBot(Bot): - pass # Tests that setting custom attributes of Bot subclass doesn't raise warning - - a = CustomBot(inst.token) - a.my_custom = 'no error!' - assert len(recwarn) == 1 @pytest.mark.parametrize( 'token', diff --git a/tests/test_botcommand.py b/tests/test_botcommand.py index a92f492c8..b413a9dd2 100644 --- a/tests/test_botcommand.py +++ b/tests/test_botcommand.py @@ -31,13 +31,10 @@ class TestBotCommand: command = 'start' description = 'A command' - def test_slot_behaviour(self, bot_command, recwarn, mro_slots): + def test_slot_behaviour(self, bot_command, mro_slots): for attr in bot_command.__slots__: assert getattr(bot_command, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not bot_command.__dict__, f"got missing slot(s): {bot_command.__dict__}" assert len(mro_slots(bot_command)) == len(set(mro_slots(bot_command))), "duplicate slot" - bot_command.custom, bot_command.command = 'should give warning', self.command - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = {'command': self.command, 'description': self.description} diff --git a/tests/test_botcommandscope.py b/tests/test_botcommandscope.py index 6a6e07b02..4275cba77 100644 --- a/tests/test_botcommandscope.py +++ b/tests/test_botcommandscope.py @@ -113,15 +113,12 @@ def bot_command_scope(scope_class_and_type, chat_id): # All the scope types are very similar, so we test everything via parametrization class TestBotCommandScope: - def test_slot_behaviour(self, bot_command_scope, mro_slots, recwarn): + def test_slot_behaviour(self, bot_command_scope, mro_slots): for attr in bot_command_scope.__slots__: assert getattr(bot_command_scope, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not bot_command_scope.__dict__, f"got missing slot(s): {bot_command_scope.__dict__}" assert len(mro_slots(bot_command_scope)) == len( set(mro_slots(bot_command_scope)) ), "duplicate slot" - bot_command_scope.custom, bot_command_scope.type = 'warning!', bot_command_scope.type - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot, scope_class_and_type, chat_id): cls = scope_class_and_type[0] diff --git a/tests/test_callbackcontext.py b/tests/test_callbackcontext.py index c6e230718..e5de5f6d2 100644 --- a/tests/test_callbackcontext.py +++ b/tests/test_callbackcontext.py @@ -38,7 +38,7 @@ CallbackContext.refresh_data is tested in TestBasePersistence class TestCallbackContext: - def test_slot_behaviour(self, cdp, recwarn, mro_slots): + def test_slot_behaviour(self, cdp, mro_slots, recwarn): c = CallbackContext(cdp) for attr in c.__slots__: assert getattr(c, attr, 'err') != 'err', f"got extra slot '{attr}'" diff --git a/tests/test_callbackdatacache.py b/tests/test_callbackdatacache.py index ac08f81c1..bcc1b4ce1 100644 --- a/tests/test_callbackdatacache.py +++ b/tests/test_callbackdatacache.py @@ -38,15 +38,13 @@ def callback_data_cache(bot): class TestInvalidCallbackData: - def test_slot_behaviour(self, mro_slots, recwarn): + def test_slot_behaviour(self, mro_slots): invalid_callback_data = InvalidCallbackData() for attr in invalid_callback_data.__slots__: assert getattr(invalid_callback_data, attr, 'err') != 'err', f"got extra slot '{attr}'" assert len(mro_slots(invalid_callback_data)) == len( set(mro_slots(invalid_callback_data)) ), "duplicate slot" - with pytest.raises(AttributeError): - invalid_callback_data.custom class TestKeyboardData: @@ -57,8 +55,6 @@ class TestKeyboardData: assert len(mro_slots(keyboard_data)) == len( set(mro_slots(keyboard_data)) ), "duplicate slot" - with pytest.raises(AttributeError): - keyboard_data.custom = 42 class TestCallbackDataCache: @@ -73,8 +69,6 @@ class TestCallbackDataCache: assert len(mro_slots(callback_data_cache)) == len( set(mro_slots(callback_data_cache)) ), "duplicate slot" - with pytest.raises(AttributeError): - callback_data_cache.custom = 42 @pytest.mark.parametrize('maxsize', [1, 5, 2048]) def test_init_maxsize(self, maxsize, bot): diff --git a/tests/test_callbackquery.py b/tests/test_callbackquery.py index 0305e0251..9e196a73a 100644 --- a/tests/test_callbackquery.py +++ b/tests/test_callbackquery.py @@ -50,13 +50,10 @@ class TestCallbackQuery: inline_message_id = 'inline_message_id' game_short_name = 'the_game' - def test_slot_behaviour(self, callback_query, recwarn, mro_slots): + def test_slot_behaviour(self, callback_query, mro_slots): for attr in callback_query.__slots__: assert getattr(callback_query, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not callback_query.__dict__, f"got missing slot(s): {callback_query.__dict__}" assert len(mro_slots(callback_query)) == len(set(mro_slots(callback_query))), "same slot" - callback_query.custom, callback_query.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @staticmethod def skip_params(callback_query: CallbackQuery): diff --git a/tests/test_callbackqueryhandler.py b/tests/test_callbackqueryhandler.py index 0f1c7e666..49964a639 100644 --- a/tests/test_callbackqueryhandler.py +++ b/tests/test_callbackqueryhandler.py @@ -72,14 +72,11 @@ def callback_query(bot): class TestCallbackQueryHandler: test_flag = False - def test_slot_behaviour(self, recwarn, mro_slots): - handler = CallbackQueryHandler(self.callback_data_1, pass_user_data=True) + def test_slot_behaviour(self, mro_slots): + handler = CallbackQueryHandler(self.callback_data_1) for attr in handler.__slots__: assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not handler.__dict__, f"got missing slot(s): {handler.__dict__}" assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot" - handler.custom, handler.callback = 'should give warning', self.callback_basic - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_chat.py b/tests/test_chat.py index 220342261..e59aa01b8 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -67,13 +67,10 @@ class TestChat: has_protected_content = True has_private_forwards = True - def test_slot_behaviour(self, chat, recwarn, mro_slots): + def test_slot_behaviour(self, chat, mro_slots): for attr in chat.__slots__: assert getattr(chat, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not chat.__dict__, f"got missing slot(s): {chat.__dict__}" assert len(mro_slots(chat)) == len(set(mro_slots(chat))), "duplicate slot" - chat.custom, chat.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = { diff --git a/tests/test_chataction.py b/tests/test_chataction.py index b081549d0..c894aa2b0 100644 --- a/tests/test_chataction.py +++ b/tests/test_chataction.py @@ -19,11 +19,8 @@ from telegram import ChatAction -def test_slot_behaviour(recwarn, mro_slots): +def test_slot_behaviour(mro_slots): action = ChatAction() for attr in action.__slots__: assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not action.__dict__, f"got missing slot(s): {action.__dict__}" assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot" - action.custom = 'should give warning' - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list diff --git a/tests/test_chatinvitelink.py b/tests/test_chatinvitelink.py index 9201a56d5..0fb549a0d 100644 --- a/tests/test_chatinvitelink.py +++ b/tests/test_chatinvitelink.py @@ -53,13 +53,10 @@ class TestChatInviteLink: name = 'LinkName' pending_join_request_count = 42 - def test_slot_behaviour(self, recwarn, mro_slots, invite_link): + def test_slot_behaviour(self, mro_slots, invite_link): for attr in invite_link.__slots__: assert getattr(invite_link, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not invite_link.__dict__, f"got missing slot(s): {invite_link.__dict__}" assert len(mro_slots(invite_link)) == len(set(mro_slots(invite_link))), "duplicate slot" - invite_link.custom = 'should give warning' - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json_required_args(self, bot, creator): json_dict = { diff --git a/tests/test_chatjoinrequest.py b/tests/test_chatjoinrequest.py index b98d12e72..b64ed6987 100644 --- a/tests/test_chatjoinrequest.py +++ b/tests/test_chatjoinrequest.py @@ -59,10 +59,7 @@ class TestChatJoinRequest: inst = chat_join_request for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.bio = 'should give warning', self.bio - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot, time): json_dict = { diff --git a/tests/test_chatjoinrequesthandler.py b/tests/test_chatjoinrequesthandler.py index 00c7a5f84..7266356f9 100644 --- a/tests/test_chatjoinrequesthandler.py +++ b/tests/test_chatjoinrequesthandler.py @@ -105,10 +105,7 @@ class TestChatJoinRequestHandler: action = ChatJoinRequestHandler(self.callback_basic) for attr in action.__slots__: assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not action.__dict__, f"got missing slot(s): {action.__dict__}" assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot" - action.custom = 'should give warning' - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_chatlocation.py b/tests/test_chatlocation.py index 07fbad494..cd4864361 100644 --- a/tests/test_chatlocation.py +++ b/tests/test_chatlocation.py @@ -31,14 +31,11 @@ class TestChatLocation: location = Location(123, 456) address = 'The Shire' - def test_slot_behaviour(self, chat_location, recwarn, mro_slots): + def test_slot_behaviour(self, chat_location, mro_slots): inst = chat_location for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.address = 'should give warning', self.address - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = { diff --git a/tests/test_chatmember.py b/tests/test_chatmember.py index f4a4e6068..c38bda4df 100644 --- a/tests/test_chatmember.py +++ b/tests/test_chatmember.py @@ -69,15 +69,12 @@ def chat_member_types(chat_member_class_and_status, user): class TestChatMember: - def test_slot_behaviour(self, chat_member_types, mro_slots, recwarn): + def test_slot_behaviour(self, chat_member_types, mro_slots): for attr in chat_member_types.__slots__: assert getattr(chat_member_types, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not chat_member_types.__dict__, f"got missing slot(s): {chat_member_types.__dict__}" assert len(mro_slots(chat_member_types)) == len( set(mro_slots(chat_member_types)) ), "duplicate slot" - chat_member_types.custom, chat_member_types.status = 'warning!', chat_member_types.status - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json_required_args(self, bot, chat_member_class_and_status, user): cls = chat_member_class_and_status[0] diff --git a/tests/test_chatmemberhandler.py b/tests/test_chatmemberhandler.py index 003dbd3cb..29d76e4bf 100644 --- a/tests/test_chatmemberhandler.py +++ b/tests/test_chatmemberhandler.py @@ -88,14 +88,11 @@ def chat_member(bot, chat_member_updated): class TestChatMemberHandler: test_flag = False - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): action = ChatMemberHandler(self.callback_basic) for attr in action.__slots__: assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not action.__dict__, f"got missing slot(s): {action.__dict__}" assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot" - action.custom = 'should give warning' - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_chatmemberupdated.py b/tests/test_chatmemberupdated.py index c72894a89..2d201e8dc 100644 --- a/tests/test_chatmemberupdated.py +++ b/tests/test_chatmemberupdated.py @@ -65,14 +65,11 @@ class TestChatMemberUpdated: old_status = ChatMember.MEMBER new_status = ChatMember.ADMINISTRATOR - def test_slot_behaviour(self, recwarn, mro_slots, chat_member_updated): + def test_slot_behaviour(self, mro_slots, chat_member_updated): action = chat_member_updated for attr in action.__slots__: assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not action.__dict__, f"got missing slot(s): {action.__dict__}" assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot" - action.custom = 'should give warning' - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json_required_args(self, bot, user, chat, old_chat_member, new_chat_member, time): json_dict = { diff --git a/tests/test_chatpermissions.py b/tests/test_chatpermissions.py index 9a9273748..353c752b7 100644 --- a/tests/test_chatpermissions.py +++ b/tests/test_chatpermissions.py @@ -46,14 +46,11 @@ class TestChatPermissions: can_invite_users = None can_pin_messages = None - def test_slot_behaviour(self, chat_permissions, recwarn, mro_slots): + def test_slot_behaviour(self, chat_permissions, mro_slots): inst = chat_permissions for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.can_send_polls = 'should give warning', self.can_send_polls - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = { diff --git a/tests/test_chatphoto.py b/tests/test_chatphoto.py index c71cc0fa2..8cf1ff2df 100644 --- a/tests/test_chatphoto.py +++ b/tests/test_chatphoto.py @@ -51,13 +51,10 @@ class TestChatPhoto: chatphoto_big_file_unique_id = 'bigadc3145fd2e84d95b64d68eaa22aa33e' chatphoto_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.jpg' - def test_slot_behaviour(self, chat_photo, recwarn, mro_slots): + def test_slot_behaviour(self, chat_photo, mro_slots): for attr in chat_photo.__slots__: assert getattr(chat_photo, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not chat_photo.__dict__, f"got missing slot(s): {chat_photo.__dict__}" assert len(mro_slots(chat_photo)) == len(set(mro_slots(chat_photo))), "duplicate slot" - chat_photo.custom, chat_photo.big_file_id = 'gives warning', self.chatphoto_big_file_id - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @flaky(3, 1) def test_send_all_args(self, bot, super_group_id, chatphoto_file, chat_photo, thumb_file): diff --git a/tests/test_choseninlineresult.py b/tests/test_choseninlineresult.py index 8ef6b527a..13f1d5ff0 100644 --- a/tests/test_choseninlineresult.py +++ b/tests/test_choseninlineresult.py @@ -36,14 +36,11 @@ class TestChosenInlineResult: result_id = 'result id' query = 'query text' - def test_slot_behaviour(self, chosen_inline_result, recwarn, mro_slots): + def test_slot_behaviour(self, chosen_inline_result, mro_slots): inst = chosen_inline_result for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.result_id = 'should give warning', self.result_id - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json_required(self, bot, user): json_dict = {'result_id': self.result_id, 'from': user.to_dict(), 'query': self.query} diff --git a/tests/test_choseninlineresulthandler.py b/tests/test_choseninlineresulthandler.py index 395666305..6cebdaf05 100644 --- a/tests/test_choseninlineresulthandler.py +++ b/tests/test_choseninlineresulthandler.py @@ -81,14 +81,11 @@ class TestChosenInlineResultHandler: def reset(self): self.test_flag = False - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): handler = ChosenInlineResultHandler(self.callback_basic) for attr in handler.__slots__: assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not handler.__dict__, f"got missing slot(s): {handler.__dict__}" assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot" - handler.custom, handler.callback = 'should give warning', self.callback_basic - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def callback_basic(self, bot, update): test_bot = isinstance(bot, Bot) diff --git a/tests/test_commandhandler.py b/tests/test_commandhandler.py index 2e5aba44d..e14e611ff 100644 --- a/tests/test_commandhandler.py +++ b/tests/test_commandhandler.py @@ -142,14 +142,11 @@ class BaseTest: class TestCommandHandler(BaseTest): CMD = '/test' - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): handler = self.make_default_handler() for attr in handler.__slots__: assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not handler.__dict__, f"got missing slot(s): {handler.__dict__}" assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot" - handler.custom, handler.command = 'should give warning', self.CMD - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(scope='class') def command(self): @@ -305,14 +302,11 @@ class TestPrefixHandler(BaseTest): COMMANDS = ['help', 'test'] COMBINATIONS = list(combinations(PREFIXES, COMMANDS)) - def test_slot_behaviour(self, mro_slots, recwarn): + def test_slot_behaviour(self, mro_slots): handler = self.make_default_handler() for attr in handler.__slots__: assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not handler.__dict__, f"got missing slot(s): {handler.__dict__}" assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot" - handler.custom, handler.command = 'should give warning', self.COMMANDS - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(scope='class', params=PREFIXES) def prefix(self, request): diff --git a/tests/test_contact.py b/tests/test_contact.py index b4a00a4f3..91bed3000 100644 --- a/tests/test_contact.py +++ b/tests/test_contact.py @@ -40,13 +40,10 @@ class TestContact: last_name = 'Toledo' user_id = 23 - def test_slot_behaviour(self, contact, recwarn, mro_slots): + def test_slot_behaviour(self, contact, mro_slots): for attr in contact.__slots__: assert getattr(contact, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not contact.__dict__, f"got missing slot(s): {contact.__dict__}" assert len(mro_slots(contact)) == len(set(mro_slots(contact))), "duplicate slot" - contact.custom, contact.first_name = 'should give warning', self.first_name - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json_required(self, bot): json_dict = {'phone_number': self.phone_number, 'first_name': self.first_name} diff --git a/tests/test_contexttypes.py b/tests/test_contexttypes.py index ee9292d42..ee931df3b 100644 --- a/tests/test_contexttypes.py +++ b/tests/test_contexttypes.py @@ -31,8 +31,6 @@ class TestContextTypes: for attr in instance.__slots__: assert getattr(instance, attr, 'err') != 'err', f"got extra slot '{attr}'" assert len(mro_slots(instance)) == len(set(mro_slots(instance))), "duplicate slot" - with pytest.raises(AttributeError): - instance.custom def test_data_init(self): ct = ContextTypes(SubClass, int, float, bool) diff --git a/tests/test_conversationhandler.py b/tests/test_conversationhandler.py index 57bbd63a8..5e48757f8 100644 --- a/tests/test_conversationhandler.py +++ b/tests/test_conversationhandler.py @@ -94,16 +94,11 @@ class TestConversationHandler: raise_dp_handler_stop = False test_flag = False - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): handler = ConversationHandler(self.entry_points, self.states, self.fallbacks) for attr in handler.__slots__: assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not handler.__dict__, f"got missing slot(s): {handler.__dict__}" assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot" - handler.custom, handler._persistence = 'should give warning', handler._persistence - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), [ - w.message for w in recwarn.list - ] # Test related @pytest.fixture(autouse=True) @@ -833,6 +828,10 @@ class TestConversationHandler: def mocked_run_once(*a, **kw): raise Exception("job error") + class DictJB(JobQueue): + pass + + dp.job_queue = DictJB() monkeypatch.setattr(dp.job_queue, "run_once", mocked_run_once) handler = ConversationHandler( entry_points=self.entry_points, diff --git a/tests/test_defaults.py b/tests/test_defaults.py index 876ef5ce8..0b705e835 100644 --- a/tests/test_defaults.py +++ b/tests/test_defaults.py @@ -24,14 +24,11 @@ from telegram import User class TestDefault: - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): a = Defaults(parse_mode='HTML', quote=True) for attr in a.__slots__: assert getattr(a, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not a.__dict__, f"got missing slot(s): {a.__dict__}" assert len(mro_slots(a)) == len(set(mro_slots(a))), "duplicate slot" - a.custom, a._parse_mode = 'should give warning', a._parse_mode - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_data_assignment(self, cdp): defaults = Defaults() diff --git a/tests/test_dice.py b/tests/test_dice.py index 13b751dfc..362e474a4 100644 --- a/tests/test_dice.py +++ b/tests/test_dice.py @@ -30,13 +30,10 @@ def dice(request): class TestDice: value = 4 - def test_slot_behaviour(self, dice, recwarn, mro_slots): + def test_slot_behaviour(self, dice, mro_slots): for attr in dice.__slots__: assert getattr(dice, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not dice.__dict__, f"got missing slot(s): {dice.__dict__}" assert len(mro_slots(dice)) == len(set(mro_slots(dice))), "duplicate slot" - dice.custom, dice.value = 'should give warning', self.value - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.mark.parametrize('emoji', Dice.ALL_EMOJI) def test_de_json(self, bot, emoji): diff --git a/tests/test_dispatcher.py b/tests/test_dispatcher.py index 1507e82c2..f89534f13 100644 --- a/tests/test_dispatcher.py +++ b/tests/test_dispatcher.py @@ -58,24 +58,11 @@ class TestDispatcher: received = None count = 0 - def test_slot_behaviour(self, dp2, recwarn, mro_slots): + def test_slot_behaviour(self, dp2, mro_slots): for at in dp2.__slots__: at = f"_Dispatcher{at}" if at.startswith('__') and not at.endswith('__') else at assert getattr(dp2, at, 'err') != 'err', f"got extra slot '{at}'" - assert not dp2.__dict__, f"got missing slot(s): {dp2.__dict__}" assert len(mro_slots(dp2)) == len(set(mro_slots(dp2))), "duplicate slot" - dp2.custom, dp2.running = 'should give warning', dp2.running - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list - - class CustomDispatcher(Dispatcher): - pass # Tests that setting custom attrs of Dispatcher subclass doesn't raise warning - - a = CustomDispatcher(None, None) - a.my_custom = 'no error!' - assert len(recwarn) == 1 - - dp2.__setattr__('__test', 'mangled success') - assert getattr(dp2, '_Dispatcher__test', 'e') == 'mangled success', "mangling failed" @pytest.fixture(autouse=True, name='reset') def reset_fixture(self): diff --git a/tests/test_document.py b/tests/test_document.py index c4c41ca1f..689141b27 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -53,13 +53,10 @@ class TestDocument: document_file_id = '5a3128a4d2a04750b5b58397f3b5e812' document_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e' - def test_slot_behaviour(self, document, recwarn, mro_slots): + def test_slot_behaviour(self, document, mro_slots): for attr in document.__slots__: assert getattr(document, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not document.__dict__, f"got missing slot(s): {document.__dict__}" assert len(mro_slots(document)) == len(set(mro_slots(document))), "duplicate slot" - document.custom, document.file_name = 'should give warning', self.file_name - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), f"{recwarn}" def test_creation(self, document): assert isinstance(document, Document) diff --git a/tests/test_encryptedcredentials.py b/tests/test_encryptedcredentials.py index dc36b34cc..3f4f6a47b 100644 --- a/tests/test_encryptedcredentials.py +++ b/tests/test_encryptedcredentials.py @@ -36,14 +36,11 @@ class TestEncryptedCredentials: hash = 'hash' secret = 'secret' - def test_slot_behaviour(self, encrypted_credentials, recwarn, mro_slots): + def test_slot_behaviour(self, encrypted_credentials, mro_slots): inst = encrypted_credentials for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.data = 'should give warning', self.data - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, encrypted_credentials): assert encrypted_credentials.data == self.data diff --git a/tests/test_encryptedpassportelement.py b/tests/test_encryptedpassportelement.py index 911e1d696..6d6c2d7ba 100644 --- a/tests/test_encryptedpassportelement.py +++ b/tests/test_encryptedpassportelement.py @@ -46,14 +46,11 @@ class TestEncryptedPassportElement: reverse_side = PassportFile('file_id', 50, 0) selfie = PassportFile('file_id', 50, 0) - def test_slot_behaviour(self, encrypted_passport_element, recwarn, mro_slots): + def test_slot_behaviour(self, encrypted_passport_element, mro_slots): inst = encrypted_passport_element for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.phone_number = 'should give warning', self.phone_number - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, encrypted_passport_element): assert encrypted_passport_element.type == self.type_ diff --git a/tests/test_file.py b/tests/test_file.py index a43cd4cf7..5238a0d13 100644 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -57,13 +57,10 @@ class TestFile: file_size = 28232 file_content = 'Saint-Saëns'.encode() # Intentionally contains unicode chars. - def test_slot_behaviour(self, file, recwarn, mro_slots): + def test_slot_behaviour(self, file, mro_slots): for attr in file.__slots__: assert getattr(file, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not file.__dict__, f"got missing slot(s): {file.__dict__}" assert len(mro_slots(file)) == len(set(mro_slots(file))), "duplicate slot" - file.custom, file.file_id = 'should give warning', self.file_id - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = { diff --git a/tests/test_filters.py b/tests/test_filters.py index 32cb106ad..d72a47908 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -22,7 +22,7 @@ import pytest from telegram import Message, User, Chat, MessageEntity, Document, Update, Dice from telegram.ext import Filters, BaseFilter, MessageFilter, UpdateFilter -from sys import version_info as py_ver + import inspect import re @@ -61,7 +61,7 @@ def base_class(request): class TestFilters: - def test_all_filters_slot_behaviour(self, recwarn, mro_slots): + def test_all_filters_slot_behaviour(self, mro_slots): """ Use depth first search to get all nested filters, and instantiate them (which need it) with the correct number of arguments, then test each filter separately. Also tests setting @@ -100,17 +100,10 @@ class TestFilters: else: inst = cls() if args < 1 else cls(*['blah'] * args) # unpack variable no. of args + assert len(mro_slots(inst)) == len(set(mro_slots(inst))), f"same slot in {name}" + for attr in cls.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}' for {name}" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__} for {name}" - assert len(mro_slots(inst)) == len(set(mro_slots(inst))), f"same slot in {name}" - - with pytest.warns(TelegramDeprecationWarning, match='custom attributes') as warn: - inst.custom = 'should give warning' - if not warn: - pytest.fail(f"Filter {name!r} didn't warn when setting custom attr") - - assert '__dict__' not in BaseFilter.__slots__ if py_ver < (3, 7) else True, 'dict in abc' class CustomFilter(MessageFilter): def filter(self, message: Message): @@ -119,9 +112,6 @@ class TestFilters: with pytest.warns(None): CustomFilter().custom = 'allowed' # Test setting custom attr to custom filters - with pytest.warns(TelegramDeprecationWarning, match='custom attributes'): - Filters().custom = 'raise warning' - def test_filters_all(self, update): assert Filters.all(update) diff --git a/tests/test_forcereply.py b/tests/test_forcereply.py index 7fa605ba3..422c6f559 100644 --- a/tests/test_forcereply.py +++ b/tests/test_forcereply.py @@ -37,13 +37,10 @@ class TestForceReply: selective = True input_field_placeholder = 'force replies can be annoying if not used properly' - def test_slot_behaviour(self, force_reply, recwarn, mro_slots): + def test_slot_behaviour(self, force_reply, mro_slots): for attr in force_reply.__slots__: assert getattr(force_reply, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not force_reply.__dict__, f"got missing slot(s): {force_reply.__dict__}" assert len(mro_slots(force_reply)) == len(set(mro_slots(force_reply))), "duplicate slot" - force_reply.custom, force_reply.force_reply = 'should give warning', self.force_reply - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @flaky(3, 1) def test_send_message_with_force_reply(self, bot, chat_id, force_reply): diff --git a/tests/test_game.py b/tests/test_game.py index 78735b70e..8a4613949 100644 --- a/tests/test_game.py +++ b/tests/test_game.py @@ -45,13 +45,10 @@ class TestGame: text_entities = [MessageEntity(13, 17, MessageEntity.URL)] animation = Animation('blah', 'unique_id', 320, 180, 1) - def test_slot_behaviour(self, game, recwarn, mro_slots): + def test_slot_behaviour(self, game, mro_slots): for attr in game.__slots__: assert getattr(game, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not game.__dict__, f"got missing slot(s): {game.__dict__}" assert len(mro_slots(game)) == len(set(mro_slots(game))), "duplicate slot" - game.custom, game.title = 'should give warning', self.title - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json_required(self, bot): json_dict = { diff --git a/tests/test_gamehighscore.py b/tests/test_gamehighscore.py index a97812502..570ec2354 100644 --- a/tests/test_gamehighscore.py +++ b/tests/test_gamehighscore.py @@ -34,13 +34,10 @@ class TestGameHighScore: user = User(2, 'test user', False) score = 42 - def test_slot_behaviour(self, game_highscore, recwarn, mro_slots): + def test_slot_behaviour(self, game_highscore, mro_slots): for attr in game_highscore.__slots__: assert getattr(game_highscore, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not game_highscore.__dict__, f"got missing slot(s): {game_highscore.__dict__}" assert len(mro_slots(game_highscore)) == len(set(mro_slots(game_highscore))), "same slot" - game_highscore.custom, game_highscore.position = 'should give warning', self.position - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = {'position': self.position, 'user': self.user.to_dict(), 'score': self.score} diff --git a/tests/test_handler.py b/tests/test_handler.py index ea39e01ad..af1c00399 100644 --- a/tests/test_handler.py +++ b/tests/test_handler.py @@ -17,13 +17,11 @@ # You should have received a copy of the GNU Lesser Public License # along with this program. If not, see [http://www.gnu.org/licenses/]. -from sys import version_info as py_ver - from telegram.ext import Handler class TestHandler: - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): class SubclassHandler(Handler): __slots__ = () @@ -36,8 +34,4 @@ class TestHandler: inst = SubclassHandler() for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - assert '__dict__' not in Handler.__slots__ if py_ver < (3, 7) else True, 'dict in abc' - inst.custom = 'should not give warning' - assert len(recwarn) == 0, recwarn.list diff --git a/tests/test_inlinekeyboardbutton.py b/tests/test_inlinekeyboardbutton.py index d1b0cc4a2..0cfa98196 100644 --- a/tests/test_inlinekeyboardbutton.py +++ b/tests/test_inlinekeyboardbutton.py @@ -46,14 +46,11 @@ class TestInlineKeyboardButton: pay = 'pay' login_url = LoginUrl("http://google.com") - def test_slot_behaviour(self, inline_keyboard_button, recwarn, mro_slots): + def test_slot_behaviour(self, inline_keyboard_button, mro_slots): inst = inline_keyboard_button for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.text = 'should give warning', self.text - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_keyboard_button): assert inline_keyboard_button.text == self.text diff --git a/tests/test_inlinekeyboardmarkup.py b/tests/test_inlinekeyboardmarkup.py index bb7e20c20..9c388c123 100644 --- a/tests/test_inlinekeyboardmarkup.py +++ b/tests/test_inlinekeyboardmarkup.py @@ -36,14 +36,11 @@ class TestInlineKeyboardMarkup: ] ] - def test_slot_behaviour(self, inline_keyboard_markup, recwarn, mro_slots): + def test_slot_behaviour(self, inline_keyboard_markup, mro_slots): inst = inline_keyboard_markup for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.inline_keyboard = 'should give warning', self.inline_keyboard - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @flaky(3, 1) def test_send_message_with_inline_keyboard_markup(self, bot, chat_id, inline_keyboard_markup): diff --git a/tests/test_inlinequery.py b/tests/test_inlinequery.py index 44172afe2..c61ef9bc4 100644 --- a/tests/test_inlinequery.py +++ b/tests/test_inlinequery.py @@ -44,13 +44,10 @@ class TestInlineQuery: location = Location(8.8, 53.1) chat_type = Chat.SENDER - def test_slot_behaviour(self, inline_query, recwarn, mro_slots): + def test_slot_behaviour(self, inline_query, mro_slots): for attr in inline_query.__slots__: assert getattr(inline_query, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inline_query.__dict__, f"got missing slot(s): {inline_query.__dict__}" assert len(mro_slots(inline_query)) == len(set(mro_slots(inline_query))), "duplicate slot" - inline_query.custom, inline_query.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = { diff --git a/tests/test_inlinequeryhandler.py b/tests/test_inlinequeryhandler.py index b95a7176e..aca3e61a5 100644 --- a/tests/test_inlinequeryhandler.py +++ b/tests/test_inlinequeryhandler.py @@ -84,14 +84,11 @@ def inline_query(bot): class TestInlineQueryHandler: test_flag = False - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): handler = InlineQueryHandler(self.callback_context) for attr in handler.__slots__: assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not handler.__dict__, f"got missing slot(s): {handler.__dict__}" assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot" - handler.custom, handler.callback = 'should give warning', self.callback_basic - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): @@ -270,4 +267,4 @@ class TestInlineQueryHandler: assert self.test_flag == result finally: - inline_query.chat_type = None + inline_query.inline_query.chat_type = None diff --git a/tests/test_inlinequeryresultarticle.py b/tests/test_inlinequeryresultarticle.py index d677791e9..a46756459 100644 --- a/tests/test_inlinequeryresultarticle.py +++ b/tests/test_inlinequeryresultarticle.py @@ -61,10 +61,7 @@ class TestInlineQueryResultArticle: inst = inline_query_result_article for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_article): assert inline_query_result_article.type == self.type_ diff --git a/tests/test_inlinequeryresultaudio.py b/tests/test_inlinequeryresultaudio.py index c85af4564..b94ea47f2 100644 --- a/tests/test_inlinequeryresultaudio.py +++ b/tests/test_inlinequeryresultaudio.py @@ -58,14 +58,11 @@ class TestInlineQueryResultAudio: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_audio, mro_slots, recwarn): + def test_slot_behaviour(self, inline_query_result_audio, mro_slots): inst = inline_query_result_audio for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_audio): assert inline_query_result_audio.type == self.type_ diff --git a/tests/test_inlinequeryresultcachedaudio.py b/tests/test_inlinequeryresultcachedaudio.py index f09998d69..6158d1121 100644 --- a/tests/test_inlinequeryresultcachedaudio.py +++ b/tests/test_inlinequeryresultcachedaudio.py @@ -52,14 +52,11 @@ class TestInlineQueryResultCachedAudio: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_cached_audio, mro_slots, recwarn): + def test_slot_behaviour(self, inline_query_result_cached_audio, mro_slots): inst = inline_query_result_cached_audio for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_cached_audio): assert inline_query_result_cached_audio.type == self.type_ diff --git a/tests/test_inlinequeryresultcacheddocument.py b/tests/test_inlinequeryresultcacheddocument.py index 20a73b7f2..c58bef120 100644 --- a/tests/test_inlinequeryresultcacheddocument.py +++ b/tests/test_inlinequeryresultcacheddocument.py @@ -56,14 +56,11 @@ class TestInlineQueryResultCachedDocument: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_cached_document, mro_slots, recwarn): + def test_slot_behaviour(self, inline_query_result_cached_document, mro_slots): inst = inline_query_result_cached_document for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_cached_document): assert inline_query_result_cached_document.id == self.id_ diff --git a/tests/test_inlinequeryresultcachedgif.py b/tests/test_inlinequeryresultcachedgif.py index e6aa7081d..a09705e3e 100644 --- a/tests/test_inlinequeryresultcachedgif.py +++ b/tests/test_inlinequeryresultcachedgif.py @@ -53,14 +53,11 @@ class TestInlineQueryResultCachedGif: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_cached_gif, recwarn, mro_slots): + def test_slot_behaviour(self, inline_query_result_cached_gif, mro_slots): inst = inline_query_result_cached_gif for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_cached_gif): assert inline_query_result_cached_gif.type == self.type_ diff --git a/tests/test_inlinequeryresultcachedmpeg4gif.py b/tests/test_inlinequeryresultcachedmpeg4gif.py index 70906076d..a225ccca7 100644 --- a/tests/test_inlinequeryresultcachedmpeg4gif.py +++ b/tests/test_inlinequeryresultcachedmpeg4gif.py @@ -53,14 +53,11 @@ class TestInlineQueryResultCachedMpeg4Gif: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_cached_mpeg4_gif, mro_slots, recwarn): + def test_slot_behaviour(self, inline_query_result_cached_mpeg4_gif, mro_slots): inst = inline_query_result_cached_mpeg4_gif for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_cached_mpeg4_gif): assert inline_query_result_cached_mpeg4_gif.type == self.type_ diff --git a/tests/test_inlinequeryresultcachedphoto.py b/tests/test_inlinequeryresultcachedphoto.py index 12d448324..051c7d831 100644 --- a/tests/test_inlinequeryresultcachedphoto.py +++ b/tests/test_inlinequeryresultcachedphoto.py @@ -55,14 +55,11 @@ class TestInlineQueryResultCachedPhoto: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_cached_photo, recwarn, mro_slots): + def test_slot_behaviour(self, inline_query_result_cached_photo, mro_slots): inst = inline_query_result_cached_photo for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_cached_photo): assert inline_query_result_cached_photo.type == self.type_ diff --git a/tests/test_inlinequeryresultcachedsticker.py b/tests/test_inlinequeryresultcachedsticker.py index 0fbc81243..cf7361222 100644 --- a/tests/test_inlinequeryresultcachedsticker.py +++ b/tests/test_inlinequeryresultcachedsticker.py @@ -44,14 +44,11 @@ class TestInlineQueryResultCachedSticker: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_cached_sticker, mro_slots, recwarn): + def test_slot_behaviour(self, inline_query_result_cached_sticker, mro_slots): inst = inline_query_result_cached_sticker for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_cached_sticker): assert inline_query_result_cached_sticker.type == self.type_ diff --git a/tests/test_inlinequeryresultcachedvideo.py b/tests/test_inlinequeryresultcachedvideo.py index 8c5386975..3f1dc747d 100644 --- a/tests/test_inlinequeryresultcachedvideo.py +++ b/tests/test_inlinequeryresultcachedvideo.py @@ -55,14 +55,11 @@ class TestInlineQueryResultCachedVideo: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_cached_video, recwarn, mro_slots): + def test_slot_behaviour(self, inline_query_result_cached_video, mro_slots): inst = inline_query_result_cached_video for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_cached_video): assert inline_query_result_cached_video.type == self.type_ diff --git a/tests/test_inlinequeryresultcachedvoice.py b/tests/test_inlinequeryresultcachedvoice.py index 347620b37..8d89d116d 100644 --- a/tests/test_inlinequeryresultcachedvoice.py +++ b/tests/test_inlinequeryresultcachedvoice.py @@ -53,14 +53,11 @@ class TestInlineQueryResultCachedVoice: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_cached_voice, recwarn, mro_slots): + def test_slot_behaviour(self, inline_query_result_cached_voice, mro_slots): inst = inline_query_result_cached_voice for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_cached_voice): assert inline_query_result_cached_voice.type == self.type_ diff --git a/tests/test_inlinequeryresultcontact.py b/tests/test_inlinequeryresultcontact.py index acf9853d0..ea38fbff7 100644 --- a/tests/test_inlinequeryresultcontact.py +++ b/tests/test_inlinequeryresultcontact.py @@ -54,14 +54,11 @@ class TestInlineQueryResultContact: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_contact, mro_slots, recwarn): + def test_slot_behaviour(self, inline_query_result_contact, mro_slots): inst = inline_query_result_contact for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_contact): assert inline_query_result_contact.id == self.id_ diff --git a/tests/test_inlinequeryresultdocument.py b/tests/test_inlinequeryresultdocument.py index 8bcffb28a..d41952b93 100644 --- a/tests/test_inlinequeryresultdocument.py +++ b/tests/test_inlinequeryresultdocument.py @@ -63,14 +63,11 @@ class TestInlineQueryResultDocument: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_document, recwarn, mro_slots): + def test_slot_behaviour(self, inline_query_result_document, mro_slots): inst = inline_query_result_document for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_document): assert inline_query_result_document.id == self.id_ diff --git a/tests/test_inlinequeryresultgame.py b/tests/test_inlinequeryresultgame.py index 2e0798011..1712d8836 100644 --- a/tests/test_inlinequeryresultgame.py +++ b/tests/test_inlinequeryresultgame.py @@ -41,14 +41,11 @@ class TestInlineQueryResultGame: game_short_name = 'game short name' reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_game, mro_slots, recwarn): + def test_slot_behaviour(self, inline_query_result_game, mro_slots): inst = inline_query_result_game for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_game): assert inline_query_result_game.type == self.type_ diff --git a/tests/test_inlinequeryresultgif.py b/tests/test_inlinequeryresultgif.py index 0da8c3d2a..402acbf1a 100644 --- a/tests/test_inlinequeryresultgif.py +++ b/tests/test_inlinequeryresultgif.py @@ -63,14 +63,11 @@ class TestInlineQueryResultGif: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_gif, recwarn, mro_slots): + def test_slot_behaviour(self, inline_query_result_gif, mro_slots): inst = inline_query_result_gif for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_gif): assert inline_query_result_gif.type == self.type_ diff --git a/tests/test_inlinequeryresultlocation.py b/tests/test_inlinequeryresultlocation.py index 00df4ab8d..7b83e086e 100644 --- a/tests/test_inlinequeryresultlocation.py +++ b/tests/test_inlinequeryresultlocation.py @@ -62,14 +62,11 @@ class TestInlineQueryResultLocation: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_location, mro_slots, recwarn): + def test_slot_behaviour(self, inline_query_result_location, mro_slots): inst = inline_query_result_location for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_location): assert inline_query_result_location.id == self.id_ diff --git a/tests/test_inlinequeryresultmpeg4gif.py b/tests/test_inlinequeryresultmpeg4gif.py index 77a2bde6b..4bf63fec0 100644 --- a/tests/test_inlinequeryresultmpeg4gif.py +++ b/tests/test_inlinequeryresultmpeg4gif.py @@ -63,14 +63,11 @@ class TestInlineQueryResultMpeg4Gif: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_mpeg4_gif, recwarn, mro_slots): + def test_slot_behaviour(self, inline_query_result_mpeg4_gif, mro_slots): inst = inline_query_result_mpeg4_gif for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_mpeg4_gif): assert inline_query_result_mpeg4_gif.type == self.type_ diff --git a/tests/test_inlinequeryresultphoto.py b/tests/test_inlinequeryresultphoto.py index 990af4b53..61bd03e68 100644 --- a/tests/test_inlinequeryresultphoto.py +++ b/tests/test_inlinequeryresultphoto.py @@ -62,14 +62,11 @@ class TestInlineQueryResultPhoto: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_photo, recwarn, mro_slots): + def test_slot_behaviour(self, inline_query_result_photo, mro_slots): inst = inline_query_result_photo for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_photo): assert inline_query_result_photo.type == self.type_ diff --git a/tests/test_inlinequeryresultvenue.py b/tests/test_inlinequeryresultvenue.py index 6ef5c595a..b165a1ba1 100644 --- a/tests/test_inlinequeryresultvenue.py +++ b/tests/test_inlinequeryresultvenue.py @@ -64,14 +64,11 @@ class TestInlineQueryResultVenue: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_venue, mro_slots, recwarn): + def test_slot_behaviour(self, inline_query_result_venue, mro_slots): inst = inline_query_result_venue for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_venue): assert inline_query_result_venue.id == self.id_ diff --git a/tests/test_inlinequeryresultvideo.py b/tests/test_inlinequeryresultvideo.py index b60e767c8..77d545154 100644 --- a/tests/test_inlinequeryresultvideo.py +++ b/tests/test_inlinequeryresultvideo.py @@ -65,14 +65,11 @@ class TestInlineQueryResultVideo: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_video, recwarn, mro_slots): + def test_slot_behaviour(self, inline_query_result_video, mro_slots): inst = inline_query_result_video for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_video): assert inline_query_result_video.type == self.type_ diff --git a/tests/test_inlinequeryresultvoice.py b/tests/test_inlinequeryresultvoice.py index 109b01214..946cbb36b 100644 --- a/tests/test_inlinequeryresultvoice.py +++ b/tests/test_inlinequeryresultvoice.py @@ -56,14 +56,11 @@ class TestInlineQueryResultVoice: input_message_content = InputTextMessageContent('input_message_content') reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_slot_behaviour(self, inline_query_result_voice, mro_slots, recwarn): + def test_slot_behaviour(self, inline_query_result_voice, mro_slots): inst = inline_query_result_voice for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, inline_query_result_voice): assert inline_query_result_voice.type == self.type_ diff --git a/tests/test_inputcontactmessagecontent.py b/tests/test_inputcontactmessagecontent.py index d3f4f0852..bb5df01a5 100644 --- a/tests/test_inputcontactmessagecontent.py +++ b/tests/test_inputcontactmessagecontent.py @@ -35,14 +35,11 @@ class TestInputContactMessageContent: first_name = 'first name' last_name = 'last name' - def test_slot_behaviour(self, input_contact_message_content, mro_slots, recwarn): + def test_slot_behaviour(self, input_contact_message_content, mro_slots): inst = input_contact_message_content for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.first_name = 'should give warning', self.first_name - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, input_contact_message_content): assert input_contact_message_content.first_name == self.first_name diff --git a/tests/test_inputfile.py b/tests/test_inputfile.py index 40b473c78..c246ef449 100644 --- a/tests/test_inputfile.py +++ b/tests/test_inputfile.py @@ -28,14 +28,11 @@ from telegram import InputFile class TestInputFile: png = os.path.join('tests', 'data', 'game.png') - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): inst = InputFile(BytesIO(b'blah'), filename='tg.jpg') for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.filename = 'should give warning', inst.filename - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_subprocess_pipe(self): if sys.platform == 'win32': diff --git a/tests/test_inputinvoicemessagecontent.py b/tests/test_inputinvoicemessagecontent.py index 95338799e..d36d60be8 100644 --- a/tests/test_inputinvoicemessagecontent.py +++ b/tests/test_inputinvoicemessagecontent.py @@ -74,14 +74,11 @@ class TestInputInvoiceMessageContent: send_email_to_provider = True is_flexible = True - def test_slot_behaviour(self, input_invoice_message_content, recwarn, mro_slots): + def test_slot_behaviour(self, input_invoice_message_content, mro_slots): inst = input_invoice_message_content for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.title = 'should give warning', self.title - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, input_invoice_message_content): assert input_invoice_message_content.title == self.title diff --git a/tests/test_inputlocationmessagecontent.py b/tests/test_inputlocationmessagecontent.py index f730167e3..587997348 100644 --- a/tests/test_inputlocationmessagecontent.py +++ b/tests/test_inputlocationmessagecontent.py @@ -41,14 +41,11 @@ class TestInputLocationMessageContent: heading = 90 proximity_alert_radius = 999 - def test_slot_behaviour(self, input_location_message_content, mro_slots, recwarn): + def test_slot_behaviour(self, input_location_message_content, mro_slots): inst = input_location_message_content for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.heading = 'should give warning', self.heading - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, input_location_message_content): assert input_location_message_content.longitude == self.longitude diff --git a/tests/test_inputmedia.py b/tests/test_inputmedia.py index d3d0715fa..e9adb5a0d 100644 --- a/tests/test_inputmedia.py +++ b/tests/test_inputmedia.py @@ -127,14 +127,11 @@ class TestInputMediaVideo: supports_streaming = True caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] - def test_slot_behaviour(self, input_media_video, recwarn, mro_slots): + def test_slot_behaviour(self, input_media_video, mro_slots): inst = input_media_video for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, input_media_video): assert input_media_video.type == self.type_ @@ -194,14 +191,11 @@ class TestInputMediaPhoto: parse_mode = 'Markdown' caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] - def test_slot_behaviour(self, input_media_photo, recwarn, mro_slots): + def test_slot_behaviour(self, input_media_photo, mro_slots): inst = input_media_photo for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, input_media_photo): assert input_media_photo.type == self.type_ @@ -249,14 +243,11 @@ class TestInputMediaAnimation: height = 30 duration = 1 - def test_slot_behaviour(self, input_media_animation, recwarn, mro_slots): + def test_slot_behaviour(self, input_media_animation, mro_slots): inst = input_media_animation for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, input_media_animation): assert input_media_animation.type == self.type_ @@ -311,14 +302,11 @@ class TestInputMediaAudio: parse_mode = 'HTML' caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] - def test_slot_behaviour(self, input_media_audio, recwarn, mro_slots): + def test_slot_behaviour(self, input_media_audio, mro_slots): inst = input_media_audio for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, input_media_audio): assert input_media_audio.type == self.type_ @@ -377,14 +365,11 @@ class TestInputMediaDocument: caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] disable_content_type_detection = True - def test_slot_behaviour(self, input_media_document, recwarn, mro_slots): + def test_slot_behaviour(self, input_media_document, mro_slots): inst = input_media_document for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, input_media_document): assert input_media_document.type == self.type_ diff --git a/tests/test_inputtextmessagecontent.py b/tests/test_inputtextmessagecontent.py index 5b57746f7..6df757dbd 100644 --- a/tests/test_inputtextmessagecontent.py +++ b/tests/test_inputtextmessagecontent.py @@ -37,14 +37,11 @@ class TestInputTextMessageContent: entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] disable_web_page_preview = True - def test_slot_behaviour(self, input_text_message_content, mro_slots, recwarn): + def test_slot_behaviour(self, input_text_message_content, mro_slots): inst = input_text_message_content for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.message_text = 'should give warning', self.message_text - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, input_text_message_content): assert input_text_message_content.parse_mode == self.parse_mode diff --git a/tests/test_inputvenuemessagecontent.py b/tests/test_inputvenuemessagecontent.py index de3392931..3413a1a4f 100644 --- a/tests/test_inputvenuemessagecontent.py +++ b/tests/test_inputvenuemessagecontent.py @@ -45,14 +45,11 @@ class TestInputVenueMessageContent: google_place_id = 'google place id' google_place_type = 'google place type' - def test_slot_behaviour(self, input_venue_message_content, recwarn, mro_slots): + def test_slot_behaviour(self, input_venue_message_content, mro_slots): inst = input_venue_message_content for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.title = 'should give warning', self.title - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, input_venue_message_content): assert input_venue_message_content.longitude == self.longitude diff --git a/tests/test_invoice.py b/tests/test_invoice.py index 6ed2f3c30..169bd7382 100644 --- a/tests/test_invoice.py +++ b/tests/test_invoice.py @@ -46,13 +46,10 @@ class TestInvoice: max_tip_amount = 42 suggested_tip_amounts = [13, 42] - def test_slot_behaviour(self, invoice, mro_slots, recwarn): + def test_slot_behaviour(self, invoice, mro_slots): for attr in invoice.__slots__: assert getattr(invoice, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not invoice.__dict__, f"got missing slot(s): {invoice.__dict__}" assert len(mro_slots(invoice)) == len(set(mro_slots(invoice))), "duplicate slot" - invoice.custom, invoice.title = 'should give warning', self.title - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): invoice_json = Invoice.de_json( diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index 384f16eca..a2d0cbd56 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -55,13 +55,10 @@ class TestJobQueue: job_time = 0 received_error = None - def test_slot_behaviour(self, job_queue, recwarn, mro_slots, _dp): + def test_slot_behaviour(self, job_queue, mro_slots, _dp): for attr in job_queue.__slots__: assert getattr(job_queue, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not job_queue.__dict__, f"got missing slot(s): {job_queue.__dict__}" assert len(mro_slots(job_queue)) == len(set(mro_slots(job_queue))), "duplicate slot" - job_queue.custom, job_queue._dispatcher = 'should give warning', _dp - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_keyboardbutton.py b/tests/test_keyboardbutton.py index 221c2a77b..3cd4e476e 100644 --- a/tests/test_keyboardbutton.py +++ b/tests/test_keyboardbutton.py @@ -38,14 +38,11 @@ class TestKeyboardButton: request_contact = True request_poll = KeyboardButtonPollType("quiz") - def test_slot_behaviour(self, keyboard_button, recwarn, mro_slots): + def test_slot_behaviour(self, keyboard_button, mro_slots): inst = keyboard_button for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.text = 'should give warning', self.text - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, keyboard_button): assert keyboard_button.text == self.text diff --git a/tests/test_keyboardbuttonpolltype.py b/tests/test_keyboardbuttonpolltype.py index d7e70fc06..6799755a4 100644 --- a/tests/test_keyboardbuttonpolltype.py +++ b/tests/test_keyboardbuttonpolltype.py @@ -29,14 +29,11 @@ def keyboard_button_poll_type(): class TestKeyboardButtonPollType: type = Poll.QUIZ - def test_slot_behaviour(self, keyboard_button_poll_type, recwarn, mro_slots): + def test_slot_behaviour(self, keyboard_button_poll_type, mro_slots): inst = keyboard_button_poll_type for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_to_dict(self, keyboard_button_poll_type): keyboard_button_poll_type_dict = keyboard_button_poll_type.to_dict() diff --git a/tests/test_labeledprice.py b/tests/test_labeledprice.py index abe5a09ee..71f26954b 100644 --- a/tests/test_labeledprice.py +++ b/tests/test_labeledprice.py @@ -30,14 +30,11 @@ class TestLabeledPrice: label = 'label' amount = 100 - def test_slot_behaviour(self, labeled_price, recwarn, mro_slots): + def test_slot_behaviour(self, labeled_price, mro_slots): inst = labeled_price for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.label = 'should give warning', self.label - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, labeled_price): assert labeled_price.label == self.label diff --git a/tests/test_location.py b/tests/test_location.py index 113c70e78..be9d68c61 100644 --- a/tests/test_location.py +++ b/tests/test_location.py @@ -43,13 +43,10 @@ class TestLocation: heading = 90 proximity_alert_radius = 50 - def test_slot_behaviour(self, location, recwarn, mro_slots): + def test_slot_behaviour(self, location, mro_slots): for attr in location.__slots__: assert getattr(location, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not location.__dict__, f"got missing slot(s): {location.__dict__}" assert len(mro_slots(location)) == len(set(mro_slots(location))), "duplicate slot" - location.custom, location.heading = 'should give warning', self.heading - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = { diff --git a/tests/test_loginurl.py b/tests/test_loginurl.py index 1c09c255a..d0f75e424 100644 --- a/tests/test_loginurl.py +++ b/tests/test_loginurl.py @@ -37,13 +37,10 @@ class TestLoginUrl: bot_username = "botname" request_write_access = True - def test_slot_behaviour(self, login_url, recwarn, mro_slots): + def test_slot_behaviour(self, login_url, mro_slots): for attr in login_url.__slots__: assert getattr(login_url, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not login_url.__dict__, f"got missing slot(s): {login_url.__dict__}" assert len(mro_slots(login_url)) == len(set(mro_slots(login_url))), "duplicate slot" - login_url.custom, login_url.url = 'should give warning', self.url - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_to_dict(self, login_url): login_url_dict = login_url.to_dict() diff --git a/tests/test_message.py b/tests/test_message.py index 69db2a8e6..426c40fcd 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -312,13 +312,10 @@ class TestMessage: caption_entities=[MessageEntity(**e) for e in test_entities_v2], ) - def test_slot_behaviour(self, message, recwarn, mro_slots): + def test_slot_behaviour(self, message, mro_slots): for attr in message.__slots__: assert getattr(message, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not message.__dict__, f"got missing slot(s): {message.__dict__}" assert len(mro_slots(message)) == len(set(mro_slots(message))), "duplicate slot" - message.custom, message.message_id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_all_possibilities_de_json_and_to_dict(self, bot, message_params): new = Message.de_json(message_params.to_dict(), bot) diff --git a/tests/test_messageautodeletetimerchanged.py b/tests/test_messageautodeletetimerchanged.py index 89b15ac0f..ef5f261d8 100644 --- a/tests/test_messageautodeletetimerchanged.py +++ b/tests/test_messageautodeletetimerchanged.py @@ -22,14 +22,11 @@ from telegram import MessageAutoDeleteTimerChanged, VoiceChatEnded class TestMessageAutoDeleteTimerChanged: message_auto_delete_time = 100 - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): action = MessageAutoDeleteTimerChanged(self.message_auto_delete_time) for attr in action.__slots__: assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not action.__dict__, f"got missing slot(s): {action.__dict__}" assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot" - action.custom = 'should give warning' - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self): json_dict = {'message_auto_delete_time': self.message_auto_delete_time} diff --git a/tests/test_messageentity.py b/tests/test_messageentity.py index 1c131ff06..ef3add809 100644 --- a/tests/test_messageentity.py +++ b/tests/test_messageentity.py @@ -42,14 +42,11 @@ class TestMessageEntity: length = 2 url = 'url' - def test_slot_behaviour(self, message_entity, recwarn, mro_slots): + def test_slot_behaviour(self, message_entity, mro_slots): inst = message_entity for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = {'type': self.type_, 'offset': self.offset, 'length': self.length} diff --git a/tests/test_messagehandler.py b/tests/test_messagehandler.py index 302df24cb..d0e6666d8 100644 --- a/tests/test_messagehandler.py +++ b/tests/test_messagehandler.py @@ -71,14 +71,11 @@ class TestMessageHandler: test_flag = False SRE_TYPE = type(re.match("", "")) - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): handler = MessageHandler(Filters.all, self.callback_basic) for attr in handler.__slots__: assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not handler.__dict__, f"got missing slot(s): {handler.__dict__}" assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot" - handler.custom, handler.callback = 'should give warning', self.callback_basic - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_messageid.py b/tests/test_messageid.py index 3dee1fc46..557d14e8e 100644 --- a/tests/test_messageid.py +++ b/tests/test_messageid.py @@ -27,13 +27,10 @@ def message_id(): class TestMessageId: m_id = 1234 - def test_slot_behaviour(self, message_id, recwarn, mro_slots): + def test_slot_behaviour(self, message_id, mro_slots): for attr in message_id.__slots__: assert getattr(message_id, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not message_id.__dict__, f"got missing slot(s): {message_id.__dict__}" assert len(mro_slots(message_id)) == len(set(mro_slots(message_id))), "duplicate slot" - message_id.custom, message_id.message_id = 'should give warning', self.m_id - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self): json_dict = {'message_id': self.m_id} diff --git a/tests/test_official.py b/tests/test_official.py index 1127ccba4..50349139e 100644 --- a/tests/test_official.py +++ b/tests/test_official.py @@ -37,6 +37,7 @@ IGNORED_PARAMETERS = { 'timeout', 'bot', 'api_kwargs', + 'kwargs', } @@ -109,8 +110,8 @@ def check_object(h4): obj = getattr(telegram, name) table = parse_table(h4) - # Check arguments based on source - sig = inspect.signature(obj, follow_wrapped=True) + # Check arguments based on source. Makes sure to only check __init__'s signature & nothing else + sig = inspect.signature(obj.__init__, follow_wrapped=True) checked = [] for parameter in table: diff --git a/tests/test_orderinfo.py b/tests/test_orderinfo.py index b52a70325..1e3669aac 100644 --- a/tests/test_orderinfo.py +++ b/tests/test_orderinfo.py @@ -37,13 +37,10 @@ class TestOrderInfo: email = 'email' shipping_address = ShippingAddress('GB', '', 'London', '12 Grimmauld Place', '', 'WC1') - def test_slot_behaviour(self, order_info, mro_slots, recwarn): + def test_slot_behaviour(self, order_info, mro_slots): for attr in order_info.__slots__: assert getattr(order_info, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not order_info.__dict__, f"got missing slot(s): {order_info.__dict__}" assert len(mro_slots(order_info)) == len(set(mro_slots(order_info))), "duplicate slot" - order_info.custom, order_info.name = 'should give warning', self.name - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = { diff --git a/tests/test_parsemode.py b/tests/test_parsemode.py index d3a53d8d8..3597a8436 100644 --- a/tests/test_parsemode.py +++ b/tests/test_parsemode.py @@ -29,14 +29,11 @@ class TestParseMode: ) formatted_text_formatted = 'bold italic link name.' - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): inst = ParseMode() for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom = 'should give warning' - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @flaky(3, 1) def test_send_message_with_parse_mode_markdown(self, bot, chat_id): diff --git a/tests/test_passport.py b/tests/test_passport.py index 342b89fc7..957eeb514 100644 --- a/tests/test_passport.py +++ b/tests/test_passport.py @@ -215,14 +215,11 @@ class TestPassport: driver_license_selfie_credentials_file_hash = 'Cila/qLXSBH7DpZFbb5bRZIRxeFW2uv/ulL0u0JNsYI=' driver_license_selfie_credentials_secret = 'tivdId6RNYNsvXYPppdzrbxOBuBOr9wXRPDcCvnXU7E=' - def test_slot_behaviour(self, passport_data, mro_slots, recwarn): + def test_slot_behaviour(self, passport_data, mro_slots): inst = passport_data for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.data = 'should give warning', passport_data.data - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_creation(self, passport_data): assert isinstance(passport_data, PassportData) diff --git a/tests/test_passportelementerrordatafield.py b/tests/test_passportelementerrordatafield.py index bdcc816fa..965f3bf25 100644 --- a/tests/test_passportelementerrordatafield.py +++ b/tests/test_passportelementerrordatafield.py @@ -38,14 +38,11 @@ class TestPassportElementErrorDataField: data_hash = 'data_hash' message = 'Error message' - def test_slot_behaviour(self, passport_element_error_data_field, recwarn, mro_slots): + def test_slot_behaviour(self, passport_element_error_data_field, mro_slots): inst = passport_element_error_data_field for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, passport_element_error_data_field): assert passport_element_error_data_field.source == self.source diff --git a/tests/test_passportelementerrorfile.py b/tests/test_passportelementerrorfile.py index f02dd498a..508d556f7 100644 --- a/tests/test_passportelementerrorfile.py +++ b/tests/test_passportelementerrorfile.py @@ -36,14 +36,11 @@ class TestPassportElementErrorFile: file_hash = 'file_hash' message = 'Error message' - def test_slot_behaviour(self, passport_element_error_file, recwarn, mro_slots): + def test_slot_behaviour(self, passport_element_error_file, mro_slots): inst = passport_element_error_file for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, passport_element_error_file): assert passport_element_error_file.source == self.source diff --git a/tests/test_passportelementerrorfiles.py b/tests/test_passportelementerrorfiles.py index 779f942f1..27057fade 100644 --- a/tests/test_passportelementerrorfiles.py +++ b/tests/test_passportelementerrorfiles.py @@ -36,14 +36,11 @@ class TestPassportElementErrorFiles: file_hashes = ['hash1', 'hash2'] message = 'Error message' - def test_slot_behaviour(self, passport_element_error_files, mro_slots, recwarn): + def test_slot_behaviour(self, passport_element_error_files, mro_slots): inst = passport_element_error_files for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, passport_element_error_files): assert passport_element_error_files.source == self.source diff --git a/tests/test_passportelementerrorfrontside.py b/tests/test_passportelementerrorfrontside.py index 7f15c03d8..7cb99751b 100644 --- a/tests/test_passportelementerrorfrontside.py +++ b/tests/test_passportelementerrorfrontside.py @@ -36,14 +36,11 @@ class TestPassportElementErrorFrontSide: file_hash = 'file_hash' message = 'Error message' - def test_slot_behaviour(self, passport_element_error_front_side, recwarn, mro_slots): + def test_slot_behaviour(self, passport_element_error_front_side, mro_slots): inst = passport_element_error_front_side for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, passport_element_error_front_side): assert passport_element_error_front_side.source == self.source diff --git a/tests/test_passportelementerrorreverseside.py b/tests/test_passportelementerrorreverseside.py index 260ca3d0a..e8129c503 100644 --- a/tests/test_passportelementerrorreverseside.py +++ b/tests/test_passportelementerrorreverseside.py @@ -36,14 +36,11 @@ class TestPassportElementErrorReverseSide: file_hash = 'file_hash' message = 'Error message' - def test_slot_behaviour(self, passport_element_error_reverse_side, mro_slots, recwarn): + def test_slot_behaviour(self, passport_element_error_reverse_side, mro_slots): inst = passport_element_error_reverse_side for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, passport_element_error_reverse_side): assert passport_element_error_reverse_side.source == self.source diff --git a/tests/test_passportelementerrorselfie.py b/tests/test_passportelementerrorselfie.py index f0e3591be..9a924f1bc 100644 --- a/tests/test_passportelementerrorselfie.py +++ b/tests/test_passportelementerrorselfie.py @@ -36,14 +36,11 @@ class TestPassportElementErrorSelfie: file_hash = 'file_hash' message = 'Error message' - def test_slot_behaviour(self, passport_element_error_selfie, recwarn, mro_slots): + def test_slot_behaviour(self, passport_element_error_selfie, mro_slots): inst = passport_element_error_selfie for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, passport_element_error_selfie): assert passport_element_error_selfie.source == self.source diff --git a/tests/test_passportelementerrortranslationfile.py b/tests/test_passportelementerrortranslationfile.py index b7fd67ccf..d271ce560 100644 --- a/tests/test_passportelementerrortranslationfile.py +++ b/tests/test_passportelementerrortranslationfile.py @@ -36,14 +36,11 @@ class TestPassportElementErrorTranslationFile: file_hash = 'file_hash' message = 'Error message' - def test_slot_behaviour(self, passport_element_error_translation_file, recwarn, mro_slots): + def test_slot_behaviour(self, passport_element_error_translation_file, mro_slots): inst = passport_element_error_translation_file for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, passport_element_error_translation_file): assert passport_element_error_translation_file.source == self.source diff --git a/tests/test_passportelementerrortranslationfiles.py b/tests/test_passportelementerrortranslationfiles.py index 8db3d5181..f9c2a6157 100644 --- a/tests/test_passportelementerrortranslationfiles.py +++ b/tests/test_passportelementerrortranslationfiles.py @@ -36,14 +36,11 @@ class TestPassportElementErrorTranslationFiles: file_hashes = ['hash1', 'hash2'] message = 'Error message' - def test_slot_behaviour(self, passport_element_error_translation_files, mro_slots, recwarn): + def test_slot_behaviour(self, passport_element_error_translation_files, mro_slots): inst = passport_element_error_translation_files for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, passport_element_error_translation_files): assert passport_element_error_translation_files.source == self.source diff --git a/tests/test_passportelementerrorunspecified.py b/tests/test_passportelementerrorunspecified.py index 202bfa72f..9f4b053c6 100644 --- a/tests/test_passportelementerrorunspecified.py +++ b/tests/test_passportelementerrorunspecified.py @@ -36,14 +36,11 @@ class TestPassportElementErrorUnspecified: element_hash = 'element_hash' message = 'Error message' - def test_slot_behaviour(self, passport_element_error_unspecified, recwarn, mro_slots): + def test_slot_behaviour(self, passport_element_error_unspecified, mro_slots): inst = passport_element_error_unspecified for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.type = 'should give warning', self.type_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, passport_element_error_unspecified): assert passport_element_error_unspecified.source == self.source diff --git a/tests/test_passportfile.py b/tests/test_passportfile.py index 8a5ef9bab..6c9d52779 100644 --- a/tests/test_passportfile.py +++ b/tests/test_passportfile.py @@ -39,14 +39,11 @@ class TestPassportFile: file_size = 50 file_date = 1532879128 - def test_slot_behaviour(self, passport_file, mro_slots, recwarn): + def test_slot_behaviour(self, passport_file, mro_slots): inst = passport_file for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.file_id = 'should give warning', self.file_id - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, passport_file): assert passport_file.file_id == self.file_id diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 50fcb0bdd..7304ed7e4 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -35,7 +35,6 @@ import pickle from collections import defaultdict from collections.abc import Container from time import sleep -from sys import version_info as py_ver import pytest @@ -242,16 +241,13 @@ class TestBasePersistence: def reset(self): self.test_flag = False - def test_slot_behaviour(self, bot_persistence, mro_slots, recwarn): + def test_slot_behaviour(self, bot_persistence, mro_slots): inst = bot_persistence for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" # assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" # The below test fails if the child class doesn't define __slots__ (not a cause of concern) assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.store_data, inst.custom = {}, "custom persistence shouldn't warn" - assert len(recwarn) == 0, recwarn.list - assert '__dict__' not in BasePersistence.__slots__ if py_ver < (3, 7) else True, 'has dict' def test_creation(self, base_persistence): assert base_persistence.store_data.chat_data @@ -1040,14 +1036,11 @@ class CustomMapping(defaultdict): class TestPicklePersistence: - def test_slot_behaviour(self, mro_slots, recwarn, pickle_persistence): + def test_slot_behaviour(self, mro_slots, pickle_persistence): inst = pickle_persistence for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - # assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.store_data = 'should give warning', {} - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_pickle_behaviour_with_slots(self, pickle_persistence): bot_data = pickle_persistence.get_bot_data() @@ -1958,10 +1951,7 @@ class TestDictPersistence: inst = DictPersistence() for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - # assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.store_data = 'should give warning', {} - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_no_json_given(self): dict_persistence = DictPersistence() diff --git a/tests/test_photo.py b/tests/test_photo.py index bc908ccf5..e6ca5e7f3 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -66,13 +66,10 @@ class TestPhoto: photo_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.jpg' file_size = 29176 - def test_slot_behaviour(self, photo, recwarn, mro_slots): + def test_slot_behaviour(self, photo, mro_slots): for attr in photo.__slots__: assert getattr(photo, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not photo.__dict__, f"got missing slot(s): {photo.__dict__}" assert len(mro_slots(photo)) == len(set(mro_slots(photo))), "duplicate slot" - photo.custom, photo.width = 'should give warning', self.width - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_creation(self, thumb, photo): # Make sure file has been uploaded. diff --git a/tests/test_poll.py b/tests/test_poll.py index a36a8319b..e4d415972 100644 --- a/tests/test_poll.py +++ b/tests/test_poll.py @@ -33,13 +33,10 @@ class TestPollOption: text = "test option" voter_count = 3 - def test_slot_behaviour(self, poll_option, mro_slots, recwarn): + def test_slot_behaviour(self, poll_option, mro_slots): for attr in poll_option.__slots__: assert getattr(poll_option, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not poll_option.__dict__, f"got missing slot(s): {poll_option.__dict__}" assert len(mro_slots(poll_option)) == len(set(mro_slots(poll_option))), "duplicate slot" - poll_option.custom, poll_option.text = 'should give warning', self.text - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self): json_dict = {'text': self.text, 'voter_count': self.voter_count} diff --git a/tests/test_pollanswerhandler.py b/tests/test_pollanswerhandler.py index d25f233e7..775cd87a0 100644 --- a/tests/test_pollanswerhandler.py +++ b/tests/test_pollanswerhandler.py @@ -74,14 +74,11 @@ def poll_answer(bot): class TestPollAnswerHandler: test_flag = False - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): handler = PollAnswerHandler(self.callback_basic) for attr in handler.__slots__: assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not handler.__dict__, f"got missing slot(s): {handler.__dict__}" assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot" - handler.custom, handler.callback = 'should give warning', self.callback_basic - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_pollhandler.py b/tests/test_pollhandler.py index 442e30379..a243f0bbe 100644 --- a/tests/test_pollhandler.py +++ b/tests/test_pollhandler.py @@ -87,14 +87,11 @@ def poll(bot): class TestPollHandler: test_flag = False - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): inst = PollHandler(self.callback_basic) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.callback = 'should give warning', self.callback_basic - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_precheckoutquery.py b/tests/test_precheckoutquery.py index c95bbadf2..642ef2df7 100644 --- a/tests/test_precheckoutquery.py +++ b/tests/test_precheckoutquery.py @@ -45,14 +45,11 @@ class TestPreCheckoutQuery: from_user = User(0, '', False) order_info = OrderInfo() - def test_slot_behaviour(self, pre_checkout_query, recwarn, mro_slots): + def test_slot_behaviour(self, pre_checkout_query, mro_slots): inst = pre_checkout_query for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = { diff --git a/tests/test_precheckoutqueryhandler.py b/tests/test_precheckoutqueryhandler.py index 1bca64e37..79c1844e0 100644 --- a/tests/test_precheckoutqueryhandler.py +++ b/tests/test_precheckoutqueryhandler.py @@ -79,14 +79,11 @@ def pre_checkout_query(): class TestPreCheckoutQueryHandler: test_flag = False - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): inst = PreCheckoutQueryHandler(self.callback_basic) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.callback = 'should give warning', self.callback_basic - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_promise.py b/tests/test_promise.py index 6a59a2f7a..22a407a7e 100644 --- a/tests/test_promise.py +++ b/tests/test_promise.py @@ -30,14 +30,11 @@ class TestPromise: test_flag = False - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): inst = Promise(self.test_call, [], {}) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.args = 'should give warning', [] - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_proximityalerttriggered.py b/tests/test_proximityalerttriggered.py index f4d7e3285..f82b1e443 100644 --- a/tests/test_proximityalerttriggered.py +++ b/tests/test_proximityalerttriggered.py @@ -35,14 +35,11 @@ class TestProximityAlertTriggered: watcher = User(2, 'bar', False) distance = 42 - def test_slot_behaviour(self, proximity_alert_triggered, mro_slots, recwarn): + def test_slot_behaviour(self, proximity_alert_triggered, mro_slots): inst = proximity_alert_triggered for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.traveler = 'should give warning', self.traveler - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = { diff --git a/tests/test_regexhandler.py b/tests/test_regexhandler.py index a61af5e71..1bacb0129 100644 --- a/tests/test_regexhandler.py +++ b/tests/test_regexhandler.py @@ -71,14 +71,11 @@ def message(bot): class TestRegexHandler: test_flag = False - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): inst = RegexHandler("", self.callback_basic) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.callback = 'should give warning', self.callback_basic - assert 'custom' in str(recwarn[-1].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_replykeyboardmarkup.py b/tests/test_replykeyboardmarkup.py index b3e813cf4..6486af0a3 100644 --- a/tests/test_replykeyboardmarkup.py +++ b/tests/test_replykeyboardmarkup.py @@ -40,14 +40,11 @@ class TestReplyKeyboardMarkup: selective = True input_field_placeholder = 'lol a keyboard' - def test_slot_behaviour(self, reply_keyboard_markup, mro_slots, recwarn): + def test_slot_behaviour(self, reply_keyboard_markup, mro_slots): inst = reply_keyboard_markup for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.selective = 'should give warning', self.selective - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @flaky(3, 1) def test_send_message_with_reply_keyboard_markup(self, bot, chat_id, reply_keyboard_markup): diff --git a/tests/test_replykeyboardremove.py b/tests/test_replykeyboardremove.py index 174b65767..0a516d6de 100644 --- a/tests/test_replykeyboardremove.py +++ b/tests/test_replykeyboardremove.py @@ -31,14 +31,11 @@ class TestReplyKeyboardRemove: remove_keyboard = True selective = True - def test_slot_behaviour(self, reply_keyboard_remove, recwarn, mro_slots): + def test_slot_behaviour(self, reply_keyboard_remove, mro_slots): inst = reply_keyboard_remove for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.selective = 'should give warning', self.selective - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @flaky(3, 1) def test_send_message_with_reply_keyboard_remove(self, bot, chat_id, reply_keyboard_remove): diff --git a/tests/test_request.py b/tests/test_request.py index b0ce3b197..e4589e0a0 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -22,14 +22,11 @@ from telegram import TelegramError from telegram.utils.request import Request -def test_slot_behaviour(recwarn, mro_slots): +def test_slot_behaviour(mro_slots): inst = Request() for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst._connect_timeout = 'should give warning', 10 - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_replaced_unprintable_char(): diff --git a/tests/test_shippingaddress.py b/tests/test_shippingaddress.py index 2ada90b0e..b68f2c87b 100644 --- a/tests/test_shippingaddress.py +++ b/tests/test_shippingaddress.py @@ -41,14 +41,11 @@ class TestShippingAddress: street_line2 = 'street_line2' post_code = 'WC1' - def test_slot_behaviour(self, shipping_address, recwarn, mro_slots): + def test_slot_behaviour(self, shipping_address, mro_slots): inst = shipping_address for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.state = 'should give warning', self.state - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = { diff --git a/tests/test_shippingoption.py b/tests/test_shippingoption.py index 4a29d0d1a..b57e445c4 100644 --- a/tests/test_shippingoption.py +++ b/tests/test_shippingoption.py @@ -33,14 +33,11 @@ class TestShippingOption: title = 'title' prices = [LabeledPrice('Fish Container', 100), LabeledPrice('Premium Fish Container', 1000)] - def test_slot_behaviour(self, shipping_option, recwarn, mro_slots): + def test_slot_behaviour(self, shipping_option, mro_slots): inst = shipping_option for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self, shipping_option): assert shipping_option.id == self.id_ diff --git a/tests/test_shippingquery.py b/tests/test_shippingquery.py index 2ca3626db..92200bf99 100644 --- a/tests/test_shippingquery.py +++ b/tests/test_shippingquery.py @@ -39,14 +39,11 @@ class TestShippingQuery: from_user = User(0, '', False) shipping_address = ShippingAddress('GB', '', 'London', '12 Grimmauld Place', '', 'WC1') - def test_slot_behaviour(self, shipping_query, recwarn, mro_slots): + def test_slot_behaviour(self, shipping_query, mro_slots): inst = shipping_query for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = { diff --git a/tests/test_shippingqueryhandler.py b/tests/test_shippingqueryhandler.py index f0290ff8a..3bf699afc 100644 --- a/tests/test_shippingqueryhandler.py +++ b/tests/test_shippingqueryhandler.py @@ -83,14 +83,11 @@ def shiping_query(): class TestShippingQueryHandler: test_flag = False - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): inst = ShippingQueryHandler(self.callback_basic) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.callback = 'should give warning', self.callback_basic - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_slots.py b/tests/test_slots.py index f2684235a..4da5da352 100644 --- a/tests/test_slots.py +++ b/tests/test_slots.py @@ -24,22 +24,14 @@ from glob import iglob import inspect -excluded = { - 'telegram.error', - '_ConversationTimeoutContext', - 'DispatcherHandlerStop', - 'Days', - 'telegram.deprecate', - 'PassportDecryptionError', - 'ContextTypes', - 'CallbackDataCache', - 'InvalidCallbackData', - '_KeyboardData', - 'PersistenceInput', # This one as a named tuple - no need to worry about slots -} # These modules/classes intentionally don't have __dict__. +included = { # These modules/classes intentionally have __dict__. + 'CallbackContext', + 'BasePersistence', + 'Dispatcher', +} -def test_class_has_slots_and_dict(mro_slots): +def test_class_has_slots_and_no_dict(): tg_paths = [p for p in iglob("telegram/**/*.py", recursive=True) if 'vendor' not in p] for path in tg_paths: @@ -58,27 +50,19 @@ def test_class_has_slots_and_dict(mro_slots): x in name for x in {'__class__', '__init__', 'Queue', 'Webhook'} ): continue + assert '__slots__' in cls.__dict__, f"class '{name}' in {path} doesn't have __slots__" - if cls.__module__ in excluded or name in excluded: + # if the class slots is a string, then mro_slots() iterates through that string (bad). + assert not isinstance(cls.__slots__, str), f"{name!r}s slots shouldn't be strings" + + # specify if a certain module/class/base class should have dict- + if any(i in included for i in {cls.__module__, name, cls.__base__.__name__}): + assert '__dict__' in get_slots(cls), f"class {name!r} ({path}) has no __dict__" continue - assert '__dict__' in get_slots(cls), f"class '{name}' in {path} doesn't have __dict__" + + assert '__dict__' not in get_slots(cls), f"class '{name}' in {path} has __dict__" def get_slots(_class): slots = [attr for cls in _class.__mro__ if hasattr(cls, '__slots__') for attr in cls.__slots__] - - # We're a bit hacky here to handle cases correctly, where we can't read the parents slots from - # the mro - if '__dict__' not in slots: - try: - - class Subclass(_class): - __slots__ = ('__dict__',) - - except TypeError as exc: - if '__dict__ slot disallowed: we already got one' in str(exc): - slots.append('__dict__') - else: - raise exc - return slots diff --git a/tests/test_sticker.py b/tests/test_sticker.py index d45cc83f8..dfa291fda 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -90,10 +90,7 @@ class TestSticker: def test_slot_behaviour(self, sticker, mro_slots, recwarn): for attr in sticker.__slots__: assert getattr(sticker, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not sticker.__dict__, f"got missing slot(s): {sticker.__dict__}" assert len(mro_slots(sticker)) == len(set(mro_slots(sticker))), "duplicate slot" - sticker.custom, sticker.emoji = 'should give warning', self.emoji - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_creation(self, sticker): # Make sure file has been uploaded. diff --git a/tests/test_stringcommandhandler.py b/tests/test_stringcommandhandler.py index bcad48094..3dd74f2a3 100644 --- a/tests/test_stringcommandhandler.py +++ b/tests/test_stringcommandhandler.py @@ -71,14 +71,11 @@ def false_update(request): class TestStringCommandHandler: test_flag = False - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): inst = StringCommandHandler('sleepy', self.callback_basic) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.callback = 'should give warning', self.callback_basic - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_stringregexhandler.py b/tests/test_stringregexhandler.py index e526abe35..d6674f5dc 100644 --- a/tests/test_stringregexhandler.py +++ b/tests/test_stringregexhandler.py @@ -71,14 +71,11 @@ def false_update(request): class TestStringRegexHandler: test_flag = False - def test_slot_behaviour(self, mro_slots, recwarn): + def test_slot_behaviour(self, mro_slots): inst = StringRegexHandler('pfft', self.callback_basic) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.callback = 'should give warning', self.callback_basic - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_successfulpayment.py b/tests/test_successfulpayment.py index c44b783a5..2b4396b51 100644 --- a/tests/test_successfulpayment.py +++ b/tests/test_successfulpayment.py @@ -43,14 +43,11 @@ class TestSuccessfulPayment: telegram_payment_charge_id = 'telegram_payment_charge_id' provider_payment_charge_id = 'provider_payment_charge_id' - def test_slot_behaviour(self, successful_payment, recwarn, mro_slots): + def test_slot_behaviour(self, successful_payment, mro_slots): inst = successful_payment for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.currency = 'should give warning', self.currency - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = { diff --git a/tests/test_telegramobject.py b/tests/test_telegramobject.py index 880d0417b..d326ebb6a 100644 --- a/tests/test_telegramobject.py +++ b/tests/test_telegramobject.py @@ -86,14 +86,11 @@ class TestTelegramObject: subclass_instance = TelegramObjectSubclass() assert subclass_instance.to_dict() == {'a': 1} - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): inst = TelegramObject() for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom = 'should give warning' - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_meaningless_comparison(self, recwarn): expected_warning = "Objects of type TGO can not be meaningfully tested for equivalence." @@ -110,7 +107,8 @@ class TestTelegramObject: def test_meaningful_comparison(self, recwarn): class TGO(TelegramObject): - _id_attrs = (1,) + def __init__(self): + self._id_attrs = (1,) a = TGO() b = TGO() diff --git a/tests/test_typehandler.py b/tests/test_typehandler.py index 83fbfb479..68e8f59f3 100644 --- a/tests/test_typehandler.py +++ b/tests/test_typehandler.py @@ -28,14 +28,11 @@ from telegram.ext import TypeHandler, CallbackContext, JobQueue class TestTypeHandler: test_flag = False - def test_slot_behaviour(self, mro_slots, recwarn): + def test_slot_behaviour(self, mro_slots): inst = TypeHandler(dict, self.callback_basic) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.callback = 'should give warning', self.callback_basic - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.fixture(autouse=True) def reset(self): diff --git a/tests/test_update.py b/tests/test_update.py index d7f4e9ee0..faa70c64d 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -103,13 +103,10 @@ def update(request): class TestUpdate: update_id = 868573637 - def test_slot_behaviour(self, update, recwarn, mro_slots): + def test_slot_behaviour(self, update, mro_slots): for attr in update.__slots__: assert getattr(update, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not update.__dict__, f"got missing slot(s): {update.__dict__}" assert len(mro_slots(update)) == len(set(mro_slots(update))), "duplicate slot" - update.custom, update.update_id = 'should give warning', self.update_id - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list @pytest.mark.parametrize('paramdict', argvalues=params, ids=ids) def test_de_json(self, bot, paramdict): diff --git a/tests/test_updater.py b/tests/test_updater.py index a861acabb..9aba2fc07 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -35,6 +35,7 @@ from urllib.request import Request, urlopen from urllib.error import HTTPError import pytest +from .conftest import DictBot from telegram import ( TelegramError, @@ -90,24 +91,11 @@ class TestUpdater: offset = 0 test_flag = False - def test_slot_behaviour(self, updater, mro_slots, recwarn): + def test_slot_behaviour(self, updater, mro_slots): for at in updater.__slots__: at = f"_Updater{at}" if at.startswith('__') and not at.endswith('__') else at assert getattr(updater, at, 'err') != 'err', f"got extra slot '{at}'" - assert not updater.__dict__, f"got missing slot(s): {updater.__dict__}" assert len(mro_slots(updater)) == len(set(mro_slots(updater))), "duplicate slot" - updater.custom, updater.running = 'should give warning', updater.running - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list - - class CustomUpdater(Updater): - pass # Tests that setting custom attributes of Updater subclass doesn't raise warning - - a = CustomUpdater(updater.bot.token) - a.my_custom = 'no error!' - assert len(recwarn) == 1 - - updater.__setattr__('__test', 'mangled success') - assert getattr(updater, '_Updater__test', 'e') == 'mangled success', "mangling failed" @pytest.fixture(autouse=True) def reset(self): @@ -213,7 +201,7 @@ class TestUpdater: if ext_bot and not isinstance(updater.bot, ExtBot): updater.bot = ExtBot(updater.bot.token) if not ext_bot and not type(updater.bot) is Bot: - updater.bot = Bot(updater.bot.token) + updater.bot = DictBot(updater.bot.token) q = Queue() monkeypatch.setattr(updater.bot, 'set_webhook', lambda *args, **kwargs: True) diff --git a/tests/test_user.py b/tests/test_user.py index e3972963b..224f12842 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -65,13 +65,10 @@ class TestUser: can_read_all_group_messages = True supports_inline_queries = False - def test_slot_behaviour(self, user, mro_slots, recwarn): + def test_slot_behaviour(self, user, mro_slots): for attr in user.__slots__: assert getattr(user, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not user.__dict__, f"got missing slot(s): {user.__dict__}" assert len(mro_slots(user)) == len(set(mro_slots(user))), "duplicate slot" - user.custom, user.id = 'should give warning', self.id_ - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, json_dict, bot): user = User.de_json(json_dict, bot) diff --git a/tests/test_userprofilephotos.py b/tests/test_userprofilephotos.py index 05bf83c33..65b4ec33b 100644 --- a/tests/test_userprofilephotos.py +++ b/tests/test_userprofilephotos.py @@ -32,14 +32,11 @@ class TestUserProfilePhotos: ], ] - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): inst = UserProfilePhotos(self.total_count, self.photos) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.total_count = 'should give warning', self.total_count - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = {'total_count': 2, 'photos': [[y.to_dict() for y in x] for x in self.photos]} diff --git a/tests/test_venue.py b/tests/test_venue.py index c5ffc4e50..43aa25ad7 100644 --- a/tests/test_venue.py +++ b/tests/test_venue.py @@ -45,13 +45,10 @@ class TestVenue: google_place_id = 'google place id' google_place_type = 'google place type' - def test_slot_behaviour(self, venue, mro_slots, recwarn): + def test_slot_behaviour(self, venue, mro_slots): for attr in venue.__slots__: assert getattr(venue, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not venue.__dict__, f"got missing slot(s): {venue.__dict__}" assert len(mro_slots(venue)) == len(set(mro_slots(venue))), "duplicate slot" - venue.custom, venue.title = 'should give warning', self.title - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, bot): json_dict = { diff --git a/tests/test_video.py b/tests/test_video.py index 3d7821a5b..6c62ea403 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -60,13 +60,10 @@ class TestVideo: video_file_id = '5a3128a4d2a04750b5b58397f3b5e812' video_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e' - def test_slot_behaviour(self, video, mro_slots, recwarn): + def test_slot_behaviour(self, video, mro_slots): for attr in video.__slots__: assert getattr(video, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not video.__dict__, f"got missing slot(s): {video.__dict__}" assert len(mro_slots(video)) == len(set(mro_slots(video))), "duplicate slot" - video.custom, video.width = 'should give warning', self.width - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_creation(self, video): # Make sure file has been uploaded. diff --git a/tests/test_videonote.py b/tests/test_videonote.py index ea9c4eff6..10385e54f 100644 --- a/tests/test_videonote.py +++ b/tests/test_videonote.py @@ -53,13 +53,10 @@ class TestVideoNote: videonote_file_id = '5a3128a4d2a04750b5b58397f3b5e812' videonote_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e' - def test_slot_behaviour(self, video_note, recwarn, mro_slots): + def test_slot_behaviour(self, video_note, mro_slots): for attr in video_note.__slots__: assert getattr(video_note, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not video_note.__dict__, f"got missing slot(s): {video_note.__dict__}" assert len(mro_slots(video_note)) == len(set(mro_slots(video_note))), "duplicate slot" - video_note.custom, video_note.length = 'should give warning', self.length - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_creation(self, video_note): # Make sure file has been uploaded. diff --git a/tests/test_voice.py b/tests/test_voice.py index 73085b746..2efb52613 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -52,13 +52,10 @@ class TestVoice: voice_file_id = '5a3128a4d2a04750b5b58397f3b5e812' voice_file_unique_id = 'adc3145fd2e84d95b64d68eaa22aa33e' - def test_slot_behaviour(self, voice, recwarn, mro_slots): + def test_slot_behaviour(self, voice, mro_slots): for attr in voice.__slots__: assert getattr(voice, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not voice.__dict__, f"got missing slot(s): {voice.__dict__}" assert len(mro_slots(voice)) == len(set(mro_slots(voice))), "duplicate slot" - voice.custom, voice.duration = 'should give warning', self.duration - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_creation(self, voice): # Make sure file has been uploaded. diff --git a/tests/test_voicechat.py b/tests/test_voicechat.py index 159638500..7602403a8 100644 --- a/tests/test_voicechat.py +++ b/tests/test_voicechat.py @@ -40,14 +40,11 @@ def user2(): class TestVoiceChatStarted: - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): action = VoiceChatStarted() for attr in action.__slots__: assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not action.__dict__, f"got missing slot(s): {action.__dict__}" assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot" - action.custom = 'should give warning' - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self): voice_chat_started = VoiceChatStarted.de_json({}, None) @@ -62,14 +59,11 @@ class TestVoiceChatStarted: class TestVoiceChatEnded: duration = 100 - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): action = VoiceChatEnded(8) for attr in action.__slots__: assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not action.__dict__, f"got missing slot(s): {action.__dict__}" assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot" - action.custom = 'should give warning' - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self): json_dict = {'duration': self.duration} @@ -101,14 +95,11 @@ class TestVoiceChatEnded: class TestVoiceChatParticipantsInvited: - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): action = VoiceChatParticipantsInvited([user1]) for attr in action.__slots__: assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not action.__dict__, f"got missing slot(s): {action.__dict__}" assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot" - action.custom = 'should give warning' - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_de_json(self, user1, user2, bot): json_data = {"users": [user1.to_dict(), user2.to_dict()]} @@ -152,14 +143,11 @@ class TestVoiceChatParticipantsInvited: class TestVoiceChatScheduled: start_date = dtm.datetime.utcnow() - def test_slot_behaviour(self, recwarn, mro_slots): + def test_slot_behaviour(self, mro_slots): inst = VoiceChatScheduled(self.start_date) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not inst.__dict__, f"got missing slot(s): {inst.__dict__}" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - inst.custom, inst.start_date = 'should give warning', self.start_date - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_expected_values(self): assert pytest.approx(VoiceChatScheduled(start_date=self.start_date) == self.start_date) diff --git a/tests/test_webhookinfo.py b/tests/test_webhookinfo.py index a21349070..402d8e2e0 100644 --- a/tests/test_webhookinfo.py +++ b/tests/test_webhookinfo.py @@ -44,13 +44,10 @@ class TestWebhookInfo: max_connections = 42 allowed_updates = ['type1', 'type2'] - def test_slot_behaviour(self, webhook_info, mro_slots, recwarn): + def test_slot_behaviour(self, webhook_info, mro_slots): for attr in webhook_info.__slots__: assert getattr(webhook_info, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert not webhook_info.__dict__, f"got missing slot(s): {webhook_info.__dict__}" assert len(mro_slots(webhook_info)) == len(set(mro_slots(webhook_info))), "duplicate slot" - webhook_info.custom, webhook_info.url = 'should give warning', self.url - assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_to_dict(self, webhook_info): webhook_info_dict = webhook_info.to_dict()