@@ -328,12 +328,18 @@ def initialize(self):
328328
329329 self .is_initialized = True
330330
331- def terminate (self ):
331+ def terminate (self , block : bool = True ):
332332 """Terminate the client by shutting down workers.
333333
334334 This method does the opposite of :meth:`~Client.initialize`.
335335 It will stop the dispatcher and shut down updates and download workers.
336336
337+ Parameters:
338+ block (``bool``, *optional*):
339+ Blocks the code execution until the client has been terminated. It is useful with ``block=False`` in
340+ case you want to terminate the own client *within* an handler in order not to cause a deadlock.
341+ Defaults to True.
342+
337343 Raises:
338344 ConnectionError: In case you try to terminate a client that is already terminated.
339345 """
@@ -345,7 +351,7 @@ def terminate(self):
345351 log .warning ("Takeout session {} finished" .format (self .takeout_id ))
346352
347353 Syncer .remove (self )
348- self .dispatcher .stop ()
354+ self .dispatcher .stop (block )
349355
350356 for _ in range (self .DOWNLOAD_WORKERS ):
351357 self .download_queue .put (None )
@@ -840,11 +846,17 @@ def start(self):
840846 self .initialize ()
841847 return self
842848
843- def stop (self ):
849+ def stop (self , block : bool = True ):
844850 """Stop the Client.
845851
846852 This method disconnects the client from Telegram and stops the underlying tasks.
847853
854+ Parameters:
855+ block (``bool``, *optional*):
856+ Blocks the code execution until the client has been stopped. It is useful with ``block=False`` in case
857+ you want to stop the own client *within* an handler in order not to cause a deadlock.
858+ Defaults to True.
859+
848860 Returns:
849861 :obj:`Client`: The stopped client itself.
850862
@@ -864,17 +876,23 @@ def stop(self):
864876
865877 app.stop()
866878 """
867- self .terminate ()
879+ self .terminate (block )
868880 self .disconnect ()
869881
870882 return self
871883
872- def restart (self ):
884+ def restart (self , block : bool = True ):
873885 """Restart the Client.
874886
875887 This method will first call :meth:`~Client.stop` and then :meth:`~Client.start` in a row in order to restart
876888 a client using a single method.
877889
890+ Parameters:
891+ block (``bool``, *optional*):
892+ Blocks the code execution until the client has been restarted. It is useful with ``block=False`` in case
893+ you want to restart the own client *within* an handler in order not to cause a deadlock.
894+ Defaults to True.
895+
878896 Returns:
879897 :obj:`Client`: The restarted client itself.
880898
@@ -898,7 +916,7 @@ def restart(self):
898916
899917 app.stop()
900918 """
901- self .stop ()
919+ self .stop (block )
902920 self .start ()
903921
904922 return self
@@ -985,7 +1003,7 @@ def run(self):
9851003 Client .idle ()
9861004 self .stop ()
9871005
988- def add_handler (self , handler : Handler , group : int = 0 ):
1006+ def add_handler (self , handler : Handler , group : int = 0 , block : bool = True ):
9891007 """Register an update handler.
9901008
9911009 You can register multiple handlers, but at most one handler within a group will be used for a single update.
@@ -1000,6 +1018,11 @@ def add_handler(self, handler: Handler, group: int = 0):
10001018 group (``int``, *optional*):
10011019 The group identifier, defaults to 0.
10021020
1021+ block (``bool``, *optional*):
1022+ Blocks the code execution until the handler has been added. It is useful with ``block=False`` in case
1023+ you want to register a new handler *within* another handler in order not to cause a deadlock.
1024+ Defaults to True.
1025+
10031026 Returns:
10041027 ``tuple``: A tuple consisting of *(handler, group)*.
10051028
@@ -1021,11 +1044,11 @@ def dump(client, message):
10211044 if isinstance (handler , DisconnectHandler ):
10221045 self .disconnect_handler = handler .callback
10231046 else :
1024- self .dispatcher .add_handler (handler , group )
1047+ self .dispatcher .add_handler (handler , group , block )
10251048
10261049 return handler , group
10271050
1028- def remove_handler (self , handler : Handler , group : int = 0 ):
1051+ def remove_handler (self , handler : Handler , group : int = 0 , block : bool = True ):
10291052 """Remove a previously-registered update handler.
10301053
10311054 Make sure to provide the right group where the handler was added in. You can use the return value of the
@@ -1038,6 +1061,13 @@ def remove_handler(self, handler: Handler, group: int = 0):
10381061 group (``int``, *optional*):
10391062 The group identifier, defaults to 0.
10401063
1064+ block (``bool``, *optional*):
1065+ Blocks the code execution until the handler has been removed. It is useful with ``block=False`` in case
1066+ you want to remove a previously registered handler *within* another handler in order not to cause a
1067+ deadlock.
1068+ Defaults to True.
1069+
1070+
10411071 Example:
10421072 .. code-block:: python
10431073 :emphasize-lines: 11
@@ -1059,7 +1089,7 @@ def dump(client, message):
10591089 if isinstance (handler , DisconnectHandler ):
10601090 self .disconnect_handler = None
10611091 else :
1062- self .dispatcher .remove_handler (handler , group )
1092+ self .dispatcher .remove_handler (handler , group , block )
10631093
10641094 def stop_transmission (self ):
10651095 """Stop downloading or uploading a file.
0 commit comments