diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index c16db36cf1b..4b3cbd48244 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -32,9 +32,14 @@ class BaseFilter(object): >>> (Filters.audio | Filters.video) + Not: + + >>> ~ Filters.command + Also works with more than two filters: >>> (Filters.text & (Filters.entity(URL) | Filters.entity(TEXT_LINK))) + >>> Filters.text & (~ Filters.forwarded) If you want to create your own filters create a class inheriting from this class and implement a `filter` method that returns a boolean: `True` if the message should be handled, `False` @@ -51,10 +56,32 @@ def __and__(self, other): def __or__(self, other): return MergedFilter(self, or_filter=other) + def __invert__(self): + return InvertedFilter(self) + def filter(self, message): raise NotImplementedError +class InvertedFilter(BaseFilter): + """Represents a filter that has been inverted. + + Args: + f: The filter to invert + """ + + def __init__(self, f): + self.f = f + + def filter(self, message): + return not self.f(message) + + def __str__(self): + return "".format(self.f) + + __repr__ = __str__ + + class MergedFilter(BaseFilter): """Represents a filter consisting of two other filters. diff --git a/tests/test_filters.py b/tests/test_filters.py index 814a85ae669..ec38c4ec2ed 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -226,6 +226,32 @@ def test_and_or_filters(self): r" or " r">>") + def test_inverted_filters(self): + self.message.text = '/test' + self.assertTrue((Filters.command)(self.message)) + self.assertFalse((~Filters.command)(self.message)) + self.message.text = 'test' + self.assertFalse((Filters.command)(self.message)) + self.assertTrue((~Filters.command)(self.message)) + + def test_inverted_and_filters(self): + self.message.text = '/test' + self.message.forward_date = 1 + self.assertTrue((Filters.forwarded & Filters.command)(self.message)) + self.assertFalse((~Filters.forwarded & Filters.command)(self.message)) + self.assertFalse((Filters.forwarded & ~Filters.command)(self.message)) + self.assertFalse((~(Filters.forwarded & Filters.command))(self.message)) + self.message.forward_date = None + self.assertFalse((Filters.forwarded & Filters.command)(self.message)) + self.assertTrue((~Filters.forwarded & Filters.command)(self.message)) + self.assertFalse((Filters.forwarded & ~Filters.command)(self.message)) + self.assertTrue((~(Filters.forwarded & Filters.command))(self.message)) + self.message.text = 'test' + self.assertFalse((Filters.forwarded & Filters.command)(self.message)) + self.assertFalse((~Filters.forwarded & Filters.command)(self.message)) + self.assertFalse((Filters.forwarded & ~Filters.command)(self.message)) + self.assertTrue((~(Filters.forwarded & Filters.command))(self.message)) + def test_faulty_custom_filter(self): class _CustomFilter(BaseFilter):