Add Filters.chat_type (#2128)

* add supergroup filter

* add chat_type filter

* re-implemented ChatType

* Add deprecations, improve tests

* Fix some docs

* Fix black

Co-authored-by: Hinrich Mahler <hinrich.mahler@freenet.de>
This commit is contained in:
GauthamramRavichandran 2020-10-30 00:12:08 +05:30 committed by GitHub
parent ff3fd34f08
commit 237e73bfb4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 119 additions and 2 deletions

View file

@ -42,6 +42,7 @@ The following wonderful people contributed directly or indirectly to this projec
- `evgfilim1 <https://github.com/evgfilim1>`_ - `evgfilim1 <https://github.com/evgfilim1>`_
- `franciscod <https://github.com/franciscod>`_ - `franciscod <https://github.com/franciscod>`_
- `gamgi <https://github.com/gamgi>`_ - `gamgi <https://github.com/gamgi>`_
- `Gauthamram Ravichandran <https://github.com/GauthamramRavichandran>`_
- `Harshil <https://github.com/harshil21>`_ - `Harshil <https://github.com/harshil21>`_
- `Hugo Damer <https://github.com/HakimusGIT>`_ - `Hugo Damer <https://github.com/HakimusGIT>`_
- `ihoru <https://github.com/ihoru>`_ - `ihoru <https://github.com/ihoru>`_

View file

@ -19,6 +19,7 @@
"""This module contains the Filters for use with the MessageHandler class.""" """This module contains the Filters for use with the MessageHandler class."""
import re import re
import warnings
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from threading import Lock from threading import Lock
@ -36,6 +37,8 @@ __all__ = [
'MergedFilter', 'MergedFilter',
] ]
from telegram.utils.deprecate import TelegramDeprecationWarning
class BaseFilter(ABC): class BaseFilter(ABC):
"""Base class for all Filters. """Base class for all Filters.
@ -949,19 +952,103 @@ officedocument.wordprocessingml.document")``-
name = 'Filters.private' name = 'Filters.private'
def filter(self, message: Message) -> bool: def filter(self, message: Message) -> bool:
warnings.warn(
'Filters.private is deprecated. Use Filters.chat_type.private instead.',
TelegramDeprecationWarning,
stacklevel=2,
)
return message.chat.type == Chat.PRIVATE return message.chat.type == Chat.PRIVATE
private = _Private() private = _Private()
"""Messages sent in a private chat.""" """
Messages sent in a private chat.
Note:
DEPRECATED. Use
:attr:`telegram.ext.Filters.chat_type.private` instead.
"""
class _Group(MessageFilter): class _Group(MessageFilter):
name = 'Filters.group' name = 'Filters.group'
def filter(self, message: Message) -> bool: def filter(self, message: Message) -> bool:
warnings.warn(
'Filters.group is deprecated. Use Filters.chat_type.groups instead.',
TelegramDeprecationWarning,
stacklevel=2,
)
return message.chat.type in [Chat.GROUP, Chat.SUPERGROUP] return message.chat.type in [Chat.GROUP, Chat.SUPERGROUP]
group = _Group() group = _Group()
"""Messages sent in a group chat.""" """
Messages sent in a group or a supergroup chat.
Note:
DEPRECATED. Use
:attr:`telegram.ext.Filters.chat_type.groups` instead.
"""
class _ChatType(MessageFilter):
name = 'Filters.chat_type'
class _Channel(MessageFilter):
name = 'Filters.chat_type.channel'
def filter(self, message: Message) -> bool:
return message.chat.type == Chat.CHANNEL
channel = _Channel()
class _Group(MessageFilter):
name = 'Filters.chat_type.group'
def filter(self, message: Message) -> bool:
return message.chat.type == Chat.GROUP
group = _Group()
class _SuperGroup(MessageFilter):
name = 'Filters.chat_type.supergroup'
def filter(self, message: Message) -> bool:
return message.chat.type == Chat.SUPERGROUP
supergroup = _SuperGroup()
class _Groups(MessageFilter):
name = 'Filters.chat_type.groups'
def filter(self, message: Message) -> bool:
return message.chat.type in [Chat.GROUP, Chat.SUPERGROUP]
groups = _Groups()
class _Private(MessageFilter):
name = 'Filters.chat_type.private'
def filter(self, message: Message) -> bool:
return message.chat.type == Chat.PRIVATE
private = _Private()
def filter(self, message: Message) -> bool:
return bool(message.chat.type)
chat_type = _ChatType()
"""Subset for filtering the type of chat.
Examples:
Use these filters like: ``Filters.chat_type.channel`` or
``Filters.chat_type.supergroup`` etc. Or use just ``Filters.chat_type`` for all
chat types.
Attributes:
channel: Updates from channel
group: Updates from group
supergroup: Updates from supergroup
groups: Updates from group *or* supergroup
private: Updates sent in private chat
"""
class user(MessageFilter): class user(MessageFilter):
"""Filters messages to allow only those which are from specified user ID(s) or """Filters messages to allow only those which are from specified user ID(s) or

View file

@ -24,6 +24,8 @@ from telegram import Message, User, Chat, MessageEntity, Document, Update, Dice
from telegram.ext import Filters, BaseFilter, MessageFilter, UpdateFilter from telegram.ext import Filters, BaseFilter, MessageFilter, UpdateFilter
import re import re
from telegram.utils.deprecate import TelegramDeprecationWarning
@pytest.fixture(scope='function') @pytest.fixture(scope='function')
def update(): def update():
@ -574,6 +576,10 @@ class TestFilters:
update.message.chat.type = 'group' update.message.chat.type = 'group'
assert not Filters.private(update) assert not Filters.private(update)
def test_private_filter_deprecation(self, update):
with pytest.warns(TelegramDeprecationWarning):
Filters.private(update)
def test_group_filter(self, update): def test_group_filter(self, update):
assert not Filters.group(update) assert not Filters.group(update)
update.message.chat.type = 'group' update.message.chat.type = 'group'
@ -581,6 +587,29 @@ class TestFilters:
update.message.chat.type = 'supergroup' update.message.chat.type = 'supergroup'
assert Filters.group(update) assert Filters.group(update)
def test_group_filter_deprecation(self, update):
with pytest.warns(TelegramDeprecationWarning):
Filters.group(update)
@pytest.mark.parametrize(
('chat_type, results'),
[
(None, (False, False, False, False, False, False)),
(Chat.PRIVATE, (True, True, False, False, False, False)),
(Chat.GROUP, (True, False, True, False, True, False)),
(Chat.SUPERGROUP, (True, False, False, True, True, False)),
(Chat.CHANNEL, (True, False, False, False, False, True)),
],
)
def test_filters_chat_types(self, update, chat_type, results):
update.message.chat.type = chat_type
assert Filters.chat_type(update) is results[0]
assert Filters.chat_type.private(update) is results[1]
assert Filters.chat_type.group(update) is results[2]
assert Filters.chat_type.supergroup(update) is results[3]
assert Filters.chat_type.groups(update) is results[4]
assert Filters.chat_type.channel(update) is results[5]
def test_filters_user_init(self): def test_filters_user_init(self):
with pytest.raises(RuntimeError, match='in conjunction with'): with pytest.raises(RuntimeError, match='in conjunction with'):
Filters.user(user_id=1, username='user') Filters.user(user_id=1, username='user')