Repository: python-telegram-bot/python-telegram-bot
Pull request: Allow edited as seperate input
In short made it possible to tune messagehandler more to your wishes. and choose exactly what updates to receive. messages, edited_message or channel_post or a combination.

- Added the edited_updates argument to MessageHandler
- Added DeprecationWarning when using allow_edited
- replaced _is_allowed_message and _is_allowed_channel_post with _is_allowed_update
- Modified tests to reflect new way

fixes #607 

Problem statement:
add ability to handle only edited messages updates
Actually if you want to develop a bot where when a user edits his message it replies "you edited this message" or a bot that in groups kicks users that edit their messages (let's imagine a strange rule), there is not a handler to handle only edited messages.

messagehandler just handles any messages and not only those edited. So a handler or a filter to handle only edited messages is needed. Thanks

Hints from issue discussion:

Commit message: Python 2 does not have assertWarns.

Patch to review:
diff --git a/telegram/ext/messagehandler.py b/telegram/ext/messagehandler.py
index f19778da4b7..944d3e16c07 100644
--- a/telegram/ext/messagehandler.py
+++ b/telegram/ext/messagehandler.py
@@ -37,8 +37,6 @@ class MessageHandler(Handler):
         callback (function): A function that takes ``bot, update`` as
             positional arguments. It will be called when the ``check_update``
             has determined that an update should be processed by this handler.
-        allow_edited (Optional[bool]): If the handler should also accept edited messages.
-            Default is ``False``
         pass_update_queue (optional[bool]): If the handler should be passed the
             update queue as a keyword argument called ``update_queue``. It can
             be used to insert updates. Default is ``False``
@@ -52,8 +50,12 @@ class MessageHandler(Handler):
             For each update in the same chat, it will be the same ``dict``. Default is ``False``.
         message_updates (Optional[bool]): Should "normal" message updates be handled? Default is
             ``True``.
+        allow_edited (Optional[bool]): If the handler should also accept edited messages.
+            Default is ``False`` - Deprecated. use edited updates instead.
         channel_post_updates (Optional[bool]): Should channel posts updates be handled? Default is
             ``True``.
+        edited_updates (Optional[bool]): Should "edited" message updates be handled? Default is
+            ``False``.
 
     """
 
@@ -66,9 +68,13 @@ def __init__(self,
                  pass_user_data=False,
                  pass_chat_data=False,
                  message_updates=True,
-                 channel_post_updates=True):
-        if not message_updates and not channel_post_updates:
-            raise ValueError('Both message_updates & channel_post_updates are False')
+                 channel_post_updates=True,
+                 edited_updates=False):
+        if not message_updates and not channel_post_updates and not edited_updates:
+            raise ValueError(
+                'message_updates, channel_post_updates and edited_updates are all False')
+        if allow_edited:
+            warnings.warn('allow_edited is getting deprecated, please use edited_updates instead')
 
         super(MessageHandler, self).__init__(
             callback,
@@ -80,6 +86,7 @@ def __init__(self,
         self.allow_edited = allow_edited
         self.message_updates = message_updates
         self.channel_post_updates = channel_post_updates
+        self.edited_updates = edited_updates
 
         # We put this up here instead of with the rest of checking code
         # in check_update since we don't wanna spam a ton
@@ -88,17 +95,14 @@ def __init__(self,
                           'deprecated, please use bitwise operators (& and |) '
                           'instead. More info: https://git.io/vPTbc.')
 
-    def _is_allowed_message(self, update):
-        return (self.message_updates
-                and (update.message or (update.edited_message and self.allow_edited)))
-
-    def _is_allowed_channel_post(self, update):
-        return (self.channel_post_updates
-                and (update.channel_post or (update.edited_channel_post and self.allow_edited)))
+    def _is_allowed_update(self, update):
+        return any([(self.message_updates and update.message),
+                    (self.allow_edited and update.edited_message),
+                    (self.edited_updates and update.edited_message),
+                    (self.channel_post_updates and update.channel_post)])
 
     def check_update(self, update):
-        if (isinstance(update, Update)
-                and (self._is_allowed_message(update) or self._is_allowed_channel_post(update))):
+        if isinstance(update, Update) and self._is_allowed_update(update):
 
             if not self.filters:
                 res = True
diff --git a/tests/test_updater.py b/tests/test_updater.py
index 25e2eb06229..3939b0250f6 100644
--- a/tests/test_updater.py
+++ b/tests/test_updater.py
@@ -108,7 +108,7 @@ def telegramHandlerTest(self, bot, update):
         self.message_count += 1
 
     def telegramHandlerEditedTest(self, bot, update):
-        self.received_message = update.edited_message.text
+        self.received_message = update.effective_message.text
         self.message_count += 1
 
     def telegramInlineHandlerTest(self, bot, update):
@@ -188,22 +188,31 @@ def test_editedMessageHandler(self):
         self._setup_updater('Test', edited=True)
         d = self.updater.dispatcher
         from telegram.ext import Filters
-        handler = MessageHandler(Filters.text, self.telegramHandlerEditedTest, allow_edited=True)
+        handler = MessageHandler(Filters.text, self.telegramHandlerEditedTest, edited_updates=True)
         d.add_handler(handler)
         self.updater.start_polling(0.01)
         sleep(.1)
         self.assertEqual(self.received_message, 'Test')
 
-        # Remove handler
+        self.reset()
         d.remove_handler(handler)
-        handler = MessageHandler(Filters.text, self.telegramHandlerEditedTest, allow_edited=False)
+        handler = MessageHandler(
+            Filters.text,
+            self.telegramHandlerEditedTest,
+            edited_updates=False,
+            message_updates=False)
         d.add_handler(handler)
-        self.reset()
-
         self.updater.bot.send_messages = 1
         sleep(.1)
         self.assertTrue(None is self.received_message)
 
+        handler = MessageHandler(Filters.text, self.telegramHandlerEditedTest, allow_edited=True)
+        d.add_handler(handler)
+        self.reset()
+        self.updater.bot.send_messages = 1
+        sleep(.1)
+        self.assertEqual(self.received_message, 'Test')
+
     def test_addTelegramMessageHandlerMultipleMessages(self):
         self._setup_updater('Multiple', 100)
         self.updater.dispatcher.add_handler(MessageHandler(Filters.all, self.telegramHandlerTest))


Code review comments:
diff_hunk: @@ -88,17 +95,14 @@ def __init__(self,
                           'deprecated, please use bitwise operators (& and |) '
                           'instead. More info: https://git.io/vPTbc.')
 
-    def _is_allowed_message(self, update):
-        return (self.message_updates
-                and (update.message or (update.edited_message and self.allow_edited)))
-
-    def _is_allowed_channel_post(self, update):
-        return (self.channel_post_updates
-                and (update.channel_post or (update.edited_channel_post and self.allow_edited)))
+    def _is_allowed_update(self, update):
+        return any([(self.message_updates and update.message),
+                    (self.allow_edited and update.edited_message),
path: telegram/ext/messagehandler.py
text: @user1:
... and this one

diff_hunk: @@ -80,6 +86,7 @@ def __init__(self,
         self.allow_edited = allow_edited
path: telegram/ext/messagehandler.py
text: @user1:
... and then you can remove this line