Skip to content

Commit d98c59d

Browse files
committed
Refactor Initialization of Persistence Classes (python-telegram-bot#2604)
1 parent 9c9fbf3 commit d98c59d

12 files changed

+125
-216
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
:github_url: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/telegram/ext/basepersistence.py
2+
3+
telegram.ext.PersistenceInput
4+
=============================
5+
6+
.. autoclass:: telegram.ext.PersistenceInput
7+
:show-inheritance:

docs/source/telegram.ext.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Persistence
4646
.. toctree::
4747

4848
telegram.ext.basepersistence
49+
telegram.ext.persistenceinput
4950
telegram.ext.picklepersistence
5051
telegram.ext.dictpersistence
5152

examples/arbitrarycallbackdatabot.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,7 @@ def handle_invalid_button(update: Update, context: CallbackContext) -> None:
8484
def main() -> None:
8585
"""Run the bot."""
8686
# We use persistence to demonstrate how buttons can still work after the bot was restarted
87-
persistence = PicklePersistence(
88-
filename='arbitrarycallbackdatabot.pickle', store_callback_data=True
89-
)
87+
persistence = PicklePersistence(filename='arbitrarycallbackdatabot.pickle')
9088
# Create the Updater and pass it your bot's token.
9189
updater = Updater("TOKEN", persistence=persistence, arbitrary_callback_data=True)
9290

telegram/ext/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"""Extensions over the Telegram Bot API to facilitate bot making"""
2121

2222
from .extbot import ExtBot
23-
from .basepersistence import BasePersistence
23+
from .basepersistence import BasePersistence, PersistenceInput
2424
from .picklepersistence import PicklePersistence
2525
from .dictpersistence import DictPersistence
2626
from .handler import Handler
@@ -90,6 +90,7 @@
9090
'MessageFilter',
9191
'MessageHandler',
9292
'MessageQueue',
93+
'PersistenceInput',
9394
'PicklePersistence',
9495
'PollAnswerHandler',
9596
'PollHandler',

telegram/ext/basepersistence.py

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from sys import version_info as py_ver
2222
from abc import ABC, abstractmethod
2323
from copy import copy
24-
from typing import Dict, Optional, Tuple, cast, ClassVar, Generic, DefaultDict
24+
from typing import Dict, Optional, Tuple, cast, ClassVar, Generic, DefaultDict, NamedTuple
2525

2626
from telegram.utils.deprecate import set_new_attribute_deprecated
2727

@@ -31,6 +31,33 @@
3131
from telegram.ext.utils.types import UD, CD, BD, ConversationDict, CDCData
3232

3333

34+
class PersistenceInput(NamedTuple):
35+
"""Convenience wrapper to group boolean input for :class:`BasePersistence`.
36+
37+
Args:
38+
bot_data (:obj:`bool`, optional): Whether the setting should be applied for ``bot_data``.
39+
Defaults to :obj:`True`.
40+
chat_data (:obj:`bool`, optional): Whether the setting should be applied for ``chat_data``.
41+
Defaults to :obj:`True`.
42+
user_data (:obj:`bool`, optional): Whether the setting should be applied for ``user_data``.
43+
Defaults to :obj:`True`.
44+
callback_data (:obj:`bool`, optional): Whether the setting should be applied for
45+
``callback_data``. Defaults to :obj:`True`.
46+
47+
Attributes:
48+
bot_data (:obj:`bool`): Whether the setting should be applied for ``bot_data``.
49+
chat_data (:obj:`bool`): Whether the setting should be applied for ``chat_data``.
50+
user_data (:obj:`bool`): Whether the setting should be applied for ``user_data``.
51+
callback_data (:obj:`bool`): Whether the setting should be applied for ``callback_data``.
52+
53+
"""
54+
55+
bot_data: bool = True
56+
chat_data: bool = True
57+
user_data: bool = True
58+
callback_data: bool = True
59+
60+
3461
class BasePersistence(Generic[UD, CD, BD], ABC):
3562
"""Interface class for adding persistence to your bot.
3663
Subclass this object for different implementations of a persistent bot.
@@ -53,7 +80,7 @@ class BasePersistence(Generic[UD, CD, BD], ABC):
5380
* :meth:`flush`
5481
5582
If you don't actually need one of those methods, a simple ``pass`` is enough. For example, if
56-
``store_bot_data=False``, you don't need :meth:`get_bot_data`, :meth:`update_bot_data` or
83+
you don't store ``bot_data``, you don't need :meth:`get_bot_data`, :meth:`update_bot_data` or
5784
:meth:`refresh_bot_data`.
5885
5986
Warning:
@@ -68,46 +95,28 @@ class BasePersistence(Generic[UD, CD, BD], ABC):
6895
of the :meth:`update/get_*` methods, i.e. you don't need to worry about it while
6996
implementing a custom persistence subclass.
7097
71-
Args:
72-
store_user_data (:obj:`bool`, optional): Whether user_data should be saved by this
73-
persistence class. Default is :obj:`True`.
74-
store_chat_data (:obj:`bool`, optional): Whether chat_data should be saved by this
75-
persistence class. Default is :obj:`True` .
76-
store_bot_data (:obj:`bool`, optional): Whether bot_data should be saved by this
77-
persistence class. Default is :obj:`True`.
78-
store_callback_data (:obj:`bool`, optional): Whether callback_data should be saved by this
79-
persistence class. Default is :obj:`True`.
98+
.. versionchanged:: 14.0
99+
The parameters and attributes ``store_*_data`` were replaced by :attr:`store_data`.
80100
81-
.. versionadded:: 13.6
101+
Args:
102+
store_data (:class:`PersistenceInput`, optional): Specifies which kinds of data will be
103+
saved by this persistence instance. By default, all available kinds of data will be
104+
saved.
82105
83106
Attributes:
84-
store_user_data (:obj:`bool`): Optional, Whether user_data should be saved by this
85-
persistence class.
86-
store_chat_data (:obj:`bool`): Optional. Whether chat_data should be saved by this
87-
persistence class.
88-
store_bot_data (:obj:`bool`): Optional. Whether bot_data should be saved by this
89-
persistence class.
90-
store_callback_data (:obj:`bool`): Optional. Whether callback_data should be saved by this
91-
persistence class.
92-
93-
.. versionadded:: 13.6
107+
store_data (:class:`PersistenceInput`): Specifies which kinds of data will be saved by this
108+
persistence instance.
94109
"""
95110

96111
# Apparently Py 3.7 and below have '__dict__' in ABC
97112
if py_ver < (3, 7):
98113
__slots__ = (
99-
'store_user_data',
100-
'store_chat_data',
101-
'store_bot_data',
102-
'store_callback_data',
114+
'store_data',
103115
'bot',
104116
)
105117
else:
106118
__slots__ = (
107-
'store_user_data', # type: ignore[assignment]
108-
'store_chat_data',
109-
'store_bot_data',
110-
'store_callback_data',
119+
'store_data', # type: ignore[assignment]
111120
'bot',
112121
'__dict__',
113122
)
@@ -173,15 +182,10 @@ def update_callback_data_replace_bot(data: CDCData) -> None:
173182

174183
def __init__(
175184
self,
176-
store_user_data: bool = True,
177-
store_chat_data: bool = True,
178-
store_bot_data: bool = True,
179-
store_callback_data: bool = True,
185+
store_data: PersistenceInput = None,
180186
):
181-
self.store_user_data = store_user_data
182-
self.store_chat_data = store_chat_data
183-
self.store_bot_data = store_bot_data
184-
self.store_callback_data = store_callback_data
187+
self.store_data = store_data or PersistenceInput()
188+
185189
self.bot: Bot = None # type: ignore[assignment]
186190

187191
def __setattr__(self, key: str, value: object) -> None:
@@ -200,8 +204,8 @@ def set_bot(self, bot: Bot) -> None:
200204
Args:
201205
bot (:class:`telegram.Bot`): The bot.
202206
"""
203-
if self.store_callback_data and not isinstance(bot, telegram.ext.extbot.ExtBot):
204-
raise TypeError('store_callback_data can only be used with telegram.ext.ExtBot.')
207+
if self.store_data.callback_data and not isinstance(bot, telegram.ext.extbot.ExtBot):
208+
raise TypeError('callback_data can only be stored when using telegram.ext.ExtBot.')
205209

206210
self.bot = bot
207211

telegram/ext/callbackcontext.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,17 @@ def refresh_data(self) -> None:
186186
.. versionadded:: 13.6
187187
"""
188188
if self.dispatcher.persistence:
189-
if self.dispatcher.persistence.store_bot_data:
189+
if self.dispatcher.persistence.store_data.bot_data:
190190
self.dispatcher.persistence.refresh_bot_data(self.bot_data)
191-
if self.dispatcher.persistence.store_chat_data and self._chat_id_and_data is not None:
191+
if (
192+
self.dispatcher.persistence.store_data.chat_data
193+
and self._chat_id_and_data is not None
194+
):
192195
self.dispatcher.persistence.refresh_chat_data(*self._chat_id_and_data)
193-
if self.dispatcher.persistence.store_user_data and self._user_id_and_data is not None:
196+
if (
197+
self.dispatcher.persistence.store_data.user_data
198+
and self._user_id_and_data is not None
199+
):
194200
self.dispatcher.persistence.refresh_user_data(*self._user_id_and_data)
195201

196202
def drop_callback_data(self, callback_query: CallbackQuery) -> None:

telegram/ext/dictpersistence.py

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
decode_user_chat_data_from_json,
2727
encode_conversations_to_json,
2828
)
29-
from telegram.ext import BasePersistence
29+
from telegram.ext import BasePersistence, PersistenceInput
3030
from telegram.ext.utils.types import ConversationDict, CDCData
3131

