diff options
| author | Victor Stinner <victor.stinner@gmail.com> | 2014-06-22 23:03:13 (GMT) |
|---|---|---|
| committer | Victor Stinner <victor.stinner@gmail.com> | 2014-06-22 23:03:13 (GMT) |
| commit | 425aaa11d88c3f831ebabf8ab3c51ffaa3c3f3d5 (patch) | |
| tree | d8ecceac0ca00efa8e912387249f2b9513b5f6e7 | |
| parent | 422a76d6adb4ab2cbfa6dc56d90be2e11c479148 (diff) | |
| parent | f328c7dc69da14766435d8608f89d81cd878bb4d (diff) | |
| download | cpython-425aaa11d88c3f831ebabf8ab3c51ffaa3c3f3d5.zip cpython-425aaa11d88c3f831ebabf8ab3c51ffaa3c3f3d5.tar.gz cpython-425aaa11d88c3f831ebabf8ab3c51ffaa3c3f3d5.tar.bz2 | |
(Merge 3.4) asyncio, Tulip issue 171: BaseEventLoop.close() now raises an
exception if the event loop is running. You must first stop the event loop and
then wait until it stopped, before closing it.
| -rw-r--r-- | Doc/library/asyncio-eventloop.rst | 2 | ||||
| -rw-r--r-- | Lib/asyncio/base_events.py | 4 | ||||
| -rw-r--r-- | Lib/asyncio/proactor_events.py | 2 | ||||
| -rw-r--r-- | Lib/asyncio/selector_events.py | 2 | ||||
| -rw-r--r-- | Lib/asyncio/unix_events.py | 2 | ||||
| -rw-r--r-- | Lib/test/test_asyncio/test_events.py | 9 |
6 files changed, 18 insertions, 3 deletions
diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index e62f5ef..c242fc3 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -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. diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 2f7f197..42d8b0b 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -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 diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 757a22e..b76f69e 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -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) diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index a62a8e5..df64aec 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -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 diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index acb327d..ad4c229 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -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. diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 37e45e1..020d123 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -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: |
