[Python-checkins] cpython (3.4): asyncio: sync with Tulip

victor.stinner python-checkins at python.org
Tue Jul 8 12:44:36 CEST 2014


http://hg.python.org/cpython/rev/8d759d8f6ccb
changeset:   91608:8d759d8f6ccb
branch:      3.4
parent:      91604:f67df13dd512
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Tue Jul 08 11:29:25 2014 +0200
summary:
  asyncio: sync with Tulip

- Tulip issue 185: Add a create_task() method to event loops. The create_task()
  method can be overriden in custom event loop to implement their own task
  class. For example, greenio and Pulsar projects use their own task class. The
  create_task() method is now preferred over creating directly task using the
  Task class.
- tests: fix a warning
- fix typo in the name of a test function
- Update AbstractEventLoop: add new event loop methods; update also the unit test

files:
  Lib/asyncio/base_events.py                |   6 ++
  Lib/asyncio/events.py                     |   9 ++++
  Lib/asyncio/streams.py                    |   2 +-
  Lib/asyncio/tasks.py                      |   4 +-
  Lib/asyncio/test_utils.py                 |   2 +-
  Lib/test/test_asyncio/test_base_events.py |  24 +++++++++++
  Lib/test/test_asyncio/test_events.py      |  14 ++++++
  Lib/test/test_asyncio/test_futures.py     |   4 +-
  Lib/test/test_asyncio/test_tasks.py       |   3 +
  9 files changed, 63 insertions(+), 5 deletions(-)


diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -151,6 +151,12 @@
                 % (self.__class__.__name__, self.is_running(),
                    self.is_closed(), self.get_debug()))
 
+    def create_task(self, coro):
+        """Schedule a coroutine object.
+
+        Return a task object."""
+        return tasks.Task(coro, loop=self)
+
     def _make_socket_transport(self, sock, protocol, waiter=None, *,
                                extra=None, server=None):
         """Create socket transport."""
diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py
--- a/Lib/asyncio/events.py
+++ b/Lib/asyncio/events.py
@@ -200,6 +200,10 @@
         """Return whether the event loop is currently running."""
         raise NotImplementedError
 
+    def is_closed(self):
+        """Returns True if the event loop was closed."""
+        raise NotImplementedError
+
     def close(self):
         """Close the loop.
 
@@ -225,6 +229,11 @@
     def time(self):
         raise NotImplementedError
 
+    # Method scheduling a coroutine object: create a task.
+
+    def create_task(self, coro):
+        raise NotImplementedError
+
     # Methods for interacting with threads.
 
     def call_soon_threadsafe(self, callback, *args):
diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py
--- a/Lib/asyncio/streams.py
+++ b/Lib/asyncio/streams.py
@@ -213,7 +213,7 @@
             res = self._client_connected_cb(self._stream_reader,
                                             self._stream_writer)
             if coroutines.iscoroutine(res):
-                tasks.Task(res, loop=self._loop)
+                self._loop.create_task(res)
 
     def connection_lost(self, exc):
         if exc is None:
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -505,7 +505,9 @@
             raise ValueError('loop argument must agree with Future')
         return coro_or_future
     elif coroutines.iscoroutine(coro_or_future):
-        task = Task(coro_or_future, loop=loop)
+        if loop is None:
+            loop = events.get_event_loop()
+        task = loop.create_task(coro_or_future)
         if task._source_traceback:
             del task._source_traceback[-1]
         return task
diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py
--- a/Lib/asyncio/test_utils.py
+++ b/Lib/asyncio/test_utils.py
@@ -48,7 +48,7 @@
     def once():
         pass
     gen = once()
-    t = tasks.Task(gen, loop=loop)
+    t = loop.create_task(gen)
     # Don't log a warning if the task is not done after run_until_complete().
     # It occurs if the loop is stopped or if a task raises a BaseException.
     t._log_destroy_pending = False
diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -12,6 +12,7 @@
 
 import asyncio
 from asyncio import base_events
+from asyncio import events
 from asyncio import constants
 from asyncio import test_utils
 
@@ -526,6 +527,29 @@
                                                PYTHONASYNCIODEBUG='1')
         self.assertEqual(stdout.rstrip(), b'False')
 
+    def test_create_task(self):
+        class MyTask(asyncio.Task):
+            pass
+
+        @asyncio.coroutine
+        def test():
+            pass
+
+        class EventLoop(base_events.BaseEventLoop):
+            def create_task(self, coro):
+                return MyTask(coro, loop=loop)
+
+        loop = EventLoop()
+        self.set_event_loop(loop)
+
+        coro = test()
+        task = asyncio.async(coro, loop=loop)
+        self.assertIsInstance(task, MyTask)
+
+        # make warnings quiet
+        task._log_destroy_pending = False
+        coro.close()
+
 
 class MyProto(asyncio.Protocol):
     done = None
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -1969,8 +1969,12 @@
         self.assertRaises(
             NotImplementedError, loop.is_running)
         self.assertRaises(
+            NotImplementedError, loop.is_closed)
+        self.assertRaises(
             NotImplementedError, loop.close)
         self.assertRaises(
+            NotImplementedError, loop.create_task, None)
+        self.assertRaises(
             NotImplementedError, loop.call_later, None, None)
         self.assertRaises(
             NotImplementedError, loop.call_at, f, f)
@@ -2027,6 +2031,16 @@
             mock.sentinel)
         self.assertRaises(
             NotImplementedError, loop.subprocess_exec, f)
+        self.assertRaises(
+            NotImplementedError, loop.set_exception_handler, f)
+        self.assertRaises(
+            NotImplementedError, loop.default_exception_handler, f)
+        self.assertRaises(
+            NotImplementedError, loop.call_exception_handler, f)
+        self.assertRaises(
+            NotImplementedError, loop.get_debug)
+        self.assertRaises(
+            NotImplementedError, loop.set_debug, f)
 
 
 class ProtocolsAbsTests(unittest.TestCase):
diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py
--- a/Lib/test/test_asyncio/test_futures.py
+++ b/Lib/test/test_asyncio/test_futures.py
@@ -301,12 +301,12 @@
     def test_future_exception_never_retrieved(self, m_log):
         self.loop.set_debug(True)
 
-        def memroy_error():
+        def memory_error():
             try:
                 raise MemoryError()
             except BaseException as exc:
                 return exc
-        exc = memroy_error()
+        exc = memory_error()
 
         future = asyncio.Future(loop=self.loop)
         source_traceback = future._source_traceback
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -233,6 +233,9 @@
         self.assertRegex(repr(task),
                          '<Task .* wait_for=%s>' % re.escape(repr(fut)))
 
+        fut.set_result(None)
+        self.loop.run_until_complete(task)
+
     def test_task_basics(self):
         @asyncio.coroutine
         def outer():

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list