diff --git a/docs/source/telegram.ext.regexhandler.rst b/docs/source/telegram.ext.regexhandler.rst deleted file mode 100644 index efe40ef29c7..00000000000 --- a/docs/source/telegram.ext.regexhandler.rst +++ /dev/null @@ -1,8 +0,0 @@ -:github_url: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/telegram/ext/regexhandler.py - -telegram.ext.RegexHandler -========================= - -.. autoclass:: telegram.ext.RegexHandler - :members: - :show-inheritance: diff --git a/docs/source/telegram.ext.rst b/docs/source/telegram.ext.rst index cef09e0c2f8..8392f506f7c 100644 --- a/docs/source/telegram.ext.rst +++ b/docs/source/telegram.ext.rst @@ -33,7 +33,6 @@ Handlers telegram.ext.pollhandler telegram.ext.precheckoutqueryhandler telegram.ext.prefixhandler - telegram.ext.regexhandler telegram.ext.shippingqueryhandler telegram.ext.stringcommandhandler telegram.ext.stringregexhandler diff --git a/telegram/ext/__init__.py b/telegram/ext/__init__.py index 624b1c2d589..c10d8b3076a 100644 --- a/telegram/ext/__init__.py +++ b/telegram/ext/__init__.py @@ -35,7 +35,6 @@ from .filters import BaseFilter, MessageFilter, UpdateFilter, Filters from .messagehandler import MessageHandler from .commandhandler import CommandHandler, PrefixHandler -from .regexhandler import RegexHandler from .stringcommandhandler import StringCommandHandler from .stringregexhandler import StringRegexHandler from .typehandler import TypeHandler @@ -82,7 +81,6 @@ 'PollHandler', 'PreCheckoutQueryHandler', 'PrefixHandler', - 'RegexHandler', 'ShippingQueryHandler', 'StringCommandHandler', 'StringRegexHandler', diff --git a/telegram/ext/callbackcontext.py b/telegram/ext/callbackcontext.py index fbbb513b29b..e7edc4b5aaa 100644 --- a/telegram/ext/callbackcontext.py +++ b/telegram/ext/callbackcontext.py @@ -108,10 +108,6 @@ def __init__(self: 'CCT', dispatcher: 'Dispatcher[CCT, UD, CD, BD]'): Args: dispatcher (:class:`telegram.ext.Dispatcher`): """ - if not dispatcher.use_context: - raise ValueError( - 'CallbackContext should not be used with a non context aware ' 'dispatcher!' - ) self._dispatcher = dispatcher self._chat_id_and_data: Optional[Tuple[int, CD]] = None self._user_id_and_data: Optional[Tuple[int, UD]] = None diff --git a/telegram/ext/callbackqueryhandler.py b/telegram/ext/callbackqueryhandler.py index beea75fe7dd..1d5c1453948 100644 --- a/telegram/ext/callbackqueryhandler.py +++ b/telegram/ext/callbackqueryhandler.py @@ -22,7 +22,6 @@ from typing import ( TYPE_CHECKING, Callable, - Dict, Match, Optional, Pattern, @@ -49,13 +48,6 @@ class CallbackQueryHandler(Handler[Update, CCT]): Read the documentation of the ``re`` module for more information. Note: - * :attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you - can use to keep any data in will be sent to the :attr:`callback` function. Related to - either the user or the chat that the update was sent in. For each update from the same - user or in the same chat, it will be the same ``dict``. - - Note that this is DEPRECATED, and you should use context based callbacks. See - https://git.io/fxJuV for more info. * If your bot allows arbitrary objects as ``callback_data``, it may happen that the original ``callback_data`` for the incoming :class:`telegram.CallbackQuery`` can not be found. This is the case when either a malicious client tempered with the @@ -72,22 +64,13 @@ class CallbackQueryHandler(Handler[Update, CCT]): Args: callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + - ``def callback(update: Update, context: CallbackContext)`` + ``def callback(update: Update, context: CallbackContext)`` The return value of the callback is usually ignored except for the special case of :class:`telegram.ext.ConversationHandler`. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. pattern (:obj:`str` | `Pattern` | :obj:`callable` | :obj:`type`, optional): Pattern to test :attr:`telegram.CallbackQuery.data` against. If a string or a regex pattern is passed, :meth:`re.match` is used on :attr:`telegram.CallbackQuery.data` to @@ -106,66 +89,30 @@ class CallbackQueryHandler(Handler[Update, CCT]): .. versionchanged:: 13.6 Added support for arbitrary callback data. - pass_groups (:obj:`bool`, optional): If the callback should be passed the result of - ``re.match(pattern, data).groups()`` as a keyword argument called ``groups``. - Default is :obj:`False` - DEPRECATED: Please switch to context based callbacks. - pass_groupdict (:obj:`bool`, optional): If the callback should be passed the result of - ``re.match(pattern, data).groupdict()`` as a keyword argument called ``groupdict``. - Default is :obj:`False` - DEPRECATED: Please switch to context based callbacks. - pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``user_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``chat_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. Attributes: callback (:obj:`callable`): The callback function for this handler. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. pattern (`Pattern` | :obj:`callable` | :obj:`type`): Optional. Regex pattern, callback or type to test :attr:`telegram.CallbackQuery.data` against. .. versionchanged:: 13.6 Added support for arbitrary callback data. - pass_groups (:obj:`bool`): Determines whether ``groups`` will be passed to the - callback function. - pass_groupdict (:obj:`bool`): Determines whether ``groupdict``. will be passed to - the callback function. - pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to - the callback function. - pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ - __slots__ = ('pattern', 'pass_groups', 'pass_groupdict') + __slots__ = ('pattern',) def __init__( self, callback: Callable[[Update, CCT], RT], - pass_update_queue: bool = False, - pass_job_queue: bool = False, pattern: Union[str, Pattern, type, Callable[[object], Optional[bool]]] = None, - pass_groups: bool = False, - pass_groupdict: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, run_async: Union[bool, DefaultValue] = DEFAULT_FALSE, ): super().__init__( callback, - pass_update_queue=pass_update_queue, - pass_job_queue=pass_job_queue, - pass_user_data=pass_user_data, - pass_chat_data=pass_chat_data, run_async=run_async, ) @@ -173,8 +120,6 @@ def __init__( pattern = re.compile(pattern) self.pattern = pattern - self.pass_groups = pass_groups - self.pass_groupdict = pass_groupdict def check_update(self, update: object) -> Optional[Union[bool, object]]: """Determines whether an update should be passed to this handlers :attr:`callback`. @@ -202,25 +147,6 @@ def check_update(self, update: object) -> Optional[Union[bool, object]]: return True return None - def collect_optional_args( - self, - dispatcher: 'Dispatcher', - update: Update = None, - check_result: Union[bool, Match] = None, - ) -> Dict[str, object]: - """Pass the results of ``re.match(pattern, data).{groups(), groupdict()}`` to the - callback as a keyword arguments called ``groups`` and ``groupdict``, respectively, if - needed. - """ - optional_args = super().collect_optional_args(dispatcher, update, check_result) - if self.pattern and not callable(self.pattern): - check_result = cast(Match, check_result) - if self.pass_groups: - optional_args['groups'] = check_result.groups() - if self.pass_groupdict: - optional_args['groupdict'] = check_result.groupdict() - return optional_args - def collect_additional_context( self, context: CCT, diff --git a/telegram/ext/chatmemberhandler.py b/telegram/ext/chatmemberhandler.py index 9499cfd2472..f5e477a6ab2 100644 --- a/telegram/ext/chatmemberhandler.py +++ b/telegram/ext/chatmemberhandler.py @@ -32,15 +32,6 @@ class ChatMemberHandler(Handler[Update, CCT]): .. versionadded:: 13.4 - Note: - :attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you - can use to keep any data in will be sent to the :attr:`callback` function. Related to - either the user or the chat that the update was sent in. For each update from the same user - or in the same chat, it will be the same ``dict``. - - Note that this is DEPRECATED, and you should use context based callbacks. See - https://git.io/fxJuV for more info. - Warning: When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info. @@ -48,7 +39,8 @@ class ChatMemberHandler(Handler[Update, CCT]): Args: callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` @@ -58,22 +50,6 @@ class ChatMemberHandler(Handler[Update, CCT]): :attr:`CHAT_MEMBER` or :attr:`ANY_CHAT_MEMBER` to specify if this handler should handle only updates with :attr:`telegram.Update.my_chat_member`, :attr:`telegram.Update.chat_member` or both. Defaults to :attr:`MY_CHAT_MEMBER`. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``user_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``chat_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. @@ -82,14 +58,6 @@ class ChatMemberHandler(Handler[Update, CCT]): chat_member_types (:obj:`int`, optional): Specifies if this handler should handle only updates with :attr:`telegram.Update.my_chat_member`, :attr:`telegram.Update.chat_member` or both. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. - pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to - the callback function. - pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ @@ -107,18 +75,10 @@ def __init__( self, callback: Callable[[Update, CCT], RT], chat_member_types: int = MY_CHAT_MEMBER, - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, run_async: Union[bool, DefaultValue] = DEFAULT_FALSE, ): super().__init__( callback, - pass_update_queue=pass_update_queue, - pass_job_queue=pass_job_queue, - pass_user_data=pass_user_data, - pass_chat_data=pass_chat_data, run_async=run_async, ) diff --git a/telegram/ext/choseninlineresulthandler.py b/telegram/ext/choseninlineresulthandler.py index ec3528945d9..f9254e11d56 100644 --- a/telegram/ext/choseninlineresulthandler.py +++ b/telegram/ext/choseninlineresulthandler.py @@ -35,15 +35,6 @@ class ChosenInlineResultHandler(Handler[Update, CCT]): """Handler class to handle Telegram updates that contain a chosen inline result. - Note: - :attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you - can use to keep any data in will be sent to the :attr:`callback` function. Related to - either the user or the chat that the update was sent in. For each update from the same user - or in the same chat, it will be the same ``dict``. - - Note that this is DEPRECATED, and you should use context based callbacks. See - https://git.io/fxJuV for more info. - Warning: When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info. @@ -51,28 +42,13 @@ class ChosenInlineResultHandler(Handler[Update, CCT]): Args: callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` The return value of the callback is usually ignored except for the special case of :class:`telegram.ext.ConversationHandler`. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``user_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``chat_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. pattern (:obj:`str` | `Pattern`, optional): Regex pattern. If not :obj:`None`, ``re.match`` @@ -84,14 +60,6 @@ class ChosenInlineResultHandler(Handler[Update, CCT]): Attributes: callback (:obj:`callable`): The callback function for this handler. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. - pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to - the callback function. - pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. pattern (`Pattern`): Optional. Regex pattern to test :attr:`telegram.ChosenInlineResult.result_id` against. @@ -105,19 +73,11 @@ class ChosenInlineResultHandler(Handler[Update, CCT]): def __init__( self, callback: Callable[[Update, 'CallbackContext'], RT], - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, run_async: Union[bool, DefaultValue] = DEFAULT_FALSE, pattern: Union[str, Pattern] = None, ): super().__init__( callback, - pass_update_queue=pass_update_queue, - pass_job_queue=pass_job_queue, - pass_user_data=pass_user_data, - pass_chat_data=pass_chat_data, run_async=run_async, ) diff --git a/telegram/ext/commandhandler.py b/telegram/ext/commandhandler.py index 1f0a32118a9..1e7f5c8dd1b 100644 --- a/telegram/ext/commandhandler.py +++ b/telegram/ext/commandhandler.py @@ -18,12 +18,10 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the CommandHandler and PrefixHandler classes.""" import re -import warnings from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple, TypeVar, Union from telegram import MessageEntity, Update from telegram.ext import BaseFilter, Filters -from telegram.utils.deprecate import TelegramDeprecationWarning from telegram.utils.types import SLT from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE @@ -49,13 +47,6 @@ class CommandHandler(Handler[Update, CCT]): Note: * :class:`CommandHandler` does *not* handle (edited) channel posts. - * :attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a :obj:`dict` you - can use to keep any data in will be sent to the :attr:`callback` function. Related to - either the user or the chat that the update was sent in. For each update from the same - user or in the same chat, it will be the same :obj:`dict`. - - Note that this is DEPRECATED, and you should use context based callbacks. See - https://git.io/fxJuV for more info. Warning: When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom @@ -67,7 +58,8 @@ class CommandHandler(Handler[Update, CCT]): Limitations are the same as described here https://core.telegram.org/bots#commands callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` @@ -77,31 +69,6 @@ class CommandHandler(Handler[Update, CCT]): :class:`telegram.ext.filters.BaseFilter`. Standard filters can be found in :class:`telegram.ext.filters.Filters`. Filters can be combined using bitwise operators (& for and, | for or, ~ for not). - allow_edited (:obj:`bool`, optional): Determines whether the handler should also accept - edited messages. Default is :obj:`False`. - DEPRECATED: Edited is allowed by default. To change this behavior use - ``~Filters.update.edited_message``. - pass_args (:obj:`bool`, optional): Determines whether the handler should be passed the - arguments passed to the command as a keyword argument called ``args``. It will contain - a list of strings, which is the text following the command split on single or - consecutive whitespace characters. Default is :obj:`False` - DEPRECATED: Please switch to context based callbacks. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``user_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``chat_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. @@ -115,42 +82,20 @@ class CommandHandler(Handler[Update, CCT]): callback (:obj:`callable`): The callback function for this handler. filters (:class:`telegram.ext.BaseFilter`): Optional. Only allow updates with these Filters. - allow_edited (:obj:`bool`): Determines whether the handler should also accept - edited messages. - pass_args (:obj:`bool`): Determines whether the handler should be passed - ``args``. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. - pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to - the callback function. - pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ - __slots__ = ('command', 'filters', 'pass_args') + __slots__ = ('command', 'filters') def __init__( self, command: SLT[str], callback: Callable[[Update, CCT], RT], filters: BaseFilter = None, - allow_edited: bool = None, - pass_args: bool = False, - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, run_async: Union[bool, DefaultValue] = DEFAULT_FALSE, ): super().__init__( callback, - pass_update_queue=pass_update_queue, - pass_job_queue=pass_job_queue, - pass_user_data=pass_user_data, - pass_chat_data=pass_chat_data, run_async=run_async, ) @@ -167,16 +112,6 @@ def __init__( else: self.filters = Filters.update.messages - if allow_edited is not None: - warnings.warn( - 'allow_edited is deprecated. See https://git.io/fxJuV for more info', - TelegramDeprecationWarning, - stacklevel=2, - ) - if not allow_edited: - self.filters &= ~Filters.update.edited_message - self.pass_args = pass_args - def check_update( self, update: object ) -> Optional[Union[bool, Tuple[List[str], Optional[Union[bool, Dict]]]]]: @@ -216,20 +151,6 @@ def check_update( return False return None - def collect_optional_args( - self, - dispatcher: 'Dispatcher', - update: Update = None, - check_result: Optional[Union[bool, Tuple[List[str], Optional[bool]]]] = None, - ) -> Dict[str, object]: - """Provide text after the command to the callback the ``args`` argument as list, split on - single whitespaces. - """ - optional_args = super().collect_optional_args(dispatcher, update) - if self.pass_args and isinstance(check_result, tuple): - optional_args['args'] = check_result[0] - return optional_args - def collect_additional_context( self, context: CCT, @@ -282,13 +203,6 @@ class PrefixHandler(CommandHandler): Note: * :class:`PrefixHandler` does *not* handle (edited) channel posts. - * :attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a :obj:`dict` you - can use to keep any data in will be sent to the :attr:`callback` function. Related to - either the user or the chat that the update was sent in. For each update from the same - user or in the same chat, it will be the same :obj:`dict`. - - Note that this is DEPRECATED, and you should use context based callbacks. See - https://git.io/fxJuV for more info. Warning: When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom @@ -301,7 +215,8 @@ class PrefixHandler(CommandHandler): The command or list of commands this handler should listen for. callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` @@ -311,27 +226,6 @@ class PrefixHandler(CommandHandler): :class:`telegram.ext.filters.BaseFilter`. Standard filters can be found in :class:`telegram.ext.filters.Filters`. Filters can be combined using bitwise operators (& for and, | for or, ~ for not). - pass_args (:obj:`bool`, optional): Determines whether the handler should be passed the - arguments passed to the command as a keyword argument called ``args``. It will contain - a list of strings, which is the text following the command split on single or - consecutive whitespace characters. Default is :obj:`False` - DEPRECATED: Please switch to context based callbacks. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``user_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``chat_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. @@ -339,16 +233,6 @@ class PrefixHandler(CommandHandler): callback (:obj:`callable`): The callback function for this handler. filters (:class:`telegram.ext.BaseFilter`): Optional. Only allow updates with these Filters. - pass_args (:obj:`bool`): Determines whether the handler should be passed - ``args``. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. - pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to - the callback function. - pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ @@ -362,11 +246,6 @@ def __init__( command: SLT[str], callback: Callable[[Update, CCT], RT], filters: BaseFilter = None, - pass_args: bool = False, - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, run_async: Union[bool, DefaultValue] = DEFAULT_FALSE, ): @@ -378,12 +257,6 @@ def __init__( 'nocommand', callback, filters=filters, - allow_edited=None, - pass_args=pass_args, - pass_update_queue=pass_update_queue, - pass_job_queue=pass_job_queue, - pass_user_data=pass_user_data, - pass_chat_data=pass_chat_data, run_async=run_async, ) diff --git a/telegram/ext/conversationhandler.py b/telegram/ext/conversationhandler.py index fe1978b5bf7..91ed42a61e2 100644 --- a/telegram/ext/conversationhandler.py +++ b/telegram/ext/conversationhandler.py @@ -53,7 +53,7 @@ def __init__( conversation_key: Tuple[int, ...], update: Update, dispatcher: 'Dispatcher', - callback_context: Optional[CallbackContext], + callback_context: CallbackContext, ): self.conversation_key = conversation_key self.update = update @@ -486,7 +486,7 @@ def _schedule_job( new_state: object, dispatcher: 'Dispatcher', update: Update, - context: Optional[CallbackContext], + context: CallbackContext, conversation_key: Tuple[int, ...], ) -> None: if new_state != self.END: @@ -598,7 +598,7 @@ def handle_update( # type: ignore[override] update: Update, dispatcher: 'Dispatcher', check_result: CheckUpdateType, - context: CallbackContext = None, + context: CallbackContext, ) -> Optional[object]: """Send the update to the callback for the current state and Handler @@ -607,11 +607,10 @@ def handle_update( # type: ignore[override] handler, and the handler's check result. update (:class:`telegram.Update`): Incoming telegram update. dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the Update. - context (:class:`telegram.ext.CallbackContext`, optional): The context as provided by + context (:class:`telegram.ext.CallbackContext`): The context as provided by the dispatcher. """ - update = cast(Update, update) # for mypy conversation_key, handler, check_result = check_result # type: ignore[assignment,misc] raise_dp_handler_stop = False @@ -690,15 +689,11 @@ def _update_state(self, new_state: object, key: Tuple[int, ...]) -> None: if self.persistent and self.persistence and self.name: self.persistence.update_conversation(self.name, key, new_state) - def _trigger_timeout(self, context: CallbackContext, job: 'Job' = None) -> None: + def _trigger_timeout(self, context: CallbackContext) -> None: self.logger.debug('conversation timeout was triggered!') - # Backward compatibility with bots that do not use CallbackContext - if isinstance(context, CallbackContext): - job = context.job - ctxt = cast(_ConversationTimeoutContext, job.context) # type: ignore[union-attr] - else: - ctxt = cast(_ConversationTimeoutContext, job.context) + job = cast('Job', context.job) + ctxt = cast(_ConversationTimeoutContext, job.context) callback_context = ctxt.callback_context diff --git a/telegram/ext/dispatcher.py b/telegram/ext/dispatcher.py index bcc4e741560..572579faa9b 100644 --- a/telegram/ext/dispatcher.py +++ b/telegram/ext/dispatcher.py @@ -135,9 +135,6 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): ``@run_async`` decorator and :meth:`run_async`. Defaults to 4. persistence (:class:`telegram.ext.BasePersistence`, optional): The persistence class to store data that should be persistent over restarts. - use_context (:obj:`bool`, optional): If set to :obj:`True` uses the context based callback - API (ignored if `dispatcher` argument is used). Defaults to :obj:`True`. - **New users**: set this to :obj:`True`. context_types (:class:`telegram.ext.ContextTypes`, optional): Pass an instance of :class:`telegram.ext.ContextTypes` to customize the types used in the ``context`` interface. If not passed, the defaults documented in @@ -168,7 +165,6 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): __slots__ = ( 'workers', 'persistence', - 'use_context', 'update_queue', 'job_queue', 'user_data', @@ -203,7 +199,6 @@ def __init__( exception_event: Event = None, job_queue: 'JobQueue' = None, persistence: BasePersistence = None, - use_context: bool = True, ): ... @@ -216,7 +211,6 @@ def __init__( exception_event: Event = None, job_queue: 'JobQueue' = None, persistence: BasePersistence = None, - use_context: bool = True, context_types: ContextTypes[CCT, UD, CD, BD] = None, ): ... @@ -229,23 +223,14 @@ def __init__( exception_event: Event = None, job_queue: 'JobQueue' = None, persistence: BasePersistence = None, - use_context: bool = True, context_types: ContextTypes[CCT, UD, CD, BD] = None, ): self.bot = bot self.update_queue = update_queue self.job_queue = job_queue self.workers = workers - self.use_context = use_context self.context_types = cast(ContextTypes[CCT, UD, CD, BD], context_types or ContextTypes()) - if not use_context: - warnings.warn( - 'Old Handler API is deprecated - see https://git.io/fxJuV for details', - TelegramDeprecationWarning, - stacklevel=3, - ) - if self.workers < 1: warnings.warn( 'Asynchronous callbacks can not be processed without at least one worker thread.' @@ -536,7 +521,7 @@ def process_update(self, update: object) -> None: for handler in self.handlers[group]: check = handler.check_update(update) if check is not None and check is not False: - if not context and self.use_context: + if not context: context = self.context_types.context.from_update(update, self) context.refresh_data() handled = True @@ -743,16 +728,15 @@ def add_error_handler( Args: callback (:obj:`callable`): The callback function for this error handler. Will be - called when an error is raised. Callback signature for context based API: + called when an error is raised. + Callback signature: + - ``def callback(update: object, context: CallbackContext)`` + ``def callback(update: Update, context: CallbackContext)`` The error that happened will be present in context.error. run_async (:obj:`bool`, optional): Whether this handlers callback should be run asynchronously using :meth:`run_async`. Defaults to :obj:`False`. - - Note: - See https://git.io/fxJuV for more info about switching to context based API. """ if callback in self.error_handlers: self.logger.debug('The callback is already registered as an error handler. Ignoring.') @@ -789,19 +773,13 @@ def dispatch_error( if self.error_handlers: for callback, run_async in self.error_handlers.items(): # pylint: disable=W0621 - if self.use_context: - context = self.context_types.context.from_error( - update, error, self, async_args=async_args, async_kwargs=async_kwargs - ) - if run_async: - self.run_async(callback, update, context, update=update) - else: - callback(update, context) + context = self.context_types.context.from_error( + update, error, self, async_args=async_args, async_kwargs=async_kwargs + ) + if run_async: + self.run_async(callback, update, context, update=update) else: - if run_async: - self.run_async(callback, self.bot, update, error, update=update) - else: - callback(self.bot, update, error) + callback(update, context) else: self.logger.exception( diff --git a/telegram/ext/handler.py b/telegram/ext/handler.py index 81e35852a18..028713811b8 100644 --- a/telegram/ext/handler.py +++ b/telegram/ext/handler.py @@ -18,9 +18,8 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the base class for handlers as used by the Dispatcher.""" from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, TypeVar, Union, Generic +from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, Union, Generic -from telegram import Update from telegram.ext.utils.promise import Promise from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE from telegram.ext.utils.types import CCT @@ -35,15 +34,6 @@ class Handler(Generic[UT, CCT], ABC): """The base class for all update handlers. Create custom handlers by inheriting from it. - Note: - :attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you - can use to keep any data in will be sent to the :attr:`callback` function. Related to - either the user or the chat that the update was sent in. For each update from the same user - or in the same chat, it will be the same ``dict``. - - Note that this is DEPRECATED, and you should use context based callbacks. See - https://git.io/fxJuV for more info. - Warning: When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info. @@ -51,68 +41,33 @@ class Handler(Generic[UT, CCT], ABC): Args: callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` The return value of the callback is usually ignored except for the special case of :class:`telegram.ext.ConversationHandler`. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``user_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``chat_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. Attributes: callback (:obj:`callable`): The callback function for this handler. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. - pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to - the callback function. - pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ __slots__ = ( 'callback', - 'pass_update_queue', - 'pass_job_queue', - 'pass_user_data', - 'pass_chat_data', 'run_async', ) def __init__( self, callback: Callable[[UT, CCT], RT], - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, run_async: Union[bool, DefaultValue] = DEFAULT_FALSE, ): self.callback = callback - self.pass_update_queue = pass_update_queue - self.pass_job_queue = pass_job_queue - self.pass_user_data = pass_user_data - self.pass_chat_data = pass_chat_data self.run_async = run_async @abstractmethod @@ -140,7 +95,7 @@ def handle_update( update: UT, dispatcher: 'Dispatcher', check_result: object, - context: CCT = None, + context: CCT, ) -> Union[RT, Promise]: """ This method is called if it was determined that an update should indeed @@ -153,7 +108,7 @@ def handle_update( update (:obj:`str` | :class:`telegram.Update`): The update to be handled. dispatcher (:class:`telegram.ext.Dispatcher`): The calling dispatcher. check_result (:obj:`obj`): The result from :attr:`check_update`. - context (:class:`telegram.ext.CallbackContext`, optional): The context as provided by + context (:class:`telegram.ext.CallbackContext`): The context as provided by the dispatcher. """ @@ -165,18 +120,10 @@ def handle_update( ): run_async = True - if context: - self.collect_additional_context(context, update, dispatcher, check_result) - if run_async: - return dispatcher.run_async(self.callback, update, context, update=update) - return self.callback(update, context) - - optional_args = self.collect_optional_args(dispatcher, update, check_result) + self.collect_additional_context(context, update, dispatcher, check_result) if run_async: - return dispatcher.run_async( - self.callback, dispatcher.bot, update, update=update, **optional_args - ) - return self.callback(dispatcher.bot, update, **optional_args) # type: ignore + return dispatcher.run_async(self.callback, update, context, update=update) + return self.callback(update, context) def collect_additional_context( self, @@ -194,41 +141,3 @@ def collect_additional_context( check_result: The result (return value) from :attr:`check_update`. """ - - def collect_optional_args( - self, - dispatcher: 'Dispatcher', - update: UT = None, - check_result: Any = None, # pylint: disable=W0613 - ) -> Dict[str, object]: - """ - Prepares the optional arguments. If the handler has additional optional args, - it should subclass this method, but remember to call this super method. - - DEPRECATED: This method is being replaced by new context based callbacks. Please see - https://git.io/fxJuV for more info. - - Args: - dispatcher (:class:`telegram.ext.Dispatcher`): The dispatcher. - update (:class:`telegram.Update`): The update to gather chat/user id from. - check_result: The result from check_update - - """ - optional_args: Dict[str, object] = {} - - if self.pass_update_queue: - optional_args['update_queue'] = dispatcher.update_queue - if self.pass_job_queue: - optional_args['job_queue'] = dispatcher.job_queue - if self.pass_user_data and isinstance(update, Update): - user = update.effective_user - optional_args['user_data'] = dispatcher.user_data[ - user.id if user else None # type: ignore[index] - ] - if self.pass_chat_data and isinstance(update, Update): - chat = update.effective_chat - optional_args['chat_data'] = dispatcher.chat_data[ - chat.id if chat else None # type: ignore[index] - ] - - return optional_args diff --git a/telegram/ext/inlinequeryhandler.py b/telegram/ext/inlinequeryhandler.py index 11103e71ff6..d5ea7630e91 100644 --- a/telegram/ext/inlinequeryhandler.py +++ b/telegram/ext/inlinequeryhandler.py @@ -21,7 +21,6 @@ from typing import ( TYPE_CHECKING, Callable, - Dict, Match, Optional, Pattern, @@ -48,15 +47,6 @@ class InlineQueryHandler(Handler[Update, CCT]): Handler class to handle Telegram inline queries. Optionally based on a regex. Read the documentation of the ``re`` module for more information. - Note: - :attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you - can use to keep any data in will be sent to the :attr:`callback` function. Related to - either the user or the chat that the update was sent in. For each update from the same user - or in the same chat, it will be the same ``dict``. - - Note that this is DEPRECATED, and you should use context based callbacks. See - https://git.io/fxJuV for more info. - Warning: * When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info. @@ -67,22 +57,13 @@ class InlineQueryHandler(Handler[Update, CCT]): Args: callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` The return value of the callback is usually ignored except for the special case of :class:`telegram.ext.ConversationHandler`. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. pattern (:obj:`str` | :obj:`Pattern`, optional): Regex pattern. If not :obj:`None`, ``re.match`` is used on :attr:`telegram.InlineQuery.query` to determine if an update should be handled by this handler. @@ -90,67 +71,31 @@ class InlineQueryHandler(Handler[Update, CCT]): handle inline queries with the appropriate :attr:`telegram.InlineQuery.chat_type`. .. versionadded:: 13.5 - pass_groups (:obj:`bool`, optional): If the callback should be passed the result of - ``re.match(pattern, data).groups()`` as a keyword argument called ``groups``. - Default is :obj:`False` - DEPRECATED: Please switch to context based callbacks. - pass_groupdict (:obj:`bool`, optional): If the callback should be passed the result of - ``re.match(pattern, data).groupdict()`` as a keyword argument called ``groupdict``. - Default is :obj:`False` - DEPRECATED: Please switch to context based callbacks. - pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``user_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``chat_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. Attributes: callback (:obj:`callable`): The callback function for this handler. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. pattern (:obj:`str` | :obj:`Pattern`): Optional. Regex pattern to test :attr:`telegram.InlineQuery.query` against. chat_types (List[:obj:`str`], optional): List of allowed chat types. .. versionadded:: 13.5 - pass_groups (:obj:`bool`): Determines whether ``groups`` will be passed to the - callback function. - pass_groupdict (:obj:`bool`): Determines whether ``groupdict``. will be passed to - the callback function. - pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to - the callback function. - pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ - __slots__ = ('pattern', 'chat_types', 'pass_groups', 'pass_groupdict') + __slots__ = ('pattern', 'chat_types') def __init__( self, callback: Callable[[Update, CCT], RT], - pass_update_queue: bool = False, - pass_job_queue: bool = False, pattern: Union[str, Pattern] = None, - pass_groups: bool = False, - pass_groupdict: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, run_async: Union[bool, DefaultValue] = DEFAULT_FALSE, chat_types: List[str] = None, ): super().__init__( callback, - pass_update_queue=pass_update_queue, - pass_job_queue=pass_job_queue, - pass_user_data=pass_user_data, - pass_chat_data=pass_chat_data, run_async=run_async, ) @@ -159,8 +104,6 @@ def __init__( self.pattern = pattern self.chat_types = chat_types - self.pass_groups = pass_groups - self.pass_groupdict = pass_groupdict def check_update(self, update: object) -> Optional[Union[bool, Match]]: """ @@ -187,25 +130,6 @@ def check_update(self, update: object) -> Optional[Union[bool, Match]]: return True return None - def collect_optional_args( - self, - dispatcher: 'Dispatcher', - update: Update = None, - check_result: Optional[Union[bool, Match]] = None, - ) -> Dict[str, object]: - """Pass the results of ``re.match(pattern, query).{groups(), groupdict()}`` to the - callback as a keyword arguments called ``groups`` and ``groupdict``, respectively, if - needed. - """ - optional_args = super().collect_optional_args(dispatcher, update, check_result) - if self.pattern: - check_result = cast(Match, check_result) - if self.pass_groups: - optional_args['groups'] = check_result.groups() - if self.pass_groupdict: - optional_args['groupdict'] = check_result.groupdict() - return optional_args - def collect_additional_context( self, context: CCT, diff --git a/telegram/ext/jobqueue.py b/telegram/ext/jobqueue.py index 99233881646..681231df539 100644 --- a/telegram/ext/jobqueue.py +++ b/telegram/ext/jobqueue.py @@ -31,7 +31,6 @@ from telegram.utils.types import JSONDict if TYPE_CHECKING: - from telegram import Bot from telegram.ext import Dispatcher import apscheduler.job # noqa: F401 @@ -64,10 +63,8 @@ def aps_log_filter(record): # type: ignore logging.getLogger('apscheduler.executors.default').addFilter(aps_log_filter) self.scheduler.add_listener(self._dispatch_error, EVENT_JOB_ERROR) - def _build_args(self, job: 'Job') -> List[Union[CallbackContext, 'Bot', 'Job']]: - if self._dispatcher.use_context: - return [self._dispatcher.context_types.context.from_job(job, self._dispatcher)] - return [self._dispatcher.bot, job] + def _build_args(self, job: 'Job') -> List[CallbackContext]: + return [self._dispatcher.context_types.context.from_job(job, self._dispatcher)] def _tz_now(self) -> datetime.datetime: return datetime.datetime.now(self.scheduler.timezone) @@ -145,12 +142,11 @@ def run_once( Args: callback (:obj:`callable`): The callback function that should be executed by the new - job. Callback signature for context based API: + job. + Callback signature: - ``def callback(CallbackContext)`` - ``context.job`` is the :class:`telegram.ext.Job` instance. It can be used to access - its ``job.context`` or change it to a repeating job. + ``def callback(update: Update, context: CallbackContext)`` when (:obj:`int` | :obj:`float` | :obj:`datetime.timedelta` | \ :obj:`datetime.datetime` | :obj:`datetime.time`): Time in or at which the job should run. This parameter will be interpreted @@ -220,12 +216,11 @@ def run_repeating( Args: callback (:obj:`callable`): The callback function that should be executed by the new - job. Callback signature for context based API: + job. + Callback signature: - ``def callback(CallbackContext)`` - ``context.job`` is the :class:`telegram.ext.Job` instance. It can be used to access - its ``job.context`` or change it to a repeating job. + ``def callback(update: Update, context: CallbackContext)`` interval (:obj:`int` | :obj:`float` | :obj:`datetime.timedelta`): The interval in which the job will run. If it is an :obj:`int` or a :obj:`float`, it will be interpreted as seconds. @@ -315,12 +310,11 @@ def run_monthly( Args: callback (:obj:`callable`): The callback function that should be executed by the new - job. Callback signature for context based API: + job. + Callback signature: - ``def callback(CallbackContext)`` - ``context.job`` is the :class:`telegram.ext.Job` instance. It can be used to access - its ``job.context`` or change it to a repeating job. + ``def callback(update: Update, context: CallbackContext)`` when (:obj:`datetime.time`): Time of day at which the job should run. If the timezone (``when.tzinfo``) is :obj:`None`, the default timezone of the bot will be used. day (:obj:`int`): Defines the day of the month whereby the job would run. It should @@ -379,12 +373,11 @@ def run_daily( Args: callback (:obj:`callable`): The callback function that should be executed by the new - job. Callback signature for context based API: + job. + Callback signature: - ``def callback(CallbackContext)`` - ``context.job`` is the :class:`telegram.ext.Job` instance. It can be used to access - its ``job.context`` or change it to a repeating job. + ``def callback(update: Update, context: CallbackContext)`` time (:obj:`datetime.time`): Time of day at which the job should run. If the timezone (``time.tzinfo``) is :obj:`None`, the default timezone of the bot will be used. days (Tuple[:obj:`int`], optional): Defines on which days of the week the job should @@ -434,12 +427,11 @@ def run_custom( Args: callback (:obj:`callable`): The callback function that should be executed by the new - job. Callback signature for context based API: + job. + Callback signature: - ``def callback(CallbackContext)`` - ``context.job`` is the :class:`telegram.ext.Job` instance. It can be used to access - its ``job.context`` or change it to a repeating job. + ``def callback(update: Update, context: CallbackContext)`` job_kwargs (:obj:`dict`): Arbitrary keyword arguments. Used as arguments for ``scheduler.add_job``. context (:obj:`object`, optional): Additional data needed for the callback function. @@ -502,12 +494,10 @@ class Job: Args: callback (:obj:`callable`): The callback function that should be executed by the new job. - Callback signature for context based API: + Callback signature: - ``def callback(CallbackContext)`` - a ``context.job`` is the :class:`telegram.ext.Job` instance. It can be used to access - its ``job.context`` or change it to a repeating job. + ``def callback(update: Update, context: CallbackContext)`` context (:obj:`object`, optional): Additional data needed for the callback function. Can be accessed through ``job.context`` in the callback. Defaults to :obj:`None`. name (:obj:`str`, optional): The name of the new job. Defaults to ``callback.__name__``. @@ -555,10 +545,7 @@ def __init__( def run(self, dispatcher: 'Dispatcher') -> None: """Executes the callback function independently of the jobs schedule.""" try: - if dispatcher.use_context: - self.callback(dispatcher.context_types.context.from_job(self, dispatcher)) - else: - self.callback(dispatcher.bot, self) # type: ignore[arg-type,call-arg] + self.callback(dispatcher.context_types.context.from_job(self, dispatcher)) except Exception as exc: try: dispatcher.dispatch_error(None, exc) diff --git a/telegram/ext/messagehandler.py b/telegram/ext/messagehandler.py index c3f0c015cd1..e5327fb4d55 100644 --- a/telegram/ext/messagehandler.py +++ b/telegram/ext/messagehandler.py @@ -16,14 +16,11 @@ # # You should have received a copy of the GNU Lesser Public License # along with this program. If not, see [http://www.gnu.org/licenses/]. -# TODO: Remove allow_edited """This module contains the MessageHandler class.""" -import warnings from typing import TYPE_CHECKING, Callable, Dict, Optional, TypeVar, Union from telegram import Update from telegram.ext import BaseFilter, Filters -from telegram.utils.deprecate import TelegramDeprecationWarning from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE from .handler import Handler @@ -38,15 +35,6 @@ class MessageHandler(Handler[Update, CCT]): """Handler class to handle telegram messages. They might contain text, media or status updates. - Note: - :attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you - can use to keep any data in will be sent to the :attr:`callback` function. Related to - either the user or the chat that the update was sent in. For each update from the same user - or in the same chat, it will be the same ``dict``. - - Note that this is DEPRECATED, and you should use context based callbacks. See - https://git.io/fxJuV for more info. - Warning: When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info. @@ -62,37 +50,13 @@ class MessageHandler(Handler[Update, CCT]): argument. callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` The return value of the callback is usually ignored except for the special case of :class:`telegram.ext.ConversationHandler`. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``user_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``chat_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - message_updates (:obj:`bool`, optional): Should "normal" message updates be handled? - Default is :obj:`None`. - DEPRECATED: Please switch to filters for update filtering. - channel_post_updates (:obj:`bool`, optional): Should channel posts updates be handled? - Default is :obj:`None`. - DEPRECATED: Please switch to filters for update filtering. - edited_updates (:obj:`bool`, optional): Should "edited" message updates be handled? Default - is :obj:`None`. - DEPRECATED: Please switch to filters for update filtering. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. @@ -103,20 +67,6 @@ class MessageHandler(Handler[Update, CCT]): filters (:obj:`Filter`): Only allow updates with these Filters. See :mod:`telegram.ext.filters` for a full list of all available filters. callback (:obj:`callable`): The callback function for this handler. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. - pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to - the callback function. - pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to - the callback function. - message_updates (:obj:`bool`): Should "normal" message updates be handled? - Default is :obj:`None`. - channel_post_updates (:obj:`bool`): Should channel posts updates be handled? - Default is :obj:`None`. - edited_updates (:obj:`bool`): Should "edited" message updates be handled? - Default is :obj:`None`. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ @@ -127,60 +77,17 @@ def __init__( self, filters: BaseFilter, callback: Callable[[Update, CCT], RT], - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, - message_updates: bool = None, - channel_post_updates: bool = None, - edited_updates: bool = None, run_async: Union[bool, DefaultValue] = DEFAULT_FALSE, ): super().__init__( callback, - pass_update_queue=pass_update_queue, - pass_job_queue=pass_job_queue, - pass_user_data=pass_user_data, - pass_chat_data=pass_chat_data, run_async=run_async, ) - if message_updates is False and channel_post_updates is False and edited_updates is False: - raise ValueError( - 'message_updates, channel_post_updates and edited_updates are all False' - ) if filters is not None: self.filters = Filters.update & filters else: self.filters = Filters.update - if message_updates is not None: - warnings.warn( - 'message_updates is deprecated. See https://git.io/fxJuV for more info', - TelegramDeprecationWarning, - stacklevel=2, - ) - if message_updates is False: - self.filters &= ~Filters.update.message - - if channel_post_updates is not None: - warnings.warn( - 'channel_post_updates is deprecated. See https://git.io/fxJuV ' 'for more info', - TelegramDeprecationWarning, - stacklevel=2, - ) - if channel_post_updates is False: - self.filters &= ~Filters.update.channel_post - - if edited_updates is not None: - warnings.warn( - 'edited_updates is deprecated. See https://git.io/fxJuV for more info', - TelegramDeprecationWarning, - stacklevel=2, - ) - if edited_updates is False: - self.filters &= ~( - Filters.update.edited_message | Filters.update.edited_channel_post - ) def check_update(self, update: object) -> Optional[Union[bool, Dict[str, list]]]: """Determines whether an update should be passed to this handlers :attr:`callback`. @@ -192,7 +99,7 @@ def check_update(self, update: object) -> Optional[Union[bool, Dict[str, list]]] :obj:`bool` """ - if isinstance(update, Update) and update.effective_message: + if isinstance(update, Update): return self.filters(update) return None diff --git a/telegram/ext/pollanswerhandler.py b/telegram/ext/pollanswerhandler.py index 199bcb3ad2b..7b0521ae954 100644 --- a/telegram/ext/pollanswerhandler.py +++ b/telegram/ext/pollanswerhandler.py @@ -28,15 +28,6 @@ class PollAnswerHandler(Handler[Update, CCT]): """Handler class to handle Telegram updates that contain a poll answer. - Note: - :attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you - can use to keep any data in will be sent to the :attr:`callback` function. Related to - either the user or the chat that the update was sent in. For each update from the same user - or in the same chat, it will be the same ``dict``. - - Note that this is DEPRECATED, and you should use context based callbacks. See - https://git.io/fxJuV for more info. - Warning: When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info. @@ -44,41 +35,18 @@ class PollAnswerHandler(Handler[Update, CCT]): Args: callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` The return value of the callback is usually ignored except for the special case of :class:`telegram.ext.ConversationHandler`. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``user_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``chat_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. Attributes: callback (:obj:`callable`): The callback function for this handler. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. - pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to - the callback function. - pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ diff --git a/telegram/ext/pollhandler.py b/telegram/ext/pollhandler.py index 7b67e76ffb1..a2538fa53d8 100644 --- a/telegram/ext/pollhandler.py +++ b/telegram/ext/pollhandler.py @@ -28,15 +28,6 @@ class PollHandler(Handler[Update, CCT]): """Handler class to handle Telegram updates that contain a poll. - Note: - :attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you - can use to keep any data in will be sent to the :attr:`callback` function. Related to - either the user or the chat that the update was sent in. For each update from the same user - or in the same chat, it will be the same ``dict``. - - Note that this is DEPRECATED, and you should use context based callbacks. See - https://git.io/fxJuV for more info. - Warning: When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info. @@ -44,41 +35,18 @@ class PollHandler(Handler[Update, CCT]): Args: callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` The return value of the callback is usually ignored except for the special case of :class:`telegram.ext.ConversationHandler`. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``user_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``chat_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. Attributes: callback (:obj:`callable`): The callback function for this handler. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. - pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to - the callback function. - pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ diff --git a/telegram/ext/precheckoutqueryhandler.py b/telegram/ext/precheckoutqueryhandler.py index 3a2eee30d0a..29d0ac7cd4c 100644 --- a/telegram/ext/precheckoutqueryhandler.py +++ b/telegram/ext/precheckoutqueryhandler.py @@ -28,15 +28,6 @@ class PreCheckoutQueryHandler(Handler[Update, CCT]): """Handler class to handle Telegram PreCheckout callback queries. - Note: - :attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you - can use to keep any data in will be sent to the :attr:`callback` function. Related to - either the user or the chat that the update was sent in. For each update from the same user - or in the same chat, it will be the same ``dict``. - - Note that this is DEPRECATED, and you should use context based callbacks. See - https://git.io/fxJuV for more info. - Warning: When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info. @@ -44,41 +35,18 @@ class PreCheckoutQueryHandler(Handler[Update, CCT]): Args: callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` The return value of the callback is usually ignored except for the special case of :class:`telegram.ext.ConversationHandler`. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - DEPRECATED: Please switch to context based callbacks. - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``user_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``chat_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. Attributes: callback (:obj:`callable`): The callback function for this handler. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. - pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to - the callback function. - pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ diff --git a/telegram/ext/regexhandler.py b/telegram/ext/regexhandler.py deleted file mode 100644 index 399e4df7d94..00000000000 --- a/telegram/ext/regexhandler.py +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015-2021 -# Leandro Toledo de Souza -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser Public License for more details. -# -# You should have received a copy of the GNU Lesser Public License -# along with this program. If not, see [http://www.gnu.org/licenses/]. -# TODO: Remove allow_edited -"""This module contains the RegexHandler class.""" - -import warnings -from typing import TYPE_CHECKING, Callable, Dict, Optional, Pattern, TypeVar, Union, Any - -from telegram import Update -from telegram.ext import Filters, MessageHandler -from telegram.utils.deprecate import TelegramDeprecationWarning -from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE -from telegram.ext.utils.types import CCT - -if TYPE_CHECKING: - from telegram.ext import Dispatcher - -RT = TypeVar('RT') - - -class RegexHandler(MessageHandler): - """Handler class to handle Telegram updates based on a regex. - - It uses a regular expression to check text messages. Read the documentation of the ``re`` - module for more information. The ``re.match`` function is used to determine if an update should - be handled by this handler. - - Note: - This handler is being deprecated. For the same use case use: - ``MessageHandler(Filters.regex(r'pattern'), callback)`` - - Warning: - When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom - attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info. - - - Args: - pattern (:obj:`str` | :obj:`Pattern`): The regex pattern. - callback (:obj:`callable`): The callback function for this handler. Will be called when - :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: - - ``def callback(update: Update, context: CallbackContext)`` - - The return value of the callback is usually ignored except for the special case of - :class:`telegram.ext.ConversationHandler`. - pass_groups (:obj:`bool`, optional): If the callback should be passed the result of - ``re.match(pattern, data).groups()`` as a keyword argument called ``groups``. - Default is :obj:`False` - pass_groupdict (:obj:`bool`, optional): If the callback should be passed the result of - ``re.match(pattern, data).groupdict()`` as a keyword argument called ``groupdict``. - Default is :obj:`False` - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``user_data`` will be passed to the callback function. Default is :obj:`False`. - pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``chat_data`` will be passed to the callback function. Default is :obj:`False`. - message_updates (:obj:`bool`, optional): Should "normal" message updates be handled? - Default is :obj:`True`. - channel_post_updates (:obj:`bool`, optional): Should channel posts updates be handled? - Default is :obj:`True`. - edited_updates (:obj:`bool`, optional): Should "edited" message updates be handled? Default - is :obj:`False`. - run_async (:obj:`bool`): Determines whether the callback will run asynchronously. - Defaults to :obj:`False`. - - Raises: - ValueError - - Attributes: - pattern (:obj:`str` | :obj:`Pattern`): The regex pattern. - callback (:obj:`callable`): The callback function for this handler. - pass_groups (:obj:`bool`): Determines whether ``groups`` will be passed to the - callback function. - pass_groupdict (:obj:`bool`): Determines whether ``groupdict``. will be passed to - the callback function. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. - pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to - the callback function. - pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to - the callback function. - run_async (:obj:`bool`): Determines whether the callback will run asynchronously. - - """ - - __slots__ = ('pass_groups', 'pass_groupdict') - - def __init__( - self, - pattern: Union[str, Pattern], - callback: Callable[[Update, CCT], RT], - pass_groups: bool = False, - pass_groupdict: bool = False, - pass_update_queue: bool = False, - pass_job_queue: bool = False, - pass_user_data: bool = False, - pass_chat_data: bool = False, - allow_edited: bool = False, # pylint: disable=W0613 - message_updates: bool = True, - channel_post_updates: bool = False, - edited_updates: bool = False, - run_async: Union[bool, DefaultValue] = DEFAULT_FALSE, - ): - warnings.warn( - 'RegexHandler is deprecated. See https://git.io/fxJuV for more info', - TelegramDeprecationWarning, - stacklevel=2, - ) - super().__init__( - Filters.regex(pattern), - callback, - pass_update_queue=pass_update_queue, - pass_job_queue=pass_job_queue, - pass_user_data=pass_user_data, - pass_chat_data=pass_chat_data, - message_updates=message_updates, - channel_post_updates=channel_post_updates, - edited_updates=edited_updates, - run_async=run_async, - ) - self.pass_groups = pass_groups - self.pass_groupdict = pass_groupdict - - def collect_optional_args( - self, - dispatcher: 'Dispatcher', - update: Update = None, - check_result: Optional[Union[bool, Dict[str, Any]]] = None, - ) -> Dict[str, object]: - """Pass the results of ``re.match(pattern, text).{groups(), groupdict()}`` to the - callback as a keyword arguments called ``groups`` and ``groupdict``, respectively, if - needed. - """ - optional_args = super().collect_optional_args(dispatcher, update, check_result) - if isinstance(check_result, dict): - if self.pass_groups: - optional_args['groups'] = check_result['matches'][0].groups() - if self.pass_groupdict: - optional_args['groupdict'] = check_result['matches'][0].groupdict() - return optional_args diff --git a/telegram/ext/shippingqueryhandler.py b/telegram/ext/shippingqueryhandler.py index e4229ceb738..6cb7e46732e 100644 --- a/telegram/ext/shippingqueryhandler.py +++ b/telegram/ext/shippingqueryhandler.py @@ -27,15 +27,6 @@ class ShippingQueryHandler(Handler[Update, CCT]): """Handler class to handle Telegram shipping callback queries. - Note: - :attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you - can use to keep any data in will be sent to the :attr:`callback` function. Related to - either the user or the chat that the update was sent in. For each update from the same user - or in the same chat, it will be the same ``dict``. - - Note that this is DEPRECATED, and you should use context based callbacks. See - https://git.io/fxJuV for more info. - Warning: When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info. @@ -43,41 +34,18 @@ class ShippingQueryHandler(Handler[Update, CCT]): Args: callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` The return value of the callback is usually ignored except for the special case of :class:`telegram.ext.ConversationHandler`. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_user_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``user_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_chat_data (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``chat_data`` will be passed to the callback function. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. Attributes: callback (:obj:`callable`): The callback function for this handler. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. - pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to - the callback function. - pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ diff --git a/telegram/ext/stringcommandhandler.py b/telegram/ext/stringcommandhandler.py index 1d84892e444..9d1428eb673 100644 --- a/telegram/ext/stringcommandhandler.py +++ b/telegram/ext/stringcommandhandler.py @@ -18,7 +18,7 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the StringCommandHandler class.""" -from typing import TYPE_CHECKING, Callable, Dict, List, Optional, TypeVar, Union +from typing import TYPE_CHECKING, Callable, List, Optional, TypeVar, Union from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE @@ -49,62 +49,36 @@ class StringCommandHandler(Handler[str, CCT]): command (:obj:`str`): The command this handler should listen for. callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` The return value of the callback is usually ignored except for the special case of :class:`telegram.ext.ConversationHandler`. - pass_args (:obj:`bool`, optional): Determines whether the handler should be passed the - arguments passed to the command as a keyword argument called ``args``. It will contain - a list of strings, which is the text following the command split on single or - consecutive whitespace characters. Default is :obj:`False` - DEPRECATED: Please switch to context based callbacks. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. Attributes: command (:obj:`str`): The command this handler should listen for. callback (:obj:`callable`): The callback function for this handler. - pass_args (:obj:`bool`): Determines whether the handler should be passed - ``args``. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ - __slots__ = ('command', 'pass_args') + __slots__ = ('command',) def __init__( self, command: str, callback: Callable[[str, CCT], RT], - pass_args: bool = False, - pass_update_queue: bool = False, - pass_job_queue: bool = False, run_async: Union[bool, DefaultValue] = DEFAULT_FALSE, ): super().__init__( callback, - pass_update_queue=pass_update_queue, - pass_job_queue=pass_job_queue, run_async=run_async, ) self.command = command - self.pass_args = pass_args def check_update(self, update: object) -> Optional[List[str]]: """Determines whether an update should be passed to this handlers :attr:`callback`. @@ -122,20 +96,6 @@ def check_update(self, update: object) -> Optional[List[str]]: return args[1:] return None - def collect_optional_args( - self, - dispatcher: 'Dispatcher', - update: str = None, - check_result: Optional[List[str]] = None, - ) -> Dict[str, object]: - """Provide text after the command to the callback the ``args`` argument as list, split on - single whitespaces. - """ - optional_args = super().collect_optional_args(dispatcher, update, check_result) - if self.pass_args: - optional_args['args'] = check_result - return optional_args - def collect_additional_context( self, context: CCT, diff --git a/telegram/ext/stringregexhandler.py b/telegram/ext/stringregexhandler.py index 282c48ad70e..92b9730a0bd 100644 --- a/telegram/ext/stringregexhandler.py +++ b/telegram/ext/stringregexhandler.py @@ -19,7 +19,7 @@ """This module contains the StringRegexHandler class.""" import re -from typing import TYPE_CHECKING, Callable, Dict, Match, Optional, Pattern, TypeVar, Union +from typing import TYPE_CHECKING, Callable, Match, Optional, Pattern, TypeVar, Union from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE @@ -50,64 +50,33 @@ class StringRegexHandler(Handler[str, CCT]): pattern (:obj:`str` | :obj:`Pattern`): The regex pattern. callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` The return value of the callback is usually ignored except for the special case of :class:`telegram.ext.ConversationHandler`. - pass_groups (:obj:`bool`, optional): If the callback should be passed the result of - ``re.match(pattern, data).groups()`` as a keyword argument called ``groups``. - Default is :obj:`False` - DEPRECATED: Please switch to context based callbacks. - pass_groupdict (:obj:`bool`, optional): If the callback should be passed the result of - ``re.match(pattern, data).groupdict()`` as a keyword argument called ``groupdict``. - Default is :obj:`False` - DEPRECATED: Please switch to context based callbacks. - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. Attributes: pattern (:obj:`str` | :obj:`Pattern`): The regex pattern. callback (:obj:`callable`): The callback function for this handler. - pass_groups (:obj:`bool`): Determines whether ``groups`` will be passed to the - callback function. - pass_groupdict (:obj:`bool`): Determines whether ``groupdict``. will be passed to - the callback function. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ - __slots__ = ('pass_groups', 'pass_groupdict', 'pattern') + __slots__ = ('pattern',) def __init__( self, pattern: Union[str, Pattern], callback: Callable[[str, CCT], RT], - pass_groups: bool = False, - pass_groupdict: bool = False, - pass_update_queue: bool = False, - pass_job_queue: bool = False, run_async: Union[bool, DefaultValue] = DEFAULT_FALSE, ): super().__init__( callback, - pass_update_queue=pass_update_queue, - pass_job_queue=pass_job_queue, run_async=run_async, ) @@ -115,8 +84,6 @@ def __init__( pattern = re.compile(pattern) self.pattern = pattern - self.pass_groups = pass_groups - self.pass_groupdict = pass_groupdict def check_update(self, update: object) -> Optional[Match]: """Determines whether an update should be passed to this handlers :attr:`callback`. @@ -134,24 +101,6 @@ def check_update(self, update: object) -> Optional[Match]: return match return None - def collect_optional_args( - self, - dispatcher: 'Dispatcher', - update: str = None, - check_result: Optional[Match] = None, - ) -> Dict[str, object]: - """Pass the results of ``re.match(pattern, update).{groups(), groupdict()}`` to the - callback as a keyword arguments called ``groups`` and ``groupdict``, respectively, if - needed. - """ - optional_args = super().collect_optional_args(dispatcher, update, check_result) - if self.pattern: - if self.pass_groups and check_result: - optional_args['groups'] = check_result.groups() - if self.pass_groupdict and check_result: - optional_args['groupdict'] = check_result.groupdict() - return optional_args - def collect_additional_context( self, context: CCT, diff --git a/telegram/ext/typehandler.py b/telegram/ext/typehandler.py index 531d10c30fa..8a9a74438ef 100644 --- a/telegram/ext/typehandler.py +++ b/telegram/ext/typehandler.py @@ -40,7 +40,8 @@ class TypeHandler(Handler[UT, CCT]): determined by ``isinstance`` callback (:obj:`callable`): The callback function for this handler. Will be called when :attr:`check_update` has determined that an update should be processed by this handler. - Callback signature for context based API: + Callback signature: + ``def callback(update: Update, context: CallbackContext)`` @@ -48,16 +49,6 @@ class TypeHandler(Handler[UT, CCT]): :class:`telegram.ext.ConversationHandler`. strict (:obj:`bool`, optional): Use ``type`` instead of ``isinstance``. Default is :obj:`False` - pass_update_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``update_queue`` will be passed to the callback function. It will be the ``Queue`` - instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher` - that contains new updates which can be used to insert updates. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. - pass_job_queue (:obj:`bool`, optional): If set to :obj:`True`, a keyword argument called - ``job_queue`` will be passed to the callback function. It will be a - :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater` - which can be used to schedule new jobs. Default is :obj:`False`. - DEPRECATED: Please switch to context based callbacks. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. Defaults to :obj:`False`. @@ -65,10 +56,6 @@ class TypeHandler(Handler[UT, CCT]): type (:obj:`type`): The ``type`` of updates this handler should process. callback (:obj:`callable`): The callback function for this handler. strict (:obj:`bool`): Use ``type`` instead of ``isinstance``. Default is :obj:`False`. - pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be - passed to the callback function. - pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to - the callback function. run_async (:obj:`bool`): Determines whether the callback will run asynchronously. """ @@ -80,14 +67,10 @@ def __init__( type: Type[UT], # pylint: disable=W0622 callback: Callable[[UT, CCT], RT], strict: bool = False, - pass_update_queue: bool = False, - pass_job_queue: bool = False, run_async: Union[bool, DefaultValue] = DEFAULT_FALSE, ): super().__init__( callback, - pass_update_queue=pass_update_queue, - pass_job_queue=pass_job_queue, run_async=run_async, ) self.type = type # pylint: disable=E0237 diff --git a/telegram/ext/updater.py b/telegram/ext/updater.py index 3793c7d52f3..4cbb2a288d5 100644 --- a/telegram/ext/updater.py +++ b/telegram/ext/updater.py @@ -93,9 +93,6 @@ class Updater(Generic[CCT, UD, CD, BD]): `telegram.utils.request.Request` object (ignored if `bot` or `dispatcher` argument is used). The request_kwargs are very useful for the advanced users who would like to control the default timeouts and/or control the proxy used for http communication. - use_context (:obj:`bool`, optional): If set to :obj:`True` uses the context based callback - API (ignored if `dispatcher` argument is used). Defaults to :obj:`True`. - **New users**: set this to :obj:`True`. persistence (:class:`telegram.ext.BasePersistence`, optional): The persistence class to store data that should be persistent over restarts (ignored if `dispatcher` argument is used). @@ -129,7 +126,6 @@ class Updater(Generic[CCT, UD, CD, BD]): running (:obj:`bool`): Indicates if the updater is running. persistence (:class:`telegram.ext.BasePersistence`): Optional. The persistence class to store data that should be persistent over restarts. - use_context (:obj:`bool`): Optional. :obj:`True` if using context based callbacks. """ @@ -164,7 +160,6 @@ def __init__( request_kwargs: Dict[str, Any] = None, persistence: 'BasePersistence' = None, # pylint: disable=E0601 defaults: 'Defaults' = None, - use_context: bool = True, base_file_url: str = None, arbitrary_callback_data: Union[DefaultValue, bool, int, None] = DEFAULT_FALSE, ): @@ -183,7 +178,6 @@ def __init__( request_kwargs: Dict[str, Any] = None, persistence: 'BasePersistence' = None, defaults: 'Defaults' = None, - use_context: bool = True, base_file_url: str = None, arbitrary_callback_data: Union[DefaultValue, bool, int, None] = DEFAULT_FALSE, context_types: ContextTypes[CCT, UD, CD, BD] = None, @@ -210,7 +204,6 @@ def __init__( # type: ignore[no-untyped-def,misc] request_kwargs: Dict[str, Any] = None, persistence: 'BasePersistence' = None, defaults: 'Defaults' = None, - use_context: bool = True, dispatcher=None, base_file_url: str = None, arbitrary_callback_data: Union[DefaultValue, bool, int, None] = DEFAULT_FALSE, @@ -243,8 +236,6 @@ def __init__( # type: ignore[no-untyped-def,misc] raise ValueError('`dispatcher` and `bot` are mutually exclusive') if persistence is not None: raise ValueError('`dispatcher` and `persistence` are mutually exclusive') - if use_context != dispatcher.use_context: - raise ValueError('`dispatcher` and `use_context` are mutually exclusive') if context_types is not None: raise ValueError('`dispatcher` and `context_types` are mutually exclusive') if workers is not None: @@ -300,7 +291,6 @@ def __init__( # type: ignore[no-untyped-def,misc] workers=workers, exception_event=self.__exception_event, persistence=persistence, - use_context=use_context, context_types=context_types, ) self.job_queue.set_dispatcher(self.dispatcher) diff --git a/tests/conftest.py b/tests/conftest.py index 2fcf61bcecc..9dad5246c10 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -159,7 +159,7 @@ def provider_token(bot_info): def create_dp(bot): # Dispatcher is heavy to init (due to many threads and such) so we have a single session # scoped one here, but before each test, reset it (dp fixture below) - dispatcher = Dispatcher(bot, Queue(), job_queue=JobQueue(), workers=2, use_context=False) + dispatcher = Dispatcher(bot, Queue(), job_queue=JobQueue(), workers=2) dispatcher.job_queue.set_dispatcher(dispatcher) thr = Thread(target=dispatcher.start) thr.start() @@ -195,23 +195,15 @@ def dp(_dp): object.__setattr__(_dp, '__async_queue', Queue()) object.__setattr__(_dp, '__async_threads', set()) _dp.persistence = None - _dp.use_context = False if _dp._Dispatcher__singleton_semaphore.acquire(blocking=0): Dispatcher._set_singleton(_dp) yield _dp Dispatcher._Dispatcher__singleton_semaphore.release() -@pytest.fixture(scope='function') -def cdp(dp): - dp.use_context = True - yield dp - dp.use_context = False - - @pytest.fixture(scope='function') def updater(bot): - up = Updater(bot=bot, workers=2, use_context=False) + up = Updater(bot=bot, workers=2) yield up if up.running: up.stop() diff --git a/tests/test_callbackcontext.py b/tests/test_callbackcontext.py index ed0fdc85e2d..7e49d5b452f 100644 --- a/tests/test_callbackcontext.py +++ b/tests/test_callbackcontext.py @@ -38,8 +38,8 @@ class TestCallbackContext: - def test_slot_behaviour(self, cdp, mro_slots, recwarn): - c = CallbackContext(cdp) + def test_slot_behaviour(self, dp, mro_slots, recwarn): + c = CallbackContext(dp) for attr in c.__slots__: assert getattr(c, attr, 'err') != 'err', f"got extra slot '{attr}'" assert not c.__dict__, f"got missing slot(s): {c.__dict__}" @@ -47,38 +47,34 @@ def test_slot_behaviour(self, cdp, mro_slots, recwarn): c.args = c.args assert len(recwarn) == 0, recwarn.list - def test_non_context_dp(self, dp): - with pytest.raises(ValueError): - CallbackContext(dp) + def test_from_job(self, dp): + job = dp.job_queue.run_once(lambda x: x, 10) - def test_from_job(self, cdp): - job = cdp.job_queue.run_once(lambda x: x, 10) - - callback_context = CallbackContext.from_job(job, cdp) + callback_context = CallbackContext.from_job(job, dp) assert callback_context.job is job assert callback_context.chat_data is None assert callback_context.user_data is None - assert callback_context.bot_data is cdp.bot_data - assert callback_context.bot is cdp.bot - assert callback_context.job_queue is cdp.job_queue - assert callback_context.update_queue is cdp.update_queue + assert callback_context.bot_data is dp.bot_data + assert callback_context.bot is dp.bot + assert callback_context.job_queue is dp.job_queue + assert callback_context.update_queue is dp.update_queue - def test_from_update(self, cdp): + def test_from_update(self, dp): update = Update( 0, message=Message(0, None, Chat(1, 'chat'), from_user=User(1, 'user', False)) ) - callback_context = CallbackContext.from_update(update, cdp) + callback_context = CallbackContext.from_update(update, dp) assert callback_context.chat_data == {} assert callback_context.user_data == {} - assert callback_context.bot_data is cdp.bot_data - assert callback_context.bot is cdp.bot - assert callback_context.job_queue is cdp.job_queue - assert callback_context.update_queue is cdp.update_queue + assert callback_context.bot_data is dp.bot_data + assert callback_context.bot is dp.bot + assert callback_context.job_queue is dp.job_queue + assert callback_context.update_queue is dp.update_queue - callback_context_same_user_chat = CallbackContext.from_update(update, cdp) + callback_context_same_user_chat = CallbackContext.from_update(update, dp) callback_context.bot_data['test'] = 'bot' callback_context.chat_data['test'] = 'chat' @@ -92,66 +88,66 @@ def test_from_update(self, cdp): 0, message=Message(0, None, Chat(2, 'chat'), from_user=User(2, 'user', False)) ) - callback_context_other_user_chat = CallbackContext.from_update(update_other_user_chat, cdp) + callback_context_other_user_chat = CallbackContext.from_update(update_other_user_chat, dp) assert callback_context_other_user_chat.bot_data is callback_context.bot_data assert callback_context_other_user_chat.chat_data is not callback_context.chat_data assert callback_context_other_user_chat.user_data is not callback_context.user_data - def test_from_update_not_update(self, cdp): - callback_context = CallbackContext.from_update(None, cdp) + def test_from_update_not_update(self, dp): + callback_context = CallbackContext.from_update(None, dp) assert callback_context.chat_data is None assert callback_context.user_data is None - assert callback_context.bot_data is cdp.bot_data - assert callback_context.bot is cdp.bot - assert callback_context.job_queue is cdp.job_queue - assert callback_context.update_queue is cdp.update_queue + assert callback_context.bot_data is dp.bot_data + assert callback_context.bot is dp.bot + assert callback_context.job_queue is dp.job_queue + assert callback_context.update_queue is dp.update_queue - callback_context = CallbackContext.from_update('', cdp) + callback_context = CallbackContext.from_update('', dp) assert callback_context.chat_data is None assert callback_context.user_data is None - assert callback_context.bot_data is cdp.bot_data - assert callback_context.bot is cdp.bot - assert callback_context.job_queue is cdp.job_queue - assert callback_context.update_queue is cdp.update_queue + assert callback_context.bot_data is dp.bot_data + assert callback_context.bot is dp.bot + assert callback_context.job_queue is dp.job_queue + assert callback_context.update_queue is dp.update_queue - def test_from_error(self, cdp): + def test_from_error(self, dp): error = TelegramError('test') update = Update( 0, message=Message(0, None, Chat(1, 'chat'), from_user=User(1, 'user', False)) ) - callback_context = CallbackContext.from_error(update, error, cdp) + callback_context = CallbackContext.from_error(update, error, dp) assert callback_context.error is error assert callback_context.chat_data == {} assert callback_context.user_data == {} - assert callback_context.bot_data is cdp.bot_data - assert callback_context.bot is cdp.bot - assert callback_context.job_queue is cdp.job_queue - assert callback_context.update_queue is cdp.update_queue + assert callback_context.bot_data is dp.bot_data + assert callback_context.bot is dp.bot + assert callback_context.job_queue is dp.job_queue + assert callback_context.update_queue is dp.update_queue assert callback_context.async_args is None assert callback_context.async_kwargs is None - def test_from_error_async_params(self, cdp): + def test_from_error_async_params(self, dp): error = TelegramError('test') args = [1, '2'] kwargs = {'one': 1, 2: 'two'} callback_context = CallbackContext.from_error( - None, error, cdp, async_args=args, async_kwargs=kwargs + None, error, dp, async_args=args, async_kwargs=kwargs ) assert callback_context.error is error assert callback_context.async_args is args assert callback_context.async_kwargs is kwargs - def test_match(self, cdp): - callback_context = CallbackContext(cdp) + def test_match(self, dp): + callback_context = CallbackContext(dp) assert callback_context.match is None @@ -159,12 +155,12 @@ def test_match(self, cdp): assert callback_context.match == 'test' - def test_data_assignment(self, cdp): + def test_data_assignment(self, dp): update = Update( 0, message=Message(0, None, Chat(1, 'chat'), from_user=User(1, 'user', False)) ) - callback_context = CallbackContext.from_update(update, cdp) + callback_context = CallbackContext.from_update(update, dp) with pytest.raises(AttributeError): callback_context.bot_data = {"test": 123} @@ -173,45 +169,45 @@ def test_data_assignment(self, cdp): with pytest.raises(AttributeError): callback_context.chat_data = "test" - def test_dispatcher_attribute(self, cdp): - callback_context = CallbackContext(cdp) - assert callback_context.dispatcher == cdp + def test_dispatcher_attribute(self, dp): + callback_context = CallbackContext(dp) + assert callback_context.dispatcher == dp - def test_drop_callback_data_exception(self, bot, cdp): + def test_drop_callback_data_exception(self, bot, dp): non_ext_bot = Bot(bot.token) update = Update( 0, message=Message(0, None, Chat(1, 'chat'), from_user=User(1, 'user', False)) ) - callback_context = CallbackContext.from_update(update, cdp) + callback_context = CallbackContext.from_update(update, dp) with pytest.raises(RuntimeError, match='This telegram.ext.ExtBot instance does not'): callback_context.drop_callback_data(None) try: - cdp.bot = non_ext_bot + dp.bot = non_ext_bot with pytest.raises(RuntimeError, match='telegram.Bot does not allow for'): callback_context.drop_callback_data(None) finally: - cdp.bot = bot + dp.bot = bot - def test_drop_callback_data(self, cdp, monkeypatch, chat_id): - monkeypatch.setattr(cdp.bot, 'arbitrary_callback_data', True) + def test_drop_callback_data(self, dp, monkeypatch, chat_id): + monkeypatch.setattr(dp.bot, 'arbitrary_callback_data', True) update = Update( 0, message=Message(0, None, Chat(1, 'chat'), from_user=User(1, 'user', False)) ) - callback_context = CallbackContext.from_update(update, cdp) - cdp.bot.send_message( + callback_context = CallbackContext.from_update(update, dp) + dp.bot.send_message( chat_id=chat_id, text='test', reply_markup=InlineKeyboardMarkup.from_button( InlineKeyboardButton('test', callback_data='callback_data') ), ) - keyboard_uuid = cdp.bot.callback_data_cache.persistence_data[0][0][0] - button_uuid = list(cdp.bot.callback_data_cache.persistence_data[0][0][2])[0] + keyboard_uuid = dp.bot.callback_data_cache.persistence_data[0][0][0] + button_uuid = list(dp.bot.callback_data_cache.persistence_data[0][0][2])[0] callback_data = keyboard_uuid + button_uuid callback_query = CallbackQuery( id='1', @@ -219,14 +215,14 @@ def test_drop_callback_data(self, cdp, monkeypatch, chat_id): chat_instance=None, data=callback_data, ) - cdp.bot.callback_data_cache.process_callback_query(callback_query) + dp.bot.callback_data_cache.process_callback_query(callback_query) try: - assert len(cdp.bot.callback_data_cache.persistence_data[0]) == 1 - assert list(cdp.bot.callback_data_cache.persistence_data[1]) == ['1'] + assert len(dp.bot.callback_data_cache.persistence_data[0]) == 1 + assert list(dp.bot.callback_data_cache.persistence_data[1]) == ['1'] callback_context.drop_callback_data(callback_query) - assert cdp.bot.callback_data_cache.persistence_data == ([], {}) + assert dp.bot.callback_data_cache.persistence_data == ([], {}) finally: - cdp.bot.callback_data_cache.clear_callback_data() - cdp.bot.callback_data_cache.clear_callback_queries() + dp.bot.callback_data_cache.clear_callback_data() + dp.bot.callback_data_cache.clear_callback_queries() diff --git a/tests/test_callbackqueryhandler.py b/tests/test_callbackqueryhandler.py index 58c4ccf34c7..ad8996a1547 100644 --- a/tests/test_callbackqueryhandler.py +++ b/tests/test_callbackqueryhandler.py @@ -82,8 +82,8 @@ def test_slot_behaviour(self, mro_slots): def reset(self): self.test_flag = False - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) + def callback_basic(self, update, context): + test_bot = isinstance(context.bot, Bot) test_update = isinstance(update, Update) self.test_flag = test_bot and test_update @@ -124,15 +124,6 @@ def callback_context_pattern(self, update, context): if context.matches[0].groupdict(): self.test_flag = context.matches[0].groupdict() == {'begin': 't', 'end': ' data'} - def test_basic(self, dp, callback_query): - handler = CallbackQueryHandler(self.callback_basic) - dp.add_handler(handler) - - assert handler.check_update(callback_query) - - dp.process_update(callback_query) - assert self.test_flag - def test_with_pattern(self, callback_query): handler = CallbackQueryHandler(self.callback_basic, pattern='.*est.*') @@ -177,103 +168,34 @@ class CallbackData: callback_query.callback_query.data = 'callback_data' assert not handler.check_update(callback_query) - def test_with_passing_group_dict(self, dp, callback_query): - handler = CallbackQueryHandler( - self.callback_group, pattern='(?P.*)est(?P.*)', pass_groups=True - ) - dp.add_handler(handler) - - dp.process_update(callback_query) - assert self.test_flag - - dp.remove_handler(handler) - handler = CallbackQueryHandler( - self.callback_group, pattern='(?P.*)est(?P.*)', pass_groupdict=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(callback_query) - assert self.test_flag - - def test_pass_user_or_chat_data(self, dp, callback_query): - handler = CallbackQueryHandler(self.callback_data_1, pass_user_data=True) - dp.add_handler(handler) - - dp.process_update(callback_query) - assert self.test_flag + def test_other_update_types(self, false_update): + handler = CallbackQueryHandler(self.callback_basic) + assert not handler.check_update(false_update) - dp.remove_handler(handler) - handler = CallbackQueryHandler(self.callback_data_1, pass_chat_data=True) + def test_context(self, dp, callback_query): + handler = CallbackQueryHandler(self.callback_context) dp.add_handler(handler) - self.test_flag = False dp.process_update(callback_query) assert self.test_flag - dp.remove_handler(handler) + def test_context_pattern(self, dp, callback_query): handler = CallbackQueryHandler( - self.callback_data_2, pass_chat_data=True, pass_user_data=True + self.callback_context_pattern, pattern=r'(?P.*)est(?P.*)' ) dp.add_handler(handler) - self.test_flag = False - dp.process_update(callback_query) - assert self.test_flag - - def test_pass_job_or_update_queue(self, dp, callback_query): - handler = CallbackQueryHandler(self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - - dp.process_update(callback_query) - assert self.test_flag - - dp.remove_handler(handler) - handler = CallbackQueryHandler(self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False dp.process_update(callback_query) assert self.test_flag dp.remove_handler(handler) - handler = CallbackQueryHandler( - self.callback_queue_2, pass_job_queue=True, pass_update_queue=True - ) + handler = CallbackQueryHandler(self.callback_context_pattern, pattern=r'(t)est(.*)') dp.add_handler(handler) - self.test_flag = False dp.process_update(callback_query) assert self.test_flag - def test_other_update_types(self, false_update): - handler = CallbackQueryHandler(self.callback_basic) - assert not handler.check_update(false_update) - - def test_context(self, cdp, callback_query): - handler = CallbackQueryHandler(self.callback_context) - cdp.add_handler(handler) - - cdp.process_update(callback_query) - assert self.test_flag - - def test_context_pattern(self, cdp, callback_query): - handler = CallbackQueryHandler( - self.callback_context_pattern, pattern=r'(?P.*)est(?P.*)' - ) - cdp.add_handler(handler) - - cdp.process_update(callback_query) - assert self.test_flag - - cdp.remove_handler(handler) - handler = CallbackQueryHandler(self.callback_context_pattern, pattern=r'(t)est(.*)') - cdp.add_handler(handler) - - cdp.process_update(callback_query) - assert self.test_flag - - def test_context_callable_pattern(self, cdp, callback_query): + def test_context_callable_pattern(self, dp, callback_query): class CallbackData: pass @@ -284,6 +206,6 @@ def callback(update, context): assert context.matches is None handler = CallbackQueryHandler(callback, pattern=pattern) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(callback_query) + dp.process_update(callback_query) diff --git a/tests/test_chatmemberhandler.py b/tests/test_chatmemberhandler.py index 999bb743264..b59055362c1 100644 --- a/tests/test_chatmemberhandler.py +++ b/tests/test_chatmemberhandler.py @@ -89,7 +89,7 @@ class TestChatMemberHandler: test_flag = False def test_slot_behaviour(self, mro_slots): - action = ChatMemberHandler(self.callback_basic) + action = ChatMemberHandler(self.callback_context) for attr in action.__slots__: assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'" assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot" @@ -98,23 +98,6 @@ def test_slot_behaviour(self, mro_slots): def reset(self): self.test_flag = False - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) - test_update = isinstance(update, Update) - self.test_flag = test_bot and test_update - - def callback_data_1(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) or (chat_data is not None) - - def callback_data_2(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) and (chat_data is not None) - - def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) or (update_queue is not None) - - def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) and (update_queue is not None) - def callback_context(self, update, context): self.test_flag = ( isinstance(context, CallbackContext) @@ -128,15 +111,6 @@ def callback_context(self, update, context): and isinstance(update.chat_member or update.my_chat_member, ChatMemberUpdated) ) - def test_basic(self, dp, chat_member): - handler = ChatMemberHandler(self.callback_basic) - dp.add_handler(handler) - - assert handler.check_update(chat_member) - - dp.process_update(chat_member) - assert self.test_flag - @pytest.mark.parametrize( argnames=['allowed_types', 'expected'], argvalues=[ @@ -151,7 +125,7 @@ def test_chat_member_types( ): result_1, result_2 = expected - handler = ChatMemberHandler(self.callback_basic, chat_member_types=allowed_types) + handler = ChatMemberHandler(self.callback_context, chat_member_types=allowed_types) dp.add_handler(handler) assert handler.check_update(chat_member) == result_1 @@ -166,62 +140,14 @@ def test_chat_member_types( dp.process_update(chat_member) assert self.test_flag == result_2 - def test_pass_user_or_chat_data(self, dp, chat_member): - handler = ChatMemberHandler(self.callback_data_1, pass_user_data=True) - dp.add_handler(handler) - - dp.process_update(chat_member) - assert self.test_flag - - dp.remove_handler(handler) - handler = ChatMemberHandler(self.callback_data_1, pass_chat_data=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(chat_member) - assert self.test_flag - - dp.remove_handler(handler) - handler = ChatMemberHandler(self.callback_data_2, pass_chat_data=True, pass_user_data=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(chat_member) - assert self.test_flag - - def test_pass_job_or_update_queue(self, dp, chat_member): - handler = ChatMemberHandler(self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - - dp.process_update(chat_member) - assert self.test_flag - - dp.remove_handler(handler) - handler = ChatMemberHandler(self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(chat_member) - assert self.test_flag - - dp.remove_handler(handler) - handler = ChatMemberHandler( - self.callback_queue_2, pass_job_queue=True, pass_update_queue=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(chat_member) - assert self.test_flag - def test_other_update_types(self, false_update): - handler = ChatMemberHandler(self.callback_basic) + handler = ChatMemberHandler(self.callback_context) assert not handler.check_update(false_update) assert not handler.check_update(True) - def test_context(self, cdp, chat_member): + def test_context(self, dp, chat_member): handler = ChatMemberHandler(self.callback_context) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(chat_member) + dp.process_update(chat_member) assert self.test_flag diff --git a/tests/test_choseninlineresulthandler.py b/tests/test_choseninlineresulthandler.py index 1c7c5e0f5e8..6b50b3b058a 100644 --- a/tests/test_choseninlineresulthandler.py +++ b/tests/test_choseninlineresulthandler.py @@ -87,8 +87,8 @@ def test_slot_behaviour(self, mro_slots): assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'" assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot" - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) + def callback_basic(self, update, context): + test_bot = isinstance(context.bot, Bot) test_update = isinstance(update, Update) self.test_flag = test_bot and test_update @@ -123,73 +123,15 @@ def callback_context_pattern(self, update, context): if context.matches[0].groupdict(): self.test_flag = context.matches[0].groupdict() == {'begin': 'res', 'end': '_id'} - def test_basic(self, dp, chosen_inline_result): - handler = ChosenInlineResultHandler(self.callback_basic) - dp.add_handler(handler) - - assert handler.check_update(chosen_inline_result) - dp.process_update(chosen_inline_result) - assert self.test_flag - - def test_pass_user_or_chat_data(self, dp, chosen_inline_result): - handler = ChosenInlineResultHandler(self.callback_data_1, pass_user_data=True) - dp.add_handler(handler) - - dp.process_update(chosen_inline_result) - assert self.test_flag - - dp.remove_handler(handler) - handler = ChosenInlineResultHandler(self.callback_data_1, pass_chat_data=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(chosen_inline_result) - assert self.test_flag - - dp.remove_handler(handler) - handler = ChosenInlineResultHandler( - self.callback_data_2, pass_chat_data=True, pass_user_data=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(chosen_inline_result) - assert self.test_flag - - def test_pass_job_or_update_queue(self, dp, chosen_inline_result): - handler = ChosenInlineResultHandler(self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - - dp.process_update(chosen_inline_result) - assert self.test_flag - - dp.remove_handler(handler) - handler = ChosenInlineResultHandler(self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(chosen_inline_result) - assert self.test_flag - - dp.remove_handler(handler) - handler = ChosenInlineResultHandler( - self.callback_queue_2, pass_job_queue=True, pass_update_queue=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(chosen_inline_result) - assert self.test_flag - def test_other_update_types(self, false_update): handler = ChosenInlineResultHandler(self.callback_basic) assert not handler.check_update(false_update) - def test_context(self, cdp, chosen_inline_result): + def test_context(self, dp, chosen_inline_result): handler = ChosenInlineResultHandler(self.callback_context) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(chosen_inline_result) + dp.process_update(chosen_inline_result) assert self.test_flag def test_with_pattern(self, chosen_inline_result): @@ -201,17 +143,17 @@ def test_with_pattern(self, chosen_inline_result): assert not handler.check_update(chosen_inline_result) chosen_inline_result.chosen_inline_result.result_id = 'result_id' - def test_context_pattern(self, cdp, chosen_inline_result): + def test_context_pattern(self, dp, chosen_inline_result): handler = ChosenInlineResultHandler( self.callback_context_pattern, pattern=r'(?P.*)ult(?P.*)' ) - cdp.add_handler(handler) - cdp.process_update(chosen_inline_result) + dp.add_handler(handler) + dp.process_update(chosen_inline_result) assert self.test_flag - cdp.remove_handler(handler) + dp.remove_handler(handler) handler = ChosenInlineResultHandler(self.callback_context_pattern, pattern=r'(res)ult(.*)') - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(chosen_inline_result) + dp.process_update(chosen_inline_result) assert self.test_flag diff --git a/tests/test_commandhandler.py b/tests/test_commandhandler.py index f183597f77b..b3850bdd806 100644 --- a/tests/test_commandhandler.py +++ b/tests/test_commandhandler.py @@ -20,8 +20,6 @@ from queue import Queue import pytest -import itertools -from telegram.utils.deprecate import TelegramDeprecationWarning from telegram import Message, Update, Chat, Bot from telegram.ext import CommandHandler, Filters, CallbackContext, JobQueue, PrefixHandler @@ -56,12 +54,6 @@ class BaseTest: def reset(self): self.test_flag = False - PASS_KEYWORDS = ('pass_user_data', 'pass_chat_data', 'pass_job_queue', 'pass_update_queue') - - @pytest.fixture(scope='module', params=itertools.combinations(PASS_KEYWORDS, 2)) - def pass_combination(self, request): - return {key: True for key in request.param} - def response(self, dispatcher, update): """ Utility to send an update to a dispatcher and assert @@ -72,8 +64,8 @@ def response(self, dispatcher, update): dispatcher.process_update(update) return self.test_flag - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) + def callback_basic(self, update, context): + test_bot = isinstance(context.bot, Bot) test_update = isinstance(update, Update) self.test_flag = test_bot and test_update @@ -112,12 +104,12 @@ def callback_context_regex2(self, update, context): num = len(context.matches) == 2 self.test_flag = types and num - def _test_context_args_or_regex(self, cdp, handler, text): - cdp.add_handler(handler) + def _test_context_args_or_regex(self, dp, handler, text): + dp.add_handler(handler) update = make_command_update(text) - assert not self.response(cdp, update) + assert not self.response(dp, update) update.message.text += ' one two' - assert self.response(cdp, update) + assert self.response(dp, update) def _test_edited(self, message, handler_edited, handler_not_edited): """ @@ -160,14 +152,6 @@ def command_message(self, command): def command_update(self, command_message): return make_command_update(command_message) - def ch_callback_args(self, bot, update, args): - if update.message.text == self.CMD: - self.test_flag = len(args) == 0 - elif update.message.text == f'{self.CMD}@{bot.username}': - self.test_flag = len(args) == 0 - else: - self.test_flag = args == ['one', 'two'] - def make_default_handler(self, callback=None, **kwargs): callback = callback or self.callback_basic return CommandHandler(self.CMD[1:], callback, **kwargs) @@ -199,23 +183,12 @@ def test_command_list(self): assert is_match(handler, make_command_update('/star')) assert not is_match(handler, make_command_update('/stop')) - def test_deprecation_warning(self): - """``allow_edited`` deprecated in favor of filters""" - with pytest.warns(TelegramDeprecationWarning, match='See https://git.io/fxJuV'): - self.make_default_handler(allow_edited=True) - def test_edited(self, command_message): - """Test that a CH responds to an edited message iff its filters allow it""" + """Test that a CH responds to an edited message if its filters allow it""" handler_edited = self.make_default_handler() handler_no_edited = self.make_default_handler(filters=~Filters.update.edited_message) self._test_edited(command_message, handler_edited, handler_no_edited) - def test_edited_deprecated(self, command_message): - """Test that a CH responds to an edited message iff ``allow_edited`` is True""" - handler_edited = self.make_default_handler(allow_edited=True) - handler_no_edited = self.make_default_handler(allow_edited=False) - self._test_edited(command_message, handler_edited, handler_no_edited) - def test_directed_commands(self, bot, command): """Test recognition of commands with a mention to the bot""" handler = self.make_default_handler() @@ -223,21 +196,11 @@ def test_directed_commands(self, bot, command): assert not is_match(handler, make_command_update(command + '@otherbot', bot=bot)) def test_with_filter(self, command): - """Test that a CH with a (generic) filter responds iff its filters match""" + """Test that a CH with a (generic) filter responds if its filters match""" handler = self.make_default_handler(filters=Filters.group) assert is_match(handler, make_command_update(command, chat=Chat(-23, Chat.GROUP))) assert not is_match(handler, make_command_update(command, chat=Chat(23, Chat.PRIVATE))) - def test_pass_args(self, dp, bot, command): - """Test the passing of arguments alongside a command""" - handler = self.make_default_handler(self.ch_callback_args, pass_args=True) - dp.add_handler(handler) - at_command = f'{command}@{bot.username}' - assert self.response(dp, make_command_update(command)) - assert self.response(dp, make_command_update(command + ' one two')) - assert self.response(dp, make_command_update(at_command, bot=bot)) - assert self.response(dp, make_command_update(at_command + ' one two', bot=bot)) - def test_newline(self, dp, command): """Assert that newlines don't interfere with a command handler matching a message""" handler = self.make_default_handler() @@ -246,12 +209,6 @@ def test_newline(self, dp, command): assert is_match(handler, update) assert self.response(dp, update) - @pytest.mark.parametrize('pass_keyword', BaseTest.PASS_KEYWORDS) - def test_pass_data(self, dp, command_update, pass_combination, pass_keyword): - handler = CommandHandler('test', self.make_callback_for(pass_keyword), **pass_combination) - dp.add_handler(handler) - assert self.response(dp, command_update) == pass_combination.get(pass_keyword, False) - def test_other_update_types(self, false_update): """Test that a command handler doesn't respond to unrelated updates""" handler = self.make_default_handler() @@ -263,30 +220,30 @@ def test_filters_for_wrong_command(self, mock_filter): assert not is_match(handler, make_command_update('/star')) assert not mock_filter.tested - def test_context(self, cdp, command_update): + def test_context(self, dp, command_update): """Test correct behaviour of CHs with context-based callbacks""" handler = self.make_default_handler(self.callback_context) - cdp.add_handler(handler) - assert self.response(cdp, command_update) + dp.add_handler(handler) + assert self.response(dp, command_update) - def test_context_args(self, cdp, command): + def test_context_args(self, dp, command): """Test CHs that pass arguments through ``context``""" handler = self.make_default_handler(self.callback_context_args) - self._test_context_args_or_regex(cdp, handler, command) + self._test_context_args_or_regex(dp, handler, command) - def test_context_regex(self, cdp, command): + def test_context_regex(self, dp, command): """Test CHs with context-based callbacks and a single filter""" handler = self.make_default_handler( self.callback_context_regex1, filters=Filters.regex('one two') ) - self._test_context_args_or_regex(cdp, handler, command) + self._test_context_args_or_regex(dp, handler, command) - def test_context_multiple_regex(self, cdp, command): + def test_context_multiple_regex(self, dp, command): """Test CHs with context-based callbacks and filters combined""" handler = self.make_default_handler( self.callback_context_regex2, filters=Filters.regex('one') & Filters.regex('two') ) - self._test_context_args_or_regex(cdp, handler, command) + self._test_context_args_or_regex(dp, handler, command) # ----------------------------- PrefixHandler ----------------------------- @@ -340,12 +297,6 @@ def make_default_handler(self, callback=None, **kwargs): callback = callback or self.callback_basic return PrefixHandler(self.PREFIXES, self.COMMANDS, callback, **kwargs) - def ch_callback_args(self, bot, update, args): - if update.message.text in TestPrefixHandler.COMBINATIONS: - self.test_flag = len(args) == 0 - else: - self.test_flag = args == ['one', 'two'] - def test_basic(self, dp, prefix, command): """Test the basic expected response from a prefix handler""" handler = self.make_default_handler() @@ -375,25 +326,6 @@ def test_with_filter(self, prefix_message_text): assert is_match(handler, make_message_update(text, chat=Chat(-23, Chat.GROUP))) assert not is_match(handler, make_message_update(text, chat=Chat(23, Chat.PRIVATE))) - def test_pass_args(self, dp, prefix_message): - handler = self.make_default_handler(self.ch_callback_args, pass_args=True) - dp.add_handler(handler) - assert self.response(dp, make_message_update(prefix_message)) - - update_with_args = make_message_update(prefix_message.text + ' one two') - assert self.response(dp, update_with_args) - - @pytest.mark.parametrize('pass_keyword', BaseTest.PASS_KEYWORDS) - def test_pass_data(self, dp, pass_combination, prefix_message_update, pass_keyword): - """Assert that callbacks receive data iff its corresponding ``pass_*`` kwarg is enabled""" - handler = self.make_default_handler( - self.make_callback_for(pass_keyword), **pass_combination - ) - dp.add_handler(handler) - assert self.response(dp, prefix_message_update) == pass_combination.get( - pass_keyword, False - ) - def test_other_update_types(self, false_update): handler = self.make_default_handler() assert not is_match(handler, false_update) @@ -427,23 +359,23 @@ def test_basic_after_editing(self, dp, prefix, command): text = prefix + 'foo' assert self.response(dp, make_message_update(text)) - def test_context(self, cdp, prefix_message_update): + def test_context(self, dp, prefix_message_update): handler = self.make_default_handler(self.callback_context) - cdp.add_handler(handler) - assert self.response(cdp, prefix_message_update) + dp.add_handler(handler) + assert self.response(dp, prefix_message_update) - def test_context_args(self, cdp, prefix_message_text): + def test_context_args(self, dp, prefix_message_text): handler = self.make_default_handler(self.callback_context_args) - self._test_context_args_or_regex(cdp, handler, prefix_message_text) + self._test_context_args_or_regex(dp, handler, prefix_message_text) - def test_context_regex(self, cdp, prefix_message_text): + def test_context_regex(self, dp, prefix_message_text): handler = self.make_default_handler( self.callback_context_regex1, filters=Filters.regex('one two') ) - self._test_context_args_or_regex(cdp, handler, prefix_message_text) + self._test_context_args_or_regex(dp, handler, prefix_message_text) - def test_context_multiple_regex(self, cdp, prefix_message_text): + def test_context_multiple_regex(self, dp, prefix_message_text): handler = self.make_default_handler( self.callback_context_regex2, filters=Filters.regex('one') & Filters.regex('two') ) - self._test_context_args_or_regex(cdp, handler, prefix_message_text) + self._test_context_args_or_regex(dp, handler, prefix_message_text) diff --git a/tests/test_conversationhandler.py b/tests/test_conversationhandler.py index 6eaefcbb328..5b1aa49a775 100644 --- a/tests/test_conversationhandler.py +++ b/tests/test_conversationhandler.py @@ -170,45 +170,45 @@ def _set_state(self, update, state): # Actions @raise_dphs - def start(self, bot, update): + def start(self, update, context): if isinstance(update, Update): return self._set_state(update, self.THIRSTY) - return self._set_state(bot, self.THIRSTY) + return self._set_state(context.bot, self.THIRSTY) @raise_dphs - def end(self, bot, update): + def end(self, update, context): return self._set_state(update, self.END) @raise_dphs - def start_end(self, bot, update): + def start_end(self, update, context): return self._set_state(update, self.END) @raise_dphs - def start_none(self, bot, update): + def start_none(self, update, context): return self._set_state(update, None) @raise_dphs - def brew(self, bot, update): + def brew(self, update, context): if isinstance(update, Update): return self._set_state(update, self.BREWING) - return self._set_state(bot, self.BREWING) + return self._set_state(context.bot, self.BREWING) @raise_dphs - def drink(self, bot, update): + def drink(self, update, context): return self._set_state(update, self.DRINKING) @raise_dphs - def code(self, bot, update): + def code(self, update, context): return self._set_state(update, self.CODING) @raise_dphs - def passout(self, bot, update): + def passout(self, update, context): assert update.message.text == '/brew' assert isinstance(update, Update) self.is_timeout = True @raise_dphs - def passout2(self, bot, update): + def passout2(self, update, context): assert isinstance(update, Update) self.is_timeout = True @@ -226,23 +226,23 @@ def passout2_context(self, update, context): # Drinking actions (nested) @raise_dphs - def hold(self, bot, update): + def hold(self, update, context): return self._set_state(update, self.HOLDING) @raise_dphs - def sip(self, bot, update): + def sip(self, update, context): return self._set_state(update, self.SIPPING) @raise_dphs - def swallow(self, bot, update): + def swallow(self, update, context): return self._set_state(update, self.SWALLOWING) @raise_dphs - def replenish(self, bot, update): + def replenish(self, update, context): return self._set_state(update, self.REPLENISHING) @raise_dphs - def stop(self, bot, update): + def stop(self, update, context): return self._set_state(update, self.STOPPING) # Tests @@ -543,13 +543,13 @@ def test_conversation_handler_per_user(self, dp, bot, user1): assert handler.conversations[(user1.id,)] == self.DRINKING def test_conversation_handler_per_message(self, dp, bot, user1, user2): - def entry(bot, update): + def entry(update, context): return 1 - def one(bot, update): + def one(update, context): return 2 - def two(bot, update): + def two(update, context): return ConversationHandler.END handler = ConversationHandler( @@ -606,7 +606,7 @@ def test_end_on_first_message_async(self, dp, bot, user1): handler = ConversationHandler( entry_points=[ CommandHandler( - 'start', lambda bot, update: dp.run_async(self.start_end, bot, update) + 'start', lambda update, context: dp.run_async(self.start_end, update, context) ) ], states={}, @@ -687,7 +687,7 @@ def test_none_on_first_message_async(self, dp, bot, user1): handler = ConversationHandler( entry_points=[ CommandHandler( - 'start', lambda bot, update: dp.run_async(self.start_none, bot, update) + 'start', lambda update, context: dp.run_async(self.start_none, update, context) ) ], states={}, @@ -1026,7 +1026,7 @@ def timeout(*args, **kwargs): rec = caplog.records[-1] assert rec.getMessage().startswith('DispatcherHandlerStop in TIMEOUT') - def test_conversation_handler_timeout_update_and_context(self, cdp, bot, user1): + def test_conversation_handler_timeout_update_and_context(self, dp, bot, user1): context = None def start_callback(u, c): @@ -1043,7 +1043,7 @@ def start_callback(u, c): fallbacks=self.fallbacks, conversation_timeout=0.5, ) - cdp.add_handler(handler) + dp.add_handler(handler) # Start state machine, then reach timeout message = Message( @@ -1067,7 +1067,7 @@ def timeout_callback(u, c): timeout_handler.callback = timeout_callback - cdp.process_update(update) + dp.process_update(update) sleep(0.7) assert handler.conversations.get((self.group.id, user1.id)) is None assert self.is_timeout @@ -1216,7 +1216,7 @@ def test_conversation_handler_timeout_state(self, dp, bot, user1): assert handler.conversations.get((self.group.id, user1.id)) is None assert not self.is_timeout - def test_conversation_handler_timeout_state_context(self, cdp, bot, user1): + def test_conversation_handler_timeout_state_context(self, dp, bot, user1): states = self.states states.update( { @@ -1232,7 +1232,7 @@ def test_conversation_handler_timeout_state_context(self, cdp, bot, user1): fallbacks=self.fallbacks, conversation_timeout=0.5, ) - cdp.add_handler(handler) + dp.add_handler(handler) # CommandHandler timeout message = Message( @@ -1246,10 +1246,10 @@ def test_conversation_handler_timeout_state_context(self, cdp, bot, user1): ], bot=bot, ) - cdp.process_update(Update(update_id=0, message=message)) + dp.process_update(Update(update_id=0, message=message)) message.text = '/brew' message.entities[0].length = len('/brew') - cdp.process_update(Update(update_id=0, message=message)) + dp.process_update(Update(update_id=0, message=message)) sleep(0.7) assert handler.conversations.get((self.group.id, user1.id)) is None assert self.is_timeout @@ -1258,20 +1258,20 @@ def test_conversation_handler_timeout_state_context(self, cdp, bot, user1): self.is_timeout = False message.text = '/start' message.entities[0].length = len('/start') - cdp.process_update(Update(update_id=1, message=message)) + dp.process_update(Update(update_id=1, message=message)) sleep(0.7) assert handler.conversations.get((self.group.id, user1.id)) is None assert self.is_timeout # Timeout but no valid handler self.is_timeout = False - cdp.process_update(Update(update_id=0, message=message)) + dp.process_update(Update(update_id=0, message=message)) message.text = '/brew' message.entities[0].length = len('/brew') - cdp.process_update(Update(update_id=0, message=message)) + dp.process_update(Update(update_id=0, message=message)) message.text = '/startCoding' message.entities[0].length = len('/startCoding') - cdp.process_update(Update(update_id=0, message=message)) + dp.process_update(Update(update_id=0, message=message)) sleep(0.7) assert handler.conversations.get((self.group.id, user1.id)) is None assert not self.is_timeout @@ -1285,7 +1285,7 @@ def test_conversation_timeout_cancel_conflict(self, dp, bot, user1): # | t=.75 /slowbrew returns (timeout=1.25) # t=1.25 timeout - def slowbrew(_bot, update): + def slowbrew(_update, context): sleep(0.25) # Let's give to the original timeout a chance to execute sleep(0.25) @@ -1395,10 +1395,10 @@ def test_per_message_false_warning_is_only_shown_once(self, recwarn): ) def test_warnings_per_chat_is_only_shown_once(self, recwarn): - def hello(bot, update): + def hello(update, context): return self.BREWING - def bye(bot, update): + def bye(update, context): return ConversationHandler.END ConversationHandler( diff --git a/tests/test_defaults.py b/tests/test_defaults.py index 754588f5e26..ab79c21efea 100644 --- a/tests/test_defaults.py +++ b/tests/test_defaults.py @@ -30,7 +30,7 @@ def test_slot_behaviour(self, mro_slots): assert getattr(a, attr, 'err') != 'err', f"got extra slot '{attr}'" assert len(mro_slots(a)) == len(set(mro_slots(a))), "duplicate slot" - def test_data_assignment(self, cdp): + def test_data_assignment(self, dp): defaults = Defaults() with pytest.raises(AttributeError): diff --git a/tests/test_dispatcher.py b/tests/test_dispatcher.py index b68af6398ed..2a6897a7731 100644 --- a/tests/test_dispatcher.py +++ b/tests/test_dispatcher.py @@ -72,16 +72,13 @@ def reset(self): self.received = None self.count = 0 - def error_handler(self, bot, update, error): - self.received = error.message - def error_handler_context(self, update, context): self.received = context.error.message - def error_handler_raise_error(self, bot, update, error): + def error_handler_raise_error(self, update, context): raise Exception('Failing bigly') - def callback_increase_count(self, bot, update): + def callback_increase_count(self, update, context): self.count += 1 def callback_set_count(self, count): @@ -90,14 +87,11 @@ def callback(bot, update): return callback - def callback_raise_error(self, bot, update): - if isinstance(bot, Bot): - raise TelegramError(update.message.text) - raise TelegramError(bot.message.text) + def callback_raise_error(self, update, context): + raise TelegramError(update.message.text) - def callback_if_not_update_queue(self, bot, update, update_queue=None): - if update_queue is not None: - self.received = update.message + def callback_received(self, update, context): + self.received = update.message def callback_context(self, update, context): if ( @@ -110,14 +104,14 @@ def callback_context(self, update, context): self.received = context.error.message def test_less_than_one_worker_warning(self, dp, recwarn): - Dispatcher(dp.bot, dp.update_queue, job_queue=dp.job_queue, workers=0, use_context=True) + Dispatcher(dp.bot, dp.update_queue, job_queue=dp.job_queue, workers=0) assert len(recwarn) == 1 assert ( str(recwarn[0].message) == 'Asynchronous callbacks can not be processed without at least one worker thread.' ) - def test_one_context_per_update(self, cdp): + def test_one_context_per_update(self, dp): def one(update, context): if update.message.text == 'test': context.my_flag = True @@ -130,22 +124,22 @@ def two(update, context): if hasattr(context, 'my_flag'): pytest.fail() - cdp.add_handler(MessageHandler(Filters.regex('test'), one), group=1) - cdp.add_handler(MessageHandler(None, two), group=2) + dp.add_handler(MessageHandler(Filters.regex('test'), one), group=1) + dp.add_handler(MessageHandler(None, two), group=2) u = Update(1, Message(1, None, None, None, text='test')) - cdp.process_update(u) + dp.process_update(u) u.message.text = 'something' - cdp.process_update(u) + dp.process_update(u) def test_error_handler(self, dp): - dp.add_error_handler(self.error_handler) + dp.add_error_handler(self.error_handler_context) error = TelegramError('Unauthorized.') dp.update_queue.put(error) sleep(0.1) assert self.received == 'Unauthorized.' # Remove handler - dp.remove_error_handler(self.error_handler) + dp.remove_error_handler(self.error_handler_context) self.reset() dp.update_queue.put(error) @@ -153,9 +147,9 @@ def test_error_handler(self, dp): assert self.received is None def test_double_add_error_handler(self, dp, caplog): - dp.add_error_handler(self.error_handler) + dp.add_error_handler(self.error_handler_context) with caplog.at_level(logging.DEBUG): - dp.add_error_handler(self.error_handler) + dp.add_error_handler(self.error_handler_context) assert len(caplog.records) == 1 assert caplog.records[-1].getMessage().startswith('The callback is already registered') @@ -202,7 +196,7 @@ def mock_async_err_handler(*args, **kwargs): dp.bot.defaults = Defaults(run_async=run_async) try: dp.add_handler(MessageHandler(Filters.all, self.callback_raise_error)) - dp.add_error_handler(self.error_handler) + dp.add_error_handler(self.error_handler_context) monkeypatch.setattr(dp, 'run_async', mock_async_err_handler) dp.process_update(self.message_update) @@ -262,17 +256,6 @@ def must_raise_runtime_error(): with pytest.raises(RuntimeError): must_raise_runtime_error() - def test_run_async_with_args(self, dp): - dp.add_handler( - MessageHandler( - Filters.all, run_async(self.callback_if_not_update_queue), pass_update_queue=True - ) - ) - - dp.update_queue.put(self.message_update) - sleep(0.1) - assert self.received == self.message_update.message - def test_multiple_run_async_deprecation(self, dp): assert isinstance(dp, Dispatcher) @@ -323,8 +306,7 @@ def test_add_async_handler(self, dp): dp.add_handler( MessageHandler( Filters.all, - self.callback_if_not_update_queue, - pass_update_queue=True, + self.callback_received, run_async=True, ) ) @@ -343,19 +325,11 @@ def func(): assert len(caplog.records) == 1 assert caplog.records[-1].getMessage().startswith('No error handlers are registered') - def test_async_handler_error_handler(self, dp): + def test_async_handler_async_error_handler_context(self, dp): dp.add_handler(MessageHandler(Filters.all, self.callback_raise_error, run_async=True)) - dp.add_error_handler(self.error_handler) + dp.add_error_handler(self.error_handler_context, run_async=True) dp.update_queue.put(self.message_update) - sleep(0.1) - assert self.received == self.message_update.message.text - - def test_async_handler_async_error_handler_context(self, cdp): - cdp.add_handler(MessageHandler(Filters.all, self.callback_raise_error, run_async=True)) - cdp.add_error_handler(self.error_handler_context, run_async=True) - - cdp.update_queue.put(self.message_update) sleep(2) assert self.received == self.message_update.message.text @@ -397,7 +371,7 @@ def test_async_handler_async_error_handler_that_raises_error(self, dp, caplog): def test_error_in_handler(self, dp): dp.add_handler(MessageHandler(Filters.all, self.callback_raise_error)) - dp.add_error_handler(self.error_handler) + dp.add_error_handler(self.error_handler_context) dp.update_queue.put(self.message_update) sleep(0.1) @@ -494,19 +468,19 @@ def test_exception_in_handler(self, dp, bot): passed = [] err = Exception('General exception') - def start1(b, u): + def start1(u, c): passed.append('start1') raise err - def start2(b, u): + def start2(u, c): passed.append('start2') - def start3(b, u): + def start3(u, c): passed.append('start3') - def error(b, u, e): + def error(u, c): passed.append('error') - passed.append(e) + passed.append(c.error) update = Update( 1, @@ -537,19 +511,19 @@ def test_telegram_error_in_handler(self, dp, bot): passed = [] err = TelegramError('Telegram error') - def start1(b, u): + def start1(u, c): passed.append('start1') raise err - def start2(b, u): + def start2(u, c): passed.append('start2') - def start3(b, u): + def start3(u, c): passed.append('start3') - def error(b, u, e): + def error(u, c): passed.append('error') - passed.append(e) + passed.append(c.error) update = Update( 1, @@ -622,10 +596,10 @@ def refresh_bot_data(self, bot_data): def flush(self): pass - def start1(b, u): + def start1(u, c): pass - def error(b, u, e): + def error(u, c): increment.append("error") # If updating a user_data or chat_data from a persistence object throws an error, @@ -646,7 +620,7 @@ def error(b, u, e): ), ) my_persistence = OwnPersistence() - dp = Dispatcher(bot, None, persistence=my_persistence, use_context=False) + dp = Dispatcher(bot, None, persistence=my_persistence) dp.add_handler(CommandHandler('start', start1)) dp.add_error_handler(error) dp.process_update(update) @@ -656,19 +630,19 @@ def test_flow_stop_in_error_handler(self, dp, bot): passed = [] err = TelegramError('Telegram error') - def start1(b, u): + def start1(u, c): passed.append('start1') raise err - def start2(b, u): + def start2(u, c): passed.append('start2') - def start3(b, u): + def start3(u, c): passed.append('start3') - def error(b, u, e): + def error(u, c): passed.append('error') - passed.append(e) + passed.append(c.error) raise DispatcherHandlerStop update = Update( @@ -696,26 +670,12 @@ def error(b, u, e): assert passed == ['start1', 'error', err] assert passed[2] is err - def test_error_handler_context(self, cdp): - cdp.add_error_handler(self.callback_context) - - error = TelegramError('Unauthorized.') - cdp.update_queue.put(error) - sleep(0.1) - assert self.received == 'Unauthorized.' - def test_sensible_worker_thread_names(self, dp2): thread_names = [thread.name for thread in dp2._Dispatcher__async_threads] for thread_name in thread_names: assert thread_name.startswith(f"Bot:{dp2.bot.id}:worker:") - def test_non_context_deprecation(self, dp): - with pytest.warns(TelegramDeprecationWarning): - Dispatcher( - dp.bot, dp.update_queue, job_queue=dp.job_queue, workers=0, use_context=False - ) - - def test_error_while_persisting(self, cdp, monkeypatch): + def test_error_while_persisting(self, dp, monkeypatch): class OwnPersistence(BasePersistence): def update(self, data): raise Exception('PersistenceError') @@ -779,15 +739,15 @@ def logger(message): 1, message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') ) handler = MessageHandler(Filters.all, callback) - cdp.add_handler(handler) - cdp.add_error_handler(error) - monkeypatch.setattr(cdp.logger, 'exception', logger) + dp.add_handler(handler) + dp.add_error_handler(error) + monkeypatch.setattr(dp.logger, 'exception', logger) - cdp.persistence = OwnPersistence() - cdp.process_update(update) + dp.persistence = OwnPersistence() + dp.process_update(update) assert test_flag - def test_persisting_no_user_no_chat(self, cdp): + def test_persisting_no_user_no_chat(self, dp): class OwnPersistence(BasePersistence): def __init__(self): super().__init__() @@ -841,25 +801,25 @@ def callback(update, context): pass handler = MessageHandler(Filters.all, callback) - cdp.add_handler(handler) - cdp.persistence = OwnPersistence() + dp.add_handler(handler) + dp.persistence = OwnPersistence() update = Update( 1, message=Message(1, None, None, from_user=User(1, '', False), text='Text') ) - cdp.process_update(update) - assert cdp.persistence.test_flag_bot_data - assert cdp.persistence.test_flag_user_data - assert not cdp.persistence.test_flag_chat_data - - cdp.persistence.test_flag_bot_data = False - cdp.persistence.test_flag_user_data = False - cdp.persistence.test_flag_chat_data = False + dp.process_update(update) + assert dp.persistence.test_flag_bot_data + assert dp.persistence.test_flag_user_data + assert not dp.persistence.test_flag_chat_data + + dp.persistence.test_flag_bot_data = False + dp.persistence.test_flag_user_data = False + dp.persistence.test_flag_chat_data = False update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='Text')) - cdp.process_update(update) - assert cdp.persistence.test_flag_bot_data - assert not cdp.persistence.test_flag_user_data - assert cdp.persistence.test_flag_chat_data + dp.process_update(update) + assert dp.persistence.test_flag_bot_data + assert not dp.persistence.test_flag_user_data + assert dp.persistence.test_flag_chat_data def test_update_persistence_once_per_update(self, monkeypatch, dp): def update_persistence(*args, **kwargs): diff --git a/tests/test_inlinequeryhandler.py b/tests/test_inlinequeryhandler.py index e084554dcaa..253c9ce2f07 100644 --- a/tests/test_inlinequeryhandler.py +++ b/tests/test_inlinequeryhandler.py @@ -94,29 +94,6 @@ def test_slot_behaviour(self, mro_slots): def reset(self): self.test_flag = False - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) - test_update = isinstance(update, Update) - self.test_flag = test_bot and test_update - - def callback_data_1(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) or (chat_data is not None) - - def callback_data_2(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) and (chat_data is not None) - - def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) or (update_queue is not None) - - def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) and (update_queue is not None) - - def callback_group(self, bot, update, groups=None, groupdict=None): - if groups is not None: - self.test_flag = groups == ('t', ' query') - if groupdict is not None: - self.test_flag = groupdict == {'begin': 't', 'end': ' query'} - def callback_context(self, update, context): self.test_flag = ( isinstance(context, CallbackContext) @@ -136,130 +113,44 @@ def callback_context_pattern(self, update, context): if context.matches[0].groupdict(): self.test_flag = context.matches[0].groupdict() == {'begin': 't', 'end': ' query'} - def test_basic(self, dp, inline_query): - handler = InlineQueryHandler(self.callback_basic) - dp.add_handler(handler) - - assert handler.check_update(inline_query) - - dp.process_update(inline_query) - assert self.test_flag - - def test_with_pattern(self, inline_query): - handler = InlineQueryHandler(self.callback_basic, pattern='(?P.*)est(?P.*)') - - assert handler.check_update(inline_query) - - inline_query.inline_query.query = 'nothing here' - assert not handler.check_update(inline_query) - - def test_with_passing_group_dict(self, dp, inline_query): - handler = InlineQueryHandler( - self.callback_group, pattern='(?P.*)est(?P.*)', pass_groups=True - ) - dp.add_handler(handler) - - dp.process_update(inline_query) - assert self.test_flag - - dp.remove_handler(handler) - handler = InlineQueryHandler( - self.callback_group, pattern='(?P.*)est(?P.*)', pass_groupdict=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(inline_query) - assert self.test_flag - - def test_pass_user_or_chat_data(self, dp, inline_query): - handler = InlineQueryHandler(self.callback_data_1, pass_user_data=True) - dp.add_handler(handler) - - dp.process_update(inline_query) - assert self.test_flag + def test_other_update_types(self, false_update): + handler = InlineQueryHandler(self.callback_context) + assert not handler.check_update(false_update) - dp.remove_handler(handler) - handler = InlineQueryHandler(self.callback_data_1, pass_chat_data=True) + def test_context(self, dp, inline_query): + handler = InlineQueryHandler(self.callback_context) dp.add_handler(handler) - self.test_flag = False dp.process_update(inline_query) assert self.test_flag - dp.remove_handler(handler) + def test_context_pattern(self, dp, inline_query): handler = InlineQueryHandler( - self.callback_data_2, pass_chat_data=True, pass_user_data=True + self.callback_context_pattern, pattern=r'(?P.*)est(?P.*)' ) dp.add_handler(handler) - self.test_flag = False - dp.process_update(inline_query) - assert self.test_flag - - def test_pass_job_or_update_queue(self, dp, inline_query): - handler = InlineQueryHandler(self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - dp.process_update(inline_query) assert self.test_flag dp.remove_handler(handler) - handler = InlineQueryHandler(self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(inline_query) - assert self.test_flag - - dp.remove_handler(handler) - handler = InlineQueryHandler( - self.callback_queue_2, pass_job_queue=True, pass_update_queue=True - ) + handler = InlineQueryHandler(self.callback_context_pattern, pattern=r'(t)est(.*)') dp.add_handler(handler) - self.test_flag = False dp.process_update(inline_query) assert self.test_flag - def test_other_update_types(self, false_update): - handler = InlineQueryHandler(self.callback_basic) - assert not handler.check_update(false_update) - - def test_context(self, cdp, inline_query): - handler = InlineQueryHandler(self.callback_context) - cdp.add_handler(handler) - - cdp.process_update(inline_query) - assert self.test_flag - - def test_context_pattern(self, cdp, inline_query): - handler = InlineQueryHandler( - self.callback_context_pattern, pattern=r'(?P.*)est(?P.*)' - ) - cdp.add_handler(handler) - - cdp.process_update(inline_query) - assert self.test_flag - - cdp.remove_handler(handler) - handler = InlineQueryHandler(self.callback_context_pattern, pattern=r'(t)est(.*)') - cdp.add_handler(handler) - - cdp.process_update(inline_query) - assert self.test_flag - @pytest.mark.parametrize('chat_types', [[Chat.SENDER], [Chat.SENDER, Chat.SUPERGROUP], []]) @pytest.mark.parametrize( 'chat_type,result', [(Chat.SENDER, True), (Chat.CHANNEL, False), (None, False)] ) - def test_chat_types(self, cdp, inline_query, chat_types, chat_type, result): + def test_chat_types(self, dp, inline_query, chat_types, chat_type, result): try: inline_query.inline_query.chat_type = chat_type handler = InlineQueryHandler(self.callback_context, chat_types=chat_types) - cdp.add_handler(handler) - cdp.process_update(inline_query) + dp.add_handler(handler) + dp.process_update(inline_query) if not chat_types: assert self.test_flag is False diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index d91964387db..67e6242b5e4 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -66,20 +66,20 @@ def reset(self): self.job_time = 0 self.received_error = None - def job_run_once(self, bot, job): + def job_run_once(self, context): self.result += 1 - def job_with_exception(self, bot, job=None): + def job_with_exception(self, context): raise Exception('Test Error') - def job_remove_self(self, bot, job): + def job_remove_self(self, context): self.result += 1 - job.schedule_removal() + context.job.schedule_removal() - def job_run_once_with_context(self, bot, job): - self.result += job.context + def job_run_once_with_context(self, context): + self.result += context.job.context - def job_datetime_tests(self, bot, job): + def job_datetime_tests(self, context): self.job_time = time.time() def job_context_based_callback(self, context): @@ -95,9 +95,6 @@ def job_context_based_callback(self, context): ): self.result += 1 - def error_handler(self, bot, update, error): - self.received_error = str(error) - def error_handler_context(self, update, context): self.received_error = str(context.error) @@ -233,7 +230,7 @@ def test_error(self, job_queue): assert self.result == 1 def test_in_updater(self, bot): - u = Updater(bot=bot, use_context=False) + u = Updater(bot=bot) u.job_queue.start() try: u.job_queue.run_repeating(self.job_run_once, 0.02) @@ -377,13 +374,8 @@ def test_default_tzinfo(self, _dp, tz_bot): finally: _dp.bot = original_bot - @pytest.mark.parametrize('use_context', [True, False]) - def test_get_jobs(self, job_queue, use_context): - job_queue._dispatcher.use_context = use_context - if use_context: - callback = self.job_context_based_callback - else: - callback = self.job_run_once + def test_get_jobs(self, job_queue): + callback = self.job_context_based_callback job1 = job_queue.run_once(callback, 10, name='name1') job2 = job_queue.run_once(callback, 10, name='name1') @@ -393,24 +385,10 @@ def test_get_jobs(self, job_queue, use_context): assert job_queue.get_jobs_by_name('name1') == (job1, job2) assert job_queue.get_jobs_by_name('name2') == (job3,) - def test_context_based_callback(self, job_queue): - job_queue._dispatcher.use_context = True - - job_queue.run_once(self.job_context_based_callback, 0.01, context=2) - sleep(0.03) - - assert self.result == 1 - job_queue._dispatcher.use_context = False - - @pytest.mark.parametrize('use_context', [True, False]) - def test_job_run(self, _dp, use_context): - _dp.use_context = use_context + def test_job_run(self, _dp): job_queue = JobQueue() job_queue.set_dispatcher(_dp) - if use_context: - job = job_queue.run_repeating(self.job_context_based_callback, 0.02, context=2) - else: - job = job_queue.run_repeating(self.job_run_once, 0.02, context=2) + job = job_queue.run_repeating(self.job_context_based_callback, 0.02, context=2) assert self.result == 0 job.run(_dp) assert self.result == 1 @@ -443,8 +421,8 @@ def test_job_lt_eq(self, job_queue): assert not job == job_queue assert not job < job - def test_dispatch_error(self, job_queue, dp): - dp.add_error_handler(self.error_handler) + def test_dispatch_error_context(self, job_queue, dp): + dp.add_error_handler(self.error_handler_context) job = job_queue.run_once(self.job_with_exception, 0.05) sleep(0.1) @@ -454,7 +432,7 @@ def test_dispatch_error(self, job_queue, dp): assert self.received_error == 'Test Error' # Remove handler - dp.remove_error_handler(self.error_handler) + dp.remove_error_handler(self.error_handler_context) self.received_error = None job = job_queue.run_once(self.job_with_exception, 0.05) @@ -463,26 +441,6 @@ def test_dispatch_error(self, job_queue, dp): job.run(dp) assert self.received_error is None - def test_dispatch_error_context(self, job_queue, cdp): - cdp.add_error_handler(self.error_handler_context) - - job = job_queue.run_once(self.job_with_exception, 0.05) - sleep(0.1) - assert self.received_error == 'Test Error' - self.received_error = None - job.run(cdp) - assert self.received_error == 'Test Error' - - # Remove handler - cdp.remove_error_handler(self.error_handler_context) - self.received_error = None - - job = job_queue.run_once(self.job_with_exception, 0.05) - sleep(0.1) - assert self.received_error is None - job.run(cdp) - assert self.received_error is None - def test_dispatch_error_that_raises_errors(self, job_queue, dp, caplog): dp.add_error_handler(self.error_handler_raise_error) diff --git a/tests/test_messagehandler.py b/tests/test_messagehandler.py index 55f05d498c3..63a58a17f29 100644 --- a/tests/test_messagehandler.py +++ b/tests/test_messagehandler.py @@ -20,7 +20,6 @@ from queue import Queue import pytest -from telegram.utils.deprecate import TelegramDeprecationWarning from telegram import ( Message, @@ -72,7 +71,7 @@ class TestMessageHandler: SRE_TYPE = type(re.match("", "")) def test_slot_behaviour(self, mro_slots): - handler = MessageHandler(Filters.all, self.callback_basic) + handler = MessageHandler(Filters.all, self.callback_context) for attr in handler.__slots__: assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'" assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot" @@ -81,23 +80,6 @@ def test_slot_behaviour(self, mro_slots): def reset(self): self.test_flag = False - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) - test_update = isinstance(update, Update) - self.test_flag = test_bot and test_update - - def callback_data_1(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) or (chat_data is not None) - - def callback_data_2(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) and (chat_data is not None) - - def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) or (update_queue is not None) - - def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) and (update_queue is not None) - def callback_context(self, update, context): self.test_flag = ( isinstance(context, CallbackContext) @@ -137,75 +119,8 @@ def callback_context_regex2(self, update, context): num = len(context.matches) == 2 self.test_flag = types and num - def test_basic(self, dp, message): - handler = MessageHandler(None, self.callback_basic) - dp.add_handler(handler) - - assert handler.check_update(Update(0, message)) - dp.process_update(Update(0, message)) - assert self.test_flag - - def test_deprecation_warning(self): - with pytest.warns(TelegramDeprecationWarning, match='See https://git.io/fxJuV'): - MessageHandler(None, self.callback_basic, edited_updates=True) - with pytest.warns(TelegramDeprecationWarning, match='See https://git.io/fxJuV'): - MessageHandler(None, self.callback_basic, message_updates=False) - with pytest.warns(TelegramDeprecationWarning, match='See https://git.io/fxJuV'): - MessageHandler(None, self.callback_basic, channel_post_updates=True) - - def test_edited_deprecated(self, message): - handler = MessageHandler( - None, - self.callback_basic, - edited_updates=True, - message_updates=False, - channel_post_updates=False, - ) - - assert handler.check_update(Update(0, edited_message=message)) - assert not handler.check_update(Update(0, message=message)) - assert not handler.check_update(Update(0, channel_post=message)) - assert handler.check_update(Update(0, edited_channel_post=message)) - - def test_channel_post_deprecated(self, message): - handler = MessageHandler( - None, - self.callback_basic, - edited_updates=False, - message_updates=False, - channel_post_updates=True, - ) - assert not handler.check_update(Update(0, edited_message=message)) - assert not handler.check_update(Update(0, message=message)) - assert handler.check_update(Update(0, channel_post=message)) - assert not handler.check_update(Update(0, edited_channel_post=message)) - - def test_multiple_flags_deprecated(self, message): - handler = MessageHandler( - None, - self.callback_basic, - edited_updates=True, - message_updates=True, - channel_post_updates=True, - ) - - assert handler.check_update(Update(0, edited_message=message)) - assert handler.check_update(Update(0, message=message)) - assert handler.check_update(Update(0, channel_post=message)) - assert handler.check_update(Update(0, edited_channel_post=message)) - - def test_none_allowed_deprecated(self): - with pytest.raises(ValueError, match='are all False'): - MessageHandler( - None, - self.callback_basic, - message_updates=False, - channel_post_updates=False, - edited_updates=False, - ) - def test_with_filter(self, message): - handler = MessageHandler(Filters.group, self.callback_basic) + handler = MessageHandler(Filters.group, self.callback_context) message.chat.type = 'group' assert handler.check_update(Update(0, message)) @@ -221,7 +136,7 @@ def filter(self, u): self.flag = True test_filter = TestFilter() - handler = MessageHandler(test_filter, self.callback_basic) + handler = MessageHandler(test_filter, self.callback_context) update = Update(1, callback_query=CallbackQuery(1, None, None, message=message)) @@ -235,110 +150,61 @@ def test_specific_filters(self, message): & ~Filters.update.channel_post & Filters.update.edited_channel_post ) - handler = MessageHandler(f, self.callback_basic) + handler = MessageHandler(f, self.callback_context) assert not handler.check_update(Update(0, edited_message=message)) assert not handler.check_update(Update(0, message=message)) assert not handler.check_update(Update(0, channel_post=message)) assert handler.check_update(Update(0, edited_channel_post=message)) - def test_pass_user_or_chat_data(self, dp, message): - handler = MessageHandler(None, self.callback_data_1, pass_user_data=True) - dp.add_handler(handler) - - dp.process_update(Update(0, message=message)) - assert self.test_flag - - dp.remove_handler(handler) - handler = MessageHandler(None, self.callback_data_1, pass_chat_data=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(Update(0, message=message)) - assert self.test_flag - - dp.remove_handler(handler) - handler = MessageHandler( - None, self.callback_data_2, pass_chat_data=True, pass_user_data=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(Update(0, message=message)) - assert self.test_flag - - def test_pass_job_or_update_queue(self, dp, message): - handler = MessageHandler(None, self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - - dp.process_update(Update(0, message=message)) - assert self.test_flag - - dp.remove_handler(handler) - handler = MessageHandler(None, self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(Update(0, message=message)) - assert self.test_flag - - dp.remove_handler(handler) - handler = MessageHandler( - None, self.callback_queue_2, pass_job_queue=True, pass_update_queue=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(Update(0, message=message)) - assert self.test_flag - def test_other_update_types(self, false_update): - handler = MessageHandler(None, self.callback_basic, edited_updates=True) + handler = MessageHandler(None, self.callback_context) assert not handler.check_update(false_update) - def test_context(self, cdp, message): + def test_context(self, dp, message): handler = MessageHandler( - None, self.callback_context, edited_updates=True, channel_post_updates=True + None, + self.callback_context, ) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(Update(0, message=message)) + dp.process_update(Update(0, message=message)) assert self.test_flag self.test_flag = False - cdp.process_update(Update(0, edited_message=message)) + dp.process_update(Update(0, edited_message=message)) assert self.test_flag self.test_flag = False - cdp.process_update(Update(0, channel_post=message)) + dp.process_update(Update(0, channel_post=message)) assert self.test_flag self.test_flag = False - cdp.process_update(Update(0, edited_channel_post=message)) + dp.process_update(Update(0, edited_channel_post=message)) assert self.test_flag - def test_context_regex(self, cdp, message): + def test_context_regex(self, dp, message): handler = MessageHandler(Filters.regex('one two'), self.callback_context_regex1) - cdp.add_handler(handler) + dp.add_handler(handler) message.text = 'not it' - cdp.process_update(Update(0, message)) + dp.process_update(Update(0, message)) assert not self.test_flag message.text += ' one two now it is' - cdp.process_update(Update(0, message)) + dp.process_update(Update(0, message)) assert self.test_flag - def test_context_multiple_regex(self, cdp, message): + def test_context_multiple_regex(self, dp, message): handler = MessageHandler( Filters.regex('one') & Filters.regex('two'), self.callback_context_regex2 ) - cdp.add_handler(handler) + dp.add_handler(handler) message.text = 'not it' - cdp.process_update(Update(0, message)) + dp.process_update(Update(0, message)) assert not self.test_flag message.text += ' one two now it is' - cdp.process_update(Update(0, message)) + dp.process_update(Update(0, message)) assert self.test_flag diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 6b6a66fc875..21645143508 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -342,7 +342,7 @@ def get_callback_data(): @pytest.mark.parametrize('run_async', [True, False], ids=['synchronous', 'run_async']) def test_dispatcher_integration_handlers( self, - cdp, + dp, caplog, bot, base_persistence, @@ -373,7 +373,7 @@ def get_callback_data(): base_persistence.refresh_bot_data = lambda x: x base_persistence.refresh_chat_data = lambda x, y: x base_persistence.refresh_user_data = lambda x, y: x - updater = Updater(bot=bot, persistence=base_persistence, use_context=True) + updater = Updater(bot=bot, persistence=base_persistence) dp = updater.dispatcher def callback_known_user(update, context): @@ -403,17 +403,14 @@ def callback_unknown_user_or_chat(update, context): known_user = MessageHandler( Filters.user(user_id=12345), callback_known_user, - pass_chat_data=True, - pass_user_data=True, ) known_chat = MessageHandler( Filters.chat(chat_id=-67890), callback_known_chat, - pass_chat_data=True, - pass_user_data=True, ) unknown = MessageHandler( - Filters.all, callback_unknown_user_or_chat, pass_chat_data=True, pass_user_data=True + Filters.all, + callback_unknown_user_or_chat, ) dp.add_handler(known_user) dp.add_handler(known_chat) @@ -481,7 +478,7 @@ def save_callback_data(data): @pytest.mark.parametrize('run_async', [True, False], ids=['synchronous', 'run_async']) def test_persistence_dispatcher_integration_refresh_data( self, - cdp, + dp, base_persistence, chat_data, bot_data, @@ -500,7 +497,7 @@ def test_persistence_dispatcher_integration_refresh_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 + dp.persistence = base_persistence self.test_flag = True @@ -535,26 +532,22 @@ def callback_without_user_and_chat(_, context): with_user_and_chat = MessageHandler( Filters.user(user_id=12345), callback_with_user_and_chat, - pass_chat_data=True, - pass_user_data=True, run_async=run_async, ) without_user_and_chat = MessageHandler( Filters.all, callback_without_user_and_chat, - pass_chat_data=True, - pass_user_data=True, run_async=run_async, ) - cdp.add_handler(with_user_and_chat) - cdp.add_handler(without_user_and_chat) + dp.add_handler(with_user_and_chat) + dp.add_handler(without_user_and_chat) user = User(id=12345, first_name='test user', is_bot=False) chat = Chat(id=-987654, type='group') m = Message(1, None, chat, from_user=user) # has user and chat u = Update(0, m) - cdp.process_update(u) + dp.process_update(u) assert self.test_flag is True @@ -562,7 +555,7 @@ def callback_without_user_and_chat(_, context): m.from_user = None m.chat = None u = Update(1, m) - cdp.process_update(u) + dp.process_update(u) assert self.test_flag is True @@ -1630,7 +1623,7 @@ def test_save_on_flush_single_files(self, pickle_persistence, good_pickle_files) assert conversations_test['name1'] == conversation1 def test_with_handler(self, bot, update, bot_data, pickle_persistence, good_pickle_files): - u = Updater(bot=bot, persistence=pickle_persistence, use_context=True) + u = Updater(bot=bot, persistence=pickle_persistence) dp = u.dispatcher bot.callback_data_cache.clear_callback_data() bot.callback_data_cache.clear_callback_queries() @@ -1659,8 +1652,8 @@ def second(update, context): if not context.bot.callback_data_cache.persistence_data == ([], {'test1': 'test0'}): pytest.fail() - h1 = MessageHandler(None, first, pass_user_data=True, pass_chat_data=True) - h2 = MessageHandler(None, second, pass_user_data=True, pass_chat_data=True) + h1 = MessageHandler(None, first) + h2 = MessageHandler(None, second) dp.add_handler(h1) dp.process_update(update) pickle_persistence_2 = PicklePersistence( @@ -1779,7 +1772,6 @@ def test_flush_on_stop_only_callback(self, bot, update, pickle_persistence_only_ def test_with_conversation_handler(self, dp, update, good_pickle_files, pickle_persistence): dp.persistence = pickle_persistence - dp.use_context = True NEXT, NEXT2 = range(2) def start(update, context): @@ -1814,7 +1806,6 @@ def test_with_nested_conversationHandler( self, dp, update, good_pickle_files, pickle_persistence ): dp.persistence = pickle_persistence - dp.use_context = True NEXT2, NEXT3 = range(1, 3) def start(update, context): @@ -1862,8 +1853,8 @@ def next2(update, context): assert nested_ch.conversations[nested_ch._get_key(update)] == 1 assert nested_ch.conversations == pickle_persistence.conversations['name3'] - def test_with_job(self, job_queue, cdp, pickle_persistence): - cdp.bot.arbitrary_callback_data = True + def test_with_job(self, job_queue, dp, pickle_persistence): + dp.bot.arbitrary_callback_data = True def job_callback(context): context.bot_data['test1'] = '456' @@ -1871,8 +1862,8 @@ def job_callback(context): context.dispatcher.user_data[789]['test3'] = '123' context.bot.callback_data_cache._callback_queries['test'] = 'Working4!' - cdp.persistence = pickle_persistence - job_queue.set_dispatcher(cdp) + dp.persistence = pickle_persistence + job_queue.set_dispatcher(dp) job_queue.start() job_queue.run_once(job_callback, 0.01) sleep(0.5) @@ -2185,7 +2176,7 @@ def test_updating( def test_with_handler(self, bot, update): dict_persistence = DictPersistence() - u = Updater(bot=bot, persistence=dict_persistence, use_context=True) + u = Updater(bot=bot, persistence=dict_persistence) dp = u.dispatcher def first(update, context): @@ -2235,7 +2226,6 @@ def second(update, context): def test_with_conversationHandler(self, dp, update, conversations_json): dict_persistence = DictPersistence(conversations_json=conversations_json) dp.persistence = dict_persistence - dp.use_context = True NEXT, NEXT2 = range(2) def start(update, context): @@ -2269,7 +2259,6 @@ def next2(update, context): def test_with_nested_conversationHandler(self, dp, update, conversations_json): dict_persistence = DictPersistence(conversations_json=conversations_json) dp.persistence = dict_persistence - dp.use_context = True NEXT2, NEXT3 = range(1, 3) def start(update, context): @@ -2317,8 +2306,8 @@ def next2(update, context): assert nested_ch.conversations[nested_ch._get_key(update)] == 1 assert nested_ch.conversations == dict_persistence.conversations['name3'] - def test_with_job(self, job_queue, cdp): - cdp.bot.arbitrary_callback_data = True + def test_with_job(self, job_queue, dp): + dp.bot.arbitrary_callback_data = True def job_callback(context): context.bot_data['test1'] = '456' @@ -2327,8 +2316,8 @@ def job_callback(context): context.bot.callback_data_cache._callback_queries['test'] = 'Working4!' dict_persistence = DictPersistence() - cdp.persistence = dict_persistence - job_queue.set_dispatcher(cdp) + dp.persistence = dict_persistence + job_queue.set_dispatcher(dp) job_queue.start() job_queue.run_once(job_callback, 0.01) sleep(0.8) diff --git a/tests/test_pollanswerhandler.py b/tests/test_pollanswerhandler.py index f8875f88750..303a2b890fe 100644 --- a/tests/test_pollanswerhandler.py +++ b/tests/test_pollanswerhandler.py @@ -75,7 +75,7 @@ class TestPollAnswerHandler: test_flag = False def test_slot_behaviour(self, mro_slots): - handler = PollAnswerHandler(self.callback_basic) + handler = PollAnswerHandler(self.callback_context) for attr in handler.__slots__: assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'" assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot" @@ -84,23 +84,6 @@ def test_slot_behaviour(self, mro_slots): def reset(self): self.test_flag = False - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) - test_update = isinstance(update, Update) - self.test_flag = test_bot and test_update - - def callback_data_1(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) or (chat_data is not None) - - def callback_data_2(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) and (chat_data is not None) - - def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) or (update_queue is not None) - - def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) and (update_queue is not None) - def callback_context(self, update, context): self.test_flag = ( isinstance(context, CallbackContext) @@ -114,70 +97,13 @@ def callback_context(self, update, context): and isinstance(update.poll_answer, PollAnswer) ) - def test_basic(self, dp, poll_answer): - handler = PollAnswerHandler(self.callback_basic) - dp.add_handler(handler) - - assert handler.check_update(poll_answer) - - dp.process_update(poll_answer) - assert self.test_flag - - def test_pass_user_or_chat_data(self, dp, poll_answer): - handler = PollAnswerHandler(self.callback_data_1, pass_user_data=True) - dp.add_handler(handler) - - dp.process_update(poll_answer) - assert self.test_flag - - dp.remove_handler(handler) - handler = PollAnswerHandler(self.callback_data_1, pass_chat_data=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(poll_answer) - assert self.test_flag - - dp.remove_handler(handler) - handler = PollAnswerHandler(self.callback_data_2, pass_chat_data=True, pass_user_data=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(poll_answer) - assert self.test_flag - - def test_pass_job_or_update_queue(self, dp, poll_answer): - handler = PollAnswerHandler(self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - - dp.process_update(poll_answer) - assert self.test_flag - - dp.remove_handler(handler) - handler = PollAnswerHandler(self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(poll_answer) - assert self.test_flag - - dp.remove_handler(handler) - handler = PollAnswerHandler( - self.callback_queue_2, pass_job_queue=True, pass_update_queue=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(poll_answer) - assert self.test_flag - def test_other_update_types(self, false_update): - handler = PollAnswerHandler(self.callback_basic) + handler = PollAnswerHandler(self.callback_context) assert not handler.check_update(false_update) - def test_context(self, cdp, poll_answer): + def test_context(self, dp, poll_answer): handler = PollAnswerHandler(self.callback_context) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(poll_answer) + dp.process_update(poll_answer) assert self.test_flag diff --git a/tests/test_pollhandler.py b/tests/test_pollhandler.py index 8c034fb76ab..713ac99bc3b 100644 --- a/tests/test_pollhandler.py +++ b/tests/test_pollhandler.py @@ -88,7 +88,7 @@ class TestPollHandler: test_flag = False def test_slot_behaviour(self, mro_slots): - inst = PollHandler(self.callback_basic) + inst = PollHandler(self.callback_context) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" @@ -97,23 +97,6 @@ def test_slot_behaviour(self, mro_slots): def reset(self): self.test_flag = False - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) - test_update = isinstance(update, Update) - self.test_flag = test_bot and test_update - - def callback_data_1(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) or (chat_data is not None) - - def callback_data_2(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) and (chat_data is not None) - - def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) or (update_queue is not None) - - def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) and (update_queue is not None) - def callback_context(self, update, context): self.test_flag = ( isinstance(context, CallbackContext) @@ -127,68 +110,13 @@ def callback_context(self, update, context): and isinstance(update.poll, Poll) ) - def test_basic(self, dp, poll): - handler = PollHandler(self.callback_basic) - dp.add_handler(handler) - - assert handler.check_update(poll) - - dp.process_update(poll) - assert self.test_flag - - def test_pass_user_or_chat_data(self, dp, poll): - handler = PollHandler(self.callback_data_1, pass_user_data=True) - dp.add_handler(handler) - - dp.process_update(poll) - assert self.test_flag - - dp.remove_handler(handler) - handler = PollHandler(self.callback_data_1, pass_chat_data=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(poll) - assert self.test_flag - - dp.remove_handler(handler) - handler = PollHandler(self.callback_data_2, pass_chat_data=True, pass_user_data=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(poll) - assert self.test_flag - - def test_pass_job_or_update_queue(self, dp, poll): - handler = PollHandler(self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - - dp.process_update(poll) - assert self.test_flag - - dp.remove_handler(handler) - handler = PollHandler(self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(poll) - assert self.test_flag - - dp.remove_handler(handler) - handler = PollHandler(self.callback_queue_2, pass_job_queue=True, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(poll) - assert self.test_flag - def test_other_update_types(self, false_update): - handler = PollHandler(self.callback_basic) + handler = PollHandler(self.callback_context) assert not handler.check_update(false_update) - def test_context(self, cdp, poll): + def test_context(self, dp, poll): handler = PollHandler(self.callback_context) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(poll) + dp.process_update(poll) assert self.test_flag diff --git a/tests/test_precheckoutqueryhandler.py b/tests/test_precheckoutqueryhandler.py index 3bda03a0a26..545acebdb7e 100644 --- a/tests/test_precheckoutqueryhandler.py +++ b/tests/test_precheckoutqueryhandler.py @@ -80,7 +80,7 @@ class TestPreCheckoutQueryHandler: test_flag = False def test_slot_behaviour(self, mro_slots): - inst = PreCheckoutQueryHandler(self.callback_basic) + inst = PreCheckoutQueryHandler(self.callback_context) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" @@ -89,23 +89,6 @@ def test_slot_behaviour(self, mro_slots): def reset(self): self.test_flag = False - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) - test_update = isinstance(update, Update) - self.test_flag = test_bot and test_update - - def callback_data_1(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) or (chat_data is not None) - - def callback_data_2(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) and (chat_data is not None) - - def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) or (update_queue is not None) - - def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) and (update_queue is not None) - def callback_context(self, update, context): self.test_flag = ( isinstance(context, CallbackContext) @@ -119,71 +102,13 @@ def callback_context(self, update, context): and isinstance(update.pre_checkout_query, PreCheckoutQuery) ) - def test_basic(self, dp, pre_checkout_query): - handler = PreCheckoutQueryHandler(self.callback_basic) - dp.add_handler(handler) - - assert handler.check_update(pre_checkout_query) - dp.process_update(pre_checkout_query) - assert self.test_flag - - def test_pass_user_or_chat_data(self, dp, pre_checkout_query): - handler = PreCheckoutQueryHandler(self.callback_data_1, pass_user_data=True) - dp.add_handler(handler) - - dp.process_update(pre_checkout_query) - assert self.test_flag - - dp.remove_handler(handler) - handler = PreCheckoutQueryHandler(self.callback_data_1, pass_chat_data=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(pre_checkout_query) - assert self.test_flag - - dp.remove_handler(handler) - handler = PreCheckoutQueryHandler( - self.callback_data_2, pass_chat_data=True, pass_user_data=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(pre_checkout_query) - assert self.test_flag - - def test_pass_job_or_update_queue(self, dp, pre_checkout_query): - handler = PreCheckoutQueryHandler(self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - - dp.process_update(pre_checkout_query) - assert self.test_flag - - dp.remove_handler(handler) - handler = PreCheckoutQueryHandler(self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(pre_checkout_query) - assert self.test_flag - - dp.remove_handler(handler) - handler = PreCheckoutQueryHandler( - self.callback_queue_2, pass_job_queue=True, pass_update_queue=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(pre_checkout_query) - assert self.test_flag - def test_other_update_types(self, false_update): - handler = PreCheckoutQueryHandler(self.callback_basic) + handler = PreCheckoutQueryHandler(self.callback_context) assert not handler.check_update(false_update) - def test_context(self, cdp, pre_checkout_query): + def test_context(self, dp, pre_checkout_query): handler = PreCheckoutQueryHandler(self.callback_context) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(pre_checkout_query) + dp.process_update(pre_checkout_query) assert self.test_flag diff --git a/tests/test_regexhandler.py b/tests/test_regexhandler.py index cbf3eba50f4..e69de29bb2d 100644 --- a/tests/test_regexhandler.py +++ b/tests/test_regexhandler.py @@ -1,289 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015-2021 -# Leandro Toledo de Souza -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser Public License for more details. -# -# You should have received a copy of the GNU Lesser Public License -# along with this program. If not, see [http://www.gnu.org/licenses/]. -from queue import Queue - -import pytest -from telegram.utils.deprecate import TelegramDeprecationWarning - -from telegram import ( - Message, - Update, - Chat, - Bot, - User, - CallbackQuery, - InlineQuery, - ChosenInlineResult, - ShippingQuery, - PreCheckoutQuery, -) -from telegram.ext import RegexHandler, CallbackContext, JobQueue - -message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text') - -params = [ - {'callback_query': CallbackQuery(1, User(1, '', False), 'chat', message=message)}, - {'inline_query': InlineQuery(1, User(1, '', False), '', '')}, - {'chosen_inline_result': ChosenInlineResult('id', User(1, '', False), '')}, - {'shipping_query': ShippingQuery('id', User(1, '', False), '', None)}, - {'pre_checkout_query': PreCheckoutQuery('id', User(1, '', False), '', 0, '')}, - {'callback_query': CallbackQuery(1, User(1, '', False), 'chat')}, -] - -ids = ( - 'callback_query', - 'inline_query', - 'chosen_inline_result', - 'shipping_query', - 'pre_checkout_query', - 'callback_query_without_message', -) - - -@pytest.fixture(scope='class', params=params, ids=ids) -def false_update(request): - return Update(update_id=1, **request.param) - - -@pytest.fixture(scope='class') -def message(bot): - return Message( - 1, None, Chat(1, ''), from_user=User(1, '', False), text='test message', bot=bot - ) - - -class TestRegexHandler: - test_flag = False - - def test_slot_behaviour(self, mro_slots): - inst = RegexHandler("", self.callback_basic) - for attr in inst.__slots__: - assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" - assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - - @pytest.fixture(autouse=True) - def reset(self): - self.test_flag = False - - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) - test_update = isinstance(update, Update) - self.test_flag = test_bot and test_update - - def callback_data_1(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) or (chat_data is not None) - - def callback_data_2(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) and (chat_data is not None) - - def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) or (update_queue is not None) - - def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) and (update_queue is not None) - - def callback_group(self, bot, update, groups=None, groupdict=None): - if groups is not None: - self.test_flag = groups == ('t', ' message') - if groupdict is not None: - self.test_flag = groupdict == {'begin': 't', 'end': ' message'} - - def callback_context(self, update, context): - self.test_flag = ( - isinstance(context, CallbackContext) - and isinstance(context.bot, Bot) - and isinstance(update, Update) - and isinstance(context.update_queue, Queue) - and isinstance(context.job_queue, JobQueue) - and isinstance(context.user_data, dict) - and isinstance(context.chat_data, dict) - and isinstance(context.bot_data, dict) - and isinstance(update.message, Message) - ) - - def callback_context_pattern(self, update, context): - if context.matches[0].groups(): - self.test_flag = context.matches[0].groups() == ('t', ' message') - if context.matches[0].groupdict(): - self.test_flag = context.matches[0].groupdict() == {'begin': 't', 'end': ' message'} - - def test_deprecation_Warning(self): - with pytest.warns(TelegramDeprecationWarning, match='RegexHandler is deprecated.'): - RegexHandler('.*', self.callback_basic) - - def test_basic(self, dp, message): - handler = RegexHandler('.*', self.callback_basic) - dp.add_handler(handler) - - assert handler.check_update(Update(0, message)) - dp.process_update(Update(0, message)) - assert self.test_flag - - def test_pattern(self, message): - handler = RegexHandler('.*est.*', self.callback_basic) - - assert handler.check_update(Update(0, message)) - - handler = RegexHandler('.*not in here.*', self.callback_basic) - assert not handler.check_update(Update(0, message)) - - def test_with_passing_group_dict(self, dp, message): - handler = RegexHandler( - '(?P.*)est(?P.*)', self.callback_group, pass_groups=True - ) - dp.add_handler(handler) - dp.process_update(Update(0, message)) - assert self.test_flag - - dp.remove_handler(handler) - handler = RegexHandler( - '(?P.*)est(?P.*)', self.callback_group, pass_groupdict=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(Update(0, message)) - assert self.test_flag - - def test_edited(self, message): - handler = RegexHandler( - '.*', - self.callback_basic, - edited_updates=True, - message_updates=False, - channel_post_updates=False, - ) - - assert handler.check_update(Update(0, edited_message=message)) - assert not handler.check_update(Update(0, message=message)) - assert not handler.check_update(Update(0, channel_post=message)) - assert handler.check_update(Update(0, edited_channel_post=message)) - - def test_channel_post(self, message): - handler = RegexHandler( - '.*', - self.callback_basic, - edited_updates=False, - message_updates=False, - channel_post_updates=True, - ) - - assert not handler.check_update(Update(0, edited_message=message)) - assert not handler.check_update(Update(0, message=message)) - assert handler.check_update(Update(0, channel_post=message)) - assert not handler.check_update(Update(0, edited_channel_post=message)) - - def test_multiple_flags(self, message): - handler = RegexHandler( - '.*', - self.callback_basic, - edited_updates=True, - message_updates=True, - channel_post_updates=True, - ) - - assert handler.check_update(Update(0, edited_message=message)) - assert handler.check_update(Update(0, message=message)) - assert handler.check_update(Update(0, channel_post=message)) - assert handler.check_update(Update(0, edited_channel_post=message)) - - def test_none_allowed(self): - with pytest.raises(ValueError, match='are all False'): - RegexHandler( - '.*', - self.callback_basic, - message_updates=False, - channel_post_updates=False, - edited_updates=False, - ) - - def test_pass_user_or_chat_data(self, dp, message): - handler = RegexHandler('.*', self.callback_data_1, pass_user_data=True) - dp.add_handler(handler) - - dp.process_update(Update(0, message=message)) - assert self.test_flag - - dp.remove_handler(handler) - handler = RegexHandler('.*', self.callback_data_1, pass_chat_data=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(Update(0, message=message)) - assert self.test_flag - - dp.remove_handler(handler) - handler = RegexHandler( - '.*', self.callback_data_2, pass_chat_data=True, pass_user_data=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(Update(0, message=message)) - assert self.test_flag - - def test_pass_job_or_update_queue(self, dp, message): - handler = RegexHandler('.*', self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - - dp.process_update(Update(0, message=message)) - assert self.test_flag - - dp.remove_handler(handler) - handler = RegexHandler('.*', self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(Update(0, message=message)) - assert self.test_flag - - dp.remove_handler(handler) - handler = RegexHandler( - '.*', self.callback_queue_2, pass_job_queue=True, pass_update_queue=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(Update(0, message=message)) - assert self.test_flag - - def test_other_update_types(self, false_update): - handler = RegexHandler('.*', self.callback_basic, edited_updates=True) - assert not handler.check_update(false_update) - - def test_context(self, cdp, message): - handler = RegexHandler(r'(t)est(.*)', self.callback_context) - cdp.add_handler(handler) - - cdp.process_update(Update(0, message=message)) - assert self.test_flag - - def test_context_pattern(self, cdp, message): - handler = RegexHandler(r'(t)est(.*)', self.callback_context_pattern) - cdp.add_handler(handler) - - cdp.process_update(Update(0, message=message)) - assert self.test_flag - - cdp.remove_handler(handler) - handler = RegexHandler(r'(t)est(.*)', self.callback_context_pattern) - cdp.add_handler(handler) - - cdp.process_update(Update(0, message=message)) - assert self.test_flag diff --git a/tests/test_shippingqueryhandler.py b/tests/test_shippingqueryhandler.py index 144d2b0c82e..9f49ac3aad4 100644 --- a/tests/test_shippingqueryhandler.py +++ b/tests/test_shippingqueryhandler.py @@ -84,7 +84,7 @@ class TestShippingQueryHandler: test_flag = False def test_slot_behaviour(self, mro_slots): - inst = ShippingQueryHandler(self.callback_basic) + inst = ShippingQueryHandler(self.callback_context) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" @@ -93,23 +93,6 @@ def test_slot_behaviour(self, mro_slots): def reset(self): self.test_flag = False - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) - test_update = isinstance(update, Update) - self.test_flag = test_bot and test_update - - def callback_data_1(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) or (chat_data is not None) - - def callback_data_2(self, bot, update, user_data=None, chat_data=None): - self.test_flag = (user_data is not None) and (chat_data is not None) - - def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) or (update_queue is not None) - - def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) and (update_queue is not None) - def callback_context(self, update, context): self.test_flag = ( isinstance(context, CallbackContext) @@ -123,71 +106,13 @@ def callback_context(self, update, context): and isinstance(update.shipping_query, ShippingQuery) ) - def test_basic(self, dp, shiping_query): - handler = ShippingQueryHandler(self.callback_basic) - dp.add_handler(handler) - - assert handler.check_update(shiping_query) - dp.process_update(shiping_query) - assert self.test_flag - - def test_pass_user_or_chat_data(self, dp, shiping_query): - handler = ShippingQueryHandler(self.callback_data_1, pass_user_data=True) - dp.add_handler(handler) - - dp.process_update(shiping_query) - assert self.test_flag - - dp.remove_handler(handler) - handler = ShippingQueryHandler(self.callback_data_1, pass_chat_data=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(shiping_query) - assert self.test_flag - - dp.remove_handler(handler) - handler = ShippingQueryHandler( - self.callback_data_2, pass_chat_data=True, pass_user_data=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(shiping_query) - assert self.test_flag - - def test_pass_job_or_update_queue(self, dp, shiping_query): - handler = ShippingQueryHandler(self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - - dp.process_update(shiping_query) - assert self.test_flag - - dp.remove_handler(handler) - handler = ShippingQueryHandler(self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(shiping_query) - assert self.test_flag - - dp.remove_handler(handler) - handler = ShippingQueryHandler( - self.callback_queue_2, pass_job_queue=True, pass_update_queue=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(shiping_query) - assert self.test_flag - def test_other_update_types(self, false_update): - handler = ShippingQueryHandler(self.callback_basic) + handler = ShippingQueryHandler(self.callback_context) assert not handler.check_update(false_update) - def test_context(self, cdp, shiping_query): + def test_context(self, dp, shiping_query): handler = ShippingQueryHandler(self.callback_context) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(shiping_query) + dp.process_update(shiping_query) assert self.test_flag diff --git a/tests/test_stringcommandhandler.py b/tests/test_stringcommandhandler.py index f1cd426042a..4849286dcc3 100644 --- a/tests/test_stringcommandhandler.py +++ b/tests/test_stringcommandhandler.py @@ -72,7 +72,7 @@ class TestStringCommandHandler: test_flag = False def test_slot_behaviour(self, mro_slots): - inst = StringCommandHandler('sleepy', self.callback_basic) + inst = StringCommandHandler('sleepy', self.callback_context) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" @@ -81,23 +81,6 @@ def test_slot_behaviour(self, mro_slots): def reset(self): self.test_flag = False - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) - test_update = isinstance(update, str) - self.test_flag = test_bot and test_update - - def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) or (update_queue is not None) - - def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) and (update_queue is not None) - - def sch_callback_args(self, bot, update, args): - if update == '/test': - self.test_flag = len(args) == 0 - else: - self.test_flag = args == ['one', 'two'] - def callback_context(self, update, context): self.test_flag = ( isinstance(context, CallbackContext) @@ -113,75 +96,23 @@ def callback_context(self, update, context): def callback_context_args(self, update, context): self.test_flag = context.args == ['one', 'two'] - def test_basic(self, dp): - handler = StringCommandHandler('test', self.callback_basic) - dp.add_handler(handler) - - check = handler.check_update('/test') - assert check is not None and check is not False - dp.process_update('/test') - assert self.test_flag - - check = handler.check_update('/nottest') - assert check is None or check is False - check = handler.check_update('not /test in front') - assert check is None or check is False - check = handler.check_update('/test followed by text') - assert check is not None and check is not False - - def test_pass_args(self, dp): - handler = StringCommandHandler('test', self.sch_callback_args, pass_args=True) - dp.add_handler(handler) - - dp.process_update('/test') - assert self.test_flag - - self.test_flag = False - dp.process_update('/test one two') - assert self.test_flag - - def test_pass_job_or_update_queue(self, dp): - handler = StringCommandHandler('test', self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - - dp.process_update('/test') - assert self.test_flag - - dp.remove_handler(handler) - handler = StringCommandHandler('test', self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update('/test') - assert self.test_flag - - dp.remove_handler(handler) - handler = StringCommandHandler( - 'test', self.callback_queue_2, pass_job_queue=True, pass_update_queue=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update('/test') - assert self.test_flag - def test_other_update_types(self, false_update): - handler = StringCommandHandler('test', self.callback_basic) + handler = StringCommandHandler('test', self.callback_context) assert not handler.check_update(false_update) - def test_context(self, cdp): + def test_context(self, dp): handler = StringCommandHandler('test', self.callback_context) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update('/test') + dp.process_update('/test') assert self.test_flag - def test_context_args(self, cdp): + def test_context_args(self, dp): handler = StringCommandHandler('test', self.callback_context_args) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update('/test') + dp.process_update('/test') assert not self.test_flag - cdp.process_update('/test one two') + dp.process_update('/test one two') assert self.test_flag diff --git a/tests/test_stringregexhandler.py b/tests/test_stringregexhandler.py index 2fc926b36e8..b7f6182eb75 100644 --- a/tests/test_stringregexhandler.py +++ b/tests/test_stringregexhandler.py @@ -72,7 +72,7 @@ class TestStringRegexHandler: test_flag = False def test_slot_behaviour(self, mro_slots): - inst = StringRegexHandler('pfft', self.callback_basic) + inst = StringRegexHandler('pfft', self.callback_context) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" @@ -81,23 +81,6 @@ def test_slot_behaviour(self, mro_slots): def reset(self): self.test_flag = False - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) - test_update = isinstance(update, str) - self.test_flag = test_bot and test_update - - def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) or (update_queue is not None) - - def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) and (update_queue is not None) - - def callback_group(self, bot, update, groups=None, groupdict=None): - if groups is not None: - self.test_flag = groups == ('t', ' message') - if groupdict is not None: - self.test_flag = groupdict == {'begin': 't', 'end': ' message'} - def callback_context(self, update, context): self.test_flag = ( isinstance(context, CallbackContext) @@ -114,7 +97,7 @@ def callback_context_pattern(self, update, context): self.test_flag = context.matches[0].groupdict() == {'begin': 't', 'end': ' message'} def test_basic(self, dp): - handler = StringRegexHandler('(?P.*)est(?P.*)', self.callback_basic) + handler = StringRegexHandler('(?P.*)est(?P.*)', self.callback_context) dp.add_handler(handler) assert handler.check_update('test message') @@ -123,71 +106,27 @@ def test_basic(self, dp): assert not handler.check_update('does not match') - def test_with_passing_group_dict(self, dp): - handler = StringRegexHandler( - '(?P.*)est(?P.*)', self.callback_group, pass_groups=True - ) - dp.add_handler(handler) - - dp.process_update('test message') - assert self.test_flag - - dp.remove_handler(handler) - handler = StringRegexHandler( - '(?P.*)est(?P.*)', self.callback_group, pass_groupdict=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update('test message') - assert self.test_flag - - def test_pass_job_or_update_queue(self, dp): - handler = StringRegexHandler('test', self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - - dp.process_update('test') - assert self.test_flag - - dp.remove_handler(handler) - handler = StringRegexHandler('test', self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update('test') - assert self.test_flag - - dp.remove_handler(handler) - handler = StringRegexHandler( - 'test', self.callback_queue_2, pass_job_queue=True, pass_update_queue=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update('test') - assert self.test_flag - def test_other_update_types(self, false_update): - handler = StringRegexHandler('test', self.callback_basic) + handler = StringRegexHandler('test', self.callback_context) assert not handler.check_update(false_update) - def test_context(self, cdp): + def test_context(self, dp): handler = StringRegexHandler(r'(t)est(.*)', self.callback_context) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update('test message') + dp.process_update('test message') assert self.test_flag - def test_context_pattern(self, cdp): + def test_context_pattern(self, dp): handler = StringRegexHandler(r'(t)est(.*)', self.callback_context_pattern) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update('test message') + dp.process_update('test message') assert self.test_flag - cdp.remove_handler(handler) + dp.remove_handler(handler) handler = StringRegexHandler(r'(t)est(.*)', self.callback_context_pattern) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update('test message') + dp.process_update('test message') assert self.test_flag diff --git a/tests/test_typehandler.py b/tests/test_typehandler.py index e355d843672..637dd388d5b 100644 --- a/tests/test_typehandler.py +++ b/tests/test_typehandler.py @@ -29,7 +29,7 @@ class TestTypeHandler: test_flag = False def test_slot_behaviour(self, mro_slots): - inst = TypeHandler(dict, self.callback_basic) + inst = TypeHandler(dict, self.callback_context) for attr in inst.__slots__: assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" @@ -38,17 +38,6 @@ def test_slot_behaviour(self, mro_slots): def reset(self): self.test_flag = False - def callback_basic(self, bot, update): - test_bot = isinstance(bot, Bot) - test_update = isinstance(update, dict) - self.test_flag = test_bot and test_update - - def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) or (update_queue is not None) - - def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): - self.test_flag = (job_queue is not None) and (update_queue is not None) - def callback_context(self, update, context): self.test_flag = ( isinstance(context, CallbackContext) @@ -62,7 +51,7 @@ def callback_context(self, update, context): ) def test_basic(self, dp): - handler = TypeHandler(dict, self.callback_basic) + handler = TypeHandler(dict, self.callback_context) dp.add_handler(handler) assert handler.check_update({'a': 1, 'b': 2}) @@ -71,39 +60,14 @@ def test_basic(self, dp): assert self.test_flag def test_strict(self): - handler = TypeHandler(dict, self.callback_basic, strict=True) + handler = TypeHandler(dict, self.callback_context, strict=True) o = OrderedDict({'a': 1, 'b': 2}) assert handler.check_update({'a': 1, 'b': 2}) assert not handler.check_update(o) - def test_pass_job_or_update_queue(self, dp): - handler = TypeHandler(dict, self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - - dp.process_update({'a': 1, 'b': 2}) - assert self.test_flag - - dp.remove_handler(handler) - handler = TypeHandler(dict, self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update({'a': 1, 'b': 2}) - assert self.test_flag - - dp.remove_handler(handler) - handler = TypeHandler( - dict, self.callback_queue_2, pass_job_queue=True, pass_update_queue=True - ) + def test_context(self, dp): + handler = TypeHandler(dict, self.callback_context) dp.add_handler(handler) - self.test_flag = False dp.process_update({'a': 1, 'b': 2}) assert self.test_flag - - def test_context(self, cdp): - handler = TypeHandler(dict, self.callback_context) - cdp.add_handler(handler) - - cdp.process_update({'a': 1, 'b': 2}) - assert self.test_flag diff --git a/tests/test_updater.py b/tests/test_updater.py index 46ea5493e51..875131f43bd 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -106,11 +106,11 @@ def reset(self): self.cb_handler_called.clear() self.test_flag = False - def error_handler(self, bot, update, error): - self.received = error.message + def error_handler(self, update, context): + self.received = context.error.message self.err_handler_called.set() - def callback(self, bot, update): + def callback(self, update, context): self.received = update.message.text self.cb_handler_called.set() @@ -500,10 +500,9 @@ def test_deprecation_warnings_start_webhook(self, recwarn, updater, monkeypatch) except AssertionError: pass - assert len(recwarn) == 3 - assert str(recwarn[0].message).startswith('Old Handler API') - assert str(recwarn[1].message).startswith('The argument `clean` of') - assert str(recwarn[2].message).startswith('The argument `force_event_loop` of') + assert len(recwarn) == 2 + assert str(recwarn[0].message).startswith('The argument `clean` of') + assert str(recwarn[1].message).startswith('The argument `force_event_loop` of') def test_clean_deprecation_warning_polling(self, recwarn, updater, monkeypatch): monkeypatch.setattr(updater.bot, 'set_webhook', lambda *args, **kwargs: True) @@ -522,9 +521,8 @@ def test_clean_deprecation_warning_polling(self, recwarn, updater, monkeypatch): except AssertionError: pass - assert len(recwarn) == 2 - assert str(recwarn[0].message).startswith('Old Handler API') - assert str(recwarn[1].message).startswith('The argument `clean` of') + assert len(recwarn) == 1 + assert str(recwarn[0].message).startswith('The argument `clean` of') def test_clean_drop_pending_mutually_exclusive(self, updater): with pytest.raises(TypeError, match='`clean` and `drop_pending_updates` are mutually'): @@ -695,12 +693,6 @@ def test_mutual_exclude_workers_dispatcher(self, bot): with pytest.raises(ValueError): Updater(dispatcher=dispatcher, workers=8) - def test_mutual_exclude_use_context_dispatcher(self, bot): - dispatcher = Dispatcher(bot, None) - use_context = not dispatcher.use_context - with pytest.raises(ValueError): - Updater(dispatcher=dispatcher, use_context=use_context) - def test_mutual_exclude_custom_context_dispatcher(self): dispatcher = Dispatcher(None, None) with pytest.raises(ValueError): 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