From 3f2645ff423ba545d9ff6610205181733d2be68d Mon Sep 17 00:00:00 2001 From: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com> Date: Wed, 14 Jul 2021 20:42:41 +0200 Subject: [PATCH 01/16] Temporarily enable tests for the v14 branch --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f9dbe68851d..f66deb611b9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,9 +3,11 @@ on: pull_request: branches: - master + - v14 push: branches: - master + - v14 jobs: pytest: From d959b614a3b1fc477849cc7de5ac2b5356c2066c Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Mon, 9 Aug 2021 01:28:57 +0530 Subject: [PATCH 02/16] removed `__dict__` from all related classes --- telegram/base.py | 7 +---- telegram/bot.py | 8 ------ telegram/chataction.py | 6 +--- telegram/error.py | 1 - telegram/ext/basepersistence.py | 41 ++++++--------------------- telegram/ext/conversationhandler.py | 1 - telegram/ext/defaults.py | 5 ---- telegram/ext/dispatcher.py | 13 +-------- telegram/ext/extbot.py | 10 +------ telegram/ext/filters.py | 25 ++--------------- 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/document.py | 2 -- telegram/files/inputfile.py | 7 +---- telegram/parsemode.py | 6 +--- telegram/utils/deprecate.py | 21 +------------- telegram/utils/helpers.py | 2 +- telegram/utils/request.py | 6 +--- 21 files changed, 31 insertions(+), 203 deletions(-) diff --git a/telegram/base.py b/telegram/base.py index 0f906e9a4ad..358c3d2feb4 100644 --- a/telegram/base.py +++ b/telegram/base.py @@ -26,7 +26,6 @@ from typing import TYPE_CHECKING, List, Optional, Tuple, Type, TypeVar from telegram.utils.types import JSONDict -from telegram.utils.deprecate import set_new_attribute_deprecated if TYPE_CHECKING: from telegram import Bot @@ -41,8 +40,7 @@ class TelegramObject: # 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__ = () def __str__(self) -> str: return str(self.to_dict()) @@ -50,9 +48,6 @@ def __str__(self) -> str: 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() diff --git a/telegram/bot.py b/telegram/bot.py index 87eec560ce4..de445d8b467 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -224,14 +224,6 @@ def __init__( 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/chataction.py b/telegram/chataction.py index c737b810fbc..9b2ebfbf1b1 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 @@ -65,6 +64,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/error.py b/telegram/error.py index 5e597cd2b77..741d033c6de 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/basepersistence.py b/telegram/ext/basepersistence.py index 974b97f8f8c..4c1ec7c1a1d 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 -from telegram.utils.deprecate import set_new_attribute_deprecated - from telegram import Bot import telegram.ext.extbot @@ -93,24 +90,14 @@ class BasePersistence(Generic[UD, CD, BD], ABC): .. versionadded:: 13.6 """ - # Apparently Py 3.7 and below have '__dict__' in ABC - if py_ver < (3, 7): - __slots__ = ( - 'store_user_data', - 'store_chat_data', - 'store_bot_data', - 'store_callback_data', - 'bot', - ) - else: - __slots__ = ( - 'store_user_data', # type: ignore[assignment] - 'store_chat_data', - 'store_bot_data', - 'store_callback_data', - 'bot', - '__dict__', - ) + __slots__ = ( + 'store_user_data', + 'store_chat_data', + 'store_bot_data', + 'store_callback_data', + 'bot', + '__dict__', + ) def __new__( cls, *args: object, **kwargs: object # pylint: disable=W0613 @@ -160,7 +147,7 @@ def update_callback_data_replace_bot(data: CDCData) -> None: 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__ + # 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) @@ -184,16 +171,6 @@ def __init__( self.store_callback_data = store_callback_data 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 ba621fdeaa5..fe1978b5bf7 100644 --- a/telegram/ext/conversationhandler.py +++ b/telegram/ext/conversationhandler.py @@ -46,7 +46,6 @@ 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 8546f717536..41b063e58b3 100644 --- a/telegram/ext/defaults.py +++ b/telegram/ext/defaults.py @@ -22,7 +22,6 @@ 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 @@ def __init__( 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 3322acfe5a0..fe0670c51ee 100644 --- a/telegram/ext/dispatcher.py +++ b/telegram/ext/dispatcher.py @@ -48,7 +48,7 @@ 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 @@ def __init__( 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 842b8e4e11d..a10e781b911 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, @@ -263,7 +255,7 @@ def _effective_inline_results( # pylint: disable=R0201 # 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 72a4b30f22a..ed7d0a85ce2 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -23,7 +23,6 @@ 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 @@ '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,10 +112,7 @@ class variable. (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 instance = super().__new__(cls) @@ -141,18 +137,6 @@ def __xor__(self, other: 'BaseFilter') -> 'BaseFilter': 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 +421,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 befaf413979..81e35852a18 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 @@ def __init__( 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 da2dea4f210..a49290e9900 100644 --- a/telegram/ext/jobqueue.py +++ b/telegram/ext/jobqueue.py @@ -31,7 +31,6 @@ 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 @@ def aps_log_filter(record): # type: ignore 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 @@ def __init__( 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 37a2e7e526a..3793c7d52f3 100644 --- a/telegram/ext/updater.py +++ b/telegram/ext/updater.py @@ -42,7 +42,7 @@ 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 @@ def __init__( # type: ignore[no-untyped-def,misc] 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 6b548242972..8277eb15ca2 100644 --- a/telegram/ext/utils/promise.py +++ b/telegram/ext/utils/promise.py @@ -22,7 +22,6 @@ 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 @@ def __init__( 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 ddf5e6904e9..b328c613aa7 100644 --- a/telegram/ext/utils/webhookhandler.py +++ b/telegram/ext/utils/webhookhandler.py @@ -31,7 +31,6 @@ 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 @@ def __init__( 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/document.py b/telegram/files/document.py index dad9f9bf37f..5d9942644be 100644 --- a/telegram/files/document.py +++ b/telegram/files/document.py @@ -71,8 +71,6 @@ class Document(TelegramObject): '_id_attrs', ) - _id_keys = ('file_id',) - def __init__( self, file_id: str, diff --git a/telegram/files/inputfile.py b/telegram/files/inputfile.py index 583f4a60d61..9f91367be23 100644 --- a/telegram/files/inputfile.py +++ b/telegram/files/inputfile.py @@ -26,8 +26,6 @@ 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 @@ def __init__(self, obj: Union[IO, bytes], filename: str = None, attach: bool = N 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/parsemode.py b/telegram/parsemode.py index 86bc07b368a..2ecdf2b6af2 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/utils/deprecate.py b/telegram/utils/deprecate.py index ebccc6eb922..7945695937b 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 6705cc90662..24fa88d1d21 100644 --- a/telegram/utils/helpers.py +++ b/telegram/utils/helpers.py @@ -544,7 +544,7 @@ def f(arg=DefaultOne): """ - __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 f2c35bfdffc..95556c4e8cb 100644 --- a/telegram/utils/request.py +++ b/telegram/utils/request.py @@ -70,7 +70,6 @@ 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 @@ def __init__( 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.""" From 5e45dc7fa5abcafcd46609734be8c2586ea745b0 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Mon, 9 Aug 2021 01:31:59 +0530 Subject: [PATCH 03/16] Modify slot tests + other stuff mentioned in pr --- tests/conftest.py | 29 ++++++++---- 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_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_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 | 45 +++++++------------ tests/test_sticker.py | 3 -- tests/test_stringcommandhandler.py | 5 +-- tests/test_stringregexhandler.py | 5 +-- tests/test_successfulpayment.py | 5 +-- tests/test_telegramobject.py | 5 +-- 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 | 3 -- 127 files changed, 176 insertions(+), 619 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 6eae0a71fc8..995b42ad0c5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -44,6 +44,7 @@ ChosenInlineResult, File, ChatPermissions, + Bot, ) from telegram.ext import ( Dispatcher, @@ -56,6 +57,7 @@ ) 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,21 @@ def bot_info(): return get_bot() +class DictRequest(Request): # Used for monkey patching attributes + pass + + +class DictExtBot(ExtBot): + pass # Subclass ExtBot to allow monkey patching of attributes & methods by adding a __dict__. + + +class DictBot(Bot): # This is used in a webhook test. + 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 = {} @@ -149,6 +158,8 @@ def provider_token(bot_info): def create_dp(bot): # Dispatcher is heavy to init (due to many threads and such) so we have a single session # scoped one here, but before each test, reset it (dp fixture below) + # class DictDispatcher(Dispatcher): + # pass dispatcher = Dispatcher(bot, Queue(), job_queue=JobQueue(), workers=2, use_context=False) dispatcher.job_queue.set_dispatcher(dispatcher) thr = Thread(target=dispatcher.start) @@ -230,7 +241,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 +372,9 @@ def _mro_slots(_class): 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 b90baeafbb1..7cfde3ba993 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 924c7220f63..c1687dbd45a 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 d2a6dadff97..747c5a96cc6 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -137,20 +137,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 1b750d99601..91c255ddd49 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 25e5d5877b6..8280921cc3c 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 7e6b73b78f2..ed0fdc85e2d 100644 --- a/tests/test_callbackcontext.py +++ b/tests/test_callbackcontext.py @@ -38,7 +38,7 @@ 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 318071328d0..c93e4166ae5 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 @@ def test_slot_behaviour(self, mro_slots): 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 @@ def test_slot_behaviour(self, callback_data_cache, mro_slots): 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 56aede6708b..04bb4ac694f 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 1f65ffd0ca0..58c4ccf34c7 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 a60956c485e..d888ce52037 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -63,13 +63,10 @@ class TestChat: linked_chat_id = 11880 location = ChatLocation(Location(123, 456), 'Barbie World') - 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 61903992872..e96510263df 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 8b4fcadfd5a..33d88cc81f2 100644 --- a/tests/test_chatinvitelink.py +++ b/tests/test_chatinvitelink.py @@ -49,13 +49,10 @@ class TestChatInviteLink: expire_date = datetime.datetime.utcnow() member_limit = 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_chatlocation.py b/tests/test_chatlocation.py index 1facfde2e63..ded9a074289 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 ce4f0757c61..62c296c37fb 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 1fc75c71d61..999bb743264 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 d90e83761f1..681be38edda 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 c47ae6669c3..2bfdd3a026c 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 3676b0e1b81..32ea64c1f53 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 a6a797ce076..0f7c1dc165a 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 1803a291b9c..1c7c5e0f5e8 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 6c6262545b2..f183597f77b 100644 --- a/tests/test_commandhandler.py +++ b/tests/test_commandhandler.py @@ -142,14 +142,11 @@ def _test_edited(self, message, handler_edited, handler_not_edited): 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 4ad6b699a97..bcc5a6c9248 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 20dd405f9fe..b19a488a328 100644 --- a/tests/test_contexttypes.py +++ b/tests/test_contexttypes.py @@ -31,8 +31,6 @@ def test_slot_behaviour(self, mro_slots): 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 eaee2afa31d..6eaefcbb328 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 @@ def test_schedule_job_exception(self, dp, bot, user1, monkeypatch, caplog): 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 99a85bae481..754588f5e26 100644 --- a/tests/test_defaults.py +++ b/tests/test_defaults.py @@ -24,14 +24,11 @@ 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 cced0400199..02c043b2ee5 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 4c25f8a3ab1..b1185105077 100644 --- a/tests/test_dispatcher.py +++ b/tests/test_dispatcher.py @@ -57,24 +57,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 fa00faf6ea1..e9e1a27d399 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 085f82f12e4..a8704a40b11 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 0505c5ad0e6..225496ee453 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 953be29e9ab..78d7a78a043 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 efebc477faf..8a5937f9995 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -22,7 +22,7 @@ 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 @@ def test_all_filters_slot_behaviour(self, recwarn, mro_slots): 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 @@ def filter(self, message: Message): 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 f5f09b26d44..630a043e9af 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 8207cd70855..376c3e9025b 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 166e22cf617..8c00c618bb2 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 b4a43c10ff2..5c107a0deb6 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 @@ def check_update(self, update: object): 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 f60fced6d02..468c7da46ca 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 719adaa4c04..8d4e35daaa5 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 3e80b27c544..d9ce3217b6c 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 4688a8004ea..e084554dcaa 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 @@ def test_chat_types(self, cdp, inline_query, chat_types, chat_type, result): 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 a5a383d1d35..16f50102c03 100644 --- a/tests/test_inlinequeryresultarticle.py +++ b/tests/test_inlinequeryresultarticle.py @@ -61,10 +61,7 @@ def test_slot_behaviour(self, inline_query_result_article, mro_slots, recwarn): 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 5071a49a169..336503c4732 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 33ee9b858bb..1664a0ca090 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 a25d089df91..ad014dc277b 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 83bf386dd03..ec8169c4f24 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 edd48538888..727d7ab0c0b 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 30f6b6c0485..b5e6b11fea8 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 42615fc66f3..b754b9f0422 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 7a933e279e7..dd068c3485c 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 a87239bd9e8..5f1c68e7509 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 c8f74e2b095..ea5aa3999a6 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 983ddbab87d..23afc727e69 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 11fe9528015..82fad84c1a8 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 a5e25168547..fc62e55bdf8 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 5b4142eee23..4b70aa735c8 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 cd5d2ec3b0c..33b95c42a88 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 5fd21bd63ef..3733c44817c 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 b6144657091..37a84f4dd05 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 5e9442a1c2f..c72468af1c0 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 ae86a48fb74..bae04225a65 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 b577059a63b..b706c29c6ff 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 3b0b4ebd24c..965a0943484 100644 --- a/tests/test_inputfile.py +++ b/tests/test_inputfile.py @@ -28,14 +28,11 @@ 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 40b0ce0be61..8826f516446 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 11f679c04ee..1187706ff6c 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 5f0d10b6506..63d6caf08fd 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 c996d8fe3f9..49cc71651e9 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 1168b91e20c..f08c62db9d6 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 92377f40d11..73ae94e9a51 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 2851827dc63..5e2bb5e58db 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 3c3fd4c04f0..94b481ec32c 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 dafe0d9f344..c230890a1b0 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 bfcd72edda2..018c8224030 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 20cd46a1192..aad299b8f9f 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 c638c9234d5..3ea18d8db55 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 5ed66b4dcb7..5203510ed27 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -307,13 +307,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 15a62f73e06..74d2208766b 100644 --- a/tests/test_messageautodeletetimerchanged.py +++ b/tests/test_messageautodeletetimerchanged.py @@ -22,14 +22,11 @@ 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 2f632c073c1..46c20b0162b 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 29d0c3d1ca3..55f05d498c3 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 2573c13d8e5..ffad09b187b 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_orderinfo.py b/tests/test_orderinfo.py index 90faeafaecb..6eaa3bd6cad 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 3c7644877bb..621143291b3 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 38687f9651b..748ce9cfe05 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 2073df2ab45..68f50e58ee3 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 f7dd0c5d85b..4f1c1f59d23 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 5dcab832d63..d6c68ef6429 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 fed480e0b17..092b803f9be 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 a4172e76d69..bd65b753f57 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 ea804012fcd..b6331d74f1e 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 e30d0af768a..3e5b0ddb5e9 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 5911d59e488..53ba8345bd9 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 7a9d67d59fd..6b9ec9974aa 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 ef3b54f6b8a..cfbe7a0c23b 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 56e797219df..87fe030c428 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -34,7 +34,6 @@ from collections import defaultdict from collections.abc import Container from time import sleep -from sys import version_info as py_ver import pytest @@ -219,16 +218,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_user_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_chat_data @@ -1030,14 +1026,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_user_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() @@ -1968,10 +1961,7 @@ def test_slot_behaviour(self, mro_slots, recwarn): 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_user_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 d6096056df5..687a992529d 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 cd93f907ca1..b811def4d4f 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 a944c09a308..f8875f88750 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 e4b52148b91..8c034fb76ab 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 d9efd8e07ad..5d57c08e568 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 642a77e3623..3bda03a0a26 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 ceb9f196e7d..5e0b324341f 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 8e09cc00d2b..2ee35026a18 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 03ee1751fec..cbf3eba50f4 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 67587a49bd7..b95cdec8c05 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 c948b04e3dd..e45fb5bb9c1 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 4442320c855..cf50d83cfe1 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -22,14 +22,11 @@ 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 4146cdad019..ba0865bbf36 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 7f0f0f3fbd0..71c91376cbf 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 58a4783ed58..ee2d67f2e88 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 cfa9ecbbdca..144d2b0c82e 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 f7579b08e7c..adba1f8b700 100644 --- a/tests/test_slots.py +++ b/tests/test_slots.py @@ -24,21 +24,14 @@ import inspect -excluded = { - 'telegram.error', - '_ConversationTimeoutContext', - 'DispatcherHandlerStop', - 'Days', - 'telegram.deprecate', - 'TelegramDecryptionError', - 'ContextTypes', - 'CallbackDataCache', - 'InvalidCallbackData', - '_KeyboardData', -} # 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: @@ -57,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 bb614b939e5..23e1e3c2988 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -77,10 +77,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 1fd7ea04881..f1cd426042a 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 160514c4e8c..2fc926b36e8 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 471f695587b..8066e43d970 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 96ae1bd3edc..90bfff65659 100644 --- a/tests/test_telegramobject.py +++ b/tests/test_telegramobject.py @@ -86,14 +86,11 @@ def __init__(self): 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." diff --git a/tests/test_typehandler.py b/tests/test_typehandler.py index c550dee9fce..e355d843672 100644 --- a/tests/test_typehandler.py +++ b/tests/test_typehandler.py @@ -28,14 +28,11 @@ 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 2777ff00893..e095541d132 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -91,13 +91,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 b574319f0f8..46ea5493e51 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -35,6 +35,7 @@ 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 @@ def test_webhook(self, monkeypatch, updater, ext_bot): 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 85f75bb8b59..653e22c9f1b 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 84a428da18c..f88d2a86b75 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 185318211ff..5272c9b7678 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 0eca16798ea..ca1537540a4 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 7f8c39773fb..6ca10f670dc 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 df45da699fd..321ad8c59cd 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 8969a2e01b2..94174bb4183 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 @@ def test_to_dict(self): 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 @@ def test_equality(self): 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 @@ def test_equality(self, user1, user2): 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 9b07932f508..c07d3e27615 100644 --- a/tests/test_webhookinfo.py +++ b/tests/test_webhookinfo.py @@ -47,10 +47,7 @@ class TestWebhookInfo: def test_slot_behaviour(self, webhook_info, mro_slots, recwarn): 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() From cd3a4d7ccce60749be80ba13f7042bf2b1b2b9f9 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Mon, 9 Aug 2021 02:11:11 +0530 Subject: [PATCH 04/16] remove unused recwarn param in test --- tests/test_webhookinfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_webhookinfo.py b/tests/test_webhookinfo.py index c07d3e27615..8da6f9aee86 100644 --- a/tests/test_webhookinfo.py +++ b/tests/test_webhookinfo.py @@ -44,7 +44,7 @@ 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 len(mro_slots(webhook_info)) == len(set(mro_slots(webhook_info))), "duplicate slot" From 4b380b54c82319af529e6bba12fd3eed899ee159 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Mon, 9 Aug 2021 02:26:18 +0530 Subject: [PATCH 05/16] remove py3.6 related code from ext's __init__.py --- telegram/ext/__init__.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/telegram/ext/__init__.py b/telegram/ext/__init__.py index 731ad2c9e49..6f43a1634cb 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 .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 From 37ef9708cd869823de210d425a74f588494b114f Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Mon, 9 Aug 2021 02:27:13 +0530 Subject: [PATCH 06/16] remove py3.6 from test matrix --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f66deb611b9..368600092dd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,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: From 0f1f9b3eeb2c9e2c6c567d19f8ac8a0434a67603 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 12 Aug 2021 17:42:36 +0530 Subject: [PATCH 07/16] Address review 1 --- telegram/ext/basepersistence.py | 18 +++++++++--------- tests/conftest.py | 7 ++++--- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/telegram/ext/basepersistence.py b/telegram/ext/basepersistence.py index 4c1ec7c1a1d..d413bff3732 100644 --- a/telegram/ext/basepersistence.py +++ b/telegram/ext/basepersistence.py @@ -96,7 +96,7 @@ class BasePersistence(Generic[UD, CD, BD], ABC): 'store_bot_data', 'store_callback_data', 'bot', - '__dict__', + '__dict__', # __dict__ is included because we replace methods in the __new__ ) def __new__( @@ -148,14 +148,14 @@ def update_callback_data_replace_bot(data: CDCData) -> None: return update_callback_data((instance.replace_bot(obj_data), queue)) # 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) + 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__( diff --git a/tests/conftest.py b/tests/conftest.py index 995b42ad0c5..c10087e1ed6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -91,15 +91,16 @@ def bot_info(): return get_bot() -class DictRequest(Request): # Used for monkey patching attributes +# Below Dict* classes are used to monkeypatch attributes since parent classes don't have __dict__ +class DictRequest(Request): pass class DictExtBot(ExtBot): - pass # Subclass ExtBot to allow monkey patching of attributes & methods by adding a __dict__. + pass -class DictBot(Bot): # This is used in a webhook test. +class DictBot(Bot): pass From b250adcdd2d84a94d6aecbdc93fa1cf7fc568d8a Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 12 Aug 2021 22:50:42 +0530 Subject: [PATCH 08/16] fix merge conflict --- tests/test_slots.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/test_slots.py b/tests/test_slots.py index aec568d00c9..adba1f8b700 100644 --- a/tests/test_slots.py +++ b/tests/test_slots.py @@ -29,18 +29,6 @@ 'BasePersistence', 'Dispatcher', } -excluded = { - 'telegram.error', - '_ConversationTimeoutContext', - 'DispatcherHandlerStop', - 'Days', - 'telegram.deprecate', - 'PassportDecryptionError', - 'ContextTypes', - 'CallbackDataCache', - 'InvalidCallbackData', - '_KeyboardData', -} # These modules/classes intentionally don't have __dict__. def test_class_has_slots_and_no_dict(): From c0c62957509442649d80a2f81d6d626d048c4281 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 12 Aug 2021 23:49:54 +0530 Subject: [PATCH 09/16] forget about DictDispatcher in tests --- tests/conftest.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index c10087e1ed6..2fcf61bcecc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -159,8 +159,6 @@ def provider_token(bot_info): def create_dp(bot): # Dispatcher is heavy to init (due to many threads and such) so we have a single session # scoped one here, but before each test, reset it (dp fixture below) - # class DictDispatcher(Dispatcher): - # pass dispatcher = Dispatcher(bot, Queue(), job_queue=JobQueue(), workers=2, use_context=False) dispatcher.job_queue.set_dispatcher(dispatcher) thr = Thread(target=dispatcher.start) From 909abcbb34d0c5208196d6563d97e34dc5058d20 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 14 Aug 2021 02:52:38 +0530 Subject: [PATCH 10/16] move _id_attrs to __new__ --- telegram/base.py | 27 +++++++++++-------- telegram/botcommand.py | 2 +- telegram/botcommandscope.py | 6 ++--- telegram/callbackquery.py | 1 - telegram/chat.py | 1 - telegram/chatinvitelink.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/files/animation.py | 1 - telegram/files/audio.py | 1 - telegram/files/chatphoto.py | 1 - telegram/files/contact.py | 2 +- telegram/files/document.py | 1 - telegram/files/file.py | 1 - 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 | 5 ++-- 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/passport/credentials.py | 1 - telegram/passport/encryptedpassportelement.py | 1 - telegram/passport/passportdata.py | 2 +- telegram/passport/passportelementerrors.py | 6 ++--- 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/voicechat.py | 6 ++--- telegram/webhookinfo.py | 1 - tests/test_telegramobject.py | 3 ++- 66 files changed, 59 insertions(+), 88 deletions(-) diff --git a/telegram/base.py b/telegram/base.py index 358c3d2feb4..77fa32f1bb8 100644 --- a/telegram/base.py +++ b/telegram/base.py @@ -23,7 +23,7 @@ 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 from telegram.utils.types import JSONDict @@ -36,11 +36,14 @@ class TelegramObject: """Base class for most Telegram objects.""" - _id_attrs: Tuple[object, ...] = () - # Adding slots reduces memory usage & allows for faster attribute access. # Only instance variables should be added to __slots__. - __slots__ = () + __slots__ = ('_id_attrs',) + + def __new__(cls, *args: object, **kwargs: object) -> 'TelegramObject': # pylint: disable=W0613 + instance = super().__new__(cls) + instance._id_attrs = () # cannot add type hint since it is not read + return instance def __str__(self) -> str: return str(self.to_dict()) @@ -71,7 +74,7 @@ def de_json(cls: Type[TO], data: Optional[JSONDict], bot: 'Bot') -> Optional[TO] 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]]: @@ -127,21 +130,23 @@ def to_dict(self) -> JSONDict: return data def __eq__(self, other: object) -> bool: + # pylint: disable=no-member if isinstance(other, self.__class__): - if self._id_attrs == (): + if self._id_attrs == (): # type: ignore[attr-defined] warnings.warn( f"Objects of type {self.__class__.__name__} can not be meaningfully tested for" " equivalence." ) - if other._id_attrs == (): + if other._id_attrs == (): # type: ignore[attr-defined] warnings.warn( f"Objects of type {other.__class__.__name__} can not be meaningfully tested" " for equivalence." ) - return self._id_attrs == other._id_attrs - return super().__eq__(other) # pylint: disable=no-member + return self._id_attrs == other._id_attrs # type: ignore[attr-defined] + return super().__eq__(other) def __hash__(self) -> int: - if self._id_attrs: - return hash((self.__class__, self._id_attrs)) # pylint: disable=no-member + # pylint: disable=no-member + if self._id_attrs: # type: ignore[attr-defined] + return hash((self.__class__, self._id_attrs)) # type: ignore[attr-defined] return super().__hash__() diff --git a/telegram/botcommand.py b/telegram/botcommand.py index 8b36e3e2e86..c5e2275644e 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 b4729290bd0..be1fdea8240 100644 --- a/telegram/botcommandscope.py +++ b/telegram/botcommandscope.py @@ -18,7 +18,7 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. # pylint: disable=W0622 """This module contains objects representing Telegram bot command scopes.""" -from typing import Any, Union, Optional, TYPE_CHECKING, Dict, Type +from typing import Any, Union, Optional, TYPE_CHECKING, Dict, Type, Tuple from telegram import TelegramObject, constants from telegram.utils.types import JSONDict @@ -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`""" @@ -76,7 +76,7 @@ class BotCommandScope(TelegramObject): def __init__(self, type: str, **_kwargs: Any): self.type = type - self._id_attrs = (self.type,) + self._id_attrs: Tuple[object, ...] = (self.type,) @classmethod def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['BotCommandScope']: diff --git a/telegram/callbackquery.py b/telegram/callbackquery.py index 47b05b97129..9630bd46fed 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 4b5b6c844ff..713d6b78fcb 100644 --- a/telegram/chat.py +++ b/telegram/chat.py @@ -166,7 +166,6 @@ class Chat(TelegramObject): 'linked_chat_id', 'all_members_are_administrators', 'message_auto_delete_time', - '_id_attrs', ) SENDER: ClassVar[str] = constants.CHAT_SENDER diff --git a/telegram/chatinvitelink.py b/telegram/chatinvitelink.py index 0755853b007..8e94c8499af 100644 --- a/telegram/chatinvitelink.py +++ b/telegram/chatinvitelink.py @@ -67,7 +67,6 @@ class ChatInviteLink(TelegramObject): 'is_revoked', 'expire_date', 'member_limit', - '_id_attrs', ) def __init__( diff --git a/telegram/chatlocation.py b/telegram/chatlocation.py index dcdbb6f0024..4cd06e8da0e 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 254836bd0e1..445ba35a97b 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 4d49a6c7eca..9654fc56131 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 0b5a7b956bb..8bedef1702d 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 384d57e638e..f4ac36a6a5e 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 3406ceedad8..2f4a302cd0b 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/files/animation.py b/telegram/files/animation.py index 199cf332826..dae6d4298b9 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 d95711acd96..72c72ec7182 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 5302c7e9826..39f1effa195 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 257fdf474be..40dfc429089 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 5d9942644be..4c57a06abf4 100644 --- a/telegram/files/document.py +++ b/telegram/files/document.py @@ -68,7 +68,6 @@ class Document(TelegramObject): 'thumb', 'mime_type', 'file_unique_id', - '_id_attrs', ) def __init__( diff --git a/telegram/files/file.py b/telegram/files/file.py index c3391bd95ca..3896e3eb7b5 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/location.py b/telegram/files/location.py index 8f5c1c63daa..2db8ef9576f 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 831a7c01194..77737e7f570 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 681c7087b24..b46732516b7 100644 --- a/telegram/files/sticker.py +++ b/telegram/files/sticker.py @@ -85,7 +85,6 @@ class Sticker(TelegramObject): 'height', 'file_unique_id', 'emoji', - '_id_attrs', ) def __init__( @@ -182,7 +181,6 @@ class StickerSet(TelegramObject): 'title', 'stickers', 'name', - '_id_attrs', ) def __init__( @@ -258,7 +256,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 3ba2c53a376..a45c9b64d46 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 76bb07cda7a..986d9576be3 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 8c704069ed7..f6821c9f023 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 f65c5c590ca..d10cd0aab31 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 baa9782810e..64e6d2293a6 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 d56bebe0275..7f3e2bc110d 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 bfa7cbfbf15..418c7f4683a 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 b9d0c32165a..72678cff2a3 100644 --- a/telegram/inline/inlinekeyboardbutton.py +++ b/telegram/inline/inlinekeyboardbutton.py @@ -18,7 +18,7 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains an object that represents a Telegram InlineKeyboardButton.""" -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Tuple from telegram import TelegramObject @@ -106,7 +106,6 @@ class InlineKeyboardButton(TelegramObject): 'pay', 'switch_inline_query', 'text', - '_id_attrs', 'login_url', ) @@ -133,7 +132,7 @@ def __init__( self.switch_inline_query_current_chat = switch_inline_query_current_chat self.callback_game = callback_game self.pay = pay - self._id_attrs = () + self._id_attrs: Tuple[object, ...] = () self._set_id_attrs() def _set_id_attrs(self) -> None: diff --git a/telegram/inline/inlinekeyboardmarkup.py b/telegram/inline/inlinekeyboardmarkup.py index a917d96f3e9..cff50391bac 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 412188db49b..24fa1f5b0bd 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 756e2fb9ce8..30068f96267 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 22e9460c76a..d7baae74553 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 2cbbcb8f437..ee6783725eb 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 fe8662882be..9d06713ad85 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 3d60f456c0d..7d3251e7993 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 55652d2a9a9..4e2689889ac 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 590801b2c42..f46d2518e6c 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 89be62a0213..7dce551fc21 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 a5f38300a61..debd6897060 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 63e18bf8069..bd80785bae2 100644 --- a/telegram/message.py +++ b/telegram/message.py @@ -390,7 +390,6 @@ class Message(TelegramObject): 'voice_chat_participants_invited', 'voice_chat_started', 'voice_chat_scheduled', - '_id_attrs', ) ATTACHMENT_TYPES: ClassVar[List[str]] = [ diff --git a/telegram/messageautodeletetimerchanged.py b/telegram/messageautodeletetimerchanged.py index 3fb1ce91913..bd06fa2dcac 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 0a0350eebbc..7f07960e0fa 100644 --- a/telegram/messageentity.py +++ b/telegram/messageentity.py @@ -59,7 +59,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 56eca3a19e6..80da7063119 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/passport/credentials.py b/telegram/passport/credentials.py index 24d853575a9..cfed2c22275 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 74e3aaf6719..700655e8cfc 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 4b09683afa4..93ba74f1953 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 4d61f962b42..210c1483c6f 100644 --- a/telegram/passport/passportelementerrors.py +++ b/telegram/passport/passportelementerrors.py @@ -19,7 +19,7 @@ # pylint: disable=W0622 """This module contains the classes that represent Telegram PassportElementError.""" -from typing import Any +from typing import Any, Tuple from telegram import TelegramObject @@ -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 @@ -54,7 +54,7 @@ def __init__(self, source: str, type: str, message: str, **_kwargs: Any): self.type = str(type) self.message = str(message) - self._id_attrs = (self.source, self.type) + self._id_attrs: Tuple[object, ...] = (self.source, self.type) class PassportElementErrorDataField(PassportElementError): diff --git a/telegram/passport/passportfile.py b/telegram/passport/passportfile.py index b5f21220044..b8356acf9b5 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 dea274035b0..34ba2496050 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 221c62dbc05..2e6f1a5d770 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 7ebe35851ed..8a78482044f 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 a8f2eb29304..0c8c5f77349 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 2ea5a458ee0..5af7152cd33 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 6ddbb0bc23d..9eba5b1522a 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 bcde858b636..9ab8594f0e1 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 6997ca7354a..696287181af 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 9c28ce57d57..dc6d7327426 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 507fb779f81..98bb41b51d7 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 1f365e6aba6..28eb87047e8 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 8497ee213a5..b8acfe9bdec 100644 --- a/telegram/update.py +++ b/telegram/update.py @@ -143,7 +143,6 @@ class Update(TelegramObject): '_effective_message', 'my_chat_member', 'chat_member', - '_id_attrs', ) MESSAGE = constants.UPDATE_MESSAGE diff --git a/telegram/user.py b/telegram/user.py index 7949e249e2d..b14984a85e3 100644 --- a/telegram/user.py +++ b/telegram/user.py @@ -107,7 +107,6 @@ class User(TelegramObject): 'id', 'bot', 'language_code', - '_id_attrs', ) def __init__( diff --git a/telegram/userprofilephotos.py b/telegram/userprofilephotos.py index bd277bf1fb7..95b44da1ce0 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/voicechat.py b/telegram/voicechat.py index 4fb7b539891..c76553d5e2f 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 0fc6741e498..de54cc96174 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/test_telegramobject.py b/tests/test_telegramobject.py index 90bfff65659..70142093e8c 100644 --- a/tests/test_telegramobject.py +++ b/tests/test_telegramobject.py @@ -107,7 +107,8 @@ class TGO(TelegramObject): def test_meaningful_comparison(self, recwarn): class TGO(TelegramObject): - _id_attrs = (1,) + def __init__(self): + self._id_attrs = (1,) a = TGO() b = TGO() From 88a7e13d1278358b6f4571fea8cdb18a882ac1cb Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Mon, 16 Aug 2021 01:11:34 +0530 Subject: [PATCH 11/16] Better workaround for type hint of _id_attrs --- telegram/base.py | 21 ++++++++++++++------- telegram/botcommandscope.py | 4 ++-- telegram/inline/inlinekeyboardbutton.py | 4 ++-- telegram/passport/passportelementerrors.py | 4 ++-- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/telegram/base.py b/telegram/base.py index 77fa32f1bb8..e8fc3a98096 100644 --- a/telegram/base.py +++ b/telegram/base.py @@ -23,7 +23,7 @@ import json # type: ignore[no-redef] import warnings -from typing import TYPE_CHECKING, List, Optional, Type, TypeVar +from typing import TYPE_CHECKING, List, Optional, Type, TypeVar, Tuple from telegram.utils.types import JSONDict @@ -36,13 +36,20 @@ class TelegramObject: """Base class for most Telegram objects.""" + # 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__. __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 = () # cannot add type hint since it is not read + instance._id_attrs = () return instance def __str__(self) -> str: @@ -132,21 +139,21 @@ def to_dict(self) -> JSONDict: def __eq__(self, other: object) -> bool: # pylint: disable=no-member if isinstance(other, self.__class__): - if self._id_attrs == (): # type: ignore[attr-defined] + if self._id_attrs == (): warnings.warn( f"Objects of type {self.__class__.__name__} can not be meaningfully tested for" " equivalence." ) - if other._id_attrs == (): # type: ignore[attr-defined] + if other._id_attrs == (): warnings.warn( f"Objects of type {other.__class__.__name__} can not be meaningfully tested" " for equivalence." ) - return self._id_attrs == other._id_attrs # type: ignore[attr-defined] + return self._id_attrs == other._id_attrs return super().__eq__(other) def __hash__(self) -> int: # pylint: disable=no-member - if self._id_attrs: # type: ignore[attr-defined] - return hash((self.__class__, self._id_attrs)) # type: ignore[attr-defined] + if self._id_attrs: + return hash((self.__class__, self._id_attrs)) return super().__hash__() diff --git a/telegram/botcommandscope.py b/telegram/botcommandscope.py index be1fdea8240..2d2a0419d39 100644 --- a/telegram/botcommandscope.py +++ b/telegram/botcommandscope.py @@ -18,7 +18,7 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. # pylint: disable=W0622 """This module contains objects representing Telegram bot command scopes.""" -from typing import Any, Union, Optional, TYPE_CHECKING, Dict, Type, Tuple +from typing import Any, Union, Optional, TYPE_CHECKING, Dict, Type from telegram import TelegramObject, constants from telegram.utils.types import JSONDict @@ -76,7 +76,7 @@ class BotCommandScope(TelegramObject): def __init__(self, type: str, **_kwargs: Any): self.type = type - self._id_attrs: Tuple[object, ...] = (self.type,) + self._id_attrs = (self.type,) @classmethod def de_json(cls, data: Optional[JSONDict], bot: 'Bot') -> Optional['BotCommandScope']: diff --git a/telegram/inline/inlinekeyboardbutton.py b/telegram/inline/inlinekeyboardbutton.py index 72678cff2a3..387d5c33930 100644 --- a/telegram/inline/inlinekeyboardbutton.py +++ b/telegram/inline/inlinekeyboardbutton.py @@ -18,7 +18,7 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains an object that represents a Telegram InlineKeyboardButton.""" -from typing import TYPE_CHECKING, Any, Tuple +from typing import TYPE_CHECKING, Any from telegram import TelegramObject @@ -132,7 +132,7 @@ def __init__( self.switch_inline_query_current_chat = switch_inline_query_current_chat self.callback_game = callback_game self.pay = pay - self._id_attrs: Tuple[object, ...] = () + self._id_attrs = () self._set_id_attrs() def _set_id_attrs(self) -> None: diff --git a/telegram/passport/passportelementerrors.py b/telegram/passport/passportelementerrors.py index 210c1483c6f..2ad945dd3dc 100644 --- a/telegram/passport/passportelementerrors.py +++ b/telegram/passport/passportelementerrors.py @@ -19,7 +19,7 @@ # pylint: disable=W0622 """This module contains the classes that represent Telegram PassportElementError.""" -from typing import Any, Tuple +from typing import Any from telegram import TelegramObject @@ -54,7 +54,7 @@ def __init__(self, source: str, type: str, message: str, **_kwargs: Any): self.type = str(type) self.message = str(message) - self._id_attrs: Tuple[object, ...] = (self.source, self.type) + self._id_attrs = (self.source, self.type) class PassportElementErrorDataField(PassportElementError): From 5ddbb24d255d4e9b6434b54f573d3b44c99c07b5 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Mon, 16 Aug 2021 01:12:44 +0530 Subject: [PATCH 12/16] set min version to py3.7 for pre-commit hooks --- .pre-commit-config.yaml | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 66f5b9b118b..d3056152e3f 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/pyproject.toml b/pyproject.toml index 956c606237c..38ece5d5b6e 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 From 3a86096d1e0ee9e999e0b3c78dbe534167b1c07c Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Wed, 18 Aug 2021 18:28:37 +0530 Subject: [PATCH 13/16] add csi comment on basefilter --- telegram/ext/filters.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index ed7d0a85ce2..3f885315d6f 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -36,6 +36,7 @@ Union, cast, NoReturn, + TYPE_CHECKING, ) from telegram import Chat, Message, MessageEntity, Update, User @@ -115,6 +116,7 @@ class variable. __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 From 948dc945373eb8466cf3aa840e4841baa035deb1 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Wed, 18 Aug 2021 18:35:02 +0530 Subject: [PATCH 14/16] Remove unused import --- telegram/ext/filters.py | 1 - 1 file changed, 1 deletion(-) diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index 3f885315d6f..2ddc2a55702 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -36,7 +36,6 @@ Union, cast, NoReturn, - TYPE_CHECKING, ) from telegram import Chat, Message, MessageEntity, Update, User From 3957b71ed4f242ac10c217a087fc1bb54c5371d9 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 20 Aug 2021 00:30:51 +0530 Subject: [PATCH 15/16] fix pre-commit --- telegram/ext/basepersistence.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/telegram/ext/basepersistence.py b/telegram/ext/basepersistence.py index 79529f10d50..98d0515556e 100644 --- a/telegram/ext/basepersistence.py +++ b/telegram/ext/basepersistence.py @@ -106,11 +106,8 @@ class BasePersistence(Generic[UD, CD, BD], ABC): """ __slots__ = ( - 'store_user_data', - 'store_chat_data', - 'store_bot_data', - 'store_callback_data', 'bot', + 'store_data', '__dict__', # __dict__ is included because we replace methods in the __new__ ) From 45d09a55338da59447066681f1af411b9d683b11 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 20 Aug 2021 00:31:14 +0530 Subject: [PATCH 16/16] fix test-official --- tests/test_official.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_official.py b/tests/test_official.py index f522ee266e6..5217d4e6932 100644 --- a/tests/test_official.py +++ b/tests/test_official.py @@ -37,6 +37,7 @@ '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: