Overhaul of Filters (#2759)

This commit is contained in:
Harshil 2021-11-20 14:36:18 +04:00 committed by Hinrich Mahler
parent b852a6866d
commit 145d04230b
26 changed files with 2775 additions and 2833 deletions

View file

@ -19,6 +19,7 @@ from typing import Tuple
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
import inspect
from docutils.nodes import Element
from sphinx.application import Sphinx
from sphinx.domains.python import PyXRefRole
@ -358,7 +359,23 @@ class TGConstXRefRole(PyXRefRole):
def autodoc_skip_member(app, what, name, obj, skip, options):
pass
"""We use this to not document certain members like filter() or check_update() for filters.
See https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#skipping-members"""
included = {'MessageFilter', 'UpdateFilter'} # filter() and check_update() only for these.
included_in_obj = any(inc in repr(obj) for inc in included)
if included_in_obj: # it's difficult to see if check_update is from an inherited-member or not
for frame in inspect.stack(): # From https://github.com/sphinx-doc/sphinx/issues/9533
if frame.function == "filter_members":
docobj = frame.frame.f_locals["self"].object
if not any(inc in str(docobj) for inc in included) and name == 'check_update':
return True
break
if name == 'filter' and obj.__module__ == 'telegram.ext.filters':
if not included_in_obj:
return True # return True to exclude from docs.
def setup(app: Sphinx):

View file

@ -3,6 +3,11 @@
telegram.ext.filters Module
===========================
.. :bysource: since e.g filters.CHAT is much above filters.Chat() in the docs when it shouldn't.
The classes in `filters.py` are sorted alphabetically such that :bysource: still is readable
.. automodule:: telegram.ext.filters
:inherited-members:
:members:
:show-inheritance:
:member-order: bysource

View file

@ -20,7 +20,7 @@ from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
from telegram.ext import (
CommandHandler,
MessageHandler,
Filters,
filters,
ConversationHandler,
Updater,
CallbackContext,
@ -146,13 +146,13 @@ def main() -> None:
conv_handler = ConversationHandler(
entry_points=[CommandHandler('start', start)],
states={
GENDER: [MessageHandler(Filters.regex('^(Boy|Girl|Other)$'), gender)],
PHOTO: [MessageHandler(Filters.photo, photo), CommandHandler('skip', skip_photo)],
GENDER: [MessageHandler(filters.Regex('^(Boy|Girl|Other)$'), gender)],
PHOTO: [MessageHandler(filters.PHOTO, photo), CommandHandler('skip', skip_photo)],
LOCATION: [
MessageHandler(Filters.location, location),
MessageHandler(filters.LOCATION, location),
CommandHandler('skip', skip_location),
],
BIO: [MessageHandler(Filters.text & ~Filters.command, bio)],
BIO: [MessageHandler(filters.TEXT & ~filters.COMMAND, bio)],
},
fallbacks=[CommandHandler('cancel', cancel)],
)

View file

@ -21,7 +21,7 @@ from telegram import ReplyKeyboardMarkup, Update, ReplyKeyboardRemove
from telegram.ext import (
CommandHandler,
MessageHandler,
Filters,
filters,
ConversationHandler,
Updater,
CallbackContext,
@ -126,23 +126,23 @@ def main() -> None:
states={
CHOOSING: [
MessageHandler(
Filters.regex('^(Age|Favourite colour|Number of siblings)$'), regular_choice
filters.Regex('^(Age|Favourite colour|Number of siblings)$'), regular_choice
),
MessageHandler(Filters.regex('^Something else...$'), custom_choice),
MessageHandler(filters.Regex('^Something else...$'), custom_choice),
],
TYPING_CHOICE: [
MessageHandler(
Filters.text & ~(Filters.command | Filters.regex('^Done$')), regular_choice
filters.TEXT & ~(filters.COMMAND | filters.Regex('^Done$')), regular_choice
)
],
TYPING_REPLY: [
MessageHandler(
Filters.text & ~(Filters.command | Filters.regex('^Done$')),
filters.TEXT & ~(filters.COMMAND | filters.Regex('^Done$')),
received_information,
)
],
},
fallbacks=[MessageHandler(Filters.regex('^Done$'), done)],
fallbacks=[MessageHandler(filters.Regex('^Done$'), done)],
)
dispatcher.add_handler(conv_handler)

View file

@ -25,7 +25,7 @@ from telegram.constants import ParseMode
from telegram.ext import (
CommandHandler,
CallbackQueryHandler,
Filters,
filters,
Updater,
CallbackContext,
)
@ -115,20 +115,20 @@ def main() -> None:
# Register a deep-linking handler
dispatcher.add_handler(
CommandHandler("start", deep_linked_level_1, Filters.regex(CHECK_THIS_OUT))
CommandHandler("start", deep_linked_level_1, filters.Regex(CHECK_THIS_OUT))
)
# This one works with a textual link instead of an URL
dispatcher.add_handler(CommandHandler("start", deep_linked_level_2, Filters.regex(SO_COOL)))
dispatcher.add_handler(CommandHandler("start", deep_linked_level_2, filters.Regex(SO_COOL)))
# We can also pass on the deep-linking payload
dispatcher.add_handler(
CommandHandler("start", deep_linked_level_3, Filters.regex(USING_ENTITIES))
CommandHandler("start", deep_linked_level_3, filters.Regex(USING_ENTITIES))
)
# Possible with inline keyboard buttons as well
dispatcher.add_handler(
CommandHandler("start", deep_linked_level_4, Filters.regex(USING_KEYBOARD))
CommandHandler("start", deep_linked_level_4, filters.Regex(USING_KEYBOARD))
)
# register callback handler for inline keyboard button

View file

@ -21,7 +21,7 @@ from telegram import Update, ForceReply
from telegram.ext import (
CommandHandler,
MessageHandler,
Filters,
filters,
Updater,
CallbackContext,
)
@ -68,7 +68,7 @@ def main() -> None:
dispatcher.add_handler(CommandHandler("help", help_command))
# on non command i.e message - echo the message on Telegram
dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, echo))
dispatcher.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
# Start the Bot
updater.start_polling()