3232
try:
@@ -53,17 +53,13 @@ class DictPersistence(BasePersistence):
5353
:meth:`telegram.ext.BasePersistence.replace_bot` and
5454
:meth:`telegram.ext.BasePersistence.insert_bot`.
5555
56-
Args:
57-
store_user_data (:obj:`bool`, optional): Whether user_data should be saved by this
58-
persistence class. Default is :obj:`True`.
59-
store_chat_data (:obj:`bool`, optional): Whether chat_data should be saved by this
60-
persistence class. Default is :obj:`True`.
61-
store_bot_data (:obj:`bool`, optional): Whether bot_data should be saved by this
62-
persistence class. Default is :obj:`True`.
63-
store_callback_data (:obj:`bool`, optional): Whether callback_data should be saved by this
64-
persistence class. Default is :obj:`False`.
56+
.. versionchanged:: 14.0
57+
The parameters and attributes ``store_*_data`` were replaced by :attr:`store_data`.
6558
66-
.. versionadded:: 13.6
59+
Args:
60+
store_data (:class:`PersistenceInput`, optional): Specifies which kinds of data will be
61+
saved by this persistence instance. By default, all available kinds of data will be
62+
saved.
6763
user_data_json (:obj:`str`, optional): JSON string that will be used to reconstruct
6864
user_data on creating this persistence. Default is ``""``.
6965
chat_data_json (:obj:`str`, optional): JSON string that will be used to reconstruct
@@ -78,16 +74,8 @@ class DictPersistence(BasePersistence):
7874
conversation on creating this persistence. Default is ``""``.
7975
8076
Attributes:
81-
store_user_data (:obj:`bool`): Whether user_data should be saved by this
82-
persistence class.
83-
store_chat_data (:obj:`bool`): Whether chat_data should be saved by this
84-
persistence class.
85-
store_bot_data (:obj:`bool`): Whether bot_data should be saved by this
86-
persistence class.
87-
store_callback_data (:obj:`bool`): Whether callback_data be saved by this
88-
persistence class.
89-
90-
.. versionadded:: 13.6
77+
store_data (:class:`PersistenceInput`): Specifies which kinds of data will be saved by this
78+
persistence instance.
9179
"""
9280

9381
__slots__ = (
@@ -105,22 +93,14 @@ class DictPersistence(BasePersistence):
10593

10694
def __init__(
10795
self,
108-
store_user_data: bool = True,
109-
store_chat_data: bool = True,
110-
store_bot_data: bool = True,
96+
store_data: PersistenceInput = None,
11197
user_data_json: str = '',
11298
chat_data_json: str = '',
11399
bot_data_json: str = '',
114100
conversations_json: str = '',
115-
store_callback_data: bool = False,
116101
callback_data_json: str = '',
117102
):
118-
super().__init__(
119-
store_user_data=store_user_data,
120-
store_chat_data=store_chat_data,
121-
store_bot_data=store_bot_data,
122-
store_callback_data=store_callback_data,
123-
)
103+
super().__init__(store_data=store_data)
124104
self._user_data = None
125105
self._chat_data = None
126106
self._bot_data = None

telegram/ext/dispatcher.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -261,21 +261,21 @@ def __init__(
261261
raise TypeError("persistence must be based on telegram.ext.BasePersistence")
262262
self.persistence = persistence
263263
self.persistence.set_bot(self.bot)
264-
if self.persistence.store_user_data:
264+
if self.persistence.store_data.user_data:
265265
self.user_data = self.persistence.get_user_data()
266266
if not isinstance(self.user_data, defaultdict):
267267
raise ValueError("user_data must be of type defaultdict")
268-
if self.persistence.store_chat_data:
268+
if self.persistence.store_data.chat_data:
269269
self.chat_data = self.persistence.get_chat_data()
270270
if not isinstance(self.chat_data, defaultdict):
271271
raise ValueError("chat_data must be of type defaultdict")
272-
if self.persistence.store_bot_data:
272+
if self.persistence.store_data.bot_data:
273273
self.bot_data = self.persistence.get_bot_data()
274274
if not isinstance(self.bot_data, self.context_types.bot_data):
275275
raise ValueError(
276276
f"bot_data must be of type {self.context_types.bot_data.__name__}"
277277
)
278-
if self.persistence.store_callback_data:
278+
if self.persistence.store_data.callback_data:
279279
self.bot = cast(telegram.ext.extbot.ExtBot, self.bot)
280280
persistent_data = self.persistence.get_callback_data()
281281
if persistent_data is not None:
@@ -679,7 +679,7 @@ def __update_persistence(self, update: object = None) -> None:
679679
else:
680680
user_ids = []
681681

682-
if self.persistence.store_callback_data:
682+
if self.persistence.store_data.callback_data:
683683
self.bot = cast(telegram.ext.extbot.ExtBot, self.bot)
684684
try:
685685
self.persistence.update_callback_data(
@@ -695,7 +695,7 @@ def __update_persistence(self, update: object = None) -> None:
695695
'the error with an error_handler'
696696
)
697697
self.logger.exception(message)
698-
if self.persistence.store_bot_data:
698+
if self.persistence.store_data.bot_data:
699699
try:
700700
self.persistence.update_bot_data(self.bot_data)
701701
except Exception as exc:
@@ -708,7 +708,7 @@ def __update_persistence(self, update: object = None) -> None:
708708
'the error with an error_handler'
709709
)
710710
self.logger.exception(message)
711-
if self.persistence.store_chat_data:
711+
if self.persistence.store_data.chat_data:
712712
for chat_id in chat_ids:
713713
try:
714714
self.persistence.update_chat_data(chat_id, self.chat_data[chat_id])
@@ -722,7 +722,7 @@ def __update_persistence(self, update: object = None) -> None:
722722
'the error with an error_handler'
723723
)
724724
self.logger.exception(message)
725-
if self.persistence.store_user_data:
725+
if self.persistence.store_data.user_data:
726726
for user_id in user_ids:
727727
try:
728728
self.persistence.update_user_data(user_id, self.user_data[user_id])

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy