diff --git a/docs/source/telegram.ext.regexhandler.rst b/docs/source/telegram.ext.regexhandler.rst deleted file mode 100644 index efe40ef29..000000000 --- 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 6e2a79cc1..9d68efdce 100644 --- a/docs/source/telegram.ext.rst +++ b/docs/source/telegram.ext.rst @@ -34,7 +34,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 b94440fa9..b911acb8a 100644 --- a/telegram/ext/__init__.py +++ b/telegram/ext/__init__.py @@ -35,7 +35,6 @@ from .inlinequeryhandler import InlineQueryHandler 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 @@ -84,7 +83,6 @@ __all__ = ( 'PollHandler', 'PreCheckoutQueryHandler', 'PrefixHandler', - 'RegexHandler', 'ShippingQueryHandler', 'StringCommandHandler', 'StringRegexHandler', diff --git a/telegram/ext/callbackcontext.py b/telegram/ext/callbackcontext.py index 8db1581e7..87a95924a 100644 --- a/telegram/ext/callbackcontext.py +++ b/telegram/ext/callbackcontext.py @@ -108,10 +108,6 @@ class CallbackContext(Generic[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 bb19fa73e..f3420f366 100644 --- a/telegram/ext/callbackqueryhandler.py +++ b/telegram/ext/callbackqueryhandler.py @@ -22,7 +22,6 @@ import re 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,10 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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` | `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 +86,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 +117,6 @@ class CallbackQueryHandler(Handler[Update, CCT]): 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 +144,6 @@ class CallbackQueryHandler(Handler[Update, CCT]): 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/chatjoinrequesthandler.py b/telegram/ext/chatjoinrequesthandler.py index aafed54c0..09fce9b82 100644 --- a/telegram/ext/chatjoinrequesthandler.py +++ b/telegram/ext/chatjoinrequesthandler.py @@ -28,15 +28,6 @@ from .utils.types import CCT class ChatJoinRequestHandler(Handler[Update, CCT]): """Handler class to handle Telegram updates that contain a chat join request. - 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. @@ -52,35 +43,11 @@ class ChatJoinRequestHandler(Handler[Update, CCT]): 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/chatmemberhandler.py b/telegram/ext/chatmemberhandler.py index eb9d91b0d..bb5b1bf20 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,9 +39,7 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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`. @@ -58,22 +47,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 +55,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 +72,10 @@ class ChatMemberHandler(Handler[Update, CCT]): 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 1d94b79a5..b5f3adc9b 100644 --- a/telegram/ext/choseninlineresulthandler.py +++ b/telegram/ext/choseninlineresulthandler.py @@ -35,15 +35,6 @@ if TYPE_CHECKING: 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,10 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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 +57,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 +70,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 6f53d23c5..64f7642b9 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,9 +58,7 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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`. @@ -77,31 +66,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 +79,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 +109,6 @@ class CommandHandler(Handler[Update, CCT]): 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 +148,6 @@ class CommandHandler(Handler[Update, CCT]): 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 +200,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,9 +212,7 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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`. @@ -311,27 +220,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 +227,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 +240,6 @@ class PrefixHandler(CommandHandler): 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 +251,6 @@ class PrefixHandler(CommandHandler): '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 98b7ccfe0..7e85f6723 100644 --- a/telegram/ext/conversationhandler.py +++ b/telegram/ext/conversationhandler.py @@ -53,7 +53,7 @@ class _ConversationTimeoutContext: 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 @@ class ConversationHandler(Handler[Update, CCT]): 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 @@ class ConversationHandler(Handler[Update, CCT]): 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 @@ class ConversationHandler(Handler[Update, CCT]): 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 @@ class ConversationHandler(Handler[Update, CCT]): 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 c74ba9038..0507ba734 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 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): exception_event: Event = None, job_queue: 'JobQueue' = None, persistence: BasePersistence = None, - use_context: bool = True, ): ... @@ -216,7 +211,6 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): 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 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): 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 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): 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,12 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): 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: - - ``def callback(update: object, context: CallbackContext)`` + called when an error is raised. + Callback signature: ``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 +770,13 @@ class Dispatcher(Generic[CCT, UD, CD, BD]): 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 aa106e929..b298cea1b 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 @@ UT = TypeVar('UT') 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,30 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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 +92,7 @@ class Handler(Generic[UT, CCT], ABC): 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 +105,7 @@ class Handler(Generic[UT, CCT], ABC): 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 +117,10 @@ class Handler(Generic[UT, CCT], ABC): ): 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 +138,3 @@ class Handler(Generic[UT, CCT], ABC): 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 de43431b8..c65af1b55 100644 --- a/telegram/ext/inlinequeryhandler.py +++ b/telegram/ext/inlinequeryhandler.py @@ -21,7 +21,6 @@ import re 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,10 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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 +68,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 +101,6 @@ class InlineQueryHandler(Handler[Update, CCT]): 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 +127,6 @@ class InlineQueryHandler(Handler[Update, CCT]): 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 7f897f4e4..3c5351bbf 100644 --- a/telegram/ext/jobqueue.py +++ b/telegram/ext/jobqueue.py @@ -31,7 +31,6 @@ from telegram.ext.callbackcontext import CallbackContext 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 @@ class JobQueue: 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,7 @@ class JobQueue: Args: callback (:obj:`callable`): The callback function that should be executed by the new - job. Callback signature for context based API: - - ``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. + job. Callback signature: ``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 +212,7 @@ class JobQueue: Args: callback (:obj:`callable`): The callback function that should be executed by the new - job. Callback signature for context based API: - - ``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. + job. Callback signature: ``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 +302,7 @@ class JobQueue: Args: callback (:obj:`callable`): The callback function that should be executed by the new - job. Callback signature for context based API: - - ``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. + job. Callback signature: ``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 +361,7 @@ class JobQueue: Args: callback (:obj:`callable`): The callback function that should be executed by the new - job. Callback signature for context based API: - - ``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. + job. Callback signature: ``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 +411,7 @@ class JobQueue: Args: callback (:obj:`callable`): The callback function that should be executed by the new - job. Callback signature for context based API: - - ``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. + job. Callback signature: ``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 +474,7 @@ class Job: Args: callback (:obj:`callable`): The callback function that should be executed by the new job. - Callback signature for context based API: - - ``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. + Callback signature: ``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 +522,7 @@ class Job: 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 57faa3f0e..0e8c5651a 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 @@ RT = TypeVar('RT') 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,10 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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 +64,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 +74,17 @@ class MessageHandler(Handler[Update, CCT]): 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 +96,7 @@ class MessageHandler(Handler[Update, CCT]): :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 53172b2b9..9ec28352c 100644 --- a/telegram/ext/pollanswerhandler.py +++ b/telegram/ext/pollanswerhandler.py @@ -28,15 +28,6 @@ from .utils.types import CCT 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,15 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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 0e2dee600..913af1445 100644 --- a/telegram/ext/pollhandler.py +++ b/telegram/ext/pollhandler.py @@ -28,15 +28,6 @@ from .utils.types import CCT 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,15 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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 bbef18efc..669919de2 100644 --- a/telegram/ext/precheckoutqueryhandler.py +++ b/telegram/ext/precheckoutqueryhandler.py @@ -28,15 +28,6 @@ from .utils.types import CCT 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,15 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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 8211d83f5..000000000 --- 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-2022 -# 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 d8b0218da..7142ed7e9 100644 --- a/telegram/ext/shippingqueryhandler.py +++ b/telegram/ext/shippingqueryhandler.py @@ -27,15 +27,6 @@ from .utils.types import CCT 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,15 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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 e3945aec2..ca237f6db 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,33 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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 +93,6 @@ class StringCommandHandler(Handler[str, CCT]): 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 9be6b3632..e9762cd2d 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,30 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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 +81,6 @@ class StringRegexHandler(Handler[str, CCT]): 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 +98,6 @@ class StringRegexHandler(Handler[str, CCT]): 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 14029ab32..6be41ff12 100644 --- a/telegram/ext/typehandler.py +++ b/telegram/ext/typehandler.py @@ -40,24 +40,12 @@ 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: - - ``def callback(update: Update, context: CallbackContext)`` + 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`. 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 +53,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 +64,10 @@ class TypeHandler(Handler[UT, CCT]): 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 74c167d9e..ee0742ab2 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 @@ class Updater(Generic[CCT, UD, CD, BD]): 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 @@ class Updater(Generic[CCT, UD, CD, BD]): 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 @@ class Updater(Generic[CCT, UD, CD, BD]): 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 @@ class Updater(Generic[CCT, UD, CD, BD]): 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 @@ class Updater(Generic[CCT, UD, CD, BD]): 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 255f6b764..1d7ddf6f0 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 e5de5f6d2..29162e245 100644 --- a/tests/test_callbackcontext.py +++ b/tests/test_callbackcontext.py @@ -38,8 +38,8 @@ CallbackContext.refresh_data is tested in TestBasePersistence 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 @@ class TestCallbackContext: 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 @@ class TestCallbackContext: 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 @@ class TestCallbackContext: 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 @@ class TestCallbackContext: 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 @@ class TestCallbackContext: 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 49964a639..1089e215b 100644 --- a/tests/test_callbackqueryhandler.py +++ b/tests/test_callbackqueryhandler.py @@ -82,8 +82,8 @@ class TestCallbackQueryHandler: 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 @@ class TestCallbackQueryHandler: 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 TestCallbackQueryHandler: 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 - - dp.remove_handler(handler) - handler = CallbackQueryHandler(self.callback_data_1, pass_chat_data=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_data_2, pass_chat_data=True, pass_user_data=True - ) - 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 - ) - 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): + def test_context(self, dp, callback_query): handler = CallbackQueryHandler(self.callback_context) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(callback_query) + dp.process_update(callback_query) assert self.test_flag - def test_context_pattern(self, cdp, callback_query): + def test_context_pattern(self, dp, callback_query): handler = CallbackQueryHandler( self.callback_context_pattern, pattern=r'(?P.*)est(?P.*)' ) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(callback_query) + dp.process_update(callback_query) assert self.test_flag - cdp.remove_handler(handler) + dp.remove_handler(handler) handler = CallbackQueryHandler(self.callback_context_pattern, pattern=r'(t)est(.*)') - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(callback_query) + dp.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 @@ class TestCallbackQueryHandler: 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_chatjoinrequesthandler.py b/tests/test_chatjoinrequesthandler.py index 7266356f9..0441399ca 100644 --- a/tests/test_chatjoinrequesthandler.py +++ b/tests/test_chatjoinrequesthandler.py @@ -102,7 +102,7 @@ class TestChatJoinRequestHandler: test_flag = False def test_slot_behaviour(self, recwarn, mro_slots): - action = ChatJoinRequestHandler(self.callback_basic) + action = ChatJoinRequestHandler(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" @@ -111,23 +111,6 @@ class TestChatJoinRequestHandler: 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) @@ -144,73 +127,14 @@ class TestChatJoinRequestHandler: ) ) - def test_basic(self, dp, chat_join_request_update): - handler = ChatJoinRequestHandler(self.callback_basic) - dp.add_handler(handler) - - assert handler.check_update(chat_join_request_update) - - dp.process_update(chat_join_request_update) - assert self.test_flag - - def test_pass_user_or_chat_data(self, dp, chat_join_request_update): - handler = ChatJoinRequestHandler(self.callback_data_1, pass_user_data=True) - dp.add_handler(handler) - - dp.process_update(chat_join_request_update) - assert self.test_flag - - dp.remove_handler(handler) - handler = ChatJoinRequestHandler(self.callback_data_1, pass_chat_data=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(chat_join_request_update) - assert self.test_flag - - dp.remove_handler(handler) - handler = ChatJoinRequestHandler( - self.callback_data_2, pass_chat_data=True, pass_user_data=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(chat_join_request_update) - assert self.test_flag - - def test_pass_job_or_update_queue(self, dp, chat_join_request_update): - handler = ChatJoinRequestHandler(self.callback_queue_1, pass_job_queue=True) - dp.add_handler(handler) - - dp.process_update(chat_join_request_update) - assert self.test_flag - - dp.remove_handler(handler) - handler = ChatJoinRequestHandler(self.callback_queue_1, pass_update_queue=True) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(chat_join_request_update) - assert self.test_flag - - dp.remove_handler(handler) - handler = ChatJoinRequestHandler( - self.callback_queue_2, pass_job_queue=True, pass_update_queue=True - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update(chat_join_request_update) - assert self.test_flag - def test_other_update_types(self, false_update): - handler = ChatJoinRequestHandler(self.callback_basic) + handler = ChatJoinRequestHandler(self.callback_context) assert not handler.check_update(false_update) assert not handler.check_update(True) - def test_context(self, cdp, chat_join_request_update): + def test_context(self, dp, chat_join_request_update): handler = ChatJoinRequestHandler(callback=self.callback_context) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(chat_join_request_update) + dp.process_update(chat_join_request_update) assert self.test_flag diff --git a/tests/test_chatmemberhandler.py b/tests/test_chatmemberhandler.py index 29d76e4bf..bf24698b4 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 @@ class TestChatMemberHandler: 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 @@ class TestChatMemberHandler: 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 @@ class TestChatMemberHandler: ): 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 @@ class TestChatMemberHandler: 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 6cebdaf05..517db8116 100644 --- a/tests/test_choseninlineresulthandler.py +++ b/tests/test_choseninlineresulthandler.py @@ -87,8 +87,8 @@ class TestChosenInlineResultHandler: 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 @@ class TestChosenInlineResultHandler: 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 @@ class TestChosenInlineResultHandler: 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 e14e611ff..15a6d3d2a 100644 --- a/tests/test_commandhandler.py +++ b/tests/test_commandhandler.py @@ -20,8 +20,6 @@ import re 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 @@ class BaseTest: 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 @@ class BaseTest: 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 @@ class TestCommandHandler(BaseTest): 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 @@ class TestCommandHandler(BaseTest): 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 @@ class TestCommandHandler(BaseTest): 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 @@ class TestCommandHandler(BaseTest): 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 @@ class TestCommandHandler(BaseTest): 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 @@ class TestPrefixHandler(BaseTest): 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 @@ class TestPrefixHandler(BaseTest): 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 @@ class TestPrefixHandler(BaseTest): 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 5e48757f8..5e6f37b3d 100644 --- a/tests/test_conversationhandler.py +++ b/tests/test_conversationhandler.py @@ -170,45 +170,45 @@ class TestConversationHandler: # 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 @@ class TestConversationHandler: # 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 @@ class TestConversationHandler: 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 @@ class TestConversationHandler: 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 @@ class TestConversationHandler: 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 @@ class TestConversationHandler: 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 @@ class TestConversationHandler: 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 @@ class TestConversationHandler: 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 @@ class TestConversationHandler: 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 @@ class TestConversationHandler: fallbacks=self.fallbacks, conversation_timeout=0.5, ) - cdp.add_handler(handler) + dp.add_handler(handler) # CommandHandler timeout message = Message( @@ -1246,10 +1246,10 @@ class TestConversationHandler: ], 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 @@ class TestConversationHandler: 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 @@ class TestConversationHandler: # | 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 @@ class TestConversationHandler: ) 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 0b705e835..19297b0f9 100644 --- a/tests/test_defaults.py +++ b/tests/test_defaults.py @@ -30,7 +30,7 @@ class TestDefault: 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 f89534f13..7f28dfa44 100644 --- a/tests/test_dispatcher.py +++ b/tests/test_dispatcher.py @@ -72,16 +72,13 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: ), ) 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 @@ class TestDispatcher: 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 + 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 - cdp.persistence.test_flag_bot_data = False - cdp.persistence.test_flag_user_data = False - cdp.persistence.test_flag_chat_data = False + 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 aca3e61a5..fc0be644a 100644 --- a/tests/test_inlinequeryhandler.py +++ b/tests/test_inlinequeryhandler.py @@ -94,29 +94,6 @@ class TestInlineQueryHandler: 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 @@ class TestInlineQueryHandler: 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 - - dp.remove_handler(handler) - handler = InlineQueryHandler(self.callback_data_1, pass_chat_data=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_data_2, pass_chat_data=True, pass_user_data=True - ) - 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 - ) - 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) + handler = InlineQueryHandler(self.callback_context) assert not handler.check_update(false_update) - def test_context(self, cdp, inline_query): + def test_context(self, dp, inline_query): handler = InlineQueryHandler(self.callback_context) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(inline_query) + dp.process_update(inline_query) assert self.test_flag - def test_context_pattern(self, cdp, inline_query): + def test_context_pattern(self, dp, inline_query): handler = InlineQueryHandler( self.callback_context_pattern, pattern=r'(?P.*)est(?P.*)' ) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(inline_query) + dp.process_update(inline_query) assert self.test_flag - cdp.remove_handler(handler) + dp.remove_handler(handler) handler = InlineQueryHandler(self.callback_context_pattern, pattern=r'(t)est(.*)') - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update(inline_query) + dp.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 74f32717b..bb9d979f5 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -66,20 +66,20 @@ class TestJobQueue: 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 @@ class TestJobQueue: ): 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 @@ class TestJobQueue: 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 @@ class TestJobQueue: 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 @@ class TestJobQueue: 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 @@ class TestJobQueue: 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 @@ class TestJobQueue: 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 @@ class TestJobQueue: 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 d0e6666d8..333cd54c7 100644 --- a/tests/test_messagehandler.py +++ b/tests/test_messagehandler.py @@ -20,7 +20,6 @@ import re 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 @@ class TestMessageHandler: 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 @@ class TestMessageHandler: 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 @@ class TestMessageHandler: 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 @@ class TestMessageHandler: & ~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 7304ed7e4..159025de9 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -342,7 +342,7 @@ class TestBasePersistence: @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 @@ class TestBasePersistence: 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 @@ class TestBasePersistence: 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 @@ class TestBasePersistence: @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 @@ class TestBasePersistence: 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 @@ class TestBasePersistence: 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 @@ class TestBasePersistence: 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 @@ class TestPicklePersistence: 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 @@ class TestPicklePersistence: 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 @@ class TestPicklePersistence: 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 @@ class TestPicklePersistence: 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 @@ class TestPicklePersistence: 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 @@ class TestPicklePersistence: 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 @@ class TestDictPersistence: 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 @@ class TestDictPersistence: 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 @@ class TestDictPersistence: 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 @@ class TestDictPersistence: 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 @@ class TestDictPersistence: 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 775cd87a0..a0704d700 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 @@ class TestPollAnswerHandler: 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 @@ class TestPollAnswerHandler: 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 a243f0bbe..83fafee93 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 @@ class TestPollHandler: 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 @@ class TestPollHandler: 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 79c1844e0..4635e2928 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 @@ class TestPreCheckoutQueryHandler: 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 @@ class TestPreCheckoutQueryHandler: 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 deleted file mode 100644 index 1bacb0129..000000000 --- a/tests/test_regexhandler.py +++ /dev/null @@ -1,289 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015-2022 -# 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 3bf699afc..f43e7f9ab 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 @@ class TestShippingQueryHandler: 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 @@ class TestShippingQueryHandler: 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 3dd74f2a3..6aca82110 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 @@ class TestStringCommandHandler: 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 @@ class TestStringCommandHandler: 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 d6674f5dc..472ac36b9 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 @@ class TestStringRegexHandler: 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 @@ class TestStringRegexHandler: 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 @@ class TestStringRegexHandler: 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 68e8f59f3..70398eae2 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 @@ class TestTypeHandler: 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 @@ class TestTypeHandler: ) 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 @@ class TestTypeHandler: 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 - ) - dp.add_handler(handler) - - self.test_flag = False - dp.process_update({'a': 1, 'b': 2}) - assert self.test_flag - - def test_context(self, cdp): + def test_context(self, dp): handler = TypeHandler(dict, self.callback_context) - cdp.add_handler(handler) + dp.add_handler(handler) - cdp.process_update({'a': 1, 'b': 2}) + dp.process_update({'a': 1, 'b': 2}) assert self.test_flag diff --git a/tests/test_updater.py b/tests/test_updater.py index 9aba2fc07..f8eaec2a7 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -106,11 +106,11 @@ class TestUpdater: 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 @@ class TestUpdater: 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 @@ class TestUpdater: 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 @@ class TestUpdater: 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):