]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #23353, asyncio: Workaround CPython bug #23353
authorVictor Stinner <victor.stinner@gmail.com>
Mon, 2 Feb 2015 17:36:31 +0000 (18:36 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Mon, 2 Feb 2015 17:36:31 +0000 (18:36 +0100)
Don't use yield/yield-from in an except block of a generator. Store the
exception and handle it outside the except block.

Lib/asyncio/test_utils.py
Lib/asyncio/unix_events.py
Lib/asyncio/windows_events.py

index 6eedc583dba0b2a97d96ced738cb9493d5937aa8..8cee95b84f95726dfb028182996e5cc1697dd5cf 100644 (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():
index 1fc39abe09ce8b2527f3f43030395a0631064ed5..75e7c9ccadd094965ff5c900ff4b9ca9c166d417 100644 (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
 
index c4bffc473465b8548d22c5bb8a99f589f255ee1d..f311e4631558683d5958366d579bfe1647991210 100644 (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