Refactor Initialization of Persistence Classes (#2604)

This commit is contained in:
Bibo-Joshi 2021-08-13 16:18:42 +02:00 committed by Hinrich Mahler
parent 633b7e7762
commit be441d56f9
12 changed files with 125 additions and 216 deletions

View file

@ -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:

View file

@ -46,6 +46,7 @@ Persistence
.. toctree::
telegram.ext.basepersistence
telegram.ext.persistenceinput
telegram.ext.picklepersistence
telegram.ext.dictpersistence

View file

@ -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)

View file

@ -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',

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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])

View file

@ -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

View file

@ -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

View file

@ -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()

View file

@ -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__.