Skip to content

Commit 896a25a

Browse files
committed
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
1 parent 630a4f6 commit 896a25a

9 files changed

Lines changed: 63 additions & 5 deletions

File tree

Lib/asyncio/base_events.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ def __repr__(self):
151151
% (self.__class__.__name__, self.is_running(),
152152
self.is_closed(), self.get_debug()))
153153

154+
def create_task(self, coro):
155+
"""Schedule a coroutine object.
156+
157+
Return a task object."""
158+
return tasks.Task(coro, loop=self)
159+
154160
def _make_socket_transport(self, sock, protocol, waiter=None, *,
155161
extra=None, server=None):
156162
"""Create socket transport."""

Lib/asyncio/events.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ def is_running(self):
200200
"""Return whether the event loop is currently running."""
201201
raise NotImplementedError
202202

203+
def is_closed(self):
204+
"""Returns True if the event loop was closed."""
205+
raise NotImplementedError
206+
203207
def close(self):
204208
"""Close the loop.
205209
@@ -225,6 +229,11 @@ def call_at(self, when, callback, *args):
225229
def time(self):
226230
raise NotImplementedError
227231

232+
# Method scheduling a coroutine object: create a task.
233+
234+
def create_task(self, coro):
235+
raise NotImplementedError
236+
228237
# Methods for interacting with threads.
229238

230239
def call_soon_threadsafe(self, callback, *args):

Lib/asyncio/streams.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ def connection_made(self, transport):
213213
res = self._client_connected_cb(self._stream_reader,
214214
self._stream_writer)
215215
if coroutines.iscoroutine(res):
216-
tasks.Task(res, loop=self._loop)
216+
self._loop.create_task(res)
217217

218218
def connection_lost(self, exc):
219219
if exc is None:

Lib/asyncio/tasks.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,9 @@ def async(coro_or_future, *, loop=None):
505505
raise ValueError('loop argument must agree with Future')
506506
return coro_or_future
507507
elif coroutines.iscoroutine(coro_or_future):
508-
task = Task(coro_or_future, loop=loop)
508+
if loop is None:
509+
loop = events.get_event_loop()
510+
task = loop.create_task(coro_or_future)
509511
if task._source_traceback:
510512
del task._source_traceback[-1]
511513
return task

Lib/asyncio/test_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def run_briefly(loop):
4848
def once():
4949
pass
5050
gen = once()
51-
t = tasks.Task(gen, loop=loop)
51+
t = loop.create_task(gen)
5252
# Don't log a warning if the task is not done after run_until_complete().
5353
# It occurs if the loop is stopped or if a task raises a BaseException.
5454
t._log_destroy_pending = False

Lib/test/test_asyncio/test_base_events.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import asyncio
1414
from asyncio import base_events
15+
from asyncio import events
1516
from asyncio import constants
1617
from asyncio import test_utils
1718

@@ -526,6 +527,29 @@ def test_env_var_debug(self):
526527
PYTHONASYNCIODEBUG='1')
527528
self.assertEqual(stdout.rstrip(), b'False')
528529

530+
def test_create_task(self):
531+
class MyTask(asyncio.Task):
532+
pass
533+
534+
@asyncio.coroutine
535+
def test():
536+
pass
537+
538+
class EventLoop(base_events.BaseEventLoop):
539+
def create_task(self, coro):
540+
return MyTask(coro, loop=loop)
541+
542+
loop = EventLoop()
543+
self.set_event_loop(loop)
544+
545+
coro = test()
546+
task = asyncio.async(coro, loop=loop)
547+
self.assertIsInstance(task, MyTask)
548+
549+
# make warnings quiet
550+
task._log_destroy_pending = False
551+
coro.close()
552+
529553

530554
class MyProto(asyncio.Protocol):
531555
done = None

Lib/test/test_asyncio/test_events.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1968,8 +1968,12 @@ def test_not_implemented(self):
19681968
NotImplementedError, loop.stop)
19691969
self.assertRaises(
19701970
NotImplementedError, loop.is_running)
1971+
self.assertRaises(
1972+
NotImplementedError, loop.is_closed)
19711973
self.assertRaises(
19721974
NotImplementedError, loop.close)
1975+
self.assertRaises(
1976+
NotImplementedError, loop.create_task, None)
19731977
self.assertRaises(
19741978
NotImplementedError, loop.call_later, None, None)
19751979
self.assertRaises(
@@ -2027,6 +2031,16 @@ def test_not_implemented(self):
20272031
mock.sentinel)
20282032
self.assertRaises(
20292033
NotImplementedError, loop.subprocess_exec, f)
2034+
self.assertRaises(
2035+
NotImplementedError, loop.set_exception_handler, f)
2036+
self.assertRaises(
2037+
NotImplementedError, loop.default_exception_handler, f)
2038+
self.assertRaises(
2039+
NotImplementedError, loop.call_exception_handler, f)
2040+
self.assertRaises(
2041+
NotImplementedError, loop.get_debug)
2042+
self.assertRaises(
2043+
NotImplementedError, loop.set_debug, f)
20302044

20312045

20322046
class ProtocolsAbsTests(unittest.TestCase):

Lib/test/test_asyncio/test_futures.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,12 +301,12 @@ def test_future_source_traceback(self):
301301
def test_future_exception_never_retrieved(self, m_log):
302302
self.loop.set_debug(True)
303303

304-
def memroy_error():
304+
def memory_error():
305305
try:
306306
raise MemoryError()
307307
except BaseException as exc:
308308
return exc
309-
exc = memroy_error()
309+
exc = memory_error()
310310

311311
future = asyncio.Future(loop=self.loop)
312312
source_traceback = future._source_traceback

Lib/test/test_asyncio/test_tasks.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ def wait_for(fut):
233233
self.assertRegex(repr(task),
234234
'<Task .* wait_for=%s>' % re.escape(repr(fut)))
235235

236+
fut.set_result(None)
237+
self.loop.run_until_complete(task)
238+
236239
def test_task_basics(self):
237240
@asyncio.coroutine
238241
def outer():

0 commit comments

Comments
 (0)