Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion telegram/ext/callbackqueryhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

from telegram import Update
from telegram.utils.types import HandlerArg
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE

from .handler import Handler

Expand Down Expand Up @@ -130,7 +131,7 @@ def __init__(
pass_groupdict: bool = False,
pass_user_data: bool = False,
pass_chat_data: bool = False,
run_async: bool = False,
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
):
super().__init__(
callback,
Expand Down
5 changes: 3 additions & 2 deletions telegram/ext/commandhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from telegram.ext import BaseFilter, Filters
from telegram.utils.deprecate import TelegramDeprecationWarning
from telegram.utils.types import HandlerArg, SLT
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE

from .handler import Handler

Expand Down Expand Up @@ -141,7 +142,7 @@ def __init__(
pass_job_queue: bool = False,
pass_user_data: bool = False,
pass_chat_data: bool = False,
run_async: bool = False,
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
):
super().__init__(
callback,
Expand Down Expand Up @@ -350,7 +351,7 @@ def __init__(
pass_job_queue: bool = False,
pass_user_data: bool = False,
pass_chat_data: bool = False,
run_async: bool = False,
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
):

self._prefix: List[str] = list()
Expand Down
20 changes: 20 additions & 0 deletions telegram/ext/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class Defaults:
be ignored. Default: :obj:`True` in group chats and :obj:`False` in private chats.
tzinfo (:obj:`tzinfo`): A timezone to be used for all date(time) objects appearing
throughout PTB.
run_async (:obj:`bool`): Optional. Default setting for the ``run_async`` parameter of
handlers and error handlers registered through :meth:`Dispatcher.add_handler` and
:meth:`Dispatcher.add_error_handler`.

Parameters:
parse_mode (:obj:`str`, optional): Send Markdown or HTML, if you want Telegram apps to show
Expand All @@ -61,6 +64,9 @@ class Defaults:
appearing throughout PTB, i.e. if a timezone naive date(time) object is passed
somewhere, it will be assumed to be in ``tzinfo``. Must be a timezone provided by the
``pytz`` module. Defaults to UTC.
run_async (:obj:`bool`, optional): Default setting for the ``run_async`` parameter of
handlers and error handlers registered through :meth:`Dispatcher.add_handler` and
:meth:`Dispatcher.add_error_handler`. Defaults to :obj:`False`.
"""

def __init__(
Expand All @@ -73,13 +79,15 @@ def __init__(
timeout: Union[float, DefaultValue] = DEFAULT_NONE,
quote: bool = None,
tzinfo: pytz.BaseTzInfo = pytz.utc,
run_async: bool = False,
):
self._parse_mode = parse_mode
self._disable_notification = disable_notification
self._disable_web_page_preview = disable_web_page_preview
self._timeout = timeout
self._quote = quote
self._tzinfo = tzinfo
self._run_async = run_async

@property
def parse_mode(self) -> Optional[str]:
Expand Down Expand Up @@ -147,6 +155,17 @@ def tzinfo(self, value: Any) -> NoReturn:
"not have any effect."
)

@property
def run_async(self) -> Optional[bool]:
return self._run_async

@run_async.setter
def run_async(self, value: Any) -> NoReturn:
raise AttributeError(
"You can not assign a new value to defaults after because it would "
"not have any effect."
)

def __hash__(self) -> int:
return hash(
(
Expand All @@ -156,6 +175,7 @@ def __hash__(self) -> int:
self._timeout,
self._quote,
self._tzinfo,
self._run_async,
)
)

Expand Down
10 changes: 8 additions & 2 deletions telegram/ext/dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
from telegram.utils.deprecate import TelegramDeprecationWarning
from telegram.utils.promise import Promise
from telegram.utils.types import HandlerArg
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE

if TYPE_CHECKING:
from telegram import Bot
Expand Down Expand Up @@ -191,7 +192,7 @@ def __init__(
"""Dict[:obj:`int`, List[:class:`telegram.ext.Handler`]]: Holds the handlers per group."""
self.groups: List[int] = []
"""List[:obj:`int`]: A list with all groups."""
self.error_handlers: Dict[Callable, bool] = {}
self.error_handlers: Dict[Callable, Union[bool, DefaultValue]] = {}
"""Dict[:obj:`callable`, :obj:`bool`]: A dict, where the keys are error handlers and the
values indicate whether they are to be run asynchronously."""

Expand Down Expand Up @@ -588,7 +589,7 @@ def __update_persistence(self, update: HandlerArg = None) -> None:
def add_error_handler(
self,
callback: Callable[[Any, CallbackContext], None],
run_async: bool = False, # pylint: disable=W0621
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE, # pylint: disable=W0621
) -> None:
"""Registers an error handler in the Dispatcher. This handler will receive every error
which happens in your bot.
Expand Down Expand Up @@ -616,6 +617,11 @@ def add_error_handler(
if callback in self.error_handlers:
self.logger.debug('The callback is already registered as an error handler. Ignoring.')
return

if run_async is DEFAULT_FALSE and self.bot.defaults:
if self.bot.defaults.run_async:
run_async = True

self.error_handlers[callback] = run_async

def remove_error_handler(self, callback: Callable[[Any, CallbackContext], None]) -> None:
Expand Down
12 changes: 9 additions & 3 deletions telegram/ext/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from telegram import Update
from telegram.utils.promise import Promise
from telegram.utils.types import HandlerArg
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE

if TYPE_CHECKING:
from telegram.ext import CallbackContext, Dispatcher
Expand Down Expand Up @@ -96,7 +97,7 @@ def __init__(
pass_job_queue: bool = False,
pass_user_data: bool = False,
pass_chat_data: bool = False,
run_async: bool = False,
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
):
self.callback: Callable[[HandlerArg, 'CallbackContext'], RT] = callback
self.pass_update_queue = pass_update_queue
Expand Down Expand Up @@ -143,14 +144,19 @@ def handle_update(
the dispatcher.

"""
run_async = self.run_async
if self.run_async is DEFAULT_FALSE and dispatcher.bot.defaults:
if dispatcher.bot.defaults.run_async:
run_async = True

if context:
self.collect_additional_context(context, update, dispatcher, check_result)
if self.run_async:
if run_async:
return dispatcher.run_async(self.callback, update, context, update=update)
return self.callback(update, context)

optional_args = self.collect_optional_args(dispatcher, update, check_result)
if self.run_async:
if run_async:
return dispatcher.run_async(
self.callback, dispatcher.bot, update, update=update, **optional_args
)
Expand Down
3 changes: 2 additions & 1 deletion telegram/ext/inlinequeryhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

from telegram import Update
from telegram.utils.types import HandlerArg
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE

from .handler import Handler

Expand Down Expand Up @@ -129,7 +130,7 @@ def __init__(
pass_groupdict: bool = False,
pass_user_data: bool = False,
pass_chat_data: bool = False,
run_async: bool = False,
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
):
super().__init__(
callback,
Expand Down
3 changes: 2 additions & 1 deletion telegram/ext/messagehandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from telegram.ext import BaseFilter, Filters
from telegram.utils.deprecate import TelegramDeprecationWarning
from telegram.utils.types import HandlerArg
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE

from .handler import Handler

Expand Down Expand Up @@ -131,7 +132,7 @@ def __init__(
message_updates: bool = None,
channel_post_updates: bool = None,
edited_updates: bool = None,
run_async: bool = False,
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
):

super().__init__(
Expand Down
3 changes: 2 additions & 1 deletion telegram/ext/regexhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from telegram.ext import Filters, MessageHandler
from telegram.utils.deprecate import TelegramDeprecationWarning
from telegram.utils.types import HandlerArg
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE

if TYPE_CHECKING:
from telegram.ext import CallbackContext, Dispatcher
Expand Down Expand Up @@ -121,7 +122,7 @@ def __init__(
message_updates: bool = True,
channel_post_updates: bool = False,
edited_updates: bool = False,
run_async: bool = False,
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
):
warnings.warn(
'RegexHandler is deprecated. See https://git.io/fxJuV for more info',
Expand Down
5 changes: 3 additions & 2 deletions telegram/ext/stringcommandhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the StringCommandHandler class."""

from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, TypeVar
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, TypeVar, Union

from telegram.utils.types import HandlerArg
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE

from .handler import Handler

Expand Down Expand Up @@ -89,7 +90,7 @@ def __init__(
pass_args: bool = False,
pass_update_queue: bool = False,
pass_job_queue: bool = False,
run_async: bool = False,
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
):
super().__init__(
callback,
Expand Down
3 changes: 2 additions & 1 deletion telegram/ext/stringregexhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from typing import TYPE_CHECKING, Any, Callable, Dict, Match, Optional, Pattern, TypeVar, Union

from telegram.utils.types import HandlerArg
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE

from .handler import Handler

Expand Down Expand Up @@ -99,7 +100,7 @@ def __init__(
pass_groupdict: bool = False,
pass_update_queue: bool = False,
pass_job_queue: bool = False,
run_async: bool = False,
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
):
super().__init__(
callback,
Expand Down
5 changes: 3 additions & 2 deletions telegram/ext/typehandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains the TypeHandler class."""

from typing import TYPE_CHECKING, Any, Callable, Type, TypeVar
from typing import TYPE_CHECKING, Any, Callable, Type, TypeVar, Union
from telegram.utils.helpers import DefaultValue, DEFAULT_FALSE

from .handler import Handler

Expand Down Expand Up @@ -80,7 +81,7 @@ def __init__(
strict: bool = False,
pass_update_queue: bool = False,
pass_job_queue: bool = False,
run_async: bool = False,
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
):
super().__init__(
callback,
Expand Down
3 changes: 3 additions & 0 deletions telegram/utils/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,3 +445,6 @@ def __bool__(self) -> bool:

DEFAULT_NONE: DefaultValue = DefaultValue(None)
""":class:`DefaultValue`: Default `None`"""

DEFAULT_FALSE: DefaultValue = DefaultValue(False)
""":class:`DefaultValue`: Default `False`"""
2 changes: 2 additions & 0 deletions tests/test_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ def test_data_assignment(self, cdp):
defaults.quote = True
with pytest.raises(AttributeError):
defaults.tzinfo = True
with pytest.raises(AttributeError):
defaults.run_async = True

def test_equality(self):
a = Defaults(parse_mode='HTML', quote=True)
Expand Down
40 changes: 40 additions & 0 deletions tests/test_dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from telegram.ext import (
MessageHandler,
Filters,
Defaults,
CommandHandler,
CallbackContext,
JobQueue,
Expand Down Expand Up @@ -174,6 +175,45 @@ def test_error_handler_that_raises_errors(self, dp):

assert self.count == 1

@pytest.mark.parametrize(['run_async', 'expected_output'], [(True, 5), (False, 0)])
def test_default_run_async_error_handler(self, dp, monkeypatch, run_async, expected_output):
def mock_async_err_handler(*args, **kwargs):
self.count = 5

# set defaults value to dp.bot
dp.bot.defaults = Defaults(run_async=run_async)
try:
dp.add_handler(MessageHandler(Filters.all, self.callback_raise_error))
dp.add_error_handler(self.error_handler)

monkeypatch.setattr(dp, 'run_async', mock_async_err_handler)
dp.process_update(self.message_update)

assert self.count == expected_output

finally:
# reset dp.bot.defaults values
dp.bot.defaults = None

@pytest.mark.parametrize(
['run_async', 'expected_output'], [(True, 'running async'), (False, None)]
)
def test_default_run_async(self, monkeypatch, dp, run_async, expected_output):
def mock_run_async(*args, **kwargs):
self.received = 'running async'

# set defaults value to dp.bot
dp.bot.defaults = Defaults(run_async=run_async)
try:
dp.add_handler(MessageHandler(Filters.all, lambda u, c: None))
monkeypatch.setattr(dp, 'run_async', mock_run_async)
dp.process_update(self.message_update)
assert self.received == expected_output

finally:
# reset defaults value
dp.bot.defaults = None

def test_run_async_multiple(self, bot, dp, dp2):
def get_dispatcher_name(q):
q.put(current_thread().name)
Expand Down