From c4527cb4206d671cd38a151bfcdb03bd17a8517d Mon Sep 17 00:00:00 2001 From: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com> Date: Wed, 28 Dec 2022 15:56:35 +0100 Subject: [PATCH 1/3] Override `Bot.__deepcopy__` --- docs/source/telegram.bot.rst | 3 ++- telegram/_bot.py | 16 +++++++++++++++- tests/test_bot.py | 4 ++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/source/telegram.bot.rst b/docs/source/telegram.bot.rst index 6b620b5fb21..5f78d37781d 100644 --- a/docs/source/telegram.bot.rst +++ b/docs/source/telegram.bot.rst @@ -3,4 +3,5 @@ telegram.Bot .. autoclass:: telegram.Bot :members: - :show-inheritance: \ No newline at end of file + :show-inheritance: + :special-members: __reduce__, __deepcopy__ \ No newline at end of file diff --git a/telegram/_bot.py b/telegram/_bot.py index 0092a11a0e8..8bd5bdcd7e5 100644 --- a/telegram/_bot.py +++ b/telegram/_bot.py @@ -299,9 +299,23 @@ def private_key(self) -> Optional[Any]: return self._private_key def __reduce__(self) -> NoReturn: - """Called by pickle.dumps(). Serializing bots is unadvisable, so we forbid pickling.""" + """Customizes how :func:`copy.deepcopy` processes objects of this type. Bots can not + be pickled and this method will always raise an exception. + + Raises: + :exc:`pickle.PicklingError` + """ raise pickle.PicklingError("Bot objects cannot be pickled!") + def __deepcopy__(self, memodict: dict) -> NoReturn: + """Customizes how :func:`copy.deepcopy` processes objects of this type. Bots can not + be deepcopied and this method will always raise an exception. + + Raises: + :exc:`TypeError` + """ + raise TypeError("Bot objects cannot be deepcopied!") + # TODO: After https://youtrack.jetbrains.com/issue/PY-50952 is fixed, we can revisit this and # consider adding Paramspec from typing_extensions to properly fix this. Currently a workaround def _log(func: Any): # type: ignore[no-untyped-def] # skipcq: PY-D0003 diff --git a/tests/test_bot.py b/tests/test_bot.py index c59d4eec1d7..00ce581bba6 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -426,6 +426,10 @@ def test_bot_pickling_error(self, bot): with pytest.raises(pickle.PicklingError, match="Bot objects cannot be pickled"): pickle.dumps(bot) + def test_bot_deepcopy_error(self, bot): + with pytest.raises(TypeError, match="Bot objects cannot be deepcopied"): + copy.deepcopy(bot) + @bot_methods(ext_bot=False) async def test_defaults_handling( self, bot_class, bot_method_name, bot_method, bot, raw_bot, monkeypatch From b2cdf63d09a679dc0e3219f46b698e31d5cf049a Mon Sep 17 00:00:00 2001 From: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com> Date: Wed, 28 Dec 2022 15:59:18 +0100 Subject: [PATCH 2/3] A bit more documentation --- telegram/_bot.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/telegram/_bot.py b/telegram/_bot.py index 8bd5bdcd7e5..98125834a83 100644 --- a/telegram/_bot.py +++ b/telegram/_bot.py @@ -140,7 +140,8 @@ class Bot(TelegramObject, AbstractAsyncContextManager): passing files. * Bots should not be serialized since if you for e.g. change the bots token, then your serialized instance will not reflect that change. Trying to pickle a bot instance will - raise :exc:`pickle.PicklingError`. + raise :exc:`pickle.PicklingError`. Trying to deepcopy a bot instance will raise + :exce:`TypeError`. Examples: :any:`Raw API Bot ` @@ -166,6 +167,7 @@ class Bot(TelegramObject, AbstractAsyncContextManager): :class:`telegram.ext.Defaults`, please use the subclass :class:`telegram.ext.ExtBot` instead. * Attempting to pickle a bot instance will now raise :exc:`pickle.PicklingError`. + * Attempting to deepcopy a bot instance will now raise :exce:`TypeError`. * The following are now keyword-only arguments in Bot methods: ``location``, ``filename``, ``venue``, ``contact``, ``{read, write, connect, pool}_timeout``, ``api_kwargs``. Use a named argument for those, @@ -302,6 +304,8 @@ def __reduce__(self) -> NoReturn: """Customizes how :func:`copy.deepcopy` processes objects of this type. Bots can not be pickled and this method will always raise an exception. + .. versionadded:: 20.0 + Raises: :exc:`pickle.PicklingError` """ @@ -311,6 +315,8 @@ def __deepcopy__(self, memodict: dict) -> NoReturn: """Customizes how :func:`copy.deepcopy` processes objects of this type. Bots can not be deepcopied and this method will always raise an exception. + .. versionadded:: 20.0 + Raises: :exc:`TypeError` """ From a9bffc27e1f766bf26addf2e881711a735a52db1 Mon Sep 17 00:00:00 2001 From: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com> Date: Wed, 28 Dec 2022 16:06:34 +0100 Subject: [PATCH 3/3] doc fix --- telegram/_bot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/telegram/_bot.py b/telegram/_bot.py index 98125834a83..c108562b513 100644 --- a/telegram/_bot.py +++ b/telegram/_bot.py @@ -141,7 +141,7 @@ class Bot(TelegramObject, AbstractAsyncContextManager): * Bots should not be serialized since if you for e.g. change the bots token, then your serialized instance will not reflect that change. Trying to pickle a bot instance will raise :exc:`pickle.PicklingError`. Trying to deepcopy a bot instance will raise - :exce:`TypeError`. + :exc:`TypeError`. Examples: :any:`Raw API Bot ` @@ -167,7 +167,7 @@ class Bot(TelegramObject, AbstractAsyncContextManager): :class:`telegram.ext.Defaults`, please use the subclass :class:`telegram.ext.ExtBot` instead. * Attempting to pickle a bot instance will now raise :exc:`pickle.PicklingError`. - * Attempting to deepcopy a bot instance will now raise :exce:`TypeError`. + * Attempting to deepcopy a bot instance will now raise :exc:`TypeError`. * The following are now keyword-only arguments in Bot methods: ``location``, ``filename``, ``venue``, ``contact``, ``{read, write, connect, pool}_timeout``, ``api_kwargs``. Use a named argument for those,