Issue #23353, asyncio: Workaround CPython bug #23353

Don't use yield/yield-from in an except block of a generator. Store the
exception and handle it outside the except block.
This commit is contained in:
Victor Stinner 2015-02-02 18:36:31 +01:00
parent 7a66fc22ad
commit 5d44c08f1c
3 changed files with 23 additions and 4 deletions

View File

@ -416,6 +416,10 @@ class TestCase(unittest.TestCase):
def tearDown(self):
events.set_event_loop(None)
# Detect CPython bug #23353: ensure that yield/yield-from is not used
# in an except block of a generator
self.assertEqual(sys.exc_info(), (None, None, None))
@contextlib.contextmanager
def disable_logger():

View File

@ -186,10 +186,18 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
self._child_watcher_callback, transp)
try:
yield from waiter
except:
except Exception as exc:
# Workaround CPython bug #23353: using yield/yield-from in an
# except block of a generator doesn't clear properly
# sys.exc_info()
err = exc
else:
err = None
if err is not None:
transp.close()
yield from transp._wait()
raise
raise err
return transp

View File

@ -373,10 +373,17 @@ class ProactorEventLoop(proactor_events.BaseProactorEventLoop):
**kwargs)
try:
yield from waiter
except:
except Exception as exc:
# Workaround CPython bug #23353: using yield/yield-from in an
# except block of a generator doesn't clear properly sys.exc_info()
err = exc
else:
err = None
if err is not None:
transp.close()
yield from transp._wait()
raise
raise err
return transp