File tree Expand file tree Collapse file tree 2 files changed +37
-2
lines changed
Expand file tree Collapse file tree 2 files changed +37
-2
lines changed Original file line number Diff line number Diff line change @@ -102,6 +102,16 @@ def _raise_stop_error(*args):
102102 raise _StopError
103103
104104
105+ def _run_until_complete_cb (fut ):
106+ exc = fut ._exception
107+ if (isinstance (exc , BaseException )
108+ and not isinstance (exc , Exception )):
109+ # Issue #22429: run_forever() already finished, no need to
110+ # stop it.
111+ return
112+ _raise_stop_error ()
113+
114+
105115class Server (events .AbstractServer ):
106116
107117 def __init__ (self , loop , sockets ):
@@ -268,7 +278,7 @@ def run_until_complete(self, future):
268278 # is no need to log the "destroy pending task" message
269279 future ._log_destroy_pending = False
270280
271- future .add_done_callback (_raise_stop_error )
281+ future .add_done_callback (_run_until_complete_cb )
272282 try :
273283 self .run_forever ()
274284 except :
@@ -278,7 +288,7 @@ def run_until_complete(self, future):
278288 # local task.
279289 future .exception ()
280290 raise
281- future .remove_done_callback (_raise_stop_error )
291+ future .remove_done_callback (_run_until_complete_cb )
282292 if not future .done ():
283293 raise RuntimeError ('Event loop stopped before Future completed.' )
284294
Original file line number Diff line number Diff line change @@ -638,6 +638,31 @@ def raise_keyboard_interrupt():
638638
639639 self .assertFalse (self .loop .call_exception_handler .called )
640640
641+ def test_run_until_complete_baseexception (self ):
642+ # Python issue #22429: run_until_complete() must not schedule a pending
643+ # call to stop() if the future raised a BaseException
644+ @asyncio .coroutine
645+ def raise_keyboard_interrupt ():
646+ raise KeyboardInterrupt
647+
648+ self .loop ._process_events = mock .Mock ()
649+
650+ try :
651+ self .loop .run_until_complete (raise_keyboard_interrupt ())
652+ except KeyboardInterrupt :
653+ pass
654+
655+ def func ():
656+ self .loop .stop ()
657+ func .called = True
658+ func .called = False
659+ try :
660+ self .loop .call_soon (func )
661+ self .loop .run_forever ()
662+ except KeyboardInterrupt :
663+ pass
664+ self .assertTrue (func .called )
665+
641666
642667class MyProto (asyncio .Protocol ):
643668 done = None
You can’t perform that action at this time.
0 commit comments