Skip to content

Commit 08ba7c7

Browse files
authored
Handle Classes as Input for BasePersistence.replace/insert_bot (python-telegram-bot#2523)
* Ignore classes on replace/insert_bot * Review
1 parent 9737b1d commit 08ba7c7

2 files changed

Lines changed: 47 additions & 2 deletions

File tree

telegram/ext/basepersistence.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ def replace_bot(cls, obj: object) -> object:
137137
Replaces all instances of :class:`telegram.Bot` that occur within the passed object with
138138
:attr:`REPLACED_BOT`. Currently, this handles objects of type ``list``, ``tuple``, ``set``,
139139
``frozenset``, ``dict``, ``defaultdict`` and objects that have a ``__dict__`` or
140-
``__slot__`` attribute, excluding objects that can't be copied with `copy.copy`.
140+
``__slot__`` attribute, excluding classes and objects that can't be copied with
141+
``copy.copy``.
141142
142143
Args:
143144
obj (:obj:`object`): The object
@@ -168,6 +169,14 @@ def _replace_bot(cls, obj: object, memo: Dict[int, object]) -> object: # pylint
168169
new_immutable = obj.__class__(cls._replace_bot(item, memo) for item in obj)
169170
memo[obj_id] = new_immutable
170171
return new_immutable
172+
if isinstance(obj, type):
173+
# classes usually do have a __dict__, but it's not writable
174+
warnings.warn(
175+
'BasePersistence.replace_bot does not handle classes. See '
176+
'the docs of BasePersistence.replace_bot for more information.',
177+
RuntimeWarning,
178+
)
179+
return obj
171180

172181
try:
173182
new_obj = copy(obj)
@@ -215,7 +224,8 @@ def insert_bot(self, obj: object) -> object:
215224
Replaces all instances of :attr:`REPLACED_BOT` that occur within the passed object with
216225
:attr:`bot`. Currently, this handles objects of type ``list``, ``tuple``, ``set``,
217226
``frozenset``, ``dict``, ``defaultdict`` and objects that have a ``__dict__`` or
218-
``__slot__`` attribute, excluding objects that can't be copied with `copy.copy`.
227+
``__slot__`` attribute, excluding classes and objects that can't be copied with
228+
``copy.copy``.
219229
220230
Args:
221231
obj (:obj:`object`): The object
@@ -248,6 +258,14 @@ def _insert_bot(self, obj: object, memo: Dict[int, object]) -> object: # pylint
248258
new_immutable = obj.__class__(self._insert_bot(item, memo) for item in obj)
249259
memo[obj_id] = new_immutable
250260
return new_immutable
261+
if isinstance(obj, type):
262+
# classes usually do have a __dict__, but it's not writable
263+
warnings.warn(
264+
'BasePersistence.insert_bot does not handle classes. See '
265+
'the docs of BasePersistence.insert_bot for more information.',
266+
RuntimeWarning,
267+
)
268+
return obj
251269

252270
try:
253271
new_obj = copy(obj)

tests/test_persistence.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,33 @@ def __copy__(self):
590590
"BasePersistence.insert_bot does not handle objects that can not be copied."
591591
)
592592

593+
def test_bot_replace_insert_bot_classes(self, bot, bot_persistence, recwarn):
594+
"""Here check that classes are just returned verbatim."""
595+
persistence = bot_persistence
596+
persistence.set_bot(bot)
597+
598+
class CustomClass:
599+
pass
600+
601+
persistence.update_bot_data({1: CustomClass})
602+
assert persistence.bot_data[1] is CustomClass
603+
persistence.update_chat_data(123, {1: CustomClass})
604+
assert persistence.chat_data[123][1] is CustomClass
605+
persistence.update_user_data(123, {1: CustomClass})
606+
assert persistence.user_data[123][1] is CustomClass
607+
608+
assert persistence.get_bot_data()[1] is CustomClass
609+
assert persistence.get_chat_data()[123][1] is CustomClass
610+
assert persistence.get_user_data()[123][1] is CustomClass
611+
612+
assert len(recwarn) == 2
613+
assert str(recwarn[0].message).startswith(
614+
"BasePersistence.replace_bot does not handle classes."
615+
)
616+
assert str(recwarn[1].message).startswith(
617+
"BasePersistence.insert_bot does not handle classes."
618+
)
619+
593620
def test_bot_replace_insert_bot_objects_with_faulty_equality(self, bot, bot_persistence):
594621
"""Here check that trying to compare obj == self.REPLACED_BOT doesn't lead to problems."""
595622
persistence = bot_persistence

0 commit comments

Comments
 (0)