From be441d56f99c464fea22fd521ad4f28b60f06ea3 Mon Sep 17 00:00:00 2001 From: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com> Date: Fri, 13 Aug 2021 16:18:42 +0200 Subject: [PATCH] Refactor Initialization of Persistence Classes (#2604) --- docs/source/telegram.ext.persistenceinput.rst | 7 ++ docs/source/telegram.ext.rst | 1 + examples/arbitrarycallbackdatabot.py | 4 +- telegram/ext/__init__.py | 3 +- telegram/ext/basepersistence.py | 84 ++++++++-------- telegram/ext/callbackcontext.py | 12 ++- telegram/ext/dictpersistence.py | 42 +++----- telegram/ext/dispatcher.py | 16 ++-- telegram/ext/picklepersistence.py | 52 +++------- tests/test_dispatcher.py | 23 +---- tests/test_persistence.py | 96 +++++-------------- tests/test_slots.py | 1 + 12 files changed, 125 insertions(+), 216 deletions(-) create mode 100644 docs/source/telegram.ext.persistenceinput.rst diff --git a/docs/source/telegram.ext.persistenceinput.rst b/docs/source/telegram.ext.persistenceinput.rst new file mode 100644 index 000000000..ea5a0b38c --- /dev/null +++ b/docs/source/telegram.ext.persistenceinput.rst @@ -0,0 +1,7 @@ +:github_url: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/telegram/ext/basepersistence.py + +telegram.ext.PersistenceInput +============================= + +.. autoclass:: telegram.ext.PersistenceInput + :show-inheritance: diff --git a/docs/source/telegram.ext.rst b/docs/source/telegram.ext.rst index 98b4417e8..6e2a79cc1 100644 --- a/docs/source/telegram.ext.rst +++ b/docs/source/telegram.ext.rst @@ -46,6 +46,7 @@ Persistence .. toctree:: telegram.ext.basepersistence + telegram.ext.persistenceinput telegram.ext.picklepersistence telegram.ext.dictpersistence diff --git a/examples/arbitrarycallbackdatabot.py b/examples/arbitrarycallbackdatabot.py index 6d1139ce9..5ffafb668 100644 --- a/examples/arbitrarycallbackdatabot.py +++ b/examples/arbitrarycallbackdatabot.py @@ -84,9 +84,7 @@ def handle_invalid_button(update: Update, context: CallbackContext) -> None: def main() -> None: """Run the bot.""" # We use persistence to demonstrate how buttons can still work after the bot was restarted - persistence = PicklePersistence( - filename='arbitrarycallbackdatabot.pickle', store_callback_data=True - ) + persistence = PicklePersistence(filename='arbitrarycallbackdatabot.pickle') # Create the Updater and pass it your bot's token. updater = Updater("TOKEN", persistence=persistence, arbitrary_callback_data=True) diff --git a/telegram/ext/__init__.py b/telegram/ext/__init__.py index 1d3a8feff..660aae3ec 100644 --- a/telegram/ext/__init__.py +++ b/telegram/ext/__init__.py @@ -20,7 +20,7 @@ """Extensions over the Telegram Bot API to facilitate bot making""" from .extbot import ExtBot -from .basepersistence import BasePersistence +from .basepersistence import BasePersistence, PersistenceInput from .picklepersistence import PicklePersistence from .dictpersistence import DictPersistence from .handler import Handler @@ -90,6 +90,7 @@ __all__ = ( 'MessageFilter', 'MessageHandler', 'MessageQueue', + 'PersistenceInput', 'PicklePersistence', 'PollAnswerHandler', 'PollHandler', diff --git a/telegram/ext/basepersistence.py b/telegram/ext/basepersistence.py index 915fe664c..c167a9993 100644 --- a/telegram/ext/basepersistence.py +++ b/telegram/ext/basepersistence.py @@ -21,7 +21,7 @@ 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 typing import Dict, Optional, Tuple, cast, ClassVar, Generic, DefaultDict, NamedTuple from telegram.utils.deprecate import set_new_attribute_deprecated @@ -31,6 +31,33 @@ import telegram.ext.extbot from telegram.ext.utils.types import UD, CD, BD, ConversationDict, CDCData +class PersistenceInput(NamedTuple): + """Convenience wrapper to group boolean input for :class:`BasePersistence`. + + Args: + bot_data (:obj:`bool`, optional): Whether the setting should be applied for ``bot_data``. + Defaults to :obj:`True`. + chat_data (:obj:`bool`, optional): Whether the setting should be applied for ``chat_data``. + Defaults to :obj:`True`. + user_data (:obj:`bool`, optional): Whether the setting should be applied for ``user_data``. + Defaults to :obj:`True`. + callback_data (:obj:`bool`, optional): Whether the setting should be applied for + ``callback_data``. Defaults to :obj:`True`. + + Attributes: + bot_data (:obj:`bool`): Whether the setting should be applied for ``bot_data``. + chat_data (:obj:`bool`): Whether the setting should be applied for ``chat_data``. + user_data (:obj:`bool`): Whether the setting should be applied for ``user_data``. + callback_data (:obj:`bool`): Whether the setting should be applied for ``callback_data``. + + """ + + bot_data: bool = True + chat_data: bool = True + user_data: bool = True + callback_data: bool = True + + class BasePersistence(Generic[UD, CD, BD], ABC): """Interface class for adding persistence to your bot. Subclass this object for different implementations of a persistent bot. @@ -53,7 +80,7 @@ class BasePersistence(Generic[UD, CD, BD], ABC): * :meth:`flush` If you don't actually need one of those methods, a simple ``pass`` is enough. For example, if - ``store_bot_data=False``, you don't need :meth:`get_bot_data`, :meth:`update_bot_data` or + you don't store ``bot_data``, you don't need :meth:`get_bot_data`, :meth:`update_bot_data` or :meth:`refresh_bot_data`. Warning: @@ -68,46 +95,28 @@ class BasePersistence(Generic[UD, CD, BD], ABC): of the :meth:`update/get_*` methods, i.e. you don't need to worry about it while implementing a custom persistence subclass. - Args: - store_user_data (:obj:`bool`, optional): Whether user_data should be saved by this - persistence class. Default is :obj:`True`. - store_chat_data (:obj:`bool`, optional): Whether chat_data should be saved by this - persistence class. Default is :obj:`True` . - store_bot_data (:obj:`bool`, optional): Whether bot_data should be saved by this - persistence class. Default is :obj:`True`. - store_callback_data (:obj:`bool`, optional): Whether callback_data should be saved by this - persistence class. Default is :obj:`True`. + .. versionchanged:: 14.0 + The parameters and attributes ``store_*_data`` were replaced by :attr:`store_data`. - .. versionadded:: 13.6 + Args: + store_data (:class:`PersistenceInput`, optional): Specifies which kinds of data will be + saved by this persistence instance. By default, all available kinds of data will be + saved. Attributes: - store_user_data (:obj:`bool`): Optional, Whether user_data should be saved by this - persistence class. - store_chat_data (:obj:`bool`): Optional. Whether chat_data should be saved by this - persistence class. - store_bot_data (:obj:`bool`): Optional. Whether bot_data should be saved by this - persistence class. - store_callback_data (:obj:`bool`): Optional. Whether callback_data should be saved by this - persistence class. - - .. versionadded:: 13.6 + store_data (:class:`PersistenceInput`): Specifies which kinds of data will be saved by this + persistence instance. """ # 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', + 'store_data', 'bot', ) else: __slots__ = ( - 'store_user_data', # type: ignore[assignment] - 'store_chat_data', - 'store_bot_data', - 'store_callback_data', + 'store_data', # type: ignore[assignment] 'bot', '__dict__', ) @@ -173,15 +182,10 @@ class BasePersistence(Generic[UD, CD, BD], ABC): def __init__( self, - store_user_data: bool = True, - store_chat_data: bool = True, - store_bot_data: bool = True, - store_callback_data: bool = True, + store_data: PersistenceInput = None, ): - self.store_user_data = store_user_data - self.store_chat_data = store_chat_data - self.store_bot_data = store_bot_data - self.store_callback_data = store_callback_data + self.store_data = store_data or PersistenceInput() + self.bot: Bot = None # type: ignore[assignment] def __setattr__(self, key: str, value: object) -> None: @@ -200,8 +204,8 @@ class BasePersistence(Generic[UD, CD, BD], ABC): Args: bot (:class:`telegram.Bot`): The bot. """ - if self.store_callback_data and not isinstance(bot, telegram.ext.extbot.ExtBot): - raise TypeError('store_callback_data can only be used with telegram.ext.ExtBot.') + if self.store_data.callback_data and not isinstance(bot, telegram.ext.extbot.ExtBot): + raise TypeError('callback_data can only be stored when using telegram.ext.ExtBot.') self.bot = bot diff --git a/telegram/ext/callbackcontext.py b/telegram/ext/callbackcontext.py index b9c419124..8db1581e7 100644 --- a/telegram/ext/callbackcontext.py +++ b/telegram/ext/callbackcontext.py @@ -186,11 +186,17 @@ class CallbackContext(Generic[UD, CD, BD]): .. versionadded:: 13.6 """ if self.dispatcher.persistence: - if self.dispatcher.persistence.store_bot_data: + if self.dispatcher.persistence.store_data.bot_data: self.dispatcher.persistence.refresh_bot_data(self.bot_data) - if self.dispatcher.persistence.store_chat_data and self._chat_id_and_data is not None: + if ( + self.dispatcher.persistence.store_data.chat_data + and self._chat_id_and_data is not None + ): self.dispatcher.persistence.refresh_chat_data(*self._chat_id_and_data) - if self.dispatcher.persistence.store_user_data and self._user_id_and_data is not None: + if ( + self.dispatcher.persistence.store_data.user_data + and self._user_id_and_data is not None + ): self.dispatcher.persistence.refresh_user_data(*self._user_id_and_data) def drop_callback_data(self, callback_query: CallbackQuery) -> None: diff --git a/telegram/ext/dictpersistence.py b/telegram/ext/dictpersistence.py index a2dfba746..7d345ee29 100644 --- a/telegram/ext/dictpersistence.py +++ b/telegram/ext/dictpersistence.py @@ -26,7 +26,7 @@ from telegram.utils.helpers import ( decode_user_chat_data_from_json, encode_conversations_to_json, ) -from telegram.ext import BasePersistence +from telegram.ext import BasePersistence, PersistenceInput from telegram.ext.utils.types import ConversationDict, CDCData try: @@ -53,17 +53,13 @@ class DictPersistence(BasePersistence): :meth:`telegram.ext.BasePersistence.replace_bot` and :meth:`telegram.ext.BasePersistence.insert_bot`. - Args: - store_user_data (:obj:`bool`, optional): Whether user_data should be saved by this - persistence class. Default is :obj:`True`. - store_chat_data (:obj:`bool`, optional): Whether chat_data should be saved by this - persistence class. Default is :obj:`True`. - store_bot_data (:obj:`bool`, optional): Whether bot_data should be saved by this - persistence class. Default is :obj:`True`. - store_callback_data (:obj:`bool`, optional): Whether callback_data should be saved by this - persistence class. Default is :obj:`False`. + .. versionchanged:: 14.0 + The parameters and attributes ``store_*_data`` were replaced by :attr:`store_data`. - .. versionadded:: 13.6 + Args: + store_data (:class:`PersistenceInput`, optional): Specifies which kinds of data will be + saved by this persistence instance. By default, all available kinds of data will be + saved. user_data_json (:obj:`str`, optional): JSON string that will be used to reconstruct user_data on creating this persistence. Default is ``""``. chat_data_json (:obj:`str`, optional): JSON string that will be used to reconstruct @@ -78,16 +74,8 @@ class DictPersistence(BasePersistence): conversation on creating this persistence. Default is ``""``. Attributes: - store_user_data (:obj:`bool`): Whether user_data should be saved by this - persistence class. - store_chat_data (:obj:`bool`): Whether chat_data should be saved by this - persistence class. - store_bot_data (:obj:`bool`): Whether bot_data should be saved by this - persistence class. - store_callback_data (:obj:`bool`): Whether callback_data be saved by this - persistence class. - - .. versionadded:: 13.6 + store_data (:class:`PersistenceInput`): Specifies which kinds of data will be saved by this + persistence instance. """ __slots__ = ( @@ -105,22 +93,14 @@ class DictPersistence(BasePersistence): def __init__( self, - store_user_data: bool = True, - store_chat_data: bool = True, - store_bot_data: bool = True, + store_data: PersistenceInput = None, user_data_json: str = '', chat_data_json: str = '', bot_data_json: str = '', conversations_json: str = '', - store_callback_data: bool = False, callback_data_json: str = '', ): - super().__init__( - store_user_data=store_user_data, - store_chat_data=store_chat_data, - store_bot_data=store_bot_data, - store_callback_data=store_callback_data, - ) + super().__init__(store_data=store_data) self._user_data = None self._chat_data = None self._bot_data = None diff --git a/telegram/ext/dispatcher.py b/telegram/ext/dispatcher.py index af241882e..42a180c71 100644 --- a/telegram/ext/dispatcher.py +++ b/telegram/ext/dispatcher.py @@ -261,21 +261,21 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): raise TypeError("persistence must be based on telegram.ext.BasePersistence") self.persistence = persistence self.persistence.set_bot(self.bot) - if self.persistence.store_user_data: + if self.persistence.store_data.user_data: self.user_data = self.persistence.get_user_data() if not isinstance(self.user_data, defaultdict): raise ValueError("user_data must be of type defaultdict") - if self.persistence.store_chat_data: + if self.persistence.store_data.chat_data: self.chat_data = self.persistence.get_chat_data() if not isinstance(self.chat_data, defaultdict): raise ValueError("chat_data must be of type defaultdict") - if self.persistence.store_bot_data: + if self.persistence.store_data.bot_data: self.bot_data = self.persistence.get_bot_data() if not isinstance(self.bot_data, self.context_types.bot_data): raise ValueError( f"bot_data must be of type {self.context_types.bot_data.__name__}" ) - if self.persistence.store_callback_data: + if self.persistence.store_data.callback_data: self.bot = cast(telegram.ext.extbot.ExtBot, self.bot) persistent_data = self.persistence.get_callback_data() if persistent_data is not None: @@ -679,7 +679,7 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): else: user_ids = [] - if self.persistence.store_callback_data: + if self.persistence.store_data.callback_data: self.bot = cast(telegram.ext.extbot.ExtBot, self.bot) try: self.persistence.update_callback_data( @@ -695,7 +695,7 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): 'the error with an error_handler' ) self.logger.exception(message) - if self.persistence.store_bot_data: + if self.persistence.store_data.bot_data: try: self.persistence.update_bot_data(self.bot_data) except Exception as exc: @@ -708,7 +708,7 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): 'the error with an error_handler' ) self.logger.exception(message) - if self.persistence.store_chat_data: + if self.persistence.store_data.chat_data: for chat_id in chat_ids: try: self.persistence.update_chat_data(chat_id, self.chat_data[chat_id]) @@ -722,7 +722,7 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): 'the error with an error_handler' ) self.logger.exception(message) - if self.persistence.store_user_data: + if self.persistence.store_data.user_data: for user_id in user_ids: try: self.persistence.update_user_data(user_id, self.user_data[user_id]) diff --git a/telegram/ext/picklepersistence.py b/telegram/ext/picklepersistence.py index c3e4ba8ab..fce63bb2a 100644 --- a/telegram/ext/picklepersistence.py +++ b/telegram/ext/picklepersistence.py @@ -29,7 +29,7 @@ from typing import ( DefaultDict, ) -from telegram.ext import BasePersistence +from telegram.ext import BasePersistence, PersistenceInput from .utils.types import UD, CD, BD, ConversationDict, CDCData from .contexttypes import ContextTypes @@ -46,19 +46,15 @@ class PicklePersistence(BasePersistence[UD, CD, BD]): :meth:`telegram.ext.BasePersistence.replace_bot` and :meth:`telegram.ext.BasePersistence.insert_bot`. + .. versionchanged:: 14.0 + The parameters and attributes ``store_*_data`` were replaced by :attr:`store_data`. + Args: filename (:obj:`str`): The filename for storing the pickle files. When :attr:`single_file` is :obj:`False` this will be used as a prefix. - store_user_data (:obj:`bool`, optional): Whether user_data should be saved by this - persistence class. Default is :obj:`True`. - store_chat_data (:obj:`bool`, optional): Whether chat_data should be saved by this - persistence class. Default is :obj:`True`. - store_bot_data (:obj:`bool`, optional): Whether bot_data should be saved by this - persistence class. Default is :obj:`True`. - store_callback_data (:obj:`bool`, optional): Whether callback_data should be saved by this - persistence class. Default is :obj:`False`. - - .. versionadded:: 13.6 + store_data (:class:`PersistenceInput`, optional): Specifies which kinds of data will be + saved by this persistence instance. By default, all available kinds of data will be + saved. single_file (:obj:`bool`, optional): When :obj:`False` will store 5 separate files of `filename_user_data`, `filename_bot_data`, `filename_chat_data`, `filename_callback_data` and `filename_conversations`. Default is :obj:`True`. @@ -76,16 +72,8 @@ class PicklePersistence(BasePersistence[UD, CD, BD]): Attributes: filename (:obj:`str`): The filename for storing the pickle files. When :attr:`single_file` is :obj:`False` this will be used as a prefix. - store_user_data (:obj:`bool`): Optional. Whether user_data should be saved by this - persistence class. - store_chat_data (:obj:`bool`): Optional. Whether chat_data should be saved by this - persistence class. - store_bot_data (:obj:`bool`): Optional. Whether bot_data should be saved by this - persistence class. - store_callback_data (:obj:`bool`): Optional. Whether callback_data be saved by this - persistence class. - - .. versionadded:: 13.6 + store_data (:class:`PersistenceInput`): Specifies which kinds of data will be saved by this + persistence instance. single_file (:obj:`bool`): Optional. When :obj:`False` will store 5 separate files of `filename_user_data`, `filename_bot_data`, `filename_chat_data`, `filename_callback_data` and `filename_conversations`. Default is :obj:`True`. @@ -115,12 +103,9 @@ class PicklePersistence(BasePersistence[UD, CD, BD]): def __init__( self: 'PicklePersistence[Dict, Dict, Dict]', filename: str, - store_user_data: bool = True, - store_chat_data: bool = True, - store_bot_data: bool = True, + store_data: PersistenceInput = None, single_file: bool = True, on_flush: bool = False, - store_callback_data: bool = False, ): ... @@ -128,12 +113,9 @@ class PicklePersistence(BasePersistence[UD, CD, BD]): def __init__( self: 'PicklePersistence[UD, CD, BD]', filename: str, - store_user_data: bool = True, - store_chat_data: bool = True, - store_bot_data: bool = True, + store_data: PersistenceInput = None, single_file: bool = True, on_flush: bool = False, - store_callback_data: bool = False, context_types: ContextTypes[Any, UD, CD, BD] = None, ): ... @@ -141,20 +123,12 @@ class PicklePersistence(BasePersistence[UD, CD, BD]): def __init__( self, filename: str, - store_user_data: bool = True, - store_chat_data: bool = True, - store_bot_data: bool = True, + store_data: PersistenceInput = None, single_file: bool = True, on_flush: bool = False, - store_callback_data: bool = False, context_types: ContextTypes[Any, UD, CD, BD] = None, ): - super().__init__( - store_user_data=store_user_data, - store_chat_data=store_chat_data, - store_bot_data=store_bot_data, - store_callback_data=store_callback_data, - ) + super().__init__(store_data=store_data) self.filename = filename self.single_file = single_file self.on_flush = on_flush diff --git a/tests/test_dispatcher.py b/tests/test_dispatcher.py index db8deedad..1507e82c2 100644 --- a/tests/test_dispatcher.py +++ b/tests/test_dispatcher.py @@ -34,6 +34,7 @@ from telegram.ext import ( BasePersistence, ContextTypes, ) +from telegram.ext import PersistenceInput from telegram.ext.dispatcher import run_async, Dispatcher, DispatcherHandlerStop from telegram.utils.deprecate import TelegramDeprecationWarning from telegram.utils.helpers import DEFAULT_FALSE @@ -174,10 +175,7 @@ class TestDispatcher: def test_construction_with_bad_persistence(self, caplog, bot): class my_per: def __init__(self): - self.store_user_data = False - self.store_chat_data = False - self.store_bot_data = False - self.store_callback_data = False + self.store_data = PersistenceInput(False, False, False, False) with pytest.raises( TypeError, match='persistence must be based on telegram.ext.BasePersistence' @@ -595,13 +593,6 @@ class TestDispatcher: increment = [] class OwnPersistence(BasePersistence): - def __init__(self): - super().__init__() - self.store_user_data = True - self.store_chat_data = True - self.store_bot_data = True - self.store_callback_data = True - def get_callback_data(self): return None @@ -739,13 +730,6 @@ class TestDispatcher: def test_error_while_persisting(self, cdp, monkeypatch): class OwnPersistence(BasePersistence): - def __init__(self): - super().__init__() - self.store_user_data = True - self.store_chat_data = True - self.store_bot_data = True - self.store_callback_data = True - def update(self, data): raise Exception('PersistenceError') @@ -820,9 +804,6 @@ class TestDispatcher: class OwnPersistence(BasePersistence): def __init__(self): super().__init__() - self.store_user_data = True - self.store_chat_data = True - self.store_bot_data = True self.test_flag_bot_data = False self.test_flag_chat_data = False self.test_flag_user_data = False diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 3e2f63fcd..50fcb0bdd 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -21,6 +21,7 @@ import signal import uuid from threading import Lock +from telegram.ext import PersistenceInput from telegram.ext.callbackdatacache import CallbackDataCache from telegram.utils.helpers import encode_conversations_to_json @@ -119,9 +120,7 @@ class OwnPersistence(BasePersistence): @pytest.fixture(scope="function") def base_persistence(): - return OwnPersistence( - store_chat_data=True, store_user_data=True, store_bot_data=True, store_callback_data=True - ) + return OwnPersistence() @pytest.fixture(scope="function") @@ -216,15 +215,9 @@ def conversations(): @pytest.fixture(scope="function") def updater(bot, base_persistence): - base_persistence.store_chat_data = False - base_persistence.store_bot_data = False - base_persistence.store_user_data = False - base_persistence.store_callback_data = False + base_persistence.store_data = PersistenceInput(False, False, False, False) u = Updater(bot=bot, persistence=base_persistence) - base_persistence.store_bot_data = True - base_persistence.store_chat_data = True - base_persistence.store_user_data = True - base_persistence.store_callback_data = True + base_persistence.store_data = PersistenceInput() return u @@ -256,14 +249,15 @@ class TestBasePersistence: # 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" + inst.store_data, inst.custom = {}, "custom persistence shouldn't warn" assert len(recwarn) == 0, recwarn.list assert '__dict__' not in BasePersistence.__slots__ if py_ver < (3, 7) else True, 'has dict' def test_creation(self, base_persistence): - assert base_persistence.store_chat_data - assert base_persistence.store_user_data - assert base_persistence.store_bot_data + assert base_persistence.store_data.chat_data + assert base_persistence.store_data.user_data + assert base_persistence.store_data.bot_data + assert base_persistence.store_data.callback_data def test_abstract_methods(self, base_persistence): with pytest.raises( @@ -507,9 +501,9 @@ class TestBasePersistence: # x is the user/chat_id base_persistence.refresh_chat_data = lambda x, y: y.setdefault('refreshed', x) base_persistence.refresh_user_data = lambda x, y: y.setdefault('refreshed', x) - base_persistence.store_bot_data = store_bot_data - base_persistence.store_chat_data = store_chat_data - base_persistence.store_user_data = store_user_data + base_persistence.store_data = PersistenceInput( + bot_data=store_bot_data, chat_data=store_chat_data, user_data=store_user_data + ) cdp.persistence = base_persistence self.test_flag = True @@ -881,8 +875,8 @@ class TestBasePersistence: def test_set_bot_exception(self, bot): non_ext_bot = Bot(bot.token) - persistence = OwnPersistence(store_callback_data=True) - with pytest.raises(TypeError, match='store_callback_data can only be used'): + persistence = OwnPersistence() + with pytest.raises(TypeError, match='callback_data can only be stored'): persistence.set_bot(non_ext_bot) @@ -890,10 +884,6 @@ class TestBasePersistence: def pickle_persistence(): return PicklePersistence( filename='pickletest', - store_user_data=True, - store_chat_data=True, - store_bot_data=True, - store_callback_data=True, single_file=False, on_flush=False, ) @@ -903,10 +893,7 @@ def pickle_persistence(): def pickle_persistence_only_bot(): return PicklePersistence( filename='pickletest', - store_user_data=False, - store_chat_data=False, - store_bot_data=True, - store_callback_data=False, + store_data=PersistenceInput(callback_data=False, user_data=False, chat_data=False), single_file=False, on_flush=False, ) @@ -916,10 +903,7 @@ def pickle_persistence_only_bot(): def pickle_persistence_only_chat(): return PicklePersistence( filename='pickletest', - store_user_data=False, - store_chat_data=True, - store_bot_data=False, - store_callback_data=False, + store_data=PersistenceInput(callback_data=False, user_data=False, bot_data=False), single_file=False, on_flush=False, ) @@ -929,10 +913,7 @@ def pickle_persistence_only_chat(): def pickle_persistence_only_user(): return PicklePersistence( filename='pickletest', - store_user_data=True, - store_chat_data=False, - store_bot_data=False, - store_callback_data=False, + store_data=PersistenceInput(callback_data=False, chat_data=False, bot_data=False), single_file=False, on_flush=False, ) @@ -942,10 +923,7 @@ def pickle_persistence_only_user(): def pickle_persistence_only_callback(): return PicklePersistence( filename='pickletest', - store_user_data=False, - store_chat_data=False, - store_bot_data=False, - store_callback_data=True, + store_data=PersistenceInput(user_data=False, chat_data=False, bot_data=False), single_file=False, on_flush=False, ) @@ -1068,7 +1046,7 @@ class TestPicklePersistence: 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', {} + inst.custom, inst.store_data = 'should give warning', {} assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_pickle_behaviour_with_slots(self, pickle_persistence): @@ -1694,10 +1672,6 @@ class TestPicklePersistence: dp.process_update(update) pickle_persistence_2 = PicklePersistence( filename='pickletest', - store_user_data=True, - store_chat_data=True, - store_bot_data=True, - store_callback_data=True, single_file=False, on_flush=False, ) @@ -1717,10 +1691,6 @@ class TestPicklePersistence: u._signal_handler(signal.SIGINT, None) pickle_persistence_2 = PicklePersistence( filename='pickletest', - store_bot_data=True, - store_user_data=True, - store_chat_data=True, - store_callback_data=True, single_file=False, on_flush=False, ) @@ -1741,10 +1711,7 @@ class TestPicklePersistence: u._signal_handler(signal.SIGINT, None) pickle_persistence_2 = PicklePersistence( filename='pickletest', - store_user_data=False, - store_chat_data=False, - store_bot_data=True, - store_callback_data=False, + store_data=PersistenceInput(callback_data=False, chat_data=False, user_data=False), single_file=False, on_flush=False, ) @@ -1764,10 +1731,7 @@ class TestPicklePersistence: u._signal_handler(signal.SIGINT, None) pickle_persistence_2 = PicklePersistence( filename='pickletest', - store_user_data=False, - store_chat_data=True, - store_bot_data=False, - store_callback_data=False, + store_data=PersistenceInput(callback_data=False, user_data=False, bot_data=False), single_file=False, on_flush=False, ) @@ -1787,10 +1751,7 @@ class TestPicklePersistence: u._signal_handler(signal.SIGINT, None) pickle_persistence_2 = PicklePersistence( filename='pickletest', - store_user_data=True, - store_chat_data=False, - store_bot_data=False, - store_callback_data=False, + store_data=PersistenceInput(callback_data=False, chat_data=False, bot_data=False), single_file=False, on_flush=False, ) @@ -1813,10 +1774,7 @@ class TestPicklePersistence: del pickle_persistence_only_callback pickle_persistence_2 = PicklePersistence( filename='pickletest', - store_user_data=False, - store_chat_data=False, - store_bot_data=False, - store_callback_data=True, + store_data=PersistenceInput(user_data=False, chat_data=False, bot_data=False), single_file=False, on_flush=False, ) @@ -2002,7 +1960,7 @@ class TestDictPersistence: 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', {} + inst.custom, inst.store_data = 'should give warning', {} assert len(recwarn) == 1 and 'custom' in str(recwarn[0].message), recwarn.list def test_no_json_given(self): @@ -2166,7 +2124,6 @@ class TestDictPersistence: bot_data_json=bot_data_json, callback_data_json=callback_data_json, conversations_json=conversations_json, - store_callback_data=True, ) user_data = dict_persistence.get_user_data() @@ -2237,7 +2194,7 @@ class TestDictPersistence: ) def test_with_handler(self, bot, update): - dict_persistence = DictPersistence(store_callback_data=True) + dict_persistence = DictPersistence() u = Updater(bot=bot, persistence=dict_persistence, use_context=True) dp = u.dispatcher @@ -2278,7 +2235,6 @@ class TestDictPersistence: chat_data_json=chat_data, bot_data_json=bot_data, callback_data_json=callback_data, - store_callback_data=True, ) u = Updater(bot=bot, persistence=dict_persistence_2) @@ -2380,7 +2336,7 @@ class TestDictPersistence: context.dispatcher.user_data[789]['test3'] = '123' context.bot.callback_data_cache._callback_queries['test'] = 'Working4!' - dict_persistence = DictPersistence(store_callback_data=True) + dict_persistence = DictPersistence() cdp.persistence = dict_persistence job_queue.set_dispatcher(cdp) job_queue.start() diff --git a/tests/test_slots.py b/tests/test_slots.py index 96ace8f59..f2684235a 100644 --- a/tests/test_slots.py +++ b/tests/test_slots.py @@ -35,6 +35,7 @@ excluded = { 'CallbackDataCache', 'InvalidCallbackData', '_KeyboardData', + 'PersistenceInput', # This one as a named tuple - no need to worry about slots } # These modules/classes intentionally don't have __dict__.