mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2025-01-18 15:20:42 +01:00
Drop Non-CallbackContext API (#2617)
This commit is contained in:
parent
4d493aff16
commit
641f931f19
47 changed files with 398 additions and 2971 deletions
|
@ -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:
|
|
|
@ -34,7 +34,6 @@ Handlers
|
||||||
telegram.ext.pollhandler
|
telegram.ext.pollhandler
|
||||||
telegram.ext.precheckoutqueryhandler
|
telegram.ext.precheckoutqueryhandler
|
||||||
telegram.ext.prefixhandler
|
telegram.ext.prefixhandler
|
||||||
telegram.ext.regexhandler
|
|
||||||
telegram.ext.shippingqueryhandler
|
telegram.ext.shippingqueryhandler
|
||||||
telegram.ext.stringcommandhandler
|
telegram.ext.stringcommandhandler
|
||||||
telegram.ext.stringregexhandler
|
telegram.ext.stringregexhandler
|
||||||
|
|
|
@ -35,7 +35,6 @@ from .inlinequeryhandler import InlineQueryHandler
|
||||||
from .filters import BaseFilter, MessageFilter, UpdateFilter, Filters
|
from .filters import BaseFilter, MessageFilter, UpdateFilter, Filters
|
||||||
from .messagehandler import MessageHandler
|
from .messagehandler import MessageHandler
|
||||||
from .commandhandler import CommandHandler, PrefixHandler
|
from .commandhandler import CommandHandler, PrefixHandler
|
||||||
from .regexhandler import RegexHandler
|
|
||||||
from .stringcommandhandler import StringCommandHandler
|
from .stringcommandhandler import StringCommandHandler
|
||||||
from .stringregexhandler import StringRegexHandler
|
from .stringregexhandler import StringRegexHandler
|
||||||
from .typehandler import TypeHandler
|
from .typehandler import TypeHandler
|
||||||
|
@ -84,7 +83,6 @@ __all__ = (
|
||||||
'PollHandler',
|
'PollHandler',
|
||||||
'PreCheckoutQueryHandler',
|
'PreCheckoutQueryHandler',
|
||||||
'PrefixHandler',
|
'PrefixHandler',
|
||||||
'RegexHandler',
|
|
||||||
'ShippingQueryHandler',
|
'ShippingQueryHandler',
|
||||||
'StringCommandHandler',
|
'StringCommandHandler',
|
||||||
'StringRegexHandler',
|
'StringRegexHandler',
|
||||||
|
|
|
@ -108,10 +108,6 @@ class CallbackContext(Generic[UD, CD, BD]):
|
||||||
Args:
|
Args:
|
||||||
dispatcher (:class:`telegram.ext.Dispatcher`):
|
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._dispatcher = dispatcher
|
||||||
self._chat_id_and_data: Optional[Tuple[int, CD]] = None
|
self._chat_id_and_data: Optional[Tuple[int, CD]] = None
|
||||||
self._user_id_and_data: Optional[Tuple[int, UD]] = None
|
self._user_id_and_data: Optional[Tuple[int, UD]] = None
|
||||||
|
|
|
@ -22,7 +22,6 @@ import re
|
||||||
from typing import (
|
from typing import (
|
||||||
TYPE_CHECKING,
|
TYPE_CHECKING,
|
||||||
Callable,
|
Callable,
|
||||||
Dict,
|
|
||||||
Match,
|
Match,
|
||||||
Optional,
|
Optional,
|
||||||
Pattern,
|
Pattern,
|
||||||
|
@ -49,13 +48,6 @@ class CallbackQueryHandler(Handler[Update, CCT]):
|
||||||
Read the documentation of the ``re`` module for more information.
|
Read the documentation of the ``re`` module for more information.
|
||||||
|
|
||||||
Note:
|
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
|
* 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
|
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
|
found. This is the case when either a malicious client tempered with the
|
||||||
|
@ -72,22 +64,10 @@ class CallbackQueryHandler(Handler[Update, CCT]):
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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 (:obj:`str` | `Pattern` | :obj:`callable` | :obj:`type`, optional):
|
||||||
Pattern to test :attr:`telegram.CallbackQuery.data` against. If a string or a regex
|
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
|
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
|
.. versionchanged:: 13.6
|
||||||
Added support for arbitrary callback data.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
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
|
pattern (`Pattern` | :obj:`callable` | :obj:`type`): Optional. Regex pattern, callback or
|
||||||
type to test :attr:`telegram.CallbackQuery.data` against.
|
type to test :attr:`telegram.CallbackQuery.data` against.
|
||||||
|
|
||||||
.. versionchanged:: 13.6
|
.. versionchanged:: 13.6
|
||||||
Added support for arbitrary callback data.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ('pattern', 'pass_groups', 'pass_groupdict')
|
__slots__ = ('pattern',)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
callback: Callable[[Update, CCT], RT],
|
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,
|
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,
|
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
callback,
|
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,
|
run_async=run_async,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -173,8 +117,6 @@ class CallbackQueryHandler(Handler[Update, CCT]):
|
||||||
pattern = re.compile(pattern)
|
pattern = re.compile(pattern)
|
||||||
|
|
||||||
self.pattern = pattern
|
self.pattern = pattern
|
||||||
self.pass_groups = pass_groups
|
|
||||||
self.pass_groupdict = pass_groupdict
|
|
||||||
|
|
||||||
def check_update(self, update: object) -> Optional[Union[bool, object]]:
|
def check_update(self, update: object) -> Optional[Union[bool, object]]:
|
||||||
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
||||||
|
@ -202,25 +144,6 @@ class CallbackQueryHandler(Handler[Update, CCT]):
|
||||||
return True
|
return True
|
||||||
return None
|
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(
|
def collect_additional_context(
|
||||||
self,
|
self,
|
||||||
context: CCT,
|
context: CCT,
|
||||||
|
|
|
@ -28,15 +28,6 @@ from .utils.types import CCT
|
||||||
class ChatJoinRequestHandler(Handler[Update, CCT]):
|
class ChatJoinRequestHandler(Handler[Update, CCT]):
|
||||||
"""Handler class to handle Telegram updates that contain a chat join request.
|
"""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:
|
Warning:
|
||||||
When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom
|
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.
|
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
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -32,15 +32,6 @@ class ChatMemberHandler(Handler[Update, CCT]):
|
||||||
|
|
||||||
.. versionadded:: 13.4
|
.. 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:
|
Warning:
|
||||||
When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom
|
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.
|
attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info.
|
||||||
|
@ -48,9 +39,7 @@ class ChatMemberHandler(Handler[Update, CCT]):
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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
|
:attr:`CHAT_MEMBER` or :attr:`ANY_CHAT_MEMBER` to specify if this handler should handle
|
||||||
only updates with :attr:`telegram.Update.my_chat_member`,
|
only updates with :attr:`telegram.Update.my_chat_member`,
|
||||||
:attr:`telegram.Update.chat_member` or both. Defaults to :attr:`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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
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
|
chat_member_types (:obj:`int`, optional): Specifies if this handler should handle
|
||||||
only updates with :attr:`telegram.Update.my_chat_member`,
|
only updates with :attr:`telegram.Update.my_chat_member`,
|
||||||
:attr:`telegram.Update.chat_member` or both.
|
: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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -107,18 +72,10 @@ class ChatMemberHandler(Handler[Update, CCT]):
|
||||||
self,
|
self,
|
||||||
callback: Callable[[Update, CCT], RT],
|
callback: Callable[[Update, CCT], RT],
|
||||||
chat_member_types: int = MY_CHAT_MEMBER,
|
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,
|
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
callback,
|
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,
|
run_async=run_async,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -35,15 +35,6 @@ if TYPE_CHECKING:
|
||||||
class ChosenInlineResultHandler(Handler[Update, CCT]):
|
class ChosenInlineResultHandler(Handler[Update, CCT]):
|
||||||
"""Handler class to handle Telegram updates that contain a chosen inline result.
|
"""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:
|
Warning:
|
||||||
When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom
|
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.
|
attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info.
|
||||||
|
@ -51,28 +42,10 @@ class ChosenInlineResultHandler(Handler[Update, CCT]):
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
pattern (:obj:`str` | `Pattern`, optional): Regex pattern. If not :obj:`None`, ``re.match``
|
pattern (:obj:`str` | `Pattern`, optional): Regex pattern. If not :obj:`None`, ``re.match``
|
||||||
|
@ -84,14 +57,6 @@ class ChosenInlineResultHandler(Handler[Update, CCT]):
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
pattern (`Pattern`): Optional. Regex pattern to test
|
pattern (`Pattern`): Optional. Regex pattern to test
|
||||||
:attr:`telegram.ChosenInlineResult.result_id` against.
|
:attr:`telegram.ChosenInlineResult.result_id` against.
|
||||||
|
@ -105,19 +70,11 @@ class ChosenInlineResultHandler(Handler[Update, CCT]):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
callback: Callable[[Update, 'CallbackContext'], RT],
|
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,
|
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
|
||||||
pattern: Union[str, Pattern] = None,
|
pattern: Union[str, Pattern] = None,
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
callback,
|
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,
|
run_async=run_async,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,10 @@
|
||||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||||
"""This module contains the CommandHandler and PrefixHandler classes."""
|
"""This module contains the CommandHandler and PrefixHandler classes."""
|
||||||
import re
|
import re
|
||||||
import warnings
|
|
||||||
from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple, TypeVar, Union
|
from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple, TypeVar, Union
|
||||||
|
|
||||||
from telegram import MessageEntity, Update
|
from telegram import MessageEntity, Update
|
||||||
from telegram.ext import BaseFilter, Filters
|
from telegram.ext import BaseFilter, Filters
|
||||||
from telegram.utils.deprecate import TelegramDeprecationWarning
|
|
||||||
from telegram.utils.types import SLT
|
from telegram.utils.types import SLT
|
||||||
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE
|
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE
|
||||||
|
|
||||||
|
@ -49,13 +47,6 @@ class CommandHandler(Handler[Update, CCT]):
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
* :class:`CommandHandler` does *not* handle (edited) channel posts.
|
* :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:
|
Warning:
|
||||||
When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom
|
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
|
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
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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.BaseFilter`. Standard filters can be found in
|
||||||
:class:`telegram.ext.filters.Filters`. Filters can be combined using bitwise
|
:class:`telegram.ext.filters.Filters`. Filters can be combined using bitwise
|
||||||
operators (& for and, | for or, ~ for not).
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
|
@ -115,42 +79,20 @@ class CommandHandler(Handler[Update, CCT]):
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
callback (:obj:`callable`): The callback function for this handler.
|
||||||
filters (:class:`telegram.ext.BaseFilter`): Optional. Only allow updates with these
|
filters (:class:`telegram.ext.BaseFilter`): Optional. Only allow updates with these
|
||||||
Filters.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ('command', 'filters', 'pass_args')
|
__slots__ = ('command', 'filters')
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
command: SLT[str],
|
command: SLT[str],
|
||||||
callback: Callable[[Update, CCT], RT],
|
callback: Callable[[Update, CCT], RT],
|
||||||
filters: BaseFilter = None,
|
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,
|
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
callback,
|
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,
|
run_async=run_async,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -167,16 +109,6 @@ class CommandHandler(Handler[Update, CCT]):
|
||||||
else:
|
else:
|
||||||
self.filters = Filters.update.messages
|
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(
|
def check_update(
|
||||||
self, update: object
|
self, update: object
|
||||||
) -> Optional[Union[bool, Tuple[List[str], Optional[Union[bool, Dict]]]]]:
|
) -> Optional[Union[bool, Tuple[List[str], Optional[Union[bool, Dict]]]]]:
|
||||||
|
@ -216,20 +148,6 @@ class CommandHandler(Handler[Update, CCT]):
|
||||||
return False
|
return False
|
||||||
return None
|
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(
|
def collect_additional_context(
|
||||||
self,
|
self,
|
||||||
context: CCT,
|
context: CCT,
|
||||||
|
@ -282,13 +200,6 @@ class PrefixHandler(CommandHandler):
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
* :class:`PrefixHandler` does *not* handle (edited) channel posts.
|
* :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:
|
Warning:
|
||||||
When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom
|
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.
|
The command or list of commands this handler should listen for.
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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.BaseFilter`. Standard filters can be found in
|
||||||
:class:`telegram.ext.filters.Filters`. Filters can be combined using bitwise
|
:class:`telegram.ext.filters.Filters`. Filters can be combined using bitwise
|
||||||
operators (& for and, | for or, ~ for not).
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
|
@ -339,16 +227,6 @@ class PrefixHandler(CommandHandler):
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
callback (:obj:`callable`): The callback function for this handler.
|
||||||
filters (:class:`telegram.ext.BaseFilter`): Optional. Only allow updates with these
|
filters (:class:`telegram.ext.BaseFilter`): Optional. Only allow updates with these
|
||||||
Filters.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -362,11 +240,6 @@ class PrefixHandler(CommandHandler):
|
||||||
command: SLT[str],
|
command: SLT[str],
|
||||||
callback: Callable[[Update, CCT], RT],
|
callback: Callable[[Update, CCT], RT],
|
||||||
filters: BaseFilter = None,
|
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,
|
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
|
||||||
):
|
):
|
||||||
|
|
||||||
|
@ -378,12 +251,6 @@ class PrefixHandler(CommandHandler):
|
||||||
'nocommand',
|
'nocommand',
|
||||||
callback,
|
callback,
|
||||||
filters=filters,
|
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,
|
run_async=run_async,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ class _ConversationTimeoutContext:
|
||||||
conversation_key: Tuple[int, ...],
|
conversation_key: Tuple[int, ...],
|
||||||
update: Update,
|
update: Update,
|
||||||
dispatcher: 'Dispatcher',
|
dispatcher: 'Dispatcher',
|
||||||
callback_context: Optional[CallbackContext],
|
callback_context: CallbackContext,
|
||||||
):
|
):
|
||||||
self.conversation_key = conversation_key
|
self.conversation_key = conversation_key
|
||||||
self.update = update
|
self.update = update
|
||||||
|
@ -486,7 +486,7 @@ class ConversationHandler(Handler[Update, CCT]):
|
||||||
new_state: object,
|
new_state: object,
|
||||||
dispatcher: 'Dispatcher',
|
dispatcher: 'Dispatcher',
|
||||||
update: Update,
|
update: Update,
|
||||||
context: Optional[CallbackContext],
|
context: CallbackContext,
|
||||||
conversation_key: Tuple[int, ...],
|
conversation_key: Tuple[int, ...],
|
||||||
) -> None:
|
) -> None:
|
||||||
if new_state != self.END:
|
if new_state != self.END:
|
||||||
|
@ -598,7 +598,7 @@ class ConversationHandler(Handler[Update, CCT]):
|
||||||
update: Update,
|
update: Update,
|
||||||
dispatcher: 'Dispatcher',
|
dispatcher: 'Dispatcher',
|
||||||
check_result: CheckUpdateType,
|
check_result: CheckUpdateType,
|
||||||
context: CallbackContext = None,
|
context: CallbackContext,
|
||||||
) -> Optional[object]:
|
) -> Optional[object]:
|
||||||
"""Send the update to the callback for the current state and Handler
|
"""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.
|
handler, and the handler's check result.
|
||||||
update (:class:`telegram.Update`): Incoming telegram update.
|
update (:class:`telegram.Update`): Incoming telegram update.
|
||||||
dispatcher (:class:`telegram.ext.Dispatcher`): Dispatcher that originated the 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.
|
the dispatcher.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
update = cast(Update, update) # for mypy
|
|
||||||
conversation_key, handler, check_result = check_result # type: ignore[assignment,misc]
|
conversation_key, handler, check_result = check_result # type: ignore[assignment,misc]
|
||||||
raise_dp_handler_stop = False
|
raise_dp_handler_stop = False
|
||||||
|
|
||||||
|
@ -690,14 +689,10 @@ class ConversationHandler(Handler[Update, CCT]):
|
||||||
if self.persistent and self.persistence and self.name:
|
if self.persistent and self.persistence and self.name:
|
||||||
self.persistence.update_conversation(self.name, key, new_state)
|
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!')
|
self.logger.debug('conversation timeout was triggered!')
|
||||||
|
|
||||||
# Backward compatibility with bots that do not use CallbackContext
|
job = cast('Job', context.job)
|
||||||
if isinstance(context, CallbackContext):
|
|
||||||
job = context.job
|
|
||||||
ctxt = cast(_ConversationTimeoutContext, job.context) # type: ignore[union-attr]
|
|
||||||
else:
|
|
||||||
ctxt = cast(_ConversationTimeoutContext, job.context)
|
ctxt = cast(_ConversationTimeoutContext, job.context)
|
||||||
|
|
||||||
callback_context = ctxt.callback_context
|
callback_context = ctxt.callback_context
|
||||||
|
|
|
@ -135,9 +135,6 @@ class Dispatcher(Generic[CCT, UD, CD, BD]):
|
||||||
``@run_async`` decorator and :meth:`run_async`. Defaults to 4.
|
``@run_async`` decorator and :meth:`run_async`. Defaults to 4.
|
||||||
persistence (:class:`telegram.ext.BasePersistence`, optional): The persistence class to
|
persistence (:class:`telegram.ext.BasePersistence`, optional): The persistence class to
|
||||||
store data that should be persistent over restarts.
|
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
|
context_types (:class:`telegram.ext.ContextTypes`, optional): Pass an instance
|
||||||
of :class:`telegram.ext.ContextTypes` to customize the types used in the
|
of :class:`telegram.ext.ContextTypes` to customize the types used in the
|
||||||
``context`` interface. If not passed, the defaults documented in
|
``context`` interface. If not passed, the defaults documented in
|
||||||
|
@ -168,7 +165,6 @@ class Dispatcher(Generic[CCT, UD, CD, BD]):
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
'workers',
|
'workers',
|
||||||
'persistence',
|
'persistence',
|
||||||
'use_context',
|
|
||||||
'update_queue',
|
'update_queue',
|
||||||
'job_queue',
|
'job_queue',
|
||||||
'user_data',
|
'user_data',
|
||||||
|
@ -203,7 +199,6 @@ class Dispatcher(Generic[CCT, UD, CD, BD]):
|
||||||
exception_event: Event = None,
|
exception_event: Event = None,
|
||||||
job_queue: 'JobQueue' = None,
|
job_queue: 'JobQueue' = None,
|
||||||
persistence: BasePersistence = None,
|
persistence: BasePersistence = None,
|
||||||
use_context: bool = True,
|
|
||||||
):
|
):
|
||||||
...
|
...
|
||||||
|
|
||||||
|
@ -216,7 +211,6 @@ class Dispatcher(Generic[CCT, UD, CD, BD]):
|
||||||
exception_event: Event = None,
|
exception_event: Event = None,
|
||||||
job_queue: 'JobQueue' = None,
|
job_queue: 'JobQueue' = None,
|
||||||
persistence: BasePersistence = None,
|
persistence: BasePersistence = None,
|
||||||
use_context: bool = True,
|
|
||||||
context_types: ContextTypes[CCT, UD, CD, BD] = None,
|
context_types: ContextTypes[CCT, UD, CD, BD] = None,
|
||||||
):
|
):
|
||||||
...
|
...
|
||||||
|
@ -229,23 +223,14 @@ class Dispatcher(Generic[CCT, UD, CD, BD]):
|
||||||
exception_event: Event = None,
|
exception_event: Event = None,
|
||||||
job_queue: 'JobQueue' = None,
|
job_queue: 'JobQueue' = None,
|
||||||
persistence: BasePersistence = None,
|
persistence: BasePersistence = None,
|
||||||
use_context: bool = True,
|
|
||||||
context_types: ContextTypes[CCT, UD, CD, BD] = None,
|
context_types: ContextTypes[CCT, UD, CD, BD] = None,
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.update_queue = update_queue
|
self.update_queue = update_queue
|
||||||
self.job_queue = job_queue
|
self.job_queue = job_queue
|
||||||
self.workers = workers
|
self.workers = workers
|
||||||
self.use_context = use_context
|
|
||||||
self.context_types = cast(ContextTypes[CCT, UD, CD, BD], context_types or ContextTypes())
|
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:
|
if self.workers < 1:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
'Asynchronous callbacks can not be processed without at least one worker thread.'
|
'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]:
|
for handler in self.handlers[group]:
|
||||||
check = handler.check_update(update)
|
check = handler.check_update(update)
|
||||||
if check is not None and check is not False:
|
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 = self.context_types.context.from_update(update, self)
|
||||||
context.refresh_data()
|
context.refresh_data()
|
||||||
handled = True
|
handled = True
|
||||||
|
@ -743,16 +728,12 @@ class Dispatcher(Generic[CCT, UD, CD, BD]):
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function for this error handler. Will be
|
callback (:obj:`callable`): The callback function for this error handler. Will be
|
||||||
called when an error is raised. Callback signature for context based API:
|
called when an error is raised.
|
||||||
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
``def callback(update: object, context: CallbackContext)``
|
|
||||||
|
|
||||||
The error that happened will be present in context.error.
|
The error that happened will be present in context.error.
|
||||||
run_async (:obj:`bool`, optional): Whether this handlers callback should be run
|
run_async (:obj:`bool`, optional): Whether this handlers callback should be run
|
||||||
asynchronously using :meth:`run_async`. Defaults to :obj:`False`.
|
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:
|
if callback in self.error_handlers:
|
||||||
self.logger.debug('The callback is already registered as an error handler. Ignoring.')
|
self.logger.debug('The callback is already registered as an error handler. Ignoring.')
|
||||||
|
@ -789,7 +770,6 @@ class Dispatcher(Generic[CCT, UD, CD, BD]):
|
||||||
|
|
||||||
if self.error_handlers:
|
if self.error_handlers:
|
||||||
for callback, run_async in self.error_handlers.items(): # pylint: disable=W0621
|
for callback, run_async in self.error_handlers.items(): # pylint: disable=W0621
|
||||||
if self.use_context:
|
|
||||||
context = self.context_types.context.from_error(
|
context = self.context_types.context.from_error(
|
||||||
update, error, self, async_args=async_args, async_kwargs=async_kwargs
|
update, error, self, async_args=async_args, async_kwargs=async_kwargs
|
||||||
)
|
)
|
||||||
|
@ -797,11 +777,6 @@ class Dispatcher(Generic[CCT, UD, CD, BD]):
|
||||||
self.run_async(callback, update, context, update=update)
|
self.run_async(callback, update, context, update=update)
|
||||||
else:
|
else:
|
||||||
callback(update, context)
|
callback(update, context)
|
||||||
else:
|
|
||||||
if run_async:
|
|
||||||
self.run_async(callback, self.bot, update, error, update=update)
|
|
||||||
else:
|
|
||||||
callback(self.bot, update, error)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.logger.exception(
|
self.logger.exception(
|
||||||
|
|
|
@ -18,9 +18,8 @@
|
||||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
# 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."""
|
"""This module contains the base class for handlers as used by the Dispatcher."""
|
||||||
from abc import ABC, abstractmethod
|
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.ext.utils.promise import Promise
|
||||||
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE
|
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE
|
||||||
from telegram.ext.utils.types import CCT
|
from telegram.ext.utils.types import CCT
|
||||||
|
@ -35,15 +34,6 @@ UT = TypeVar('UT')
|
||||||
class Handler(Generic[UT, CCT], ABC):
|
class Handler(Generic[UT, CCT], ABC):
|
||||||
"""The base class for all update handlers. Create custom handlers by inheriting from it.
|
"""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:
|
Warning:
|
||||||
When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom
|
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.
|
attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info.
|
||||||
|
@ -51,68 +41,30 @@ class Handler(Generic[UT, CCT], ABC):
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
'callback',
|
'callback',
|
||||||
'pass_update_queue',
|
|
||||||
'pass_job_queue',
|
|
||||||
'pass_user_data',
|
|
||||||
'pass_chat_data',
|
|
||||||
'run_async',
|
'run_async',
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
callback: Callable[[UT, CCT], RT],
|
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,
|
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
|
||||||
):
|
):
|
||||||
self.callback = callback
|
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
|
self.run_async = run_async
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -140,7 +92,7 @@ class Handler(Generic[UT, CCT], ABC):
|
||||||
update: UT,
|
update: UT,
|
||||||
dispatcher: 'Dispatcher',
|
dispatcher: 'Dispatcher',
|
||||||
check_result: object,
|
check_result: object,
|
||||||
context: CCT = None,
|
context: CCT,
|
||||||
) -> Union[RT, Promise]:
|
) -> Union[RT, Promise]:
|
||||||
"""
|
"""
|
||||||
This method is called if it was determined that an update should indeed
|
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.
|
update (:obj:`str` | :class:`telegram.Update`): The update to be handled.
|
||||||
dispatcher (:class:`telegram.ext.Dispatcher`): The calling dispatcher.
|
dispatcher (:class:`telegram.ext.Dispatcher`): The calling dispatcher.
|
||||||
check_result (:obj:`obj`): The result from :attr:`check_update`.
|
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.
|
the dispatcher.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -165,19 +117,11 @@ class Handler(Generic[UT, CCT], ABC):
|
||||||
):
|
):
|
||||||
run_async = True
|
run_async = True
|
||||||
|
|
||||||
if context:
|
|
||||||
self.collect_additional_context(context, update, dispatcher, check_result)
|
self.collect_additional_context(context, update, dispatcher, check_result)
|
||||||
if run_async:
|
if run_async:
|
||||||
return dispatcher.run_async(self.callback, update, context, update=update)
|
return dispatcher.run_async(self.callback, update, context, update=update)
|
||||||
return self.callback(update, context)
|
return self.callback(update, context)
|
||||||
|
|
||||||
optional_args = self.collect_optional_args(dispatcher, update, 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
|
|
||||||
|
|
||||||
def collect_additional_context(
|
def collect_additional_context(
|
||||||
self,
|
self,
|
||||||
context: CCT,
|
context: CCT,
|
||||||
|
@ -194,41 +138,3 @@ class Handler(Generic[UT, CCT], ABC):
|
||||||
check_result: The result (return value) from :attr:`check_update`.
|
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
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ import re
|
||||||
from typing import (
|
from typing import (
|
||||||
TYPE_CHECKING,
|
TYPE_CHECKING,
|
||||||
Callable,
|
Callable,
|
||||||
Dict,
|
|
||||||
Match,
|
Match,
|
||||||
Optional,
|
Optional,
|
||||||
Pattern,
|
Pattern,
|
||||||
|
@ -48,15 +47,6 @@ class InlineQueryHandler(Handler[Update, CCT]):
|
||||||
Handler class to handle Telegram inline queries. Optionally based on a regex. Read the
|
Handler class to handle Telegram inline queries. Optionally based on a regex. Read the
|
||||||
documentation of the ``re`` module for more information.
|
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:
|
Warning:
|
||||||
* When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom
|
* 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.
|
attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info.
|
||||||
|
@ -67,22 +57,10 @@ class InlineQueryHandler(Handler[Update, CCT]):
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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`,
|
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
|
``re.match`` is used on :attr:`telegram.InlineQuery.query` to determine if an update
|
||||||
should be handled by this handler.
|
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`.
|
handle inline queries with the appropriate :attr:`telegram.InlineQuery.chat_type`.
|
||||||
|
|
||||||
.. versionadded:: 13.5
|
.. 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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
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
|
pattern (:obj:`str` | :obj:`Pattern`): Optional. Regex pattern to test
|
||||||
:attr:`telegram.InlineQuery.query` against.
|
:attr:`telegram.InlineQuery.query` against.
|
||||||
chat_types (List[:obj:`str`], optional): List of allowed chat types.
|
chat_types (List[:obj:`str`], optional): List of allowed chat types.
|
||||||
|
|
||||||
.. versionadded:: 13.5
|
.. 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.
|
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__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
callback: Callable[[Update, CCT], RT],
|
callback: Callable[[Update, CCT], RT],
|
||||||
pass_update_queue: bool = False,
|
|
||||||
pass_job_queue: bool = False,
|
|
||||||
pattern: Union[str, Pattern] = None,
|
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,
|
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
|
||||||
chat_types: List[str] = None,
|
chat_types: List[str] = None,
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
callback,
|
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,
|
run_async=run_async,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -159,8 +101,6 @@ class InlineQueryHandler(Handler[Update, CCT]):
|
||||||
|
|
||||||
self.pattern = pattern
|
self.pattern = pattern
|
||||||
self.chat_types = chat_types
|
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]]:
|
def check_update(self, update: object) -> Optional[Union[bool, Match]]:
|
||||||
"""
|
"""
|
||||||
|
@ -187,25 +127,6 @@ class InlineQueryHandler(Handler[Update, CCT]):
|
||||||
return True
|
return True
|
||||||
return None
|
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(
|
def collect_additional_context(
|
||||||
self,
|
self,
|
||||||
context: CCT,
|
context: CCT,
|
||||||
|
|
|
@ -31,7 +31,6 @@ from telegram.ext.callbackcontext import CallbackContext
|
||||||
from telegram.utils.types import JSONDict
|
from telegram.utils.types import JSONDict
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from telegram import Bot
|
|
||||||
from telegram.ext import Dispatcher
|
from telegram.ext import Dispatcher
|
||||||
import apscheduler.job # noqa: F401
|
import apscheduler.job # noqa: F401
|
||||||
|
|
||||||
|
@ -64,10 +63,8 @@ class JobQueue:
|
||||||
logging.getLogger('apscheduler.executors.default').addFilter(aps_log_filter)
|
logging.getLogger('apscheduler.executors.default').addFilter(aps_log_filter)
|
||||||
self.scheduler.add_listener(self._dispatch_error, EVENT_JOB_ERROR)
|
self.scheduler.add_listener(self._dispatch_error, EVENT_JOB_ERROR)
|
||||||
|
|
||||||
def _build_args(self, job: 'Job') -> List[Union[CallbackContext, 'Bot', 'Job']]:
|
def _build_args(self, job: 'Job') -> List[CallbackContext]:
|
||||||
if self._dispatcher.use_context:
|
|
||||||
return [self._dispatcher.context_types.context.from_job(job, self._dispatcher)]
|
return [self._dispatcher.context_types.context.from_job(job, self._dispatcher)]
|
||||||
return [self._dispatcher.bot, job]
|
|
||||||
|
|
||||||
def _tz_now(self) -> datetime.datetime:
|
def _tz_now(self) -> datetime.datetime:
|
||||||
return datetime.datetime.now(self.scheduler.timezone)
|
return datetime.datetime.now(self.scheduler.timezone)
|
||||||
|
@ -145,12 +142,7 @@ class JobQueue:
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function that should be executed by the new
|
callback (:obj:`callable`): The callback function that should be executed by the new
|
||||||
job. Callback signature for context based API:
|
job. Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``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.
|
|
||||||
when (:obj:`int` | :obj:`float` | :obj:`datetime.timedelta` | \
|
when (:obj:`int` | :obj:`float` | :obj:`datetime.timedelta` | \
|
||||||
:obj:`datetime.datetime` | :obj:`datetime.time`):
|
:obj:`datetime.datetime` | :obj:`datetime.time`):
|
||||||
Time in or at which the job should run. This parameter will be interpreted
|
Time in or at which the job should run. This parameter will be interpreted
|
||||||
|
@ -220,12 +212,7 @@ class JobQueue:
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function that should be executed by the new
|
callback (:obj:`callable`): The callback function that should be executed by the new
|
||||||
job. Callback signature for context based API:
|
job. Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``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.
|
|
||||||
interval (:obj:`int` | :obj:`float` | :obj:`datetime.timedelta`): The interval in which
|
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
|
the job will run. If it is an :obj:`int` or a :obj:`float`, it will be interpreted
|
||||||
as seconds.
|
as seconds.
|
||||||
|
@ -315,12 +302,7 @@ class JobQueue:
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function that should be executed by the new
|
callback (:obj:`callable`): The callback function that should be executed by the new
|
||||||
job. Callback signature for context based API:
|
job. Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``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.
|
|
||||||
when (:obj:`datetime.time`): Time of day at which the job should run. If the timezone
|
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.
|
(``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
|
day (:obj:`int`): Defines the day of the month whereby the job would run. It should
|
||||||
|
@ -379,12 +361,7 @@ class JobQueue:
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function that should be executed by the new
|
callback (:obj:`callable`): The callback function that should be executed by the new
|
||||||
job. Callback signature for context based API:
|
job. Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``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.
|
|
||||||
time (:obj:`datetime.time`): Time of day at which the job should run. If the timezone
|
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.
|
(``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
|
days (Tuple[:obj:`int`], optional): Defines on which days of the week the job should
|
||||||
|
@ -434,12 +411,7 @@ class JobQueue:
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function that should be executed by the new
|
callback (:obj:`callable`): The callback function that should be executed by the new
|
||||||
job. Callback signature for context based API:
|
job. Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``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_kwargs (:obj:`dict`): Arbitrary keyword arguments. Used as arguments for
|
job_kwargs (:obj:`dict`): Arbitrary keyword arguments. Used as arguments for
|
||||||
``scheduler.add_job``.
|
``scheduler.add_job``.
|
||||||
context (:obj:`object`, optional): Additional data needed for the callback function.
|
context (:obj:`object`, optional): Additional data needed for the callback function.
|
||||||
|
@ -502,12 +474,7 @@ class Job:
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function that should be executed by the new job.
|
callback (:obj:`callable`): The callback function that should be executed by the new job.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``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.
|
|
||||||
context (:obj:`object`, optional): Additional data needed for the callback function. Can be
|
context (:obj:`object`, optional): Additional data needed for the callback function. Can be
|
||||||
accessed through ``job.context`` in the callback. Defaults to :obj:`None`.
|
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__``.
|
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:
|
def run(self, dispatcher: 'Dispatcher') -> None:
|
||||||
"""Executes the callback function independently of the jobs schedule."""
|
"""Executes the callback function independently of the jobs schedule."""
|
||||||
try:
|
try:
|
||||||
if dispatcher.use_context:
|
|
||||||
self.callback(dispatcher.context_types.context.from_job(self, dispatcher))
|
self.callback(dispatcher.context_types.context.from_job(self, dispatcher))
|
||||||
else:
|
|
||||||
self.callback(dispatcher.bot, self) # type: ignore[arg-type,call-arg]
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
try:
|
try:
|
||||||
dispatcher.dispatch_error(None, exc)
|
dispatcher.dispatch_error(None, exc)
|
||||||
|
|
|
@ -16,14 +16,11 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser Public License
|
# You should have received a copy of the GNU Lesser Public License
|
||||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||||
# TODO: Remove allow_edited
|
|
||||||
"""This module contains the MessageHandler class."""
|
"""This module contains the MessageHandler class."""
|
||||||
import warnings
|
|
||||||
from typing import TYPE_CHECKING, Callable, Dict, Optional, TypeVar, Union
|
from typing import TYPE_CHECKING, Callable, Dict, Optional, TypeVar, Union
|
||||||
|
|
||||||
from telegram import Update
|
from telegram import Update
|
||||||
from telegram.ext import BaseFilter, Filters
|
from telegram.ext import BaseFilter, Filters
|
||||||
from telegram.utils.deprecate import TelegramDeprecationWarning
|
|
||||||
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE
|
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE
|
||||||
|
|
||||||
from .handler import Handler
|
from .handler import Handler
|
||||||
|
@ -38,15 +35,6 @@ RT = TypeVar('RT')
|
||||||
class MessageHandler(Handler[Update, CCT]):
|
class MessageHandler(Handler[Update, CCT]):
|
||||||
"""Handler class to handle telegram messages. They might contain text, media or status updates.
|
"""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:
|
Warning:
|
||||||
When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom
|
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.
|
attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info.
|
||||||
|
@ -62,37 +50,10 @@ class MessageHandler(Handler[Update, CCT]):
|
||||||
argument.
|
argument.
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
|
@ -103,20 +64,6 @@ class MessageHandler(Handler[Update, CCT]):
|
||||||
filters (:obj:`Filter`): Only allow updates with these Filters. See
|
filters (:obj:`Filter`): Only allow updates with these Filters. See
|
||||||
:mod:`telegram.ext.filters` for a full list of all available filters.
|
:mod:`telegram.ext.filters` for a full list of all available filters.
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -127,60 +74,17 @@ class MessageHandler(Handler[Update, CCT]):
|
||||||
self,
|
self,
|
||||||
filters: BaseFilter,
|
filters: BaseFilter,
|
||||||
callback: Callable[[Update, CCT], RT],
|
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,
|
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
|
||||||
):
|
):
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
callback,
|
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,
|
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:
|
if filters is not None:
|
||||||
self.filters = Filters.update & filters
|
self.filters = Filters.update & filters
|
||||||
else:
|
else:
|
||||||
self.filters = Filters.update
|
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]]]:
|
def check_update(self, update: object) -> Optional[Union[bool, Dict[str, list]]]:
|
||||||
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
||||||
|
@ -192,7 +96,7 @@ class MessageHandler(Handler[Update, CCT]):
|
||||||
:obj:`bool`
|
:obj:`bool`
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(update, Update) and update.effective_message:
|
if isinstance(update, Update):
|
||||||
return self.filters(update)
|
return self.filters(update)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -28,15 +28,6 @@ from .utils.types import CCT
|
||||||
class PollAnswerHandler(Handler[Update, CCT]):
|
class PollAnswerHandler(Handler[Update, CCT]):
|
||||||
"""Handler class to handle Telegram updates that contain a poll answer.
|
"""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:
|
Warning:
|
||||||
When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom
|
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.
|
attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info.
|
||||||
|
@ -44,41 +35,15 @@ class PollAnswerHandler(Handler[Update, CCT]):
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -28,15 +28,6 @@ from .utils.types import CCT
|
||||||
class PollHandler(Handler[Update, CCT]):
|
class PollHandler(Handler[Update, CCT]):
|
||||||
"""Handler class to handle Telegram updates that contain a poll.
|
"""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:
|
Warning:
|
||||||
When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom
|
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.
|
attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info.
|
||||||
|
@ -44,41 +35,15 @@ class PollHandler(Handler[Update, CCT]):
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -28,15 +28,6 @@ from .utils.types import CCT
|
||||||
class PreCheckoutQueryHandler(Handler[Update, CCT]):
|
class PreCheckoutQueryHandler(Handler[Update, CCT]):
|
||||||
"""Handler class to handle Telegram PreCheckout callback queries.
|
"""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:
|
Warning:
|
||||||
When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom
|
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.
|
attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info.
|
||||||
|
@ -44,41 +35,15 @@ class PreCheckoutQueryHandler(Handler[Update, CCT]):
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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 <devs@python-telegram-bot.org>
|
|
||||||
#
|
|
||||||
# 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
|
|
|
@ -27,15 +27,6 @@ from .utils.types import CCT
|
||||||
class ShippingQueryHandler(Handler[Update, CCT]):
|
class ShippingQueryHandler(Handler[Update, CCT]):
|
||||||
"""Handler class to handle Telegram shipping callback queries.
|
"""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:
|
Warning:
|
||||||
When setting ``run_async`` to :obj:`True`, you cannot rely on adding custom
|
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.
|
attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info.
|
||||||
|
@ -43,41 +34,15 @@ class ShippingQueryHandler(Handler[Update, CCT]):
|
||||||
Args:
|
Args:
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
# along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||||
"""This module contains the StringCommandHandler class."""
|
"""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
|
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.
|
command (:obj:`str`): The command this handler should listen for.
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
command (:obj:`str`): The command this handler should listen for.
|
command (:obj:`str`): The command this handler should listen for.
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ('command', 'pass_args')
|
__slots__ = ('command',)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
command: str,
|
command: str,
|
||||||
callback: Callable[[str, CCT], RT],
|
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,
|
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
callback,
|
callback,
|
||||||
pass_update_queue=pass_update_queue,
|
|
||||||
pass_job_queue=pass_job_queue,
|
|
||||||
run_async=run_async,
|
run_async=run_async,
|
||||||
)
|
)
|
||||||
self.command = command
|
self.command = command
|
||||||
self.pass_args = pass_args
|
|
||||||
|
|
||||||
def check_update(self, update: object) -> Optional[List[str]]:
|
def check_update(self, update: object) -> Optional[List[str]]:
|
||||||
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
"""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 args[1:]
|
||||||
return None
|
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(
|
def collect_additional_context(
|
||||||
self,
|
self,
|
||||||
context: CCT,
|
context: CCT,
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
"""This module contains the StringRegexHandler class."""
|
"""This module contains the StringRegexHandler class."""
|
||||||
|
|
||||||
import re
|
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
|
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.
|
pattern (:obj:`str` | :obj:`Pattern`): The regex pattern.
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
: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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
pattern (:obj:`str` | :obj:`Pattern`): The regex pattern.
|
pattern (:obj:`str` | :obj:`Pattern`): The regex pattern.
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ('pass_groups', 'pass_groupdict', 'pattern')
|
__slots__ = ('pattern',)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
pattern: Union[str, Pattern],
|
pattern: Union[str, Pattern],
|
||||||
callback: Callable[[str, CCT], RT],
|
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,
|
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
callback,
|
callback,
|
||||||
pass_update_queue=pass_update_queue,
|
|
||||||
pass_job_queue=pass_job_queue,
|
|
||||||
run_async=run_async,
|
run_async=run_async,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -115,8 +81,6 @@ class StringRegexHandler(Handler[str, CCT]):
|
||||||
pattern = re.compile(pattern)
|
pattern = re.compile(pattern)
|
||||||
|
|
||||||
self.pattern = pattern
|
self.pattern = pattern
|
||||||
self.pass_groups = pass_groups
|
|
||||||
self.pass_groupdict = pass_groupdict
|
|
||||||
|
|
||||||
def check_update(self, update: object) -> Optional[Match]:
|
def check_update(self, update: object) -> Optional[Match]:
|
||||||
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
"""Determines whether an update should be passed to this handlers :attr:`callback`.
|
||||||
|
@ -134,24 +98,6 @@ class StringRegexHandler(Handler[str, CCT]):
|
||||||
return match
|
return match
|
||||||
return None
|
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(
|
def collect_additional_context(
|
||||||
self,
|
self,
|
||||||
context: CCT,
|
context: CCT,
|
||||||
|
|
|
@ -40,24 +40,12 @@ class TypeHandler(Handler[UT, CCT]):
|
||||||
determined by ``isinstance``
|
determined by ``isinstance``
|
||||||
callback (:obj:`callable`): The callback function for this handler. Will be called when
|
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.
|
:attr:`check_update` has determined that an update should be processed by this handler.
|
||||||
Callback signature for context based API:
|
Callback signature: ``def callback(update: Update, context: CallbackContext)``
|
||||||
|
|
||||||
``def callback(update: Update, context: CallbackContext)``
|
|
||||||
|
|
||||||
The return value of the callback is usually ignored except for the special case of
|
The return value of the callback is usually ignored except for the special case of
|
||||||
:class:`telegram.ext.ConversationHandler`.
|
:class:`telegram.ext.ConversationHandler`.
|
||||||
strict (:obj:`bool`, optional): Use ``type`` instead of ``isinstance``.
|
strict (:obj:`bool`, optional): Use ``type`` instead of ``isinstance``.
|
||||||
Default is :obj:`False`
|
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.
|
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
|
||||||
Defaults to :obj:`False`.
|
Defaults to :obj:`False`.
|
||||||
|
|
||||||
|
@ -65,10 +53,6 @@ class TypeHandler(Handler[UT, CCT]):
|
||||||
type (:obj:`type`): The ``type`` of updates this handler should process.
|
type (:obj:`type`): The ``type`` of updates this handler should process.
|
||||||
callback (:obj:`callable`): The callback function for this handler.
|
callback (:obj:`callable`): The callback function for this handler.
|
||||||
strict (:obj:`bool`): Use ``type`` instead of ``isinstance``. Default is :obj:`False`.
|
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.
|
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
|
type: Type[UT], # pylint: disable=W0622
|
||||||
callback: Callable[[UT, CCT], RT],
|
callback: Callable[[UT, CCT], RT],
|
||||||
strict: bool = False,
|
strict: bool = False,
|
||||||
pass_update_queue: bool = False,
|
|
||||||
pass_job_queue: bool = False,
|
|
||||||
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
|
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
callback,
|
callback,
|
||||||
pass_update_queue=pass_update_queue,
|
|
||||||
pass_job_queue=pass_job_queue,
|
|
||||||
run_async=run_async,
|
run_async=run_async,
|
||||||
)
|
)
|
||||||
self.type = type # pylint: disable=E0237
|
self.type = type # pylint: disable=E0237
|
||||||
|
|
|
@ -93,9 +93,6 @@ class Updater(Generic[CCT, UD, CD, BD]):
|
||||||
`telegram.utils.request.Request` object (ignored if `bot` or `dispatcher` argument is
|
`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
|
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.
|
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
|
persistence (:class:`telegram.ext.BasePersistence`, optional): The persistence class to
|
||||||
store data that should be persistent over restarts (ignored if `dispatcher` argument is
|
store data that should be persistent over restarts (ignored if `dispatcher` argument is
|
||||||
used).
|
used).
|
||||||
|
@ -129,7 +126,6 @@ class Updater(Generic[CCT, UD, CD, BD]):
|
||||||
running (:obj:`bool`): Indicates if the updater is running.
|
running (:obj:`bool`): Indicates if the updater is running.
|
||||||
persistence (:class:`telegram.ext.BasePersistence`): Optional. The persistence class to
|
persistence (:class:`telegram.ext.BasePersistence`): Optional. The persistence class to
|
||||||
store data that should be persistent over restarts.
|
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,
|
request_kwargs: Dict[str, Any] = None,
|
||||||
persistence: 'BasePersistence' = None, # pylint: disable=E0601
|
persistence: 'BasePersistence' = None, # pylint: disable=E0601
|
||||||
defaults: 'Defaults' = None,
|
defaults: 'Defaults' = None,
|
||||||
use_context: bool = True,
|
|
||||||
base_file_url: str = None,
|
base_file_url: str = None,
|
||||||
arbitrary_callback_data: Union[DefaultValue, bool, int, None] = DEFAULT_FALSE,
|
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,
|
request_kwargs: Dict[str, Any] = None,
|
||||||
persistence: 'BasePersistence' = None,
|
persistence: 'BasePersistence' = None,
|
||||||
defaults: 'Defaults' = None,
|
defaults: 'Defaults' = None,
|
||||||
use_context: bool = True,
|
|
||||||
base_file_url: str = None,
|
base_file_url: str = None,
|
||||||
arbitrary_callback_data: Union[DefaultValue, bool, int, None] = DEFAULT_FALSE,
|
arbitrary_callback_data: Union[DefaultValue, bool, int, None] = DEFAULT_FALSE,
|
||||||
context_types: ContextTypes[CCT, UD, CD, BD] = None,
|
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,
|
request_kwargs: Dict[str, Any] = None,
|
||||||
persistence: 'BasePersistence' = None,
|
persistence: 'BasePersistence' = None,
|
||||||
defaults: 'Defaults' = None,
|
defaults: 'Defaults' = None,
|
||||||
use_context: bool = True,
|
|
||||||
dispatcher=None,
|
dispatcher=None,
|
||||||
base_file_url: str = None,
|
base_file_url: str = None,
|
||||||
arbitrary_callback_data: Union[DefaultValue, bool, int, None] = DEFAULT_FALSE,
|
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')
|
raise ValueError('`dispatcher` and `bot` are mutually exclusive')
|
||||||
if persistence is not None:
|
if persistence is not None:
|
||||||
raise ValueError('`dispatcher` and `persistence` are mutually exclusive')
|
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:
|
if context_types is not None:
|
||||||
raise ValueError('`dispatcher` and `context_types` are mutually exclusive')
|
raise ValueError('`dispatcher` and `context_types` are mutually exclusive')
|
||||||
if workers is not None:
|
if workers is not None:
|
||||||
|
@ -300,7 +291,6 @@ class Updater(Generic[CCT, UD, CD, BD]):
|
||||||
workers=workers,
|
workers=workers,
|
||||||
exception_event=self.__exception_event,
|
exception_event=self.__exception_event,
|
||||||
persistence=persistence,
|
persistence=persistence,
|
||||||
use_context=use_context,
|
|
||||||
context_types=context_types,
|
context_types=context_types,
|
||||||
)
|
)
|
||||||
self.job_queue.set_dispatcher(self.dispatcher)
|
self.job_queue.set_dispatcher(self.dispatcher)
|
||||||
|
|
|
@ -159,7 +159,7 @@ def provider_token(bot_info):
|
||||||
def create_dp(bot):
|
def create_dp(bot):
|
||||||
# Dispatcher is heavy to init (due to many threads and such) so we have a single session
|
# 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)
|
# 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)
|
dispatcher.job_queue.set_dispatcher(dispatcher)
|
||||||
thr = Thread(target=dispatcher.start)
|
thr = Thread(target=dispatcher.start)
|
||||||
thr.start()
|
thr.start()
|
||||||
|
@ -195,23 +195,15 @@ def dp(_dp):
|
||||||
object.__setattr__(_dp, '__async_queue', Queue())
|
object.__setattr__(_dp, '__async_queue', Queue())
|
||||||
object.__setattr__(_dp, '__async_threads', set())
|
object.__setattr__(_dp, '__async_threads', set())
|
||||||
_dp.persistence = None
|
_dp.persistence = None
|
||||||
_dp.use_context = False
|
|
||||||
if _dp._Dispatcher__singleton_semaphore.acquire(blocking=0):
|
if _dp._Dispatcher__singleton_semaphore.acquire(blocking=0):
|
||||||
Dispatcher._set_singleton(_dp)
|
Dispatcher._set_singleton(_dp)
|
||||||
yield _dp
|
yield _dp
|
||||||
Dispatcher._Dispatcher__singleton_semaphore.release()
|
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')
|
@pytest.fixture(scope='function')
|
||||||
def updater(bot):
|
def updater(bot):
|
||||||
up = Updater(bot=bot, workers=2, use_context=False)
|
up = Updater(bot=bot, workers=2)
|
||||||
yield up
|
yield up
|
||||||
if up.running:
|
if up.running:
|
||||||
up.stop()
|
up.stop()
|
||||||
|
|
|
@ -38,8 +38,8 @@ CallbackContext.refresh_data is tested in TestBasePersistence
|
||||||
|
|
||||||
|
|
||||||
class TestCallbackContext:
|
class TestCallbackContext:
|
||||||
def test_slot_behaviour(self, cdp, mro_slots, recwarn):
|
def test_slot_behaviour(self, dp, mro_slots, recwarn):
|
||||||
c = CallbackContext(cdp)
|
c = CallbackContext(dp)
|
||||||
for attr in c.__slots__:
|
for attr in c.__slots__:
|
||||||
assert getattr(c, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
assert getattr(c, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||||
assert not c.__dict__, f"got missing slot(s): {c.__dict__}"
|
assert not c.__dict__, f"got missing slot(s): {c.__dict__}"
|
||||||
|
@ -47,38 +47,34 @@ class TestCallbackContext:
|
||||||
c.args = c.args
|
c.args = c.args
|
||||||
assert len(recwarn) == 0, recwarn.list
|
assert len(recwarn) == 0, recwarn.list
|
||||||
|
|
||||||
def test_non_context_dp(self, dp):
|
def test_from_job(self, dp):
|
||||||
with pytest.raises(ValueError):
|
job = dp.job_queue.run_once(lambda x: x, 10)
|
||||||
CallbackContext(dp)
|
|
||||||
|
|
||||||
def test_from_job(self, cdp):
|
callback_context = CallbackContext.from_job(job, dp)
|
||||||
job = cdp.job_queue.run_once(lambda x: x, 10)
|
|
||||||
|
|
||||||
callback_context = CallbackContext.from_job(job, cdp)
|
|
||||||
|
|
||||||
assert callback_context.job is job
|
assert callback_context.job is job
|
||||||
assert callback_context.chat_data is None
|
assert callback_context.chat_data is None
|
||||||
assert callback_context.user_data is None
|
assert callback_context.user_data is None
|
||||||
assert callback_context.bot_data is cdp.bot_data
|
assert callback_context.bot_data is dp.bot_data
|
||||||
assert callback_context.bot is cdp.bot
|
assert callback_context.bot is dp.bot
|
||||||
assert callback_context.job_queue is cdp.job_queue
|
assert callback_context.job_queue is dp.job_queue
|
||||||
assert callback_context.update_queue is cdp.update_queue
|
assert callback_context.update_queue is dp.update_queue
|
||||||
|
|
||||||
def test_from_update(self, cdp):
|
def test_from_update(self, dp):
|
||||||
update = Update(
|
update = Update(
|
||||||
0, message=Message(0, None, Chat(1, 'chat'), from_user=User(1, 'user', False))
|
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.chat_data == {}
|
||||||
assert callback_context.user_data == {}
|
assert callback_context.user_data == {}
|
||||||
assert callback_context.bot_data is cdp.bot_data
|
assert callback_context.bot_data is dp.bot_data
|
||||||
assert callback_context.bot is cdp.bot
|
assert callback_context.bot is dp.bot
|
||||||
assert callback_context.job_queue is cdp.job_queue
|
assert callback_context.job_queue is dp.job_queue
|
||||||
assert callback_context.update_queue is cdp.update_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.bot_data['test'] = 'bot'
|
||||||
callback_context.chat_data['test'] = 'chat'
|
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))
|
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.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.chat_data is not callback_context.chat_data
|
||||||
assert callback_context_other_user_chat.user_data is not callback_context.user_data
|
assert callback_context_other_user_chat.user_data is not callback_context.user_data
|
||||||
|
|
||||||
def test_from_update_not_update(self, cdp):
|
def test_from_update_not_update(self, dp):
|
||||||
callback_context = CallbackContext.from_update(None, cdp)
|
callback_context = CallbackContext.from_update(None, dp)
|
||||||
|
|
||||||
assert callback_context.chat_data is None
|
assert callback_context.chat_data is None
|
||||||
assert callback_context.user_data is None
|
assert callback_context.user_data is None
|
||||||
assert callback_context.bot_data is cdp.bot_data
|
assert callback_context.bot_data is dp.bot_data
|
||||||
assert callback_context.bot is cdp.bot
|
assert callback_context.bot is dp.bot
|
||||||
assert callback_context.job_queue is cdp.job_queue
|
assert callback_context.job_queue is dp.job_queue
|
||||||
assert callback_context.update_queue is cdp.update_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.chat_data is None
|
||||||
assert callback_context.user_data is None
|
assert callback_context.user_data is None
|
||||||
assert callback_context.bot_data is cdp.bot_data
|
assert callback_context.bot_data is dp.bot_data
|
||||||
assert callback_context.bot is cdp.bot
|
assert callback_context.bot is dp.bot
|
||||||
assert callback_context.job_queue is cdp.job_queue
|
assert callback_context.job_queue is dp.job_queue
|
||||||
assert callback_context.update_queue is cdp.update_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')
|
error = TelegramError('test')
|
||||||
|
|
||||||
update = Update(
|
update = Update(
|
||||||
0, message=Message(0, None, Chat(1, 'chat'), from_user=User(1, 'user', False))
|
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.error is error
|
||||||
assert callback_context.chat_data == {}
|
assert callback_context.chat_data == {}
|
||||||
assert callback_context.user_data == {}
|
assert callback_context.user_data == {}
|
||||||
assert callback_context.bot_data is cdp.bot_data
|
assert callback_context.bot_data is dp.bot_data
|
||||||
assert callback_context.bot is cdp.bot
|
assert callback_context.bot is dp.bot
|
||||||
assert callback_context.job_queue is cdp.job_queue
|
assert callback_context.job_queue is dp.job_queue
|
||||||
assert callback_context.update_queue is cdp.update_queue
|
assert callback_context.update_queue is dp.update_queue
|
||||||
assert callback_context.async_args is None
|
assert callback_context.async_args is None
|
||||||
assert callback_context.async_kwargs 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')
|
error = TelegramError('test')
|
||||||
|
|
||||||
args = [1, '2']
|
args = [1, '2']
|
||||||
kwargs = {'one': 1, 2: 'two'}
|
kwargs = {'one': 1, 2: 'two'}
|
||||||
|
|
||||||
callback_context = CallbackContext.from_error(
|
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.error is error
|
||||||
assert callback_context.async_args is args
|
assert callback_context.async_args is args
|
||||||
assert callback_context.async_kwargs is kwargs
|
assert callback_context.async_kwargs is kwargs
|
||||||
|
|
||||||
def test_match(self, cdp):
|
def test_match(self, dp):
|
||||||
callback_context = CallbackContext(cdp)
|
callback_context = CallbackContext(dp)
|
||||||
|
|
||||||
assert callback_context.match is None
|
assert callback_context.match is None
|
||||||
|
|
||||||
|
@ -159,12 +155,12 @@ class TestCallbackContext:
|
||||||
|
|
||||||
assert callback_context.match == 'test'
|
assert callback_context.match == 'test'
|
||||||
|
|
||||||
def test_data_assignment(self, cdp):
|
def test_data_assignment(self, dp):
|
||||||
update = Update(
|
update = Update(
|
||||||
0, message=Message(0, None, Chat(1, 'chat'), from_user=User(1, 'user', False))
|
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):
|
with pytest.raises(AttributeError):
|
||||||
callback_context.bot_data = {"test": 123}
|
callback_context.bot_data = {"test": 123}
|
||||||
|
@ -173,45 +169,45 @@ class TestCallbackContext:
|
||||||
with pytest.raises(AttributeError):
|
with pytest.raises(AttributeError):
|
||||||
callback_context.chat_data = "test"
|
callback_context.chat_data = "test"
|
||||||
|
|
||||||
def test_dispatcher_attribute(self, cdp):
|
def test_dispatcher_attribute(self, dp):
|
||||||
callback_context = CallbackContext(cdp)
|
callback_context = CallbackContext(dp)
|
||||||
assert callback_context.dispatcher == cdp
|
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)
|
non_ext_bot = Bot(bot.token)
|
||||||
update = Update(
|
update = Update(
|
||||||
0, message=Message(0, None, Chat(1, 'chat'), from_user=User(1, 'user', False))
|
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'):
|
with pytest.raises(RuntimeError, match='This telegram.ext.ExtBot instance does not'):
|
||||||
callback_context.drop_callback_data(None)
|
callback_context.drop_callback_data(None)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cdp.bot = non_ext_bot
|
dp.bot = non_ext_bot
|
||||||
with pytest.raises(RuntimeError, match='telegram.Bot does not allow for'):
|
with pytest.raises(RuntimeError, match='telegram.Bot does not allow for'):
|
||||||
callback_context.drop_callback_data(None)
|
callback_context.drop_callback_data(None)
|
||||||
finally:
|
finally:
|
||||||
cdp.bot = bot
|
dp.bot = bot
|
||||||
|
|
||||||
def test_drop_callback_data(self, cdp, monkeypatch, chat_id):
|
def test_drop_callback_data(self, dp, monkeypatch, chat_id):
|
||||||
monkeypatch.setattr(cdp.bot, 'arbitrary_callback_data', True)
|
monkeypatch.setattr(dp.bot, 'arbitrary_callback_data', True)
|
||||||
|
|
||||||
update = Update(
|
update = Update(
|
||||||
0, message=Message(0, None, Chat(1, 'chat'), from_user=User(1, 'user', False))
|
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)
|
||||||
cdp.bot.send_message(
|
dp.bot.send_message(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
text='test',
|
text='test',
|
||||||
reply_markup=InlineKeyboardMarkup.from_button(
|
reply_markup=InlineKeyboardMarkup.from_button(
|
||||||
InlineKeyboardButton('test', callback_data='callback_data')
|
InlineKeyboardButton('test', callback_data='callback_data')
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
keyboard_uuid = cdp.bot.callback_data_cache.persistence_data[0][0][0]
|
keyboard_uuid = dp.bot.callback_data_cache.persistence_data[0][0][0]
|
||||||
button_uuid = list(cdp.bot.callback_data_cache.persistence_data[0][0][2])[0]
|
button_uuid = list(dp.bot.callback_data_cache.persistence_data[0][0][2])[0]
|
||||||
callback_data = keyboard_uuid + button_uuid
|
callback_data = keyboard_uuid + button_uuid
|
||||||
callback_query = CallbackQuery(
|
callback_query = CallbackQuery(
|
||||||
id='1',
|
id='1',
|
||||||
|
@ -219,14 +215,14 @@ class TestCallbackContext:
|
||||||
chat_instance=None,
|
chat_instance=None,
|
||||||
data=callback_data,
|
data=callback_data,
|
||||||
)
|
)
|
||||||
cdp.bot.callback_data_cache.process_callback_query(callback_query)
|
dp.bot.callback_data_cache.process_callback_query(callback_query)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
assert len(cdp.bot.callback_data_cache.persistence_data[0]) == 1
|
assert len(dp.bot.callback_data_cache.persistence_data[0]) == 1
|
||||||
assert list(cdp.bot.callback_data_cache.persistence_data[1]) == ['1']
|
assert list(dp.bot.callback_data_cache.persistence_data[1]) == ['1']
|
||||||
|
|
||||||
callback_context.drop_callback_data(callback_query)
|
callback_context.drop_callback_data(callback_query)
|
||||||
assert cdp.bot.callback_data_cache.persistence_data == ([], {})
|
assert dp.bot.callback_data_cache.persistence_data == ([], {})
|
||||||
finally:
|
finally:
|
||||||
cdp.bot.callback_data_cache.clear_callback_data()
|
dp.bot.callback_data_cache.clear_callback_data()
|
||||||
cdp.bot.callback_data_cache.clear_callback_queries()
|
dp.bot.callback_data_cache.clear_callback_queries()
|
||||||
|
|
|
@ -82,8 +82,8 @@ class TestCallbackQueryHandler:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.test_flag = False
|
self.test_flag = False
|
||||||
|
|
||||||
def callback_basic(self, bot, update):
|
def callback_basic(self, update, context):
|
||||||
test_bot = isinstance(bot, Bot)
|
test_bot = isinstance(context.bot, Bot)
|
||||||
test_update = isinstance(update, Update)
|
test_update = isinstance(update, Update)
|
||||||
self.test_flag = test_bot and test_update
|
self.test_flag = test_bot and test_update
|
||||||
|
|
||||||
|
@ -124,15 +124,6 @@ class TestCallbackQueryHandler:
|
||||||
if context.matches[0].groupdict():
|
if context.matches[0].groupdict():
|
||||||
self.test_flag = context.matches[0].groupdict() == {'begin': 't', 'end': ' data'}
|
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):
|
def test_with_pattern(self, callback_query):
|
||||||
handler = CallbackQueryHandler(self.callback_basic, pattern='.*est.*')
|
handler = CallbackQueryHandler(self.callback_basic, pattern='.*est.*')
|
||||||
|
|
||||||
|
@ -177,103 +168,34 @@ class TestCallbackQueryHandler:
|
||||||
callback_query.callback_query.data = 'callback_data'
|
callback_query.callback_query.data = 'callback_data'
|
||||||
assert not handler.check_update(callback_query)
|
assert not handler.check_update(callback_query)
|
||||||
|
|
||||||
def test_with_passing_group_dict(self, dp, callback_query):
|
|
||||||
handler = CallbackQueryHandler(
|
|
||||||
self.callback_group, pattern='(?P<begin>.*)est(?P<end>.*)', 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<begin>.*)est(?P<end>.*)', 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):
|
def test_other_update_types(self, false_update):
|
||||||
handler = CallbackQueryHandler(self.callback_basic)
|
handler = CallbackQueryHandler(self.callback_basic)
|
||||||
assert not handler.check_update(false_update)
|
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)
|
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
|
assert self.test_flag
|
||||||
|
|
||||||
def test_context_pattern(self, cdp, callback_query):
|
def test_context_pattern(self, dp, callback_query):
|
||||||
handler = CallbackQueryHandler(
|
handler = CallbackQueryHandler(
|
||||||
self.callback_context_pattern, pattern=r'(?P<begin>.*)est(?P<end>.*)'
|
self.callback_context_pattern, pattern=r'(?P<begin>.*)est(?P<end>.*)'
|
||||||
)
|
)
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
|
|
||||||
cdp.process_update(callback_query)
|
dp.process_update(callback_query)
|
||||||
assert self.test_flag
|
assert self.test_flag
|
||||||
|
|
||||||
cdp.remove_handler(handler)
|
dp.remove_handler(handler)
|
||||||
handler = CallbackQueryHandler(self.callback_context_pattern, pattern=r'(t)est(.*)')
|
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
|
assert self.test_flag
|
||||||
|
|
||||||
def test_context_callable_pattern(self, cdp, callback_query):
|
def test_context_callable_pattern(self, dp, callback_query):
|
||||||
class CallbackData:
|
class CallbackData:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -284,6 +206,6 @@ class TestCallbackQueryHandler:
|
||||||
assert context.matches is None
|
assert context.matches is None
|
||||||
|
|
||||||
handler = CallbackQueryHandler(callback, pattern=pattern)
|
handler = CallbackQueryHandler(callback, pattern=pattern)
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
|
|
||||||
cdp.process_update(callback_query)
|
dp.process_update(callback_query)
|
||||||
|
|
|
@ -102,7 +102,7 @@ class TestChatJoinRequestHandler:
|
||||||
test_flag = False
|
test_flag = False
|
||||||
|
|
||||||
def test_slot_behaviour(self, recwarn, mro_slots):
|
def test_slot_behaviour(self, recwarn, mro_slots):
|
||||||
action = ChatJoinRequestHandler(self.callback_basic)
|
action = ChatJoinRequestHandler(self.callback_context)
|
||||||
for attr in action.__slots__:
|
for attr in action.__slots__:
|
||||||
assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||||
assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot"
|
assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot"
|
||||||
|
@ -111,23 +111,6 @@ class TestChatJoinRequestHandler:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.test_flag = False
|
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):
|
def callback_context(self, update, context):
|
||||||
self.test_flag = (
|
self.test_flag = (
|
||||||
isinstance(context, CallbackContext)
|
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):
|
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(false_update)
|
||||||
assert not handler.check_update(True)
|
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)
|
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
|
assert self.test_flag
|
||||||
|
|
|
@ -89,7 +89,7 @@ class TestChatMemberHandler:
|
||||||
test_flag = False
|
test_flag = False
|
||||||
|
|
||||||
def test_slot_behaviour(self, mro_slots):
|
def test_slot_behaviour(self, mro_slots):
|
||||||
action = ChatMemberHandler(self.callback_basic)
|
action = ChatMemberHandler(self.callback_context)
|
||||||
for attr in action.__slots__:
|
for attr in action.__slots__:
|
||||||
assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
assert getattr(action, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||||
assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot"
|
assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot"
|
||||||
|
@ -98,23 +98,6 @@ class TestChatMemberHandler:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.test_flag = False
|
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):
|
def callback_context(self, update, context):
|
||||||
self.test_flag = (
|
self.test_flag = (
|
||||||
isinstance(context, CallbackContext)
|
isinstance(context, CallbackContext)
|
||||||
|
@ -128,15 +111,6 @@ class TestChatMemberHandler:
|
||||||
and isinstance(update.chat_member or update.my_chat_member, ChatMemberUpdated)
|
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(
|
@pytest.mark.parametrize(
|
||||||
argnames=['allowed_types', 'expected'],
|
argnames=['allowed_types', 'expected'],
|
||||||
argvalues=[
|
argvalues=[
|
||||||
|
@ -151,7 +125,7 @@ class TestChatMemberHandler:
|
||||||
):
|
):
|
||||||
result_1, result_2 = expected
|
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)
|
dp.add_handler(handler)
|
||||||
|
|
||||||
assert handler.check_update(chat_member) == result_1
|
assert handler.check_update(chat_member) == result_1
|
||||||
|
@ -166,62 +140,14 @@ class TestChatMemberHandler:
|
||||||
dp.process_update(chat_member)
|
dp.process_update(chat_member)
|
||||||
assert self.test_flag == result_2
|
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):
|
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(false_update)
|
||||||
assert not handler.check_update(True)
|
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)
|
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
|
assert self.test_flag
|
||||||
|
|
|
@ -87,8 +87,8 @@ class TestChosenInlineResultHandler:
|
||||||
assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||||
assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot"
|
assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot"
|
||||||
|
|
||||||
def callback_basic(self, bot, update):
|
def callback_basic(self, update, context):
|
||||||
test_bot = isinstance(bot, Bot)
|
test_bot = isinstance(context.bot, Bot)
|
||||||
test_update = isinstance(update, Update)
|
test_update = isinstance(update, Update)
|
||||||
self.test_flag = test_bot and test_update
|
self.test_flag = test_bot and test_update
|
||||||
|
|
||||||
|
@ -123,73 +123,15 @@ class TestChosenInlineResultHandler:
|
||||||
if context.matches[0].groupdict():
|
if context.matches[0].groupdict():
|
||||||
self.test_flag = context.matches[0].groupdict() == {'begin': 'res', 'end': '_id'}
|
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):
|
def test_other_update_types(self, false_update):
|
||||||
handler = ChosenInlineResultHandler(self.callback_basic)
|
handler = ChosenInlineResultHandler(self.callback_basic)
|
||||||
assert not handler.check_update(false_update)
|
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)
|
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
|
assert self.test_flag
|
||||||
|
|
||||||
def test_with_pattern(self, chosen_inline_result):
|
def test_with_pattern(self, chosen_inline_result):
|
||||||
|
@ -201,17 +143,17 @@ class TestChosenInlineResultHandler:
|
||||||
assert not handler.check_update(chosen_inline_result)
|
assert not handler.check_update(chosen_inline_result)
|
||||||
chosen_inline_result.chosen_inline_result.result_id = 'result_id'
|
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(
|
handler = ChosenInlineResultHandler(
|
||||||
self.callback_context_pattern, pattern=r'(?P<begin>.*)ult(?P<end>.*)'
|
self.callback_context_pattern, pattern=r'(?P<begin>.*)ult(?P<end>.*)'
|
||||||
)
|
)
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
cdp.process_update(chosen_inline_result)
|
dp.process_update(chosen_inline_result)
|
||||||
assert self.test_flag
|
assert self.test_flag
|
||||||
|
|
||||||
cdp.remove_handler(handler)
|
dp.remove_handler(handler)
|
||||||
handler = ChosenInlineResultHandler(self.callback_context_pattern, pattern=r'(res)ult(.*)')
|
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
|
assert self.test_flag
|
||||||
|
|
|
@ -20,8 +20,6 @@ import re
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import itertools
|
|
||||||
from telegram.utils.deprecate import TelegramDeprecationWarning
|
|
||||||
|
|
||||||
from telegram import Message, Update, Chat, Bot
|
from telegram import Message, Update, Chat, Bot
|
||||||
from telegram.ext import CommandHandler, Filters, CallbackContext, JobQueue, PrefixHandler
|
from telegram.ext import CommandHandler, Filters, CallbackContext, JobQueue, PrefixHandler
|
||||||
|
@ -56,12 +54,6 @@ class BaseTest:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.test_flag = False
|
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):
|
def response(self, dispatcher, update):
|
||||||
"""
|
"""
|
||||||
Utility to send an update to a dispatcher and assert
|
Utility to send an update to a dispatcher and assert
|
||||||
|
@ -72,8 +64,8 @@ class BaseTest:
|
||||||
dispatcher.process_update(update)
|
dispatcher.process_update(update)
|
||||||
return self.test_flag
|
return self.test_flag
|
||||||
|
|
||||||
def callback_basic(self, bot, update):
|
def callback_basic(self, update, context):
|
||||||
test_bot = isinstance(bot, Bot)
|
test_bot = isinstance(context.bot, Bot)
|
||||||
test_update = isinstance(update, Update)
|
test_update = isinstance(update, Update)
|
||||||
self.test_flag = test_bot and test_update
|
self.test_flag = test_bot and test_update
|
||||||
|
|
||||||
|
@ -112,12 +104,12 @@ class BaseTest:
|
||||||
num = len(context.matches) == 2
|
num = len(context.matches) == 2
|
||||||
self.test_flag = types and num
|
self.test_flag = types and num
|
||||||
|
|
||||||
def _test_context_args_or_regex(self, cdp, handler, text):
|
def _test_context_args_or_regex(self, dp, handler, text):
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
update = make_command_update(text)
|
update = make_command_update(text)
|
||||||
assert not self.response(cdp, update)
|
assert not self.response(dp, update)
|
||||||
update.message.text += ' one two'
|
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):
|
def _test_edited(self, message, handler_edited, handler_not_edited):
|
||||||
"""
|
"""
|
||||||
|
@ -160,14 +152,6 @@ class TestCommandHandler(BaseTest):
|
||||||
def command_update(self, command_message):
|
def command_update(self, command_message):
|
||||||
return make_command_update(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):
|
def make_default_handler(self, callback=None, **kwargs):
|
||||||
callback = callback or self.callback_basic
|
callback = callback or self.callback_basic
|
||||||
return CommandHandler(self.CMD[1:], callback, **kwargs)
|
return CommandHandler(self.CMD[1:], callback, **kwargs)
|
||||||
|
@ -199,23 +183,12 @@ class TestCommandHandler(BaseTest):
|
||||||
assert is_match(handler, make_command_update('/star'))
|
assert is_match(handler, make_command_update('/star'))
|
||||||
assert not is_match(handler, make_command_update('/stop'))
|
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):
|
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_edited = self.make_default_handler()
|
||||||
handler_no_edited = self.make_default_handler(filters=~Filters.update.edited_message)
|
handler_no_edited = self.make_default_handler(filters=~Filters.update.edited_message)
|
||||||
self._test_edited(command_message, handler_edited, handler_no_edited)
|
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):
|
def test_directed_commands(self, bot, command):
|
||||||
"""Test recognition of commands with a mention to the bot"""
|
"""Test recognition of commands with a mention to the bot"""
|
||||||
handler = self.make_default_handler()
|
handler = self.make_default_handler()
|
||||||
|
@ -223,21 +196,11 @@ class TestCommandHandler(BaseTest):
|
||||||
assert not is_match(handler, make_command_update(command + '@otherbot', bot=bot))
|
assert not is_match(handler, make_command_update(command + '@otherbot', bot=bot))
|
||||||
|
|
||||||
def test_with_filter(self, command):
|
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)
|
handler = self.make_default_handler(filters=Filters.group)
|
||||||
assert is_match(handler, make_command_update(command, chat=Chat(-23, Chat.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)))
|
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):
|
def test_newline(self, dp, command):
|
||||||
"""Assert that newlines don't interfere with a command handler matching a message"""
|
"""Assert that newlines don't interfere with a command handler matching a message"""
|
||||||
handler = self.make_default_handler()
|
handler = self.make_default_handler()
|
||||||
|
@ -246,12 +209,6 @@ class TestCommandHandler(BaseTest):
|
||||||
assert is_match(handler, update)
|
assert is_match(handler, update)
|
||||||
assert self.response(dp, 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):
|
def test_other_update_types(self, false_update):
|
||||||
"""Test that a command handler doesn't respond to unrelated updates"""
|
"""Test that a command handler doesn't respond to unrelated updates"""
|
||||||
handler = self.make_default_handler()
|
handler = self.make_default_handler()
|
||||||
|
@ -263,30 +220,30 @@ class TestCommandHandler(BaseTest):
|
||||||
assert not is_match(handler, make_command_update('/star'))
|
assert not is_match(handler, make_command_update('/star'))
|
||||||
assert not mock_filter.tested
|
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"""
|
"""Test correct behaviour of CHs with context-based callbacks"""
|
||||||
handler = self.make_default_handler(self.callback_context)
|
handler = self.make_default_handler(self.callback_context)
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
assert self.response(cdp, command_update)
|
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``"""
|
"""Test CHs that pass arguments through ``context``"""
|
||||||
handler = self.make_default_handler(self.callback_context_args)
|
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"""
|
"""Test CHs with context-based callbacks and a single filter"""
|
||||||
handler = self.make_default_handler(
|
handler = self.make_default_handler(
|
||||||
self.callback_context_regex1, filters=Filters.regex('one two')
|
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"""
|
"""Test CHs with context-based callbacks and filters combined"""
|
||||||
handler = self.make_default_handler(
|
handler = self.make_default_handler(
|
||||||
self.callback_context_regex2, filters=Filters.regex('one') & Filters.regex('two')
|
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 -----------------------------
|
# ----------------------------- PrefixHandler -----------------------------
|
||||||
|
@ -340,12 +297,6 @@ class TestPrefixHandler(BaseTest):
|
||||||
callback = callback or self.callback_basic
|
callback = callback or self.callback_basic
|
||||||
return PrefixHandler(self.PREFIXES, self.COMMANDS, callback, **kwargs)
|
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):
|
def test_basic(self, dp, prefix, command):
|
||||||
"""Test the basic expected response from a prefix handler"""
|
"""Test the basic expected response from a prefix handler"""
|
||||||
handler = self.make_default_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 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)))
|
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):
|
def test_other_update_types(self, false_update):
|
||||||
handler = self.make_default_handler()
|
handler = self.make_default_handler()
|
||||||
assert not is_match(handler, false_update)
|
assert not is_match(handler, false_update)
|
||||||
|
@ -427,23 +359,23 @@ class TestPrefixHandler(BaseTest):
|
||||||
text = prefix + 'foo'
|
text = prefix + 'foo'
|
||||||
assert self.response(dp, make_message_update(text))
|
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)
|
handler = self.make_default_handler(self.callback_context)
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
assert self.response(cdp, prefix_message_update)
|
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)
|
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(
|
handler = self.make_default_handler(
|
||||||
self.callback_context_regex1, filters=Filters.regex('one two')
|
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(
|
handler = self.make_default_handler(
|
||||||
self.callback_context_regex2, filters=Filters.regex('one') & Filters.regex('two')
|
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)
|
||||||
|
|
|
@ -170,45 +170,45 @@ class TestConversationHandler:
|
||||||
|
|
||||||
# Actions
|
# Actions
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def start(self, bot, update):
|
def start(self, update, context):
|
||||||
if isinstance(update, Update):
|
if isinstance(update, Update):
|
||||||
return self._set_state(update, self.THIRSTY)
|
return self._set_state(update, self.THIRSTY)
|
||||||
return self._set_state(bot, self.THIRSTY)
|
return self._set_state(context.bot, self.THIRSTY)
|
||||||
|
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def end(self, bot, update):
|
def end(self, update, context):
|
||||||
return self._set_state(update, self.END)
|
return self._set_state(update, self.END)
|
||||||
|
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def start_end(self, bot, update):
|
def start_end(self, update, context):
|
||||||
return self._set_state(update, self.END)
|
return self._set_state(update, self.END)
|
||||||
|
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def start_none(self, bot, update):
|
def start_none(self, update, context):
|
||||||
return self._set_state(update, None)
|
return self._set_state(update, None)
|
||||||
|
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def brew(self, bot, update):
|
def brew(self, update, context):
|
||||||
if isinstance(update, Update):
|
if isinstance(update, Update):
|
||||||
return self._set_state(update, self.BREWING)
|
return self._set_state(update, self.BREWING)
|
||||||
return self._set_state(bot, self.BREWING)
|
return self._set_state(context.bot, self.BREWING)
|
||||||
|
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def drink(self, bot, update):
|
def drink(self, update, context):
|
||||||
return self._set_state(update, self.DRINKING)
|
return self._set_state(update, self.DRINKING)
|
||||||
|
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def code(self, bot, update):
|
def code(self, update, context):
|
||||||
return self._set_state(update, self.CODING)
|
return self._set_state(update, self.CODING)
|
||||||
|
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def passout(self, bot, update):
|
def passout(self, update, context):
|
||||||
assert update.message.text == '/brew'
|
assert update.message.text == '/brew'
|
||||||
assert isinstance(update, Update)
|
assert isinstance(update, Update)
|
||||||
self.is_timeout = True
|
self.is_timeout = True
|
||||||
|
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def passout2(self, bot, update):
|
def passout2(self, update, context):
|
||||||
assert isinstance(update, Update)
|
assert isinstance(update, Update)
|
||||||
self.is_timeout = True
|
self.is_timeout = True
|
||||||
|
|
||||||
|
@ -226,23 +226,23 @@ class TestConversationHandler:
|
||||||
# Drinking actions (nested)
|
# Drinking actions (nested)
|
||||||
|
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def hold(self, bot, update):
|
def hold(self, update, context):
|
||||||
return self._set_state(update, self.HOLDING)
|
return self._set_state(update, self.HOLDING)
|
||||||
|
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def sip(self, bot, update):
|
def sip(self, update, context):
|
||||||
return self._set_state(update, self.SIPPING)
|
return self._set_state(update, self.SIPPING)
|
||||||
|
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def swallow(self, bot, update):
|
def swallow(self, update, context):
|
||||||
return self._set_state(update, self.SWALLOWING)
|
return self._set_state(update, self.SWALLOWING)
|
||||||
|
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def replenish(self, bot, update):
|
def replenish(self, update, context):
|
||||||
return self._set_state(update, self.REPLENISHING)
|
return self._set_state(update, self.REPLENISHING)
|
||||||
|
|
||||||
@raise_dphs
|
@raise_dphs
|
||||||
def stop(self, bot, update):
|
def stop(self, update, context):
|
||||||
return self._set_state(update, self.STOPPING)
|
return self._set_state(update, self.STOPPING)
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
|
@ -543,13 +543,13 @@ class TestConversationHandler:
|
||||||
assert handler.conversations[(user1.id,)] == self.DRINKING
|
assert handler.conversations[(user1.id,)] == self.DRINKING
|
||||||
|
|
||||||
def test_conversation_handler_per_message(self, dp, bot, user1, user2):
|
def test_conversation_handler_per_message(self, dp, bot, user1, user2):
|
||||||
def entry(bot, update):
|
def entry(update, context):
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def one(bot, update):
|
def one(update, context):
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
def two(bot, update):
|
def two(update, context):
|
||||||
return ConversationHandler.END
|
return ConversationHandler.END
|
||||||
|
|
||||||
handler = ConversationHandler(
|
handler = ConversationHandler(
|
||||||
|
@ -606,7 +606,7 @@ class TestConversationHandler:
|
||||||
handler = ConversationHandler(
|
handler = ConversationHandler(
|
||||||
entry_points=[
|
entry_points=[
|
||||||
CommandHandler(
|
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={},
|
states={},
|
||||||
|
@ -687,7 +687,7 @@ class TestConversationHandler:
|
||||||
handler = ConversationHandler(
|
handler = ConversationHandler(
|
||||||
entry_points=[
|
entry_points=[
|
||||||
CommandHandler(
|
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={},
|
states={},
|
||||||
|
@ -1026,7 +1026,7 @@ class TestConversationHandler:
|
||||||
rec = caplog.records[-1]
|
rec = caplog.records[-1]
|
||||||
assert rec.getMessage().startswith('DispatcherHandlerStop in TIMEOUT')
|
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
|
context = None
|
||||||
|
|
||||||
def start_callback(u, c):
|
def start_callback(u, c):
|
||||||
|
@ -1043,7 +1043,7 @@ class TestConversationHandler:
|
||||||
fallbacks=self.fallbacks,
|
fallbacks=self.fallbacks,
|
||||||
conversation_timeout=0.5,
|
conversation_timeout=0.5,
|
||||||
)
|
)
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
|
|
||||||
# Start state machine, then reach timeout
|
# Start state machine, then reach timeout
|
||||||
message = Message(
|
message = Message(
|
||||||
|
@ -1067,7 +1067,7 @@ class TestConversationHandler:
|
||||||
|
|
||||||
timeout_handler.callback = timeout_callback
|
timeout_handler.callback = timeout_callback
|
||||||
|
|
||||||
cdp.process_update(update)
|
dp.process_update(update)
|
||||||
sleep(0.7)
|
sleep(0.7)
|
||||||
assert handler.conversations.get((self.group.id, user1.id)) is None
|
assert handler.conversations.get((self.group.id, user1.id)) is None
|
||||||
assert self.is_timeout
|
assert self.is_timeout
|
||||||
|
@ -1216,7 +1216,7 @@ class TestConversationHandler:
|
||||||
assert handler.conversations.get((self.group.id, user1.id)) is None
|
assert handler.conversations.get((self.group.id, user1.id)) is None
|
||||||
assert not self.is_timeout
|
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 = self.states
|
||||||
states.update(
|
states.update(
|
||||||
{
|
{
|
||||||
|
@ -1232,7 +1232,7 @@ class TestConversationHandler:
|
||||||
fallbacks=self.fallbacks,
|
fallbacks=self.fallbacks,
|
||||||
conversation_timeout=0.5,
|
conversation_timeout=0.5,
|
||||||
)
|
)
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
|
|
||||||
# CommandHandler timeout
|
# CommandHandler timeout
|
||||||
message = Message(
|
message = Message(
|
||||||
|
@ -1246,10 +1246,10 @@ class TestConversationHandler:
|
||||||
],
|
],
|
||||||
bot=bot,
|
bot=bot,
|
||||||
)
|
)
|
||||||
cdp.process_update(Update(update_id=0, message=message))
|
dp.process_update(Update(update_id=0, message=message))
|
||||||
message.text = '/brew'
|
message.text = '/brew'
|
||||||
message.entities[0].length = len('/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)
|
sleep(0.7)
|
||||||
assert handler.conversations.get((self.group.id, user1.id)) is None
|
assert handler.conversations.get((self.group.id, user1.id)) is None
|
||||||
assert self.is_timeout
|
assert self.is_timeout
|
||||||
|
@ -1258,20 +1258,20 @@ class TestConversationHandler:
|
||||||
self.is_timeout = False
|
self.is_timeout = False
|
||||||
message.text = '/start'
|
message.text = '/start'
|
||||||
message.entities[0].length = len('/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)
|
sleep(0.7)
|
||||||
assert handler.conversations.get((self.group.id, user1.id)) is None
|
assert handler.conversations.get((self.group.id, user1.id)) is None
|
||||||
assert self.is_timeout
|
assert self.is_timeout
|
||||||
|
|
||||||
# Timeout but no valid handler
|
# Timeout but no valid handler
|
||||||
self.is_timeout = False
|
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.text = '/brew'
|
||||||
message.entities[0].length = len('/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.text = '/startCoding'
|
||||||
message.entities[0].length = len('/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)
|
sleep(0.7)
|
||||||
assert handler.conversations.get((self.group.id, user1.id)) is None
|
assert handler.conversations.get((self.group.id, user1.id)) is None
|
||||||
assert not self.is_timeout
|
assert not self.is_timeout
|
||||||
|
@ -1285,7 +1285,7 @@ class TestConversationHandler:
|
||||||
# | t=.75 /slowbrew returns (timeout=1.25)
|
# | t=.75 /slowbrew returns (timeout=1.25)
|
||||||
# t=1.25 timeout
|
# t=1.25 timeout
|
||||||
|
|
||||||
def slowbrew(_bot, update):
|
def slowbrew(_update, context):
|
||||||
sleep(0.25)
|
sleep(0.25)
|
||||||
# Let's give to the original timeout a chance to execute
|
# Let's give to the original timeout a chance to execute
|
||||||
sleep(0.25)
|
sleep(0.25)
|
||||||
|
@ -1395,10 +1395,10 @@ class TestConversationHandler:
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_warnings_per_chat_is_only_shown_once(self, recwarn):
|
def test_warnings_per_chat_is_only_shown_once(self, recwarn):
|
||||||
def hello(bot, update):
|
def hello(update, context):
|
||||||
return self.BREWING
|
return self.BREWING
|
||||||
|
|
||||||
def bye(bot, update):
|
def bye(update, context):
|
||||||
return ConversationHandler.END
|
return ConversationHandler.END
|
||||||
|
|
||||||
ConversationHandler(
|
ConversationHandler(
|
||||||
|
|
|
@ -30,7 +30,7 @@ class TestDefault:
|
||||||
assert getattr(a, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
assert getattr(a, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||||
assert len(mro_slots(a)) == len(set(mro_slots(a))), "duplicate slot"
|
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()
|
defaults = Defaults()
|
||||||
|
|
||||||
with pytest.raises(AttributeError):
|
with pytest.raises(AttributeError):
|
||||||
|
|
|
@ -72,16 +72,13 @@ class TestDispatcher:
|
||||||
self.received = None
|
self.received = None
|
||||||
self.count = 0
|
self.count = 0
|
||||||
|
|
||||||
def error_handler(self, bot, update, error):
|
|
||||||
self.received = error.message
|
|
||||||
|
|
||||||
def error_handler_context(self, update, context):
|
def error_handler_context(self, update, context):
|
||||||
self.received = context.error.message
|
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')
|
raise Exception('Failing bigly')
|
||||||
|
|
||||||
def callback_increase_count(self, bot, update):
|
def callback_increase_count(self, update, context):
|
||||||
self.count += 1
|
self.count += 1
|
||||||
|
|
||||||
def callback_set_count(self, count):
|
def callback_set_count(self, count):
|
||||||
|
@ -90,13 +87,10 @@ class TestDispatcher:
|
||||||
|
|
||||||
return callback
|
return callback
|
||||||
|
|
||||||
def callback_raise_error(self, bot, update):
|
def callback_raise_error(self, update, context):
|
||||||
if isinstance(bot, Bot):
|
|
||||||
raise TelegramError(update.message.text)
|
raise TelegramError(update.message.text)
|
||||||
raise TelegramError(bot.message.text)
|
|
||||||
|
|
||||||
def callback_if_not_update_queue(self, bot, update, update_queue=None):
|
def callback_received(self, update, context):
|
||||||
if update_queue is not None:
|
|
||||||
self.received = update.message
|
self.received = update.message
|
||||||
|
|
||||||
def callback_context(self, update, context):
|
def callback_context(self, update, context):
|
||||||
|
@ -110,14 +104,14 @@ class TestDispatcher:
|
||||||
self.received = context.error.message
|
self.received = context.error.message
|
||||||
|
|
||||||
def test_less_than_one_worker_warning(self, dp, recwarn):
|
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 len(recwarn) == 1
|
||||||
assert (
|
assert (
|
||||||
str(recwarn[0].message)
|
str(recwarn[0].message)
|
||||||
== 'Asynchronous callbacks can not be processed without at least one worker thread.'
|
== '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):
|
def one(update, context):
|
||||||
if update.message.text == 'test':
|
if update.message.text == 'test':
|
||||||
context.my_flag = True
|
context.my_flag = True
|
||||||
|
@ -130,22 +124,22 @@ class TestDispatcher:
|
||||||
if hasattr(context, 'my_flag'):
|
if hasattr(context, 'my_flag'):
|
||||||
pytest.fail()
|
pytest.fail()
|
||||||
|
|
||||||
cdp.add_handler(MessageHandler(Filters.regex('test'), one), group=1)
|
dp.add_handler(MessageHandler(Filters.regex('test'), one), group=1)
|
||||||
cdp.add_handler(MessageHandler(None, two), group=2)
|
dp.add_handler(MessageHandler(None, two), group=2)
|
||||||
u = Update(1, Message(1, None, None, None, text='test'))
|
u = Update(1, Message(1, None, None, None, text='test'))
|
||||||
cdp.process_update(u)
|
dp.process_update(u)
|
||||||
u.message.text = 'something'
|
u.message.text = 'something'
|
||||||
cdp.process_update(u)
|
dp.process_update(u)
|
||||||
|
|
||||||
def test_error_handler(self, dp):
|
def test_error_handler(self, dp):
|
||||||
dp.add_error_handler(self.error_handler)
|
dp.add_error_handler(self.error_handler_context)
|
||||||
error = TelegramError('Unauthorized.')
|
error = TelegramError('Unauthorized.')
|
||||||
dp.update_queue.put(error)
|
dp.update_queue.put(error)
|
||||||
sleep(0.1)
|
sleep(0.1)
|
||||||
assert self.received == 'Unauthorized.'
|
assert self.received == 'Unauthorized.'
|
||||||
|
|
||||||
# Remove handler
|
# Remove handler
|
||||||
dp.remove_error_handler(self.error_handler)
|
dp.remove_error_handler(self.error_handler_context)
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
dp.update_queue.put(error)
|
dp.update_queue.put(error)
|
||||||
|
@ -153,9 +147,9 @@ class TestDispatcher:
|
||||||
assert self.received is None
|
assert self.received is None
|
||||||
|
|
||||||
def test_double_add_error_handler(self, dp, caplog):
|
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):
|
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 len(caplog.records) == 1
|
||||||
assert caplog.records[-1].getMessage().startswith('The callback is already registered')
|
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)
|
dp.bot.defaults = Defaults(run_async=run_async)
|
||||||
try:
|
try:
|
||||||
dp.add_handler(MessageHandler(Filters.all, self.callback_raise_error))
|
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)
|
monkeypatch.setattr(dp, 'run_async', mock_async_err_handler)
|
||||||
dp.process_update(self.message_update)
|
dp.process_update(self.message_update)
|
||||||
|
@ -262,17 +256,6 @@ class TestDispatcher:
|
||||||
with pytest.raises(RuntimeError):
|
with pytest.raises(RuntimeError):
|
||||||
must_raise_runtime_error()
|
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):
|
def test_multiple_run_async_deprecation(self, dp):
|
||||||
assert isinstance(dp, Dispatcher)
|
assert isinstance(dp, Dispatcher)
|
||||||
|
|
||||||
|
@ -323,8 +306,7 @@ class TestDispatcher:
|
||||||
dp.add_handler(
|
dp.add_handler(
|
||||||
MessageHandler(
|
MessageHandler(
|
||||||
Filters.all,
|
Filters.all,
|
||||||
self.callback_if_not_update_queue,
|
self.callback_received,
|
||||||
pass_update_queue=True,
|
|
||||||
run_async=True,
|
run_async=True,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -343,19 +325,11 @@ class TestDispatcher:
|
||||||
assert len(caplog.records) == 1
|
assert len(caplog.records) == 1
|
||||||
assert caplog.records[-1].getMessage().startswith('No error handlers are registered')
|
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_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)
|
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)
|
sleep(2)
|
||||||
assert self.received == self.message_update.message.text
|
assert self.received == self.message_update.message.text
|
||||||
|
|
||||||
|
@ -397,7 +371,7 @@ class TestDispatcher:
|
||||||
|
|
||||||
def test_error_in_handler(self, dp):
|
def test_error_in_handler(self, dp):
|
||||||
dp.add_handler(MessageHandler(Filters.all, self.callback_raise_error))
|
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)
|
dp.update_queue.put(self.message_update)
|
||||||
sleep(0.1)
|
sleep(0.1)
|
||||||
|
@ -494,19 +468,19 @@ class TestDispatcher:
|
||||||
passed = []
|
passed = []
|
||||||
err = Exception('General exception')
|
err = Exception('General exception')
|
||||||
|
|
||||||
def start1(b, u):
|
def start1(u, c):
|
||||||
passed.append('start1')
|
passed.append('start1')
|
||||||
raise err
|
raise err
|
||||||
|
|
||||||
def start2(b, u):
|
def start2(u, c):
|
||||||
passed.append('start2')
|
passed.append('start2')
|
||||||
|
|
||||||
def start3(b, u):
|
def start3(u, c):
|
||||||
passed.append('start3')
|
passed.append('start3')
|
||||||
|
|
||||||
def error(b, u, e):
|
def error(u, c):
|
||||||
passed.append('error')
|
passed.append('error')
|
||||||
passed.append(e)
|
passed.append(c.error)
|
||||||
|
|
||||||
update = Update(
|
update = Update(
|
||||||
1,
|
1,
|
||||||
|
@ -537,19 +511,19 @@ class TestDispatcher:
|
||||||
passed = []
|
passed = []
|
||||||
err = TelegramError('Telegram error')
|
err = TelegramError('Telegram error')
|
||||||
|
|
||||||
def start1(b, u):
|
def start1(u, c):
|
||||||
passed.append('start1')
|
passed.append('start1')
|
||||||
raise err
|
raise err
|
||||||
|
|
||||||
def start2(b, u):
|
def start2(u, c):
|
||||||
passed.append('start2')
|
passed.append('start2')
|
||||||
|
|
||||||
def start3(b, u):
|
def start3(u, c):
|
||||||
passed.append('start3')
|
passed.append('start3')
|
||||||
|
|
||||||
def error(b, u, e):
|
def error(u, c):
|
||||||
passed.append('error')
|
passed.append('error')
|
||||||
passed.append(e)
|
passed.append(c.error)
|
||||||
|
|
||||||
update = Update(
|
update = Update(
|
||||||
1,
|
1,
|
||||||
|
@ -622,10 +596,10 @@ class TestDispatcher:
|
||||||
def flush(self):
|
def flush(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def start1(b, u):
|
def start1(u, c):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def error(b, u, e):
|
def error(u, c):
|
||||||
increment.append("error")
|
increment.append("error")
|
||||||
|
|
||||||
# If updating a user_data or chat_data from a persistence object throws an 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()
|
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_handler(CommandHandler('start', start1))
|
||||||
dp.add_error_handler(error)
|
dp.add_error_handler(error)
|
||||||
dp.process_update(update)
|
dp.process_update(update)
|
||||||
|
@ -656,19 +630,19 @@ class TestDispatcher:
|
||||||
passed = []
|
passed = []
|
||||||
err = TelegramError('Telegram error')
|
err = TelegramError('Telegram error')
|
||||||
|
|
||||||
def start1(b, u):
|
def start1(u, c):
|
||||||
passed.append('start1')
|
passed.append('start1')
|
||||||
raise err
|
raise err
|
||||||
|
|
||||||
def start2(b, u):
|
def start2(u, c):
|
||||||
passed.append('start2')
|
passed.append('start2')
|
||||||
|
|
||||||
def start3(b, u):
|
def start3(u, c):
|
||||||
passed.append('start3')
|
passed.append('start3')
|
||||||
|
|
||||||
def error(b, u, e):
|
def error(u, c):
|
||||||
passed.append('error')
|
passed.append('error')
|
||||||
passed.append(e)
|
passed.append(c.error)
|
||||||
raise DispatcherHandlerStop
|
raise DispatcherHandlerStop
|
||||||
|
|
||||||
update = Update(
|
update = Update(
|
||||||
|
@ -696,26 +670,12 @@ class TestDispatcher:
|
||||||
assert passed == ['start1', 'error', err]
|
assert passed == ['start1', 'error', err]
|
||||||
assert passed[2] is 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):
|
def test_sensible_worker_thread_names(self, dp2):
|
||||||
thread_names = [thread.name for thread in dp2._Dispatcher__async_threads]
|
thread_names = [thread.name for thread in dp2._Dispatcher__async_threads]
|
||||||
for thread_name in thread_names:
|
for thread_name in thread_names:
|
||||||
assert thread_name.startswith(f"Bot:{dp2.bot.id}:worker:")
|
assert thread_name.startswith(f"Bot:{dp2.bot.id}:worker:")
|
||||||
|
|
||||||
def test_non_context_deprecation(self, dp):
|
def test_error_while_persisting(self, dp, monkeypatch):
|
||||||
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):
|
|
||||||
class OwnPersistence(BasePersistence):
|
class OwnPersistence(BasePersistence):
|
||||||
def update(self, data):
|
def update(self, data):
|
||||||
raise Exception('PersistenceError')
|
raise Exception('PersistenceError')
|
||||||
|
@ -779,15 +739,15 @@ class TestDispatcher:
|
||||||
1, message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text')
|
1, message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text')
|
||||||
)
|
)
|
||||||
handler = MessageHandler(Filters.all, callback)
|
handler = MessageHandler(Filters.all, callback)
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
cdp.add_error_handler(error)
|
dp.add_error_handler(error)
|
||||||
monkeypatch.setattr(cdp.logger, 'exception', logger)
|
monkeypatch.setattr(dp.logger, 'exception', logger)
|
||||||
|
|
||||||
cdp.persistence = OwnPersistence()
|
dp.persistence = OwnPersistence()
|
||||||
cdp.process_update(update)
|
dp.process_update(update)
|
||||||
assert test_flag
|
assert test_flag
|
||||||
|
|
||||||
def test_persisting_no_user_no_chat(self, cdp):
|
def test_persisting_no_user_no_chat(self, dp):
|
||||||
class OwnPersistence(BasePersistence):
|
class OwnPersistence(BasePersistence):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@ -841,25 +801,25 @@ class TestDispatcher:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
handler = MessageHandler(Filters.all, callback)
|
handler = MessageHandler(Filters.all, callback)
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
cdp.persistence = OwnPersistence()
|
dp.persistence = OwnPersistence()
|
||||||
|
|
||||||
update = Update(
|
update = Update(
|
||||||
1, message=Message(1, None, None, from_user=User(1, '', False), text='Text')
|
1, message=Message(1, None, None, from_user=User(1, '', False), text='Text')
|
||||||
)
|
)
|
||||||
cdp.process_update(update)
|
dp.process_update(update)
|
||||||
assert cdp.persistence.test_flag_bot_data
|
assert dp.persistence.test_flag_bot_data
|
||||||
assert cdp.persistence.test_flag_user_data
|
assert dp.persistence.test_flag_user_data
|
||||||
assert not cdp.persistence.test_flag_chat_data
|
assert not dp.persistence.test_flag_chat_data
|
||||||
|
|
||||||
cdp.persistence.test_flag_bot_data = False
|
dp.persistence.test_flag_bot_data = False
|
||||||
cdp.persistence.test_flag_user_data = False
|
dp.persistence.test_flag_user_data = False
|
||||||
cdp.persistence.test_flag_chat_data = False
|
dp.persistence.test_flag_chat_data = False
|
||||||
update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='Text'))
|
update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='Text'))
|
||||||
cdp.process_update(update)
|
dp.process_update(update)
|
||||||
assert cdp.persistence.test_flag_bot_data
|
assert dp.persistence.test_flag_bot_data
|
||||||
assert not cdp.persistence.test_flag_user_data
|
assert not dp.persistence.test_flag_user_data
|
||||||
assert cdp.persistence.test_flag_chat_data
|
assert dp.persistence.test_flag_chat_data
|
||||||
|
|
||||||
def test_update_persistence_once_per_update(self, monkeypatch, dp):
|
def test_update_persistence_once_per_update(self, monkeypatch, dp):
|
||||||
def update_persistence(*args, **kwargs):
|
def update_persistence(*args, **kwargs):
|
||||||
|
|
|
@ -94,29 +94,6 @@ class TestInlineQueryHandler:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.test_flag = False
|
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):
|
def callback_context(self, update, context):
|
||||||
self.test_flag = (
|
self.test_flag = (
|
||||||
isinstance(context, CallbackContext)
|
isinstance(context, CallbackContext)
|
||||||
|
@ -136,130 +113,44 @@ class TestInlineQueryHandler:
|
||||||
if context.matches[0].groupdict():
|
if context.matches[0].groupdict():
|
||||||
self.test_flag = context.matches[0].groupdict() == {'begin': 't', 'end': ' query'}
|
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<begin>.*)est(?P<end>.*)')
|
|
||||||
|
|
||||||
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<begin>.*)est(?P<end>.*)', 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<begin>.*)est(?P<end>.*)', 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):
|
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)
|
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)
|
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
|
assert self.test_flag
|
||||||
|
|
||||||
def test_context_pattern(self, cdp, inline_query):
|
def test_context_pattern(self, dp, inline_query):
|
||||||
handler = InlineQueryHandler(
|
handler = InlineQueryHandler(
|
||||||
self.callback_context_pattern, pattern=r'(?P<begin>.*)est(?P<end>.*)'
|
self.callback_context_pattern, pattern=r'(?P<begin>.*)est(?P<end>.*)'
|
||||||
)
|
)
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
|
|
||||||
cdp.process_update(inline_query)
|
dp.process_update(inline_query)
|
||||||
assert self.test_flag
|
assert self.test_flag
|
||||||
|
|
||||||
cdp.remove_handler(handler)
|
dp.remove_handler(handler)
|
||||||
handler = InlineQueryHandler(self.callback_context_pattern, pattern=r'(t)est(.*)')
|
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
|
assert self.test_flag
|
||||||
|
|
||||||
@pytest.mark.parametrize('chat_types', [[Chat.SENDER], [Chat.SENDER, Chat.SUPERGROUP], []])
|
@pytest.mark.parametrize('chat_types', [[Chat.SENDER], [Chat.SENDER, Chat.SUPERGROUP], []])
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'chat_type,result', [(Chat.SENDER, True), (Chat.CHANNEL, False), (None, False)]
|
'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:
|
try:
|
||||||
inline_query.inline_query.chat_type = chat_type
|
inline_query.inline_query.chat_type = chat_type
|
||||||
|
|
||||||
handler = InlineQueryHandler(self.callback_context, chat_types=chat_types)
|
handler = InlineQueryHandler(self.callback_context, chat_types=chat_types)
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
cdp.process_update(inline_query)
|
dp.process_update(inline_query)
|
||||||
|
|
||||||
if not chat_types:
|
if not chat_types:
|
||||||
assert self.test_flag is False
|
assert self.test_flag is False
|
||||||
|
|
|
@ -66,20 +66,20 @@ class TestJobQueue:
|
||||||
self.job_time = 0
|
self.job_time = 0
|
||||||
self.received_error = None
|
self.received_error = None
|
||||||
|
|
||||||
def job_run_once(self, bot, job):
|
def job_run_once(self, context):
|
||||||
self.result += 1
|
self.result += 1
|
||||||
|
|
||||||
def job_with_exception(self, bot, job=None):
|
def job_with_exception(self, context):
|
||||||
raise Exception('Test Error')
|
raise Exception('Test Error')
|
||||||
|
|
||||||
def job_remove_self(self, bot, job):
|
def job_remove_self(self, context):
|
||||||
self.result += 1
|
self.result += 1
|
||||||
job.schedule_removal()
|
context.job.schedule_removal()
|
||||||
|
|
||||||
def job_run_once_with_context(self, bot, job):
|
def job_run_once_with_context(self, context):
|
||||||
self.result += job.context
|
self.result += context.job.context
|
||||||
|
|
||||||
def job_datetime_tests(self, bot, job):
|
def job_datetime_tests(self, context):
|
||||||
self.job_time = time.time()
|
self.job_time = time.time()
|
||||||
|
|
||||||
def job_context_based_callback(self, context):
|
def job_context_based_callback(self, context):
|
||||||
|
@ -95,9 +95,6 @@ class TestJobQueue:
|
||||||
):
|
):
|
||||||
self.result += 1
|
self.result += 1
|
||||||
|
|
||||||
def error_handler(self, bot, update, error):
|
|
||||||
self.received_error = str(error)
|
|
||||||
|
|
||||||
def error_handler_context(self, update, context):
|
def error_handler_context(self, update, context):
|
||||||
self.received_error = str(context.error)
|
self.received_error = str(context.error)
|
||||||
|
|
||||||
|
@ -233,7 +230,7 @@ class TestJobQueue:
|
||||||
assert self.result == 1
|
assert self.result == 1
|
||||||
|
|
||||||
def test_in_updater(self, bot):
|
def test_in_updater(self, bot):
|
||||||
u = Updater(bot=bot, use_context=False)
|
u = Updater(bot=bot)
|
||||||
u.job_queue.start()
|
u.job_queue.start()
|
||||||
try:
|
try:
|
||||||
u.job_queue.run_repeating(self.job_run_once, 0.02)
|
u.job_queue.run_repeating(self.job_run_once, 0.02)
|
||||||
|
@ -377,13 +374,8 @@ class TestJobQueue:
|
||||||
finally:
|
finally:
|
||||||
_dp.bot = original_bot
|
_dp.bot = original_bot
|
||||||
|
|
||||||
@pytest.mark.parametrize('use_context', [True, False])
|
def test_get_jobs(self, job_queue):
|
||||||
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
|
callback = self.job_context_based_callback
|
||||||
else:
|
|
||||||
callback = self.job_run_once
|
|
||||||
|
|
||||||
job1 = job_queue.run_once(callback, 10, name='name1')
|
job1 = job_queue.run_once(callback, 10, name='name1')
|
||||||
job2 = 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('name1') == (job1, job2)
|
||||||
assert job_queue.get_jobs_by_name('name2') == (job3,)
|
assert job_queue.get_jobs_by_name('name2') == (job3,)
|
||||||
|
|
||||||
def test_context_based_callback(self, job_queue):
|
def test_job_run(self, _dp):
|
||||||
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
|
|
||||||
job_queue = JobQueue()
|
job_queue = JobQueue()
|
||||||
job_queue.set_dispatcher(_dp)
|
job_queue.set_dispatcher(_dp)
|
||||||
if use_context:
|
|
||||||
job = job_queue.run_repeating(self.job_context_based_callback, 0.02, context=2)
|
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)
|
|
||||||
assert self.result == 0
|
assert self.result == 0
|
||||||
job.run(_dp)
|
job.run(_dp)
|
||||||
assert self.result == 1
|
assert self.result == 1
|
||||||
|
@ -443,8 +421,8 @@ class TestJobQueue:
|
||||||
assert not job == job_queue
|
assert not job == job_queue
|
||||||
assert not job < job
|
assert not job < job
|
||||||
|
|
||||||
def test_dispatch_error(self, job_queue, dp):
|
def test_dispatch_error_context(self, job_queue, dp):
|
||||||
dp.add_error_handler(self.error_handler)
|
dp.add_error_handler(self.error_handler_context)
|
||||||
|
|
||||||
job = job_queue.run_once(self.job_with_exception, 0.05)
|
job = job_queue.run_once(self.job_with_exception, 0.05)
|
||||||
sleep(0.1)
|
sleep(0.1)
|
||||||
|
@ -454,7 +432,7 @@ class TestJobQueue:
|
||||||
assert self.received_error == 'Test Error'
|
assert self.received_error == 'Test Error'
|
||||||
|
|
||||||
# Remove handler
|
# Remove handler
|
||||||
dp.remove_error_handler(self.error_handler)
|
dp.remove_error_handler(self.error_handler_context)
|
||||||
self.received_error = None
|
self.received_error = None
|
||||||
|
|
||||||
job = job_queue.run_once(self.job_with_exception, 0.05)
|
job = job_queue.run_once(self.job_with_exception, 0.05)
|
||||||
|
@ -463,26 +441,6 @@ class TestJobQueue:
|
||||||
job.run(dp)
|
job.run(dp)
|
||||||
assert self.received_error is None
|
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):
|
def test_dispatch_error_that_raises_errors(self, job_queue, dp, caplog):
|
||||||
dp.add_error_handler(self.error_handler_raise_error)
|
dp.add_error_handler(self.error_handler_raise_error)
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ import re
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from telegram.utils.deprecate import TelegramDeprecationWarning
|
|
||||||
|
|
||||||
from telegram import (
|
from telegram import (
|
||||||
Message,
|
Message,
|
||||||
|
@ -72,7 +71,7 @@ class TestMessageHandler:
|
||||||
SRE_TYPE = type(re.match("", ""))
|
SRE_TYPE = type(re.match("", ""))
|
||||||
|
|
||||||
def test_slot_behaviour(self, mro_slots):
|
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__:
|
for attr in handler.__slots__:
|
||||||
assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||||
assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot"
|
assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot"
|
||||||
|
@ -81,23 +80,6 @@ class TestMessageHandler:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.test_flag = False
|
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):
|
def callback_context(self, update, context):
|
||||||
self.test_flag = (
|
self.test_flag = (
|
||||||
isinstance(context, CallbackContext)
|
isinstance(context, CallbackContext)
|
||||||
|
@ -137,75 +119,8 @@ class TestMessageHandler:
|
||||||
num = len(context.matches) == 2
|
num = len(context.matches) == 2
|
||||||
self.test_flag = types and num
|
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):
|
def test_with_filter(self, message):
|
||||||
handler = MessageHandler(Filters.group, self.callback_basic)
|
handler = MessageHandler(Filters.group, self.callback_context)
|
||||||
|
|
||||||
message.chat.type = 'group'
|
message.chat.type = 'group'
|
||||||
assert handler.check_update(Update(0, message))
|
assert handler.check_update(Update(0, message))
|
||||||
|
@ -221,7 +136,7 @@ class TestMessageHandler:
|
||||||
self.flag = True
|
self.flag = True
|
||||||
|
|
||||||
test_filter = TestFilter()
|
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))
|
update = Update(1, callback_query=CallbackQuery(1, None, None, message=message))
|
||||||
|
|
||||||
|
@ -235,110 +150,61 @@ class TestMessageHandler:
|
||||||
& ~Filters.update.channel_post
|
& ~Filters.update.channel_post
|
||||||
& Filters.update.edited_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, edited_message=message))
|
||||||
assert not handler.check_update(Update(0, message=message))
|
assert not handler.check_update(Update(0, message=message))
|
||||||
assert not handler.check_update(Update(0, channel_post=message))
|
assert not handler.check_update(Update(0, channel_post=message))
|
||||||
assert handler.check_update(Update(0, edited_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):
|
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)
|
assert not handler.check_update(false_update)
|
||||||
|
|
||||||
def test_context(self, cdp, message):
|
def test_context(self, dp, message):
|
||||||
handler = MessageHandler(
|
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
|
assert self.test_flag
|
||||||
|
|
||||||
self.test_flag = False
|
self.test_flag = False
|
||||||
cdp.process_update(Update(0, edited_message=message))
|
dp.process_update(Update(0, edited_message=message))
|
||||||
assert self.test_flag
|
assert self.test_flag
|
||||||
|
|
||||||
self.test_flag = False
|
self.test_flag = False
|
||||||
cdp.process_update(Update(0, channel_post=message))
|
dp.process_update(Update(0, channel_post=message))
|
||||||
assert self.test_flag
|
assert self.test_flag
|
||||||
|
|
||||||
self.test_flag = False
|
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
|
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)
|
handler = MessageHandler(Filters.regex('one two'), self.callback_context_regex1)
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
|
|
||||||
message.text = 'not it'
|
message.text = 'not it'
|
||||||
cdp.process_update(Update(0, message))
|
dp.process_update(Update(0, message))
|
||||||
assert not self.test_flag
|
assert not self.test_flag
|
||||||
|
|
||||||
message.text += ' one two now it is'
|
message.text += ' one two now it is'
|
||||||
cdp.process_update(Update(0, message))
|
dp.process_update(Update(0, message))
|
||||||
assert self.test_flag
|
assert self.test_flag
|
||||||
|
|
||||||
def test_context_multiple_regex(self, cdp, message):
|
def test_context_multiple_regex(self, dp, message):
|
||||||
handler = MessageHandler(
|
handler = MessageHandler(
|
||||||
Filters.regex('one') & Filters.regex('two'), self.callback_context_regex2
|
Filters.regex('one') & Filters.regex('two'), self.callback_context_regex2
|
||||||
)
|
)
|
||||||
cdp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
|
|
||||||
message.text = 'not it'
|
message.text = 'not it'
|
||||||
cdp.process_update(Update(0, message))
|
dp.process_update(Update(0, message))
|
||||||
assert not self.test_flag
|
assert not self.test_flag
|
||||||
|
|
||||||
message.text += ' one two now it is'
|
message.text += ' one two now it is'
|
||||||
cdp.process_update(Update(0, message))
|
dp.process_update(Update(0, message))
|
||||||
assert self.test_flag
|
assert self.test_flag
|
||||||
|
|
|
@ -342,7 +342,7 @@ class TestBasePersistence:
|
||||||
@pytest.mark.parametrize('run_async', [True, False], ids=['synchronous', 'run_async'])
|
@pytest.mark.parametrize('run_async', [True, False], ids=['synchronous', 'run_async'])
|
||||||
def test_dispatcher_integration_handlers(
|
def test_dispatcher_integration_handlers(
|
||||||
self,
|
self,
|
||||||
cdp,
|
dp,
|
||||||
caplog,
|
caplog,
|
||||||
bot,
|
bot,
|
||||||
base_persistence,
|
base_persistence,
|
||||||
|
@ -373,7 +373,7 @@ class TestBasePersistence:
|
||||||
base_persistence.refresh_bot_data = lambda x: x
|
base_persistence.refresh_bot_data = lambda x: x
|
||||||
base_persistence.refresh_chat_data = lambda x, y: x
|
base_persistence.refresh_chat_data = lambda x, y: x
|
||||||
base_persistence.refresh_user_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
|
dp = updater.dispatcher
|
||||||
|
|
||||||
def callback_known_user(update, context):
|
def callback_known_user(update, context):
|
||||||
|
@ -403,17 +403,14 @@ class TestBasePersistence:
|
||||||
known_user = MessageHandler(
|
known_user = MessageHandler(
|
||||||
Filters.user(user_id=12345),
|
Filters.user(user_id=12345),
|
||||||
callback_known_user,
|
callback_known_user,
|
||||||
pass_chat_data=True,
|
|
||||||
pass_user_data=True,
|
|
||||||
)
|
)
|
||||||
known_chat = MessageHandler(
|
known_chat = MessageHandler(
|
||||||
Filters.chat(chat_id=-67890),
|
Filters.chat(chat_id=-67890),
|
||||||
callback_known_chat,
|
callback_known_chat,
|
||||||
pass_chat_data=True,
|
|
||||||
pass_user_data=True,
|
|
||||||
)
|
)
|
||||||
unknown = MessageHandler(
|
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_user)
|
||||||
dp.add_handler(known_chat)
|
dp.add_handler(known_chat)
|
||||||
|
@ -481,7 +478,7 @@ class TestBasePersistence:
|
||||||
@pytest.mark.parametrize('run_async', [True, False], ids=['synchronous', 'run_async'])
|
@pytest.mark.parametrize('run_async', [True, False], ids=['synchronous', 'run_async'])
|
||||||
def test_persistence_dispatcher_integration_refresh_data(
|
def test_persistence_dispatcher_integration_refresh_data(
|
||||||
self,
|
self,
|
||||||
cdp,
|
dp,
|
||||||
base_persistence,
|
base_persistence,
|
||||||
chat_data,
|
chat_data,
|
||||||
bot_data,
|
bot_data,
|
||||||
|
@ -500,7 +497,7 @@ class TestBasePersistence:
|
||||||
base_persistence.store_data = PersistenceInput(
|
base_persistence.store_data = PersistenceInput(
|
||||||
bot_data=store_bot_data, chat_data=store_chat_data, user_data=store_user_data
|
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
|
self.test_flag = True
|
||||||
|
|
||||||
|
@ -535,26 +532,22 @@ class TestBasePersistence:
|
||||||
with_user_and_chat = MessageHandler(
|
with_user_and_chat = MessageHandler(
|
||||||
Filters.user(user_id=12345),
|
Filters.user(user_id=12345),
|
||||||
callback_with_user_and_chat,
|
callback_with_user_and_chat,
|
||||||
pass_chat_data=True,
|
|
||||||
pass_user_data=True,
|
|
||||||
run_async=run_async,
|
run_async=run_async,
|
||||||
)
|
)
|
||||||
without_user_and_chat = MessageHandler(
|
without_user_and_chat = MessageHandler(
|
||||||
Filters.all,
|
Filters.all,
|
||||||
callback_without_user_and_chat,
|
callback_without_user_and_chat,
|
||||||
pass_chat_data=True,
|
|
||||||
pass_user_data=True,
|
|
||||||
run_async=run_async,
|
run_async=run_async,
|
||||||
)
|
)
|
||||||
cdp.add_handler(with_user_and_chat)
|
dp.add_handler(with_user_and_chat)
|
||||||
cdp.add_handler(without_user_and_chat)
|
dp.add_handler(without_user_and_chat)
|
||||||
user = User(id=12345, first_name='test user', is_bot=False)
|
user = User(id=12345, first_name='test user', is_bot=False)
|
||||||
chat = Chat(id=-987654, type='group')
|
chat = Chat(id=-987654, type='group')
|
||||||
m = Message(1, None, chat, from_user=user)
|
m = Message(1, None, chat, from_user=user)
|
||||||
|
|
||||||
# has user and chat
|
# has user and chat
|
||||||
u = Update(0, m)
|
u = Update(0, m)
|
||||||
cdp.process_update(u)
|
dp.process_update(u)
|
||||||
|
|
||||||
assert self.test_flag is True
|
assert self.test_flag is True
|
||||||
|
|
||||||
|
@ -562,7 +555,7 @@ class TestBasePersistence:
|
||||||
m.from_user = None
|
m.from_user = None
|
||||||
m.chat = None
|
m.chat = None
|
||||||
u = Update(1, m)
|
u = Update(1, m)
|
||||||
cdp.process_update(u)
|
dp.process_update(u)
|
||||||
|
|
||||||
assert self.test_flag is True
|
assert self.test_flag is True
|
||||||
|
|
||||||
|
@ -1630,7 +1623,7 @@ class TestPicklePersistence:
|
||||||
assert conversations_test['name1'] == conversation1
|
assert conversations_test['name1'] == conversation1
|
||||||
|
|
||||||
def test_with_handler(self, bot, update, bot_data, pickle_persistence, good_pickle_files):
|
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
|
dp = u.dispatcher
|
||||||
bot.callback_data_cache.clear_callback_data()
|
bot.callback_data_cache.clear_callback_data()
|
||||||
bot.callback_data_cache.clear_callback_queries()
|
bot.callback_data_cache.clear_callback_queries()
|
||||||
|
@ -1659,8 +1652,8 @@ class TestPicklePersistence:
|
||||||
if not context.bot.callback_data_cache.persistence_data == ([], {'test1': 'test0'}):
|
if not context.bot.callback_data_cache.persistence_data == ([], {'test1': 'test0'}):
|
||||||
pytest.fail()
|
pytest.fail()
|
||||||
|
|
||||||
h1 = MessageHandler(None, first, pass_user_data=True, pass_chat_data=True)
|
h1 = MessageHandler(None, first)
|
||||||
h2 = MessageHandler(None, second, pass_user_data=True, pass_chat_data=True)
|
h2 = MessageHandler(None, second)
|
||||||
dp.add_handler(h1)
|
dp.add_handler(h1)
|
||||||
dp.process_update(update)
|
dp.process_update(update)
|
||||||
pickle_persistence_2 = PicklePersistence(
|
pickle_persistence_2 = PicklePersistence(
|
||||||
|
@ -1779,7 +1772,6 @@ class TestPicklePersistence:
|
||||||
|
|
||||||
def test_with_conversation_handler(self, dp, update, good_pickle_files, pickle_persistence):
|
def test_with_conversation_handler(self, dp, update, good_pickle_files, pickle_persistence):
|
||||||
dp.persistence = pickle_persistence
|
dp.persistence = pickle_persistence
|
||||||
dp.use_context = True
|
|
||||||
NEXT, NEXT2 = range(2)
|
NEXT, NEXT2 = range(2)
|
||||||
|
|
||||||
def start(update, context):
|
def start(update, context):
|
||||||
|
@ -1814,7 +1806,6 @@ class TestPicklePersistence:
|
||||||
self, dp, update, good_pickle_files, pickle_persistence
|
self, dp, update, good_pickle_files, pickle_persistence
|
||||||
):
|
):
|
||||||
dp.persistence = pickle_persistence
|
dp.persistence = pickle_persistence
|
||||||
dp.use_context = True
|
|
||||||
NEXT2, NEXT3 = range(1, 3)
|
NEXT2, NEXT3 = range(1, 3)
|
||||||
|
|
||||||
def start(update, context):
|
def start(update, context):
|
||||||
|
@ -1862,8 +1853,8 @@ class TestPicklePersistence:
|
||||||
assert nested_ch.conversations[nested_ch._get_key(update)] == 1
|
assert nested_ch.conversations[nested_ch._get_key(update)] == 1
|
||||||
assert nested_ch.conversations == pickle_persistence.conversations['name3']
|
assert nested_ch.conversations == pickle_persistence.conversations['name3']
|
||||||
|
|
||||||
def test_with_job(self, job_queue, cdp, pickle_persistence):
|
def test_with_job(self, job_queue, dp, pickle_persistence):
|
||||||
cdp.bot.arbitrary_callback_data = True
|
dp.bot.arbitrary_callback_data = True
|
||||||
|
|
||||||
def job_callback(context):
|
def job_callback(context):
|
||||||
context.bot_data['test1'] = '456'
|
context.bot_data['test1'] = '456'
|
||||||
|
@ -1871,8 +1862,8 @@ class TestPicklePersistence:
|
||||||
context.dispatcher.user_data[789]['test3'] = '123'
|
context.dispatcher.user_data[789]['test3'] = '123'
|
||||||
context.bot.callback_data_cache._callback_queries['test'] = 'Working4!'
|
context.bot.callback_data_cache._callback_queries['test'] = 'Working4!'
|
||||||
|
|
||||||
cdp.persistence = pickle_persistence
|
dp.persistence = pickle_persistence
|
||||||
job_queue.set_dispatcher(cdp)
|
job_queue.set_dispatcher(dp)
|
||||||
job_queue.start()
|
job_queue.start()
|
||||||
job_queue.run_once(job_callback, 0.01)
|
job_queue.run_once(job_callback, 0.01)
|
||||||
sleep(0.5)
|
sleep(0.5)
|
||||||
|
@ -2185,7 +2176,7 @@ class TestDictPersistence:
|
||||||
|
|
||||||
def test_with_handler(self, bot, update):
|
def test_with_handler(self, bot, update):
|
||||||
dict_persistence = DictPersistence()
|
dict_persistence = DictPersistence()
|
||||||
u = Updater(bot=bot, persistence=dict_persistence, use_context=True)
|
u = Updater(bot=bot, persistence=dict_persistence)
|
||||||
dp = u.dispatcher
|
dp = u.dispatcher
|
||||||
|
|
||||||
def first(update, context):
|
def first(update, context):
|
||||||
|
@ -2235,7 +2226,6 @@ class TestDictPersistence:
|
||||||
def test_with_conversationHandler(self, dp, update, conversations_json):
|
def test_with_conversationHandler(self, dp, update, conversations_json):
|
||||||
dict_persistence = DictPersistence(conversations_json=conversations_json)
|
dict_persistence = DictPersistence(conversations_json=conversations_json)
|
||||||
dp.persistence = dict_persistence
|
dp.persistence = dict_persistence
|
||||||
dp.use_context = True
|
|
||||||
NEXT, NEXT2 = range(2)
|
NEXT, NEXT2 = range(2)
|
||||||
|
|
||||||
def start(update, context):
|
def start(update, context):
|
||||||
|
@ -2269,7 +2259,6 @@ class TestDictPersistence:
|
||||||
def test_with_nested_conversationHandler(self, dp, update, conversations_json):
|
def test_with_nested_conversationHandler(self, dp, update, conversations_json):
|
||||||
dict_persistence = DictPersistence(conversations_json=conversations_json)
|
dict_persistence = DictPersistence(conversations_json=conversations_json)
|
||||||
dp.persistence = dict_persistence
|
dp.persistence = dict_persistence
|
||||||
dp.use_context = True
|
|
||||||
NEXT2, NEXT3 = range(1, 3)
|
NEXT2, NEXT3 = range(1, 3)
|
||||||
|
|
||||||
def start(update, context):
|
def start(update, context):
|
||||||
|
@ -2317,8 +2306,8 @@ class TestDictPersistence:
|
||||||
assert nested_ch.conversations[nested_ch._get_key(update)] == 1
|
assert nested_ch.conversations[nested_ch._get_key(update)] == 1
|
||||||
assert nested_ch.conversations == dict_persistence.conversations['name3']
|
assert nested_ch.conversations == dict_persistence.conversations['name3']
|
||||||
|
|
||||||
def test_with_job(self, job_queue, cdp):
|
def test_with_job(self, job_queue, dp):
|
||||||
cdp.bot.arbitrary_callback_data = True
|
dp.bot.arbitrary_callback_data = True
|
||||||
|
|
||||||
def job_callback(context):
|
def job_callback(context):
|
||||||
context.bot_data['test1'] = '456'
|
context.bot_data['test1'] = '456'
|
||||||
|
@ -2327,8 +2316,8 @@ class TestDictPersistence:
|
||||||
context.bot.callback_data_cache._callback_queries['test'] = 'Working4!'
|
context.bot.callback_data_cache._callback_queries['test'] = 'Working4!'
|
||||||
|
|
||||||
dict_persistence = DictPersistence()
|
dict_persistence = DictPersistence()
|
||||||
cdp.persistence = dict_persistence
|
dp.persistence = dict_persistence
|
||||||
job_queue.set_dispatcher(cdp)
|
job_queue.set_dispatcher(dp)
|
||||||
job_queue.start()
|
job_queue.start()
|
||||||
job_queue.run_once(job_callback, 0.01)
|
job_queue.run_once(job_callback, 0.01)
|
||||||
sleep(0.8)
|
sleep(0.8)
|
||||||
|
|
|
@ -75,7 +75,7 @@ class TestPollAnswerHandler:
|
||||||
test_flag = False
|
test_flag = False
|
||||||
|
|
||||||
def test_slot_behaviour(self, mro_slots):
|
def test_slot_behaviour(self, mro_slots):
|
||||||
handler = PollAnswerHandler(self.callback_basic)
|
handler = PollAnswerHandler(self.callback_context)
|
||||||
for attr in handler.__slots__:
|
for attr in handler.__slots__:
|
||||||
assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||||
assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot"
|
assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot"
|
||||||
|
@ -84,23 +84,6 @@ class TestPollAnswerHandler:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.test_flag = False
|
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):
|
def callback_context(self, update, context):
|
||||||
self.test_flag = (
|
self.test_flag = (
|
||||||
isinstance(context, CallbackContext)
|
isinstance(context, CallbackContext)
|
||||||
|
@ -114,70 +97,13 @@ class TestPollAnswerHandler:
|
||||||
and isinstance(update.poll_answer, PollAnswer)
|
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):
|
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)
|
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)
|
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
|
assert self.test_flag
|
||||||
|
|
|
@ -88,7 +88,7 @@ class TestPollHandler:
|
||||||
test_flag = False
|
test_flag = False
|
||||||
|
|
||||||
def test_slot_behaviour(self, mro_slots):
|
def test_slot_behaviour(self, mro_slots):
|
||||||
inst = PollHandler(self.callback_basic)
|
inst = PollHandler(self.callback_context)
|
||||||
for attr in inst.__slots__:
|
for attr in inst.__slots__:
|
||||||
assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||||
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||||
|
@ -97,23 +97,6 @@ class TestPollHandler:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.test_flag = False
|
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):
|
def callback_context(self, update, context):
|
||||||
self.test_flag = (
|
self.test_flag = (
|
||||||
isinstance(context, CallbackContext)
|
isinstance(context, CallbackContext)
|
||||||
|
@ -127,68 +110,13 @@ class TestPollHandler:
|
||||||
and isinstance(update.poll, Poll)
|
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):
|
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)
|
assert not handler.check_update(false_update)
|
||||||
|
|
||||||
def test_context(self, cdp, poll):
|
def test_context(self, dp, poll):
|
||||||
handler = PollHandler(self.callback_context)
|
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
|
assert self.test_flag
|
||||||
|
|
|
@ -80,7 +80,7 @@ class TestPreCheckoutQueryHandler:
|
||||||
test_flag = False
|
test_flag = False
|
||||||
|
|
||||||
def test_slot_behaviour(self, mro_slots):
|
def test_slot_behaviour(self, mro_slots):
|
||||||
inst = PreCheckoutQueryHandler(self.callback_basic)
|
inst = PreCheckoutQueryHandler(self.callback_context)
|
||||||
for attr in inst.__slots__:
|
for attr in inst.__slots__:
|
||||||
assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||||
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||||
|
@ -89,23 +89,6 @@ class TestPreCheckoutQueryHandler:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.test_flag = False
|
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):
|
def callback_context(self, update, context):
|
||||||
self.test_flag = (
|
self.test_flag = (
|
||||||
isinstance(context, CallbackContext)
|
isinstance(context, CallbackContext)
|
||||||
|
@ -119,71 +102,13 @@ class TestPreCheckoutQueryHandler:
|
||||||
and isinstance(update.pre_checkout_query, PreCheckoutQuery)
|
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):
|
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)
|
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)
|
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
|
assert self.test_flag
|
||||||
|
|
|
@ -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 <devs@python-telegram-bot.org>
|
|
||||||
#
|
|
||||||
# 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<begin>.*)est(?P<end>.*)', 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<begin>.*)est(?P<end>.*)', 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
|
|
|
@ -84,7 +84,7 @@ class TestShippingQueryHandler:
|
||||||
test_flag = False
|
test_flag = False
|
||||||
|
|
||||||
def test_slot_behaviour(self, mro_slots):
|
def test_slot_behaviour(self, mro_slots):
|
||||||
inst = ShippingQueryHandler(self.callback_basic)
|
inst = ShippingQueryHandler(self.callback_context)
|
||||||
for attr in inst.__slots__:
|
for attr in inst.__slots__:
|
||||||
assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||||
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||||
|
@ -93,23 +93,6 @@ class TestShippingQueryHandler:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.test_flag = False
|
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):
|
def callback_context(self, update, context):
|
||||||
self.test_flag = (
|
self.test_flag = (
|
||||||
isinstance(context, CallbackContext)
|
isinstance(context, CallbackContext)
|
||||||
|
@ -123,71 +106,13 @@ class TestShippingQueryHandler:
|
||||||
and isinstance(update.shipping_query, ShippingQuery)
|
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):
|
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)
|
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)
|
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
|
assert self.test_flag
|
||||||
|
|
|
@ -72,7 +72,7 @@ class TestStringCommandHandler:
|
||||||
test_flag = False
|
test_flag = False
|
||||||
|
|
||||||
def test_slot_behaviour(self, mro_slots):
|
def test_slot_behaviour(self, mro_slots):
|
||||||
inst = StringCommandHandler('sleepy', self.callback_basic)
|
inst = StringCommandHandler('sleepy', self.callback_context)
|
||||||
for attr in inst.__slots__:
|
for attr in inst.__slots__:
|
||||||
assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||||
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||||
|
@ -81,23 +81,6 @@ class TestStringCommandHandler:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.test_flag = False
|
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):
|
def callback_context(self, update, context):
|
||||||
self.test_flag = (
|
self.test_flag = (
|
||||||
isinstance(context, CallbackContext)
|
isinstance(context, CallbackContext)
|
||||||
|
@ -113,75 +96,23 @@ class TestStringCommandHandler:
|
||||||
def callback_context_args(self, update, context):
|
def callback_context_args(self, update, context):
|
||||||
self.test_flag = context.args == ['one', 'two']
|
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):
|
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)
|
assert not handler.check_update(false_update)
|
||||||
|
|
||||||
def test_context(self, cdp):
|
def test_context(self, dp):
|
||||||
handler = StringCommandHandler('test', self.callback_context)
|
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
|
assert self.test_flag
|
||||||
|
|
||||||
def test_context_args(self, cdp):
|
def test_context_args(self, dp):
|
||||||
handler = StringCommandHandler('test', self.callback_context_args)
|
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
|
assert not self.test_flag
|
||||||
|
|
||||||
cdp.process_update('/test one two')
|
dp.process_update('/test one two')
|
||||||
assert self.test_flag
|
assert self.test_flag
|
||||||
|
|
|
@ -72,7 +72,7 @@ class TestStringRegexHandler:
|
||||||
test_flag = False
|
test_flag = False
|
||||||
|
|
||||||
def test_slot_behaviour(self, mro_slots):
|
def test_slot_behaviour(self, mro_slots):
|
||||||
inst = StringRegexHandler('pfft', self.callback_basic)
|
inst = StringRegexHandler('pfft', self.callback_context)
|
||||||
for attr in inst.__slots__:
|
for attr in inst.__slots__:
|
||||||
assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||||
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||||
|
@ -81,23 +81,6 @@ class TestStringRegexHandler:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.test_flag = False
|
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):
|
def callback_context(self, update, context):
|
||||||
self.test_flag = (
|
self.test_flag = (
|
||||||
isinstance(context, CallbackContext)
|
isinstance(context, CallbackContext)
|
||||||
|
@ -114,7 +97,7 @@ class TestStringRegexHandler:
|
||||||
self.test_flag = context.matches[0].groupdict() == {'begin': 't', 'end': ' message'}
|
self.test_flag = context.matches[0].groupdict() == {'begin': 't', 'end': ' message'}
|
||||||
|
|
||||||
def test_basic(self, dp):
|
def test_basic(self, dp):
|
||||||
handler = StringRegexHandler('(?P<begin>.*)est(?P<end>.*)', self.callback_basic)
|
handler = StringRegexHandler('(?P<begin>.*)est(?P<end>.*)', self.callback_context)
|
||||||
dp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
|
|
||||||
assert handler.check_update('test message')
|
assert handler.check_update('test message')
|
||||||
|
@ -123,71 +106,27 @@ class TestStringRegexHandler:
|
||||||
|
|
||||||
assert not handler.check_update('does not match')
|
assert not handler.check_update('does not match')
|
||||||
|
|
||||||
def test_with_passing_group_dict(self, dp):
|
|
||||||
handler = StringRegexHandler(
|
|
||||||
'(?P<begin>.*)est(?P<end>.*)', 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<begin>.*)est(?P<end>.*)', 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):
|
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)
|
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)
|
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
|
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)
|
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
|
assert self.test_flag
|
||||||
|
|
||||||
cdp.remove_handler(handler)
|
dp.remove_handler(handler)
|
||||||
handler = StringRegexHandler(r'(t)est(.*)', self.callback_context_pattern)
|
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
|
assert self.test_flag
|
||||||
|
|
|
@ -29,7 +29,7 @@ class TestTypeHandler:
|
||||||
test_flag = False
|
test_flag = False
|
||||||
|
|
||||||
def test_slot_behaviour(self, mro_slots):
|
def test_slot_behaviour(self, mro_slots):
|
||||||
inst = TypeHandler(dict, self.callback_basic)
|
inst = TypeHandler(dict, self.callback_context)
|
||||||
for attr in inst.__slots__:
|
for attr in inst.__slots__:
|
||||||
assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
assert getattr(inst, attr, 'err') != 'err', f"got extra slot '{attr}'"
|
||||||
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
|
||||||
|
@ -38,17 +38,6 @@ class TestTypeHandler:
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.test_flag = False
|
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):
|
def callback_context(self, update, context):
|
||||||
self.test_flag = (
|
self.test_flag = (
|
||||||
isinstance(context, CallbackContext)
|
isinstance(context, CallbackContext)
|
||||||
|
@ -62,7 +51,7 @@ class TestTypeHandler:
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_basic(self, dp):
|
def test_basic(self, dp):
|
||||||
handler = TypeHandler(dict, self.callback_basic)
|
handler = TypeHandler(dict, self.callback_context)
|
||||||
dp.add_handler(handler)
|
dp.add_handler(handler)
|
||||||
|
|
||||||
assert handler.check_update({'a': 1, 'b': 2})
|
assert handler.check_update({'a': 1, 'b': 2})
|
||||||
|
@ -71,39 +60,14 @@ class TestTypeHandler:
|
||||||
assert self.test_flag
|
assert self.test_flag
|
||||||
|
|
||||||
def test_strict(self):
|
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})
|
o = OrderedDict({'a': 1, 'b': 2})
|
||||||
assert handler.check_update({'a': 1, 'b': 2})
|
assert handler.check_update({'a': 1, 'b': 2})
|
||||||
assert not handler.check_update(o)
|
assert not handler.check_update(o)
|
||||||
|
|
||||||
def test_pass_job_or_update_queue(self, dp):
|
def test_context(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):
|
|
||||||
handler = TypeHandler(dict, self.callback_context)
|
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
|
assert self.test_flag
|
||||||
|
|
|
@ -106,11 +106,11 @@ class TestUpdater:
|
||||||
self.cb_handler_called.clear()
|
self.cb_handler_called.clear()
|
||||||
self.test_flag = False
|
self.test_flag = False
|
||||||
|
|
||||||
def error_handler(self, bot, update, error):
|
def error_handler(self, update, context):
|
||||||
self.received = error.message
|
self.received = context.error.message
|
||||||
self.err_handler_called.set()
|
self.err_handler_called.set()
|
||||||
|
|
||||||
def callback(self, bot, update):
|
def callback(self, update, context):
|
||||||
self.received = update.message.text
|
self.received = update.message.text
|
||||||
self.cb_handler_called.set()
|
self.cb_handler_called.set()
|
||||||
|
|
||||||
|
@ -500,10 +500,9 @@ class TestUpdater:
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
assert len(recwarn) == 3
|
assert len(recwarn) == 2
|
||||||
assert str(recwarn[0].message).startswith('Old Handler API')
|
assert str(recwarn[0].message).startswith('The argument `clean` of')
|
||||||
assert str(recwarn[1].message).startswith('The argument `clean` of')
|
assert str(recwarn[1].message).startswith('The argument `force_event_loop` of')
|
||||||
assert str(recwarn[2].message).startswith('The argument `force_event_loop` of')
|
|
||||||
|
|
||||||
def test_clean_deprecation_warning_polling(self, recwarn, updater, monkeypatch):
|
def test_clean_deprecation_warning_polling(self, recwarn, updater, monkeypatch):
|
||||||
monkeypatch.setattr(updater.bot, 'set_webhook', lambda *args, **kwargs: True)
|
monkeypatch.setattr(updater.bot, 'set_webhook', lambda *args, **kwargs: True)
|
||||||
|
@ -522,9 +521,8 @@ class TestUpdater:
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
assert len(recwarn) == 2
|
assert len(recwarn) == 1
|
||||||
assert str(recwarn[0].message).startswith('Old Handler API')
|
assert str(recwarn[0].message).startswith('The argument `clean` of')
|
||||||
assert str(recwarn[1].message).startswith('The argument `clean` of')
|
|
||||||
|
|
||||||
def test_clean_drop_pending_mutually_exclusive(self, updater):
|
def test_clean_drop_pending_mutually_exclusive(self, updater):
|
||||||
with pytest.raises(TypeError, match='`clean` and `drop_pending_updates` are mutually'):
|
with pytest.raises(TypeError, match='`clean` and `drop_pending_updates` are mutually'):
|
||||||
|
@ -695,12 +693,6 @@ class TestUpdater:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
Updater(dispatcher=dispatcher, workers=8)
|
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):
|
def test_mutual_exclude_custom_context_dispatcher(self):
|
||||||
dispatcher = Dispatcher(None, None)
|
dispatcher = Dispatcher(None, None)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
|
|
Loading…
Reference in a new issue