]> granicus.if.org Git - python/commitdiff
asyncio, Tulip issue 171: BaseEventLoop.close() now raises an exception if the
authorVictor Stinner <victor.stinner@gmail.com>
Sun, 22 Jun 2014 23:02:37 +0000 (01:02 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Sun, 22 Jun 2014 23:02:37 +0000 (01:02 +0200)
event loop is running. You must first stop the event loop and then wait until
it stopped, before closing it.

Doc/library/asyncio-eventloop.rst
Lib/asyncio/base_events.py
Lib/asyncio/proactor_events.py
Lib/asyncio/selector_events.py
Lib/asyncio/unix_events.py
Lib/test/test_asyncio/test_events.py

index e62f5efa6389b321b6973db78d7d73806c806b63..c242fc3dc1b3f452cad8d775f18178f5fd6f8897 100644 (file)
@@ -132,6 +132,8 @@ Run an event loop
    This clears the queues and shuts down the executor, but does not wait for
    the executor to finish.
 
+   The event loop must not be running.
+
    This is idempotent and irreversible. No other methods should be called after
    this one.
 
index 2f7f1979d3e886757b745ed4afcec26cba716da7..42d8b0b4027cda4d6a49fa3d4a8cd0a4af3b94d4 100644 (file)
@@ -247,7 +247,11 @@ class BaseEventLoop(events.AbstractEventLoop):
 
         This clears the queues and shuts down the executor,
         but does not wait for the executor to finish.
+
+        The event loop must not be running.
         """
+        if self._running:
+            raise RuntimeError("cannot close a running event loop")
         if self._closed:
             return
         self._closed = True
index 757a22e83ab253db6f3435d1a0608fda41f78226..b76f69ee57107d0b07e5a63b53d6e4d1b0a1141d 100644 (file)
@@ -355,12 +355,12 @@ class BaseProactorEventLoop(base_events.BaseEventLoop):
     def close(self):
         if self.is_closed():
             return
+        super().close()
         self._stop_accept_futures()
         self._close_self_pipe()
         self._proactor.close()
         self._proactor = None
         self._selector = None
-        super().close()
 
     def sock_recv(self, sock, n):
         return self._proactor.recv(sock, n)
index a62a8e58267a7b733026f7ddd3f2a14d9fc19576..df64aece3ba0f3c9ed0edf0c518cfdf1ad475482 100644 (file)
@@ -57,11 +57,11 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
     def close(self):
         if self.is_closed():
             return
+        super().close()
         self._close_self_pipe()
         if self._selector is not None:
             self._selector.close()
             self._selector = None
-        super().close()
 
     def _socketpair(self):
         raise NotImplementedError
index acb327d9981c8ce74818a6c37fa8ed053aa6b28f..ad4c229438cd17822f5326cb38ac8e874c13769e 100644 (file)
@@ -44,9 +44,9 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
         return socket.socketpair()
 
     def close(self):
+        super().close()
         for sig in list(self._signal_handlers):
             self.remove_signal_handler(sig)
-        super().close()
 
     def add_signal_handler(self, sig, callback, *args):
         """Add a handler for a signal.  UNIX only.
index 37e45e1df70842859c237253387b3b48ce677493..020d12303d819bb0fa7eae4e4a027c72d580ecc3 100644 (file)
@@ -1365,6 +1365,15 @@ class EventLoopTestsMixin:
         with self.assertRaises(RuntimeError):
             loop.add_writer(w, callback)
 
+    def test_close_running_event_loop(self):
+        @asyncio.coroutine
+        def close_loop(loop):
+            self.loop.close()
+
+        coro = close_loop(self.loop)
+        with self.assertRaises(RuntimeError):
+            self.loop.run_until_complete(coro)
+
 
 class SubprocessTestsMixin: