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):
102
102
raise _StopError
103
103
104
104
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
+
105
115
class Server (events .AbstractServer ):
106
116
107
117
def __init__ (self , loop , sockets ):
@@ -268,7 +278,7 @@ def run_until_complete(self, future):
268
278
# is no need to log the "destroy pending task" message
269
279
future ._log_destroy_pending = False
270
280
271
- future .add_done_callback (_raise_stop_error )
281
+ future .add_done_callback (_run_until_complete_cb )
272
282
try :
273
283
self .run_forever ()
274
284
except :
@@ -278,7 +288,7 @@ def run_until_complete(self, future):
278
288
# local task.
279
289
future .exception ()
280
290
raise
281
- future .remove_done_callback (_raise_stop_error )
291
+ future .remove_done_callback (_run_until_complete_cb )
282
292
if not future .done ():
283
293
raise RuntimeError ('Event loop stopped before Future completed.' )
284
294
Original file line number Diff line number Diff line change @@ -638,6 +638,31 @@ def raise_keyboard_interrupt():
638
638
639
639
self .assertFalse (self .loop .call_exception_handler .called )
640
640
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
+
641
666
642
667
class MyProto (asyncio .Protocol ):
643
668
done = None
You can’t perform that action at this time.
0 commit comments