-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Description
Currently filters check updates via the __call__
method. When switching from function-based filters to class-based filters, this was mainly done to maintain backwards compatibility with filter(update)
. However with some of the new filters functionalities, this leads to ugly workarounds like
python-telegram-bot/telegram/ext/filters.py
Lines 329 to 350 in 8e7c0d6
class _Text(MessageFilter): | |
name = 'Filters.text' | |
class _TextStrings(MessageFilter): | |
def __init__(self, strings: List[str]): | |
self.strings = strings | |
self.name = 'Filters.text({})'.format(strings) | |
def filter(self, message: Message) -> bool: | |
if message.text: | |
return message.text in self.strings | |
return False | |
def __call__( # type: ignore[override] | |
self, update: Union[Update, List[str]] | |
) -> Union[bool, '_TextStrings']: | |
if isinstance(update, Update): | |
return self.filter(update.effective_message) | |
return self._TextStrings(update) | |
def filter(self, message: Message) -> bool: | |
return bool(message.text) |
I therefore propose to refactor to something along the lines of
class BaseFilter:
def __call__(self, *args, **kwargs):
return self.__class__(*args, **kwargs)
@abstractmethod
def check_update(update/method):
...
This matches the Handler.check_update
interface and allows for filters having a custom __init__
, wich can still be called through instances of those filters.
However, this is somewhat breaking: While BaseFilter.__call__
is undocumented, people might still have Filters.existing_filter(update)
somewhere within their custom filters. So maybe this is better suited for a major release.