Handle Classes as Input for BasePersistence.replace/insert_bot (#2523)

* Ignore classes on replace/insert_bot

* Review
This commit is contained in:
Bibo-Joshi 2021-05-16 20:02:35 +02:00 committed by GitHub
parent 9737b1d3c7
commit 08ba7c7793
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 2 deletions

View file

@ -137,7 +137,8 @@ class BasePersistence(ABC):
Replaces all instances of :class:`telegram.Bot` that occur within the passed object with
:attr:`REPLACED_BOT`. Currently, this handles objects of type ``list``, ``tuple``, ``set``,
``frozenset``, ``dict``, ``defaultdict`` and objects that have a ``__dict__`` or
``__slot__`` attribute, excluding objects that can't be copied with `copy.copy`.
``__slot__`` attribute, excluding classes and objects that can't be copied with
``copy.copy``.
Args:
obj (:obj:`object`): The object
@ -168,6 +169,14 @@ class BasePersistence(ABC):
new_immutable = obj.__class__(cls._replace_bot(item, memo) for item in obj)
memo[obj_id] = new_immutable
return new_immutable
if isinstance(obj, type):
# classes usually do have a __dict__, but it's not writable
warnings.warn(
'BasePersistence.replace_bot does not handle classes. See '
'the docs of BasePersistence.replace_bot for more information.',
RuntimeWarning,
)
return obj
try:
new_obj = copy(obj)
@ -215,7 +224,8 @@ class BasePersistence(ABC):
Replaces all instances of :attr:`REPLACED_BOT` that occur within the passed object with
:attr:`bot`. Currently, this handles objects of type ``list``, ``tuple``, ``set``,
``frozenset``, ``dict``, ``defaultdict`` and objects that have a ``__dict__`` or
``__slot__`` attribute, excluding objects that can't be copied with `copy.copy`.
``__slot__`` attribute, excluding classes and objects that can't be copied with
``copy.copy``.
Args:
obj (:obj:`object`): The object
@ -248,6 +258,14 @@ class BasePersistence(ABC):
new_immutable = obj.__class__(self._insert_bot(item, memo) for item in obj)
memo[obj_id] = new_immutable
return new_immutable
if isinstance(obj, type):
# classes usually do have a __dict__, but it's not writable
warnings.warn(
'BasePersistence.insert_bot does not handle classes. See '
'the docs of BasePersistence.insert_bot for more information.',
RuntimeWarning,
)
return obj
try:
new_obj = copy(obj)

View file

@ -590,6 +590,33 @@ class TestBasePersistence:
"BasePersistence.insert_bot does not handle objects that can not be copied."
)
def test_bot_replace_insert_bot_classes(self, bot, bot_persistence, recwarn):
"""Here check that classes are just returned verbatim."""
persistence = bot_persistence
persistence.set_bot(bot)
class CustomClass:
pass
persistence.update_bot_data({1: CustomClass})
assert persistence.bot_data[1] is CustomClass
persistence.update_chat_data(123, {1: CustomClass})
assert persistence.chat_data[123][1] is CustomClass
persistence.update_user_data(123, {1: CustomClass})
assert persistence.user_data[123][1] is CustomClass
assert persistence.get_bot_data()[1] is CustomClass
assert persistence.get_chat_data()[123][1] is CustomClass
assert persistence.get_user_data()[123][1] is CustomClass
assert len(recwarn) == 2
assert str(recwarn[0].message).startswith(
"BasePersistence.replace_bot does not handle classes."
)
assert str(recwarn[1].message).startswith(
"BasePersistence.insert_bot does not handle classes."
)
def test_bot_replace_insert_bot_objects_with_faulty_equality(self, bot, bot_persistence):
"""Here check that trying to compare obj == self.REPLACED_BOT doesn't lead to problems."""
persistence = bot_persistence