Skip to content

Commit 0d595af

Browse files
committed
fix handle case with no exception
1 parent 37837ed commit 0d595af

File tree

2 files changed

+31
-14
lines changed

2 files changed

+31
-14
lines changed

Lib/asyncio/tasks.py

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -908,18 +908,23 @@ def _done_callback(fut, cur_task=cur_task):
908908
return outer
909909

910910

911-
def _log_on_cancel_callback(inner):
912-
if not inner.cancelled():
913-
exc = inner.exception()
914-
context = {
915-
'message':
916-
f'{exc.__class__.__name__} exception in shielded future',
917-
'exception': exc,
918-
'future': inner,
919-
}
920-
if inner._source_traceback:
921-
context['source_traceback'] = inner._source_traceback
922-
inner._loop.call_exception_handler(context)
911+
def _log_on_exception(fut):
912+
if fut.cancelled():
913+
return
914+
915+
exc = fut.exception()
916+
if exc is None:
917+
return
918+
919+
context = {
920+
'message':
921+
f'{exc.__class__.__name__} exception in shielded future',
922+
'exception': exc,
923+
'future': fut,
924+
}
925+
if fut._source_traceback:
926+
context['source_traceback'] = fut._source_traceback
927+
fut._loop.call_exception_handler(context)
923928

924929

925930
def shield(arg):
@@ -987,8 +992,8 @@ def _outer_done_callback(outer):
987992
if not inner.done():
988993
inner.remove_done_callback(_inner_done_callback)
989994
# Keep only one callback to log on cancel
990-
inner.remove_done_callback(_log_on_cancel_callback)
991-
inner.add_done_callback(_log_on_cancel_callback)
995+
inner.remove_done_callback(_log_on_exception)
996+
inner.add_done_callback(_log_on_exception)
992997

993998
if cur_task is not None:
994999
inner.add_done_callback(_clear_awaited_by_callback)

Lib/test/test_asyncio/test_tasks.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,6 +2116,18 @@ def test_shield_cancel_outer(self):
21162116
self.assertTrue(outer.cancelled())
21172117
self.assertEqual(0, 0 if outer._callbacks is None else len(outer._callbacks))
21182118

2119+
def test_shield_cancel_outer_result(self):
2120+
mock_handler = mock.Mock()
2121+
self.loop.set_exception_handler(mock_handler)
2122+
inner = self.new_future(self.loop)
2123+
outer = asyncio.shield(inner)
2124+
test_utils.run_briefly(self.loop)
2125+
outer.cancel()
2126+
test_utils.run_briefly(self.loop)
2127+
inner.set_result(1)
2128+
test_utils.run_briefly(self.loop)
2129+
mock_handler.assert_not_called()
2130+
21192131
def test_shield_cancel_outer_exception(self):
21202132
mock_handler = mock.Mock()
21212133
self.loop.set_exception_handler(mock_handler)

0 commit comments

Comments
 (0)