mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2024-11-24 08:06:26 +01:00
Refactor Initialization of Persistence Classes (#2604)
This commit is contained in:
parent
633b7e7762
commit
be441d56f9
12 changed files with 125 additions and 216 deletions
7
docs/source/telegram.ext.persistenceinput.rst
Normal file
7
docs/source/telegram.ext.persistenceinput.rst
Normal 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:
|
|
@ -46,6 +46,7 @@ Persistence
|
|||
.. toctree::
|
||||
|
||||
telegram.ext.basepersistence
|
||||
telegram.ext.persistenceinput
|
||||
telegram.ext.picklepersistence
|
||||
telegram.ext.dictpersistence
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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__.
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue