2
0
mirror of https://github.com/pyrogram/pyrogram synced 2025-08-28 21:07:59 +00:00

Add a way to continue the update propagation within a group

Add continue_propagation() method and ContinuePropagation exception
Closes #212
This commit is contained in:
Dan 2019-02-04 12:33:54 +01:00
parent ccecbd6a50
commit a6dbed6dfb
5 changed files with 91 additions and 8 deletions

View File

@ -91,13 +91,14 @@ Stop Propagation
In order to prevent further propagation of an update in the dispatching phase, you can do *one* of the following: In order to prevent further propagation of an update in the dispatching phase, you can do *one* of the following:
- Call the update's bound-method ``.stop_propagation()`` (preferred way). - Call the update's bound-method ``.stop_propagation()`` (preferred way).
- Manually ``raise StopPropagation`` error (more suitable for raw updates only). - Manually ``raise StopPropagation`` exception (more suitable for raw updates only).
.. note:: .. note::
Note that ``.stop_propagation()`` is just an elegant and intuitive way to raise a ``StopPropagation`` error; Internally, the propagation is stopped by handling a custom exception. ``.stop_propagation()`` is just an elegant
this means that any code coming *after* calling it won't be executed as your function just raised a custom exception and intuitive way to ``raise StopPropagation``; this also means that any code coming *after* calling the method
to signal the dispatcher not to propagate the update anymore. won't be executed as your function just raised an exception to signal the dispatcher not to propagate the
update anymore.
Example with ``stop_propagation()``: Example with ``stop_propagation()``:
@ -139,10 +140,82 @@ Example with ``raise StopPropagation``:
def _(client, message): def _(client, message):
print(2) print(2)
The handler in group number 2 will never be executed because the propagation was stopped before. The output of both Each handler is registered in a different group, but the handler in group number 2 will never be executed because the
examples will be: propagation was stopped earlier. The output of both (equivalent) examples will be:
.. code-block:: text .. code-block:: text
0 0
1 1
Continue Propagation
^^^^^^^^^^^^^^^^^^^^
As opposed to `stopping the update propagation <#stop-propagation>`_ and also as an alternative to the
`handler groups <#handler-groups>`_, you can signal the internal dispatcher to continue the update propagation within
the group regardless of the next handler's filters. This allows you to register multiple handlers with overlapping
filters in the same group; to let the dispatcher process the next handler you can do *one* of the following in each
handler you want to grant permission to continue:
- Call the update's bound-method ``.continue_propagation()`` (preferred way).
- Manually ``raise ContinuePropagation`` exception (more suitable for raw updates only).
.. note::
Internally, the propagation is continued by handling a custom exception. ``.continue_propagation()`` is just an
elegant and intuitive way to ``raise ContinuePropagation``; this also means that any code coming *after* calling the
method won't be executed as your function just raised an exception to signal the dispatcher to continue with the
next available handler.
Example with ``continue_propagation()``:
.. code-block:: python
@app.on_message(Filters.private)
def _(client, message):
print(0)
message.continue_propagation()
@app.on_message(Filters.private)
def _(client, message):
print(1)
message.continue_propagation()
@app.on_message(Filters.private)
def _(client, message):
print(2)
Example with ``raise ContinuePropagation``:
.. code-block:: python
from pyrogram import ContinuePropagation
@app.on_message(Filters.private)
def _(client, message):
print(0)
raise ContinuePropagation
@app.on_message(Filters.private)
def _(client, message):
print(1)
raise ContinuePropagation
@app.on_message(Filters.private)
def _(client, message):
print(2)
Three handlers are registered in the same group, and all of them will be executed because the propagation was continued
in each handler (except in the last one, where is useless to do so since there is no more handlers after).
The output of both (equivalent) examples will be:
.. code-block:: text
0
1
2

View File

@ -32,7 +32,8 @@ from .client.types import (
Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, User, UserStatus, Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, User, UserStatus,
UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply, UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply,
InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove, InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove,
Poll, PollOption, ChatPreview, StopPropagation, Game, CallbackGame, GameHighScore, GameHighScores Poll, PollOption, ChatPreview, StopPropagation, ContinuePropagation, Game, CallbackGame, GameHighScore,
GameHighScores
) )
from .client import ( from .client import (
Client, ChatAction, ParseMode, Emoji, Client, ChatAction, ParseMode, Emoji,

View File

@ -151,6 +151,8 @@ class Dispatcher:
handler.callback(self.client, *args) handler.callback(self.client, *args)
except pyrogram.StopPropagation: except pyrogram.StopPropagation:
raise raise
except pyrogram.ContinuePropagation:
continue
except Exception as e: except Exception as e:
log.error(e, exc_info=True) log.error(e, exc_info=True)

View File

@ -30,7 +30,7 @@ from .messages_and_media import (
Sticker, Venue, Video, VideoNote, Voice, UserProfilePhotos, Sticker, Venue, Video, VideoNote, Voice, UserProfilePhotos,
Message, Messages, MessageEntity, Poll, PollOption, Game Message, Messages, MessageEntity, Poll, PollOption, Game
) )
from .update import StopPropagation from .update import StopPropagation, ContinuePropagation
from .user_and_chats import ( from .user_and_chats import (
Chat, ChatMember, ChatMembers, ChatPhoto, Chat, ChatMember, ChatMembers, ChatPhoto,
Dialog, Dialogs, User, UserStatus, ChatPreview Dialog, Dialogs, User, UserStatus, ChatPreview

View File

@ -21,6 +21,13 @@ class StopPropagation(StopIteration):
pass pass
class ContinuePropagation(StopIteration):
pass
class Update: class Update:
def stop_propagation(self): def stop_propagation(self):
raise StopPropagation raise StopPropagation
def continue_propagation(self):
raise ContinuePropagation