View file

@ -21,7 +21,7 @@ from telegram import InlineKeyboardMarkup, InlineKeyboardButton, Update
from telegram.ext import (
CommandHandler,
MessageHandler,
Filters,
filters,
ConversationHandler,
CallbackQueryHandler,
Updater,
@ -319,7 +319,7 @@ def main() -> None:
SELECTING_FEATURE: [
CallbackQueryHandler(ask_for_input, pattern='^(?!' + str(END) + ').*$')
],
TYPING: [MessageHandler(Filters.text & ~Filters.command, save_input)],
TYPING: [MessageHandler(filters.TEXT & ~filters.COMMAND, save_input)],
},
fallbacks=[
CallbackQueryHandler(end_describing, pattern='^' + str(END) + '$'),

View file

@ -14,7 +14,7 @@ import logging
from pathlib import Path
from telegram import Update
from telegram.ext import MessageHandler, Filters, Updater, CallbackContext
from telegram.ext import MessageHandler, filters, Updater, CallbackContext
# Enable logging
@ -110,7 +110,7 @@ def main() -> None:
dispatcher = updater.dispatcher
# On messages that include passport data call msg
dispatcher.add_handler(MessageHandler(Filters.passport_data, msg))
dispatcher.add_handler(MessageHandler(filters.PASSPORT_DATA, msg))
# Start the Bot
updater.start_polling()

View file

@ -10,7 +10,7 @@ from telegram import LabeledPrice, ShippingOption, Update
from telegram.ext import (
CommandHandler,
MessageHandler,
Filters,
filters,
PreCheckoutQueryHandler,
ShippingQueryHandler,
Updater,
@ -149,7 +149,7 @@ def main() -> None:
dispatcher.add_handler(PreCheckoutQueryHandler(precheckout_callback))
# Success! Notify your user!
dispatcher.add_handler(MessageHandler(Filters.successful_payment, successful_payment_callback))
dispatcher.add_handler(MessageHandler(filters.SUCCESSFUL_PAYMENT, successful_payment_callback))
# Start the Bot
updater.start_polling()

View file

@ -21,7 +21,7 @@ from telegram import ReplyKeyboardMarkup, Update, ReplyKeyboardRemove
from telegram.ext import (
CommandHandler,
MessageHandler,
Filters,
filters,
ConversationHandler,
PicklePersistence,
Updater,
@ -144,23 +144,23 @@ def main() -> None:
states={
CHOOSING: [
MessageHandler(
Filters.regex('^(Age|Favourite colour|Number of siblings)$'), regular_choice
filters.Regex('^(Age|Favourite colour|Number of siblings)$'), regular_choice
),
MessageHandler(Filters.regex('^Something else...$'), custom_choice),
MessageHandler(filters.Regex('^Something else...$'), custom_choice),
],
TYPING_CHOICE: [
MessageHandler(
Filters.text & ~(Filters.command | Filters.regex('^Done$')), regular_choice
filters.TEXT & ~(filters.COMMAND | filters.Regex('^Done$')), regular_choice
)
],
TYPING_REPLY: [
MessageHandler(
Filters.text & ~(Filters.command | Filters.regex('^Done$')),
filters.TEXT & ~(filters.COMMAND | filters.Regex('^Done$')),
received_information,
)
],
},
fallbacks=[MessageHandler(Filters.regex('^Done$'), done)],
fallbacks=[MessageHandler(filters.Regex('^Done$'), done)],
name="my_conversation",
persistent=True,
)

View file

@ -23,7 +23,7 @@ from telegram.ext import (
PollAnswerHandler,
PollHandler,
MessageHandler,
Filters,
filters,
Updater,
CallbackContext,
)
@ -163,7 +163,7 @@ def main() -> None:
dispatcher.add_handler(CommandHandler('quiz', quiz))
dispatcher.add_handler(PollHandler(receive_quiz_answer))
dispatcher.add_handler(CommandHandler('preview', preview))
dispatcher.add_handler(MessageHandler(Filters.poll, receive_poll))
dispatcher.add_handler(MessageHandler(filters.POLL, receive_poll))
dispatcher.add_handler(CommandHandler('help', help_handler))
# Start the Bot

View file

@ -31,7 +31,7 @@ from ._updater import Updater
from ._callbackqueryhandler import CallbackQueryHandler
from ._choseninlineresulthandler import ChosenInlineResultHandler
from ._inlinequeryhandler import InlineQueryHandler
from .filters import BaseFilter, MessageFilter, UpdateFilter, Filters
from . import filters
from ._messagehandler import MessageHandler
from ._commandhandler import CommandHandler, PrefixHandler
from ._stringcommandhandler import StringCommandHandler
@ -49,7 +49,6 @@ from ._callbackdatacache import CallbackDataCache, InvalidCallbackData
from ._builders import DispatcherBuilder, UpdaterBuilder
__all__ = (
'BaseFilter',
'BasePersistence',
'CallbackContext',
'CallbackDataCache',
@ -66,13 +65,12 @@ __all__ = (
'DispatcherBuilder',
'DispatcherHandlerStop',
'ExtBot',
'Filters',
'filters',
'Handler',
'InlineQueryHandler',
'InvalidCallbackData',
'Job',
'JobQueue',
'MessageFilter',
'MessageHandler',
'PersistenceInput',
'PicklePersistence',
@ -84,7 +82,6 @@ __all__ = (
'StringCommandHandler',
'StringRegexHandler',
'TypeHandler',
'UpdateFilter',
'Updater',
'UpdaterBuilder',
)

View file

@ -29,7 +29,7 @@ from telegram._utils.warnings import warn
from telegram.ext._utils.types import UD, CD, BD, ConversationDict, CDCData
class PersistenceInput(NamedTuple):
class PersistenceInput(NamedTuple): # skipcq: PYL-E0239
"""Convenience wrapper to group boolean input for :class:`BasePersistence`.
Args:

View file

@ -68,10 +68,9 @@ class CallbackContext(Generic[BT, UD, CD, BD]):
Attributes:
matches (List[:obj:`re match object`]): Optional. If the associated update originated from
a regex-supported handler or had a :class:`Filters.regex`, this will contain a list of
match objects for every pattern where ``re.search(pattern, string)`` returned a match.
Note that filters short circuit, so combined regex filters will not always
be evaluated.
a :class:`filters.Regex`, this will contain a list of match objects for every pattern
where ``re.search(pattern, string)`` returned a match. Note that filters short circuit,
so combined regex filters will not always be evaluated.
args (List[:obj:`str`]): Optional. Arguments passed to a command if the associated update
is handled by :class:`telegram.ext.CommandHandler`, :class:`telegram.ext.PrefixHandler`
or :class:`telegram.ext.StringCommandHandler`. It contains a list of the words in the

View file

@ -21,7 +21,7 @@ import re
from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple, TypeVar, Union
from telegram import MessageEntity, Update
from telegram.ext import BaseFilter, Filters, Handler
from telegram.ext import filters as filters_module, Handler
from telegram._utils.types import SLT
from telegram._utils.defaultvalue import DefaultValue, DEFAULT_FALSE
from telegram.ext._utils.types import CCT
@ -41,7 +41,7 @@ class CommandHandler(Handler[Update, CCT]):
which is the text following the command split on single or consecutive whitespace characters.
By default the handler listens to messages as well as edited messages. To change this behavior
use ``~Filters.update.edited_message`` in the filter argument.
use ``~filters.UpdateType.EDITED_MESSAGE`` in the filter argument.
Note:
* :class:`CommandHandler` does *not* handle (edited) channel posts.
@ -62,7 +62,7 @@ class CommandHandler(Handler[Update, CCT]):
:class:`telegram.ext.ConversationHandler`.
filters (:class:`telegram.ext.BaseFilter`, optional): A filter inheriting from
:class:`telegram.ext.filters.BaseFilter`. Standard filters can be found in
:class:`telegram.ext.filters.Filters`. Filters can be combined using bitwise
:mod:`telegram.ext.filters`. Filters can be combined using bitwise
operators (& for and, | for or, ~ for not).
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
Defaults to :obj:`False`.
@ -86,13 +86,10 @@ class CommandHandler(Handler[Update, CCT]):
self,
command: SLT[str],
callback: Callable[[Update, CCT], RT],
filters: BaseFilter = None,
filters: filters_module.BaseFilter = None,
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
):
super().__init__(
callback,
run_async=run_async,
)
super().__init__(callback, run_async=run_async)
if isinstance(command, str):
self.command = [command.lower()]
@ -102,10 +99,7 @@ class CommandHandler(Handler[Update, CCT]):
if not re.match(r'^[\da-z_]{1,32}$', comm):
raise ValueError('Command is not a valid bot command')
if filters:
self.filters = Filters.update.messages & filters
else:
self.filters = Filters.update.messages
self.filters = filters if filters is not None else filters_module.UpdateType.MESSAGES
def check_update(
self, update: object
@ -140,7 +134,7 @@ class CommandHandler(Handler[Update, CCT]):
):
return None
filter_result = self.filters(update)
filter_result = self.filters.check_update(update)
if filter_result:
return args, filter_result
return False
@ -167,7 +161,7 @@ class PrefixHandler(CommandHandler):
This is a intermediate handler between :class:`MessageHandler` and :class:`CommandHandler`.
It supports configurable commands with the same options as CommandHandler. It will respond to
every combination of :attr:`prefix` and :attr:`command`. It will add a ``list`` to the
every combination of :attr:`prefix` and :attr:`command`. It will add a :obj:`list` to the
:class:`CallbackContext` named :attr:`CallbackContext.args`. It will contain a list of strings,
which is the text following the command split on single or consecutive whitespace characters.
@ -194,7 +188,7 @@ class PrefixHandler(CommandHandler):
By default the handler listens to messages as well as edited messages. To change this behavior
use ``~Filters.update.edited_message``.
use ``~filters.UpdateType.EDITED_MESSAGE``.
Note:
* :class:`PrefixHandler` does *not* handle (edited) channel posts.
@ -216,7 +210,7 @@ class PrefixHandler(CommandHandler):
:class:`telegram.ext.ConversationHandler`.
filters (:class:`telegram.ext.BaseFilter`, optional): A filter inheriting from
:class:`telegram.ext.filters.BaseFilter`. Standard filters can be found in
:class:`telegram.ext.filters.Filters`. Filters can be combined using bitwise
:mod:`telegram.ext.filters`. Filters can be combined using bitwise
operators (& for and, | for or, ~ for not).
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
Defaults to :obj:`False`.
@ -237,7 +231,7 @@ class PrefixHandler(CommandHandler):
prefix: SLT[str],
command: SLT[str],
callback: Callable[[Update, CCT], RT],
filters: BaseFilter = None,
filters: filters_module.BaseFilter = None,
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
):
@ -314,7 +308,7 @@ class PrefixHandler(CommandHandler):
text_list = message.text.split()
if text_list[0].lower() not in self._commands:
return None
filter_result = self.filters(update)
filter_result = self.filters.check_update(update)
if filter_result:
return text_list[1:], filter_result
return False

View file

@ -20,7 +20,7 @@
from typing import TYPE_CHECKING, Callable, Dict, Optional, TypeVar, Union
from telegram import Update
from telegram.ext import BaseFilter, Filters, Handler
from telegram.ext import filters as filters_module, Handler
from telegram._utils.defaultvalue import DefaultValue, DEFAULT_FALSE
from telegram.ext._utils.types import CCT
@ -39,13 +39,13 @@ class MessageHandler(Handler[Update, CCT]):
attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info.
Args:
filters (:class:`telegram.ext.BaseFilter`, optional): A filter inheriting from
filters (:class:`telegram.ext.BaseFilter`): A filter inheriting from
:class:`telegram.ext.filters.BaseFilter`. Standard filters can be found in
:class:`telegram.ext.filters.Filters`. Filters can be combined using bitwise
operators (& for and, | for or, ~ for not). Default is
:attr:`telegram.ext.filters.Filters.update`. This defaults to all message_type updates
being: ``message``, ``edited_message``, ``channel_post`` and ``edited_channel_post``.
If you don't want or need any of those pass ``~Filters.update.*`` in the filter
:mod:`telegram.ext.filters`. Filters can be combined using bitwise
operators (& for and, | for or, ~ for not). This defaults to all message updates
being: :attr:`Update.message`, :attr:`Update.edited_message`,
:attr:`Update.channel_post` and :attr:`Update.edited_channel_post`.
If you don't want or need any of those pass ``~filters.UpdateType.*`` in the filter
argument.
callback (:obj:`callable`): The callback function for this handler. Will be called when
:attr:`check_update` has determined that an update should be processed by this handler.
@ -60,8 +60,8 @@ class MessageHandler(Handler[Update, CCT]):
ValueError
Attributes:
filters (:obj:`Filter`): Only allow updates with these Filters. See
:mod:`telegram.ext.filters` for a full list of all available filters.
filters (:class:`telegram.ext.filters.BaseFilter`): Only allow updates with these Filters.
See :mod:`telegram.ext.filters` for a full list of all available filters.
callback (:obj:`callable`): The callback function for this handler.
run_async (:obj:`bool`): Determines whether the callback will run asynchronously.
@ -71,19 +71,13 @@ class MessageHandler(Handler[Update, CCT]):
def __init__(
self,
filters: BaseFilter,
filters: filters_module.BaseFilter,
callback: Callable[[Update, CCT], RT],
run_async: Union[bool, DefaultValue] = DEFAULT_FALSE,
):
super().__init__(
callback,
run_async=run_async,
)
if filters is not None:
self.filters = Filters.update & filters
else:
self.filters = Filters.update
super().__init__(callback, run_async=run_async)
self.filters = filters if filters is not None else filters_module.ALL
def check_update(self, update: object) -> Optional[Union[bool, Dict[str, list]]]:
"""Determines whether an update should be passed to this handlers :attr:`callback`.
@ -96,7 +90,7 @@ class MessageHandler(Handler[Update, CCT]):
"""
if isinstance(update, Update):
return self.filters(update)
return self.filters.check_update(update)
return None
def collect_additional_context(

File diff suppressed because it is too large Load diff

View file

@ -134,7 +134,7 @@ def create_deep_linked_url(bot_username: str, payload: str = None, group: bool =
Note:
Works well in conjunction with
``CommandHandler("start", callback, filters = Filters.regex('payload'))``
``CommandHandler("start", callback, filters = filters.Regex('payload'))``
Examples:
``create_deep_linked_url(bot.get_me().username, "some-params")``

View file

@ -54,13 +54,12 @@ from telegram import (
)
from telegram.ext import (
Dispatcher,
MessageFilter,
Defaults,
UpdateFilter,
ExtBot,
DispatcherBuilder,
UpdaterBuilder,
)
from telegram.ext.filters import UpdateFilter, MessageFilter
from telegram.error import BadRequest
from telegram._utils.defaultvalue import DefaultValue, DEFAULT_NONE
from telegram.request import Request
@ -335,6 +334,7 @@ def make_command_update(message, edited=False, **kwargs):
def mock_filter(request):
class MockFilter(request.param['class']):
def __init__(self):
super().__init__()
self.tested = False
def filter(self, _):

View file

@ -22,7 +22,7 @@ from queue import Queue
import pytest
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
from tests.conftest import (
make_command_message,
make_command_update,
@ -186,7 +186,7 @@ class TestCommandHandler(BaseTest):
def test_edited(self, command_message):
"""Test that a CH responds to an edited message if its filters allow it"""
handler_edited = self.make_default_handler()
handler_no_edited = self.make_default_handler(filters=~Filters.update.edited_message)
handler_no_edited = self.make_default_handler(filters=~filters.UpdateType.EDITED_MESSAGE)
self._test_edited(command_message, handler_edited, handler_no_edited)
def test_directed_commands(self, bot, command):
@ -197,7 +197,7 @@ class TestCommandHandler(BaseTest):
def test_with_filter(self, command):
"""Test that a CH with a (generic) filter responds if its filters match"""
handler = self.make_default_handler(filters=Filters.chat_type.group)
handler = self.make_default_handler(filters=filters.ChatType.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)))
@ -234,14 +234,14 @@ class TestCommandHandler(BaseTest):
def test_context_regex(self, dp, command):
"""Test CHs with context-based callbacks and a single filter"""
handler = self.make_default_handler(
self.callback_context_regex1, filters=Filters.regex('one two')
self.callback_context_regex1, filters=filters.Regex('one two')
)
self._test_context_args_or_regex(dp, handler, command)
def test_context_multiple_regex(self, dp, command):
"""Test CHs with context-based callbacks and filters combined"""
handler = self.make_default_handler(
self.callback_context_regex2, filters=Filters.regex('one') & Filters.regex('two')
self.callback_context_regex2, filters=filters.Regex('one') & filters.Regex('two')
)
self._test_context_args_or_regex(dp, handler, command)
@ -317,11 +317,11 @@ class TestPrefixHandler(BaseTest):
def test_edited(self, prefix_message):
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.UpdateType.EDITED_MESSAGE)
self._test_edited(prefix_message, handler_edited, handler_no_edited)
def test_with_filter(self, prefix_message_text):
handler = self.make_default_handler(filters=Filters.chat_type.group)
handler = self.make_default_handler(filters=filters.ChatType.GROUP)
text = prefix_message_text
assert is_match(handler, make_message_update(text, chat=Chat(-23, Chat.GROUP)))
assert not is_match(handler, make_message_update(text, chat=Chat(23, Chat.PRIVATE)))
@ -370,12 +370,12 @@ class TestPrefixHandler(BaseTest):
def test_context_regex(self, dp, prefix_message_text):
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(dp, handler, prefix_message_text)
def test_context_multiple_regex(self, dp, prefix_message_text):
handler = self.make_default_handler(
self.callback_context_regex2, filters=Filters.regex('one') & Filters.regex('two')
self.callback_context_regex2, filters=filters.Regex('one') & filters.Regex('two')
)
self._test_context_args_or_regex(dp, handler, prefix_message_text)

View file

@ -40,7 +40,7 @@ from telegram.ext import (
CommandHandler,
CallbackQueryHandler,
MessageHandler,
Filters,
filters,
InlineQueryHandler,
CallbackContext,
DispatcherHandlerStop,
@ -770,7 +770,7 @@ class TestConversationHandler:
def test_channel_message_without_chat(self, bot):
handler = ConversationHandler(
entry_points=[MessageHandler(Filters.all, self.start_end)], states={}, fallbacks=[]
entry_points=[MessageHandler(filters.ALL, self.start_end)], states={}, fallbacks=[]
)
message = Message(0, date=None, chat=Chat(0, Chat.CHANNEL, 'Misses Test'), bot=bot)
@ -885,7 +885,7 @@ class TestConversationHandler:
handler = ConversationHandler(
entry_points=[CommandHandler("start", conv_entry)],
states={1: [MessageHandler(Filters.all, raise_error)]},
states={1: [MessageHandler(filters.ALL, raise_error)]},
fallbacks=self.fallbacks,
run_async=True,
)
@ -1168,7 +1168,7 @@ class TestConversationHandler:
{
ConversationHandler.TIMEOUT: [
CommandHandler('brew', self.passout),
MessageHandler(~Filters.regex('oding'), self.passout2),
MessageHandler(~filters.Regex('oding'), self.passout2),
]
}
)
@ -1228,7 +1228,7 @@ class TestConversationHandler:
{
ConversationHandler.TIMEOUT: [
CommandHandler('brew', self.passout_context),
MessageHandler(~Filters.regex('oding'), self.passout2_context),
MessageHandler(~filters.Regex('oding'), self.passout2_context),
]
}
)

View file

@ -28,7 +28,7 @@ from telegram.ext import (
CommandHandler,
MessageHandler,
JobQueue,
Filters,
filters,
Defaults,
CallbackContext,
ContextTypes,
@ -164,7 +164,7 @@ class TestDispatcher:
if hasattr(context, 'my_flag'):
pytest.fail()
dp.add_handler(MessageHandler(Filters.regex('test'), one), group=1)
dp.add_handler(MessageHandler(filters.Regex('test'), one), group=1)
dp.add_handler(MessageHandler(None, two), group=2)
u = Update(1, Message(1, None, None, None, text='test'))
dp.process_update(u)
@ -207,8 +207,8 @@ class TestDispatcher:
"""
Make sure that errors raised in error handlers don't break the main loop of the dispatcher
"""
handler_raise_error = MessageHandler(Filters.all, self.callback_raise_error)
handler_increase_count = MessageHandler(Filters.all, self.callback_increase_count)
handler_raise_error = MessageHandler(filters.ALL, self.callback_raise_error)
handler_increase_count = MessageHandler(filters.ALL, self.callback_increase_count)
error = TelegramError('Unauthorized.')
dp.add_error_handler(self.error_handler_raise_error)
@ -235,7 +235,7 @@ class TestDispatcher:
# 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_handler(MessageHandler(filters.ALL, self.callback_raise_error))
dp.add_error_handler(self.error_handler_context)
monkeypatch.setattr(dp, 'run_async', mock_async_err_handler)
@ -257,7 +257,7 @@ class TestDispatcher:
# 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))
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
@ -287,7 +287,7 @@ class TestDispatcher:
def callback(update, context):
raise DispatcherHandlerStop()
dp.add_handler(MessageHandler(Filters.all, callback, run_async=True))
dp.add_handler(MessageHandler(filters.ALL, callback, run_async=True))
dp.update_queue.put(self.message_update)
sleep(0.1)
@ -299,7 +299,7 @@ class TestDispatcher:
def test_add_async_handler(self, dp):
dp.add_handler(
MessageHandler(
Filters.all,
filters.ALL,
self.callback_received,
run_async=True,
)
@ -320,7 +320,7 @@ class TestDispatcher:
assert caplog.records[-1].getMessage().startswith('No error handlers are registered')
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_context, run_async=True)
dp.update_queue.put(self.message_update)
@ -328,7 +328,7 @@ class TestDispatcher:
assert self.received == self.message_update.message.text
def test_async_handler_error_handler_that_raises_error(self, dp, caplog):
handler = MessageHandler(Filters.all, self.callback_raise_error, run_async=True)
handler = MessageHandler(filters.ALL, self.callback_raise_error, run_async=True)
dp.add_handler(handler)
dp.add_error_handler(self.error_handler_raise_error, run_async=False)
@ -342,13 +342,13 @@ class TestDispatcher:
# Make sure that the main loop still runs
dp.remove_handler(handler)
dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count, run_async=True))
dp.add_handler(MessageHandler(filters.ALL, self.callback_increase_count, run_async=True))
dp.update_queue.put(self.message_update)
sleep(0.1)
assert self.count == 1
def test_async_handler_async_error_handler_that_raises_error(self, dp, caplog):
handler = MessageHandler(Filters.all, self.callback_raise_error, run_async=True)
handler = MessageHandler(filters.ALL, self.callback_raise_error, run_async=True)
dp.add_handler(handler)
dp.add_error_handler(self.error_handler_raise_error, run_async=True)
@ -362,13 +362,13 @@ class TestDispatcher:
# Make sure that the main loop still runs
dp.remove_handler(handler)
dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count, run_async=True))
dp.add_handler(MessageHandler(filters.ALL, self.callback_increase_count, run_async=True))
dp.update_queue.put(self.message_update)
sleep(0.1)
assert self.count == 1
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_context)
dp.update_queue.put(self.message_update)
@ -376,7 +376,7 @@ class TestDispatcher:
assert self.received == self.message_update.message.text
def test_add_remove_handler(self, dp):
handler = MessageHandler(Filters.all, self.callback_increase_count)
handler = MessageHandler(filters.ALL, self.callback_increase_count)
dp.add_handler(handler)
dp.update_queue.put(self.message_update)
sleep(0.1)
@ -386,7 +386,7 @@ class TestDispatcher:
assert self.count == 1
def test_add_remove_handler_non_default_group(self, dp):
handler = MessageHandler(Filters.all, self.callback_increase_count)
handler = MessageHandler(filters.ALL, self.callback_increase_count)
dp.add_handler(handler, group=2)
with pytest.raises(KeyError):
dp.remove_handler(handler)
@ -397,17 +397,17 @@ class TestDispatcher:
dp.start()
def test_handler_order_in_group(self, dp):
dp.add_handler(MessageHandler(Filters.photo, self.callback_set_count(1)))
dp.add_handler(MessageHandler(Filters.all, self.callback_set_count(2)))
dp.add_handler(MessageHandler(Filters.text, self.callback_set_count(3)))
dp.add_handler(MessageHandler(filters.PHOTO, self.callback_set_count(1)))
dp.add_handler(MessageHandler(filters.ALL, self.callback_set_count(2)))
dp.add_handler(MessageHandler(filters.TEXT, self.callback_set_count(3)))
dp.update_queue.put(self.message_update)
sleep(0.1)
assert self.count == 2
def test_groups(self, dp):
dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count))
dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count), group=2)
dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count), group=-1)
dp.add_handler(MessageHandler(filters.ALL, self.callback_increase_count))
dp.add_handler(MessageHandler(filters.ALL, self.callback_increase_count), group=2)
dp.add_handler(MessageHandler(filters.ALL, self.callback_increase_count), group=-1)
dp.update_queue.put(self.message_update)
sleep(0.1)
@ -418,7 +418,7 @@ class TestDispatcher:
with pytest.raises(TypeError, match='handler is not an instance of'):
dp.add_handler(handler)
handler = MessageHandler(Filters.photo, self.callback_set_count(1))
handler = MessageHandler(filters.PHOTO, self.callback_set_count(1))
with pytest.raises(TypeError, match='group is not int'):
dp.add_handler(handler, 'one')
@ -733,7 +733,7 @@ class TestDispatcher:
update = Update(
1, message=Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text')
)
handler = MessageHandler(Filters.all, callback)
handler = MessageHandler(filters.ALL, callback)
dp.add_handler(handler)
dp.add_error_handler(error)
@ -801,7 +801,7 @@ class TestDispatcher:
def callback(update, context):
pass
handler = MessageHandler(Filters.all, callback)
handler = MessageHandler(filters.ALL, callback)
dp.add_handler(handler)
dp.persistence = OwnPersistence()
@ -832,7 +832,7 @@ class TestDispatcher:
monkeypatch.setattr(dp, 'update_persistence', update_persistence)
for group in range(5):
dp.add_handler(MessageHandler(Filters.text, dummy_callback), group=group)
dp.add_handler(MessageHandler(filters.TEXT, dummy_callback), group=group)
update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text=None))
dp.process_update(update)
@ -854,7 +854,7 @@ class TestDispatcher:
for group in range(5):
dp.add_handler(
MessageHandler(Filters.text, dummy_callback, run_async=True), group=group
MessageHandler(filters.TEXT, dummy_callback, run_async=True), group=group
)
update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='Text'))
@ -864,7 +864,7 @@ class TestDispatcher:
dp.bot._defaults = Defaults(run_async=True)
try:
for group in range(5):
dp.add_handler(MessageHandler(Filters.text, dummy_callback), group=group)
dp.add_handler(MessageHandler(filters.TEXT, dummy_callback), group=group)
update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='Text'))
dp.process_update(update)
@ -885,9 +885,9 @@ class TestDispatcher:
for group in range(5):
dp.add_handler(
MessageHandler(Filters.text, dummy_callback, run_async=True), group=group
MessageHandler(filters.TEXT, dummy_callback, run_async=True), group=group
)
dp.add_handler(MessageHandler(Filters.text, dummy_callback, run_async=run_async), group=5)
dp.add_handler(MessageHandler(filters.TEXT, dummy_callback, run_async=run_async), group=5)
update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='Text'))
dp.process_update(update)
@ -907,7 +907,7 @@ class TestDispatcher:
try:
for group in range(5):
dp.add_handler(MessageHandler(Filters.text, dummy_callback), group=group)
dp.add_handler(MessageHandler(filters.TEXT, dummy_callback), group=group)
update = Update(1, message=Message(1, None, Chat(1, ''), from_user=None, text='Text'))
dp.process_update(update)
@ -949,7 +949,7 @@ class TestDispatcher:
.build()
)
dispatcher.add_error_handler(error_handler)
dispatcher.add_handler(MessageHandler(Filters.all, self.callback_raise_error))
dispatcher.add_handler(MessageHandler(filters.ALL, self.callback_raise_error))
dispatcher.process_update(self.message_update)
sleep(0.1)
@ -974,7 +974,7 @@ class TestDispatcher:
)
.build()
)
dispatcher.add_handler(MessageHandler(Filters.all, callback))
dispatcher.add_handler(MessageHandler(filters.ALL, callback))
dispatcher.process_update(self.message_update)
sleep(0.1)

File diff suppressed because it is too large Load diff

View file

@ -350,7 +350,7 @@ class TestJobQueue:
sleep(delta + 0.1)
assert self.result == 1
scheduled_time = job_queue.jobs()[0].next_t.timestamp()
assert scheduled_time == pytest.approx(expected_reschedule_time)
assert scheduled_time == pytest.approx(expected_reschedule_time, rel=1e-3)
def test_run_monthly_non_strict_day(self, job_queue, timezone):
delta, now = 1, dtm.datetime.now(timezone)

View file

@ -33,7 +33,7 @@ from telegram import (
ShippingQuery,
PreCheckoutQuery,
)
from telegram.ext import Filters, MessageHandler, CallbackContext, JobQueue, UpdateFilter
from telegram.ext import filters, MessageHandler, CallbackContext, JobQueue
message = Message(1, None, Chat(1, ''), from_user=User(1, '', False), text='Text')
@ -71,7 +71,7 @@ class TestMessageHandler:
SRE_TYPE = type(re.match("", ""))
def test_slot_behaviour(self, mro_slots):
handler = MessageHandler(Filters.all, self.callback_context)
handler = MessageHandler(filters.ALL, self.callback_context)
for attr in handler.__slots__:
assert getattr(handler, attr, 'err') != 'err', f"got extra slot '{attr}'"
assert len(mro_slots(handler)) == len(set(mro_slots(handler))), "duplicate slot"
@ -120,7 +120,7 @@ class TestMessageHandler:
self.test_flag = types and num
def test_with_filter(self, message):
handler = MessageHandler(Filters.chat_type.group, self.callback_context)
handler = MessageHandler(filters.ChatType.GROUP, self.callback_context)
message.chat.type = 'group'
assert handler.check_update(Update(0, message))
@ -129,7 +129,7 @@ class TestMessageHandler:
assert not handler.check_update(Update(0, message))
def test_callback_query_with_filter(self, message):
class TestFilter(UpdateFilter):
class TestFilter(filters.UpdateFilter):
flag = False
def filter(self, u):
@ -146,9 +146,9 @@ class TestMessageHandler:
def test_specific_filters(self, message):
f = (
~Filters.update.messages
& ~Filters.update.channel_post
& Filters.update.edited_channel_post
~filters.UpdateType.MESSAGES
& ~filters.UpdateType.CHANNEL_POST
& filters.UpdateType.EDITED_CHANNEL_POST
)
handler = MessageHandler(f, self.callback_context)
@ -184,7 +184,7 @@ class TestMessageHandler:
assert self.test_flag
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)
dp.add_handler(handler)
message.text = 'not it'
@ -197,7 +197,7 @@ class TestMessageHandler:
def test_context_multiple_regex(self, dp, message):
handler = MessageHandler(
Filters.regex('one') & Filters.regex('two'), self.callback_context_regex2
filters.Regex('one') & filters.Regex('two'), self.callback_context_regex2
)
dp.add_handler(handler)

View file

@ -42,7 +42,7 @@ from telegram.ext import (
BasePersistence,
ConversationHandler,
MessageHandler,
Filters,
filters,
PicklePersistence,
CommandHandler,
DictPersistence,
@ -401,15 +401,15 @@ class TestBasePersistence:
context.bot.callback_data_cache.put('test0')
known_user = MessageHandler(
Filters.user(user_id=12345),
filters.User(user_id=12345),
callback_known_user,
)
known_chat = MessageHandler(
Filters.chat(chat_id=-67890),
filters.Chat(chat_id=-67890),
callback_known_chat,
)
unknown = MessageHandler(
Filters.all,
filters.ALL,
callback_unknown_user_or_chat,
)
dp.add_handler(known_user)
@ -530,12 +530,12 @@ class TestBasePersistence:
self.test_flag = 'bot_data was wrongly refreshed'
with_user_and_chat = MessageHandler(
Filters.user(user_id=12345),
filters.User(user_id=12345),
callback_with_user_and_chat,
run_async=run_async,
)
without_user_and_chat = MessageHandler(
Filters.all,
filters.ALL,
callback_without_user_and_chat,
run_async=run_async,
)
@ -2221,8 +2221,8 @@ class TestDictPersistence:
if not context.bot.callback_data_cache.persistence_data == ([], {'test1': 'test0'}):
pytest.fail()
h1 = MessageHandler(Filters.all, first)
h2 = MessageHandler(Filters.all, second)
h1 = MessageHandler(filters.ALL, first)
h2 = MessageHandler(filters.ALL, second)
dp.add_handler(h1)
dp.process_update(update)
user_data = dict_persistence.user_data_json