Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Favor concrete types over "Iterable" #1882

Merged
merged 3 commits into from
Apr 8, 2020
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
42 changes: 21 additions & 21 deletions telegram/ext/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,35 +236,35 @@ def filter(self, message):
class _Text(BaseFilter):
name = 'Filters.text'

class _TextIterable(BaseFilter):
class _TextStrings(BaseFilter):

def __init__(self, iterable):
self.iterable = iterable
self.name = 'Filters.text({})'.format(iterable)
def __init__(self, strings):
self.strings = strings
self.name = 'Filters.text({})'.format(strings)

def filter(self, message):
if message.text:
return message.text in self.iterable
return message.text in self.strings
return False

def __call__(self, update):
if isinstance(update, Update):
return self.filter(update.effective_message)
else:
return self._TextIterable(update)
return self._TextStrings(update)

def filter(self, message):
return bool(message.text)

text = _Text()
"""Text Messages. If an iterable of strings is passed, it filters messages to only allow those
whose text is appearing in the given iterable.
"""Text Messages. If a list of strings is passed, it filters messages to only allow those
whose text is appearing in the given list.

Examples:
To allow any text message, simply use
``MessageHandler(Filters.text, callback_method)``.

A simple usecase for passing an iterable is to allow only messages that were send by a
A simple usecase for passing a list is to allow only messages that were send by a
custom :class:`telegram.ReplyKeyboardMarkup`::

buttons = ['Start', 'Settings', 'Back']
Expand All @@ -273,43 +273,43 @@ def filter(self, message):
MessageHandler(Filters.text(buttons), callback_method)

Args:
update (Iterable[:obj:`str`], optional): Which messages to allow. Only exact matches
are allowed. If not specified, will allow any text message.
update (List[:obj:`str`] | Tuple[:obj:`str`], optional): Which messages to allow. Only
exact matches are allowed. If not specified, will allow any text message.
"""

class _Caption(BaseFilter):
name = 'Filters.caption'

class _CaptionIterable(BaseFilter):
class _CaptionStrings(BaseFilter):

def __init__(self, iterable):
self.iterable = iterable
self.name = 'Filters.caption({})'.format(iterable)
def __init__(self, strings):
self.strings = strings
self.name = 'Filters.caption({})'.format(strings)

def filter(self, message):
if message.caption:
return message.caption in self.iterable
return message.caption in self.strings
return False

def __call__(self, update):
if isinstance(update, Update):
return self.filter(update.effective_message)
else:
return self._CaptionIterable(update)
return self._CaptionStrings(update)

def filter(self, message):
return bool(message.caption)

caption = _Caption()
"""Messages with a caption. If an iterable of strings is passed, it filters messages to only
allow those whose caption is appearing in the given iterable.
"""Messages with a caption. If a list of strings is passed, it filters messages to only
allow those whose caption is appearing in the given list.

Examples:
``MessageHandler(Filters.caption, callback_method)``

Args:
update (Iterable[:obj:`str`], optional): Which captions to allow. Only exact matches
are allowed. If not specified, will allow any message with a caption.
update (List[:obj:`str`] | Tuple[:obj:`str`], optional): Which captions to allow. Only
exact matches are allowed. If not specified, will allow any message with a caption.
"""

class _Command(BaseFilter):
Expand Down
6 changes: 3 additions & 3 deletions telegram/ext/updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -570,9 +570,9 @@ def idle(self, stop_signals=(SIGINT, SIGTERM, SIGABRT)):
"""Blocks until one of the signals are received and stops the updater.

Args:
stop_signals (:obj:`iterable`): Iterable containing signals from the signal module that
should be subscribed to. Updater.stop() will be called on receiving one of those
signals. Defaults to (``SIGINT``, ``SIGTERM``, ``SIGABRT``).
stop_signals (:obj:`list` | :obj:`tuple`): List containing signals from the signal
module that should be subscribed to. Updater.stop() will be called on receiving one
of those signals. Defaults to (``SIGINT``, ``SIGTERM``, ``SIGABRT``).

"""
for sig in stop_signals:
Expand Down
4 changes: 2 additions & 2 deletions tests/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def test_filters_text(self, update):
update.message.text = '/test'
assert (Filters.text)(update)

def test_filters_text_iterable(self, update):
def test_filters_text_strings(self, update):
update.message.text = '/test'
assert Filters.text({'/test', 'test1'})(update)
assert not Filters.text(['test1', 'test2'])(update)
Expand All @@ -58,7 +58,7 @@ def test_filters_caption(self, update):
update.message.caption = None
assert not (Filters.caption)(update)

def test_filters_caption_iterable(self, update):
def test_filters_caption_strings(self, update):
update.message.caption = 'test'
assert Filters.caption({'test', 'test1'})(update)
assert not Filters.caption(['test1', 'test2'])(update)
Expand Down