Sync asyncio changes from the main repo.
This commit is contained in:
parent
37c4f78390
commit
740169cd24
|
@ -197,6 +197,7 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
# exceed this duration in seconds, the slow callback/task is logged.
|
||||
self.slow_callback_duration = 0.1
|
||||
self._current_handle = None
|
||||
self._task_factory = None
|
||||
|
||||
def __repr__(self):
|
||||
return ('<%s running=%s closed=%s debug=%s>'
|
||||
|
@ -209,11 +210,32 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
Return a task object.
|
||||
"""
|
||||
self._check_closed()
|
||||
task = tasks.Task(coro, loop=self)
|
||||
if task._source_traceback:
|
||||
del task._source_traceback[-1]
|
||||
if self._task_factory is None:
|
||||
task = tasks.Task(coro, loop=self)
|
||||
if task._source_traceback:
|
||||
del task._source_traceback[-1]
|
||||
else:
|
||||
task = self._task_factory(self, coro)
|
||||
return task
|
||||
|
||||
def set_task_factory(self, factory):
|
||||
"""Set a task factory that will be used by loop.create_task().
|
||||
|
||||
If factory is None the default task factory will be set.
|
||||
|
||||
If factory is a callable, it should have a signature matching
|
||||
'(loop, coro)', where 'loop' will be a reference to the active
|
||||
event loop, 'coro' will be a coroutine object. The callable
|
||||
must return a Future.
|
||||
"""
|
||||
if factory is not None and not callable(factory):
|
||||
raise TypeError('task factory must be a callable or None')
|
||||
self._task_factory = factory
|
||||
|
||||
def get_task_factory(self):
|
||||
"""Return a task factory, or None if the default one is in use."""
|
||||
return self._task_factory
|
||||
|
||||
def _make_socket_transport(self, sock, protocol, waiter=None, *,
|
||||
extra=None, server=None):
|
||||
"""Create socket transport."""
|
||||
|
@ -465,25 +487,25 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
self._write_to_self()
|
||||
return handle
|
||||
|
||||
def run_in_executor(self, executor, callback, *args):
|
||||
if (coroutines.iscoroutine(callback)
|
||||
or coroutines.iscoroutinefunction(callback)):
|
||||
def run_in_executor(self, executor, func, *args):
|
||||
if (coroutines.iscoroutine(func)
|
||||
or coroutines.iscoroutinefunction(func)):
|
||||
raise TypeError("coroutines cannot be used with run_in_executor()")
|
||||
self._check_closed()
|
||||
if isinstance(callback, events.Handle):
|
||||
if isinstance(func, events.Handle):
|
||||
assert not args
|
||||
assert not isinstance(callback, events.TimerHandle)
|
||||
if callback._cancelled:
|
||||
assert not isinstance(func, events.TimerHandle)
|
||||
if func._cancelled:
|
||||
f = futures.Future(loop=self)
|
||||
f.set_result(None)
|
||||
return f
|
||||
callback, args = callback._callback, callback._args
|
||||
func, args = func._callback, func._args
|
||||
if executor is None:
|
||||
executor = self._default_executor
|
||||
if executor is None:
|
||||
executor = concurrent.futures.ThreadPoolExecutor(_MAX_WORKERS)
|
||||
self._default_executor = executor
|
||||
return futures.wrap_future(executor.submit(callback, *args), loop=self)
|
||||
return futures.wrap_future(executor.submit(func, *args), loop=self)
|
||||
|
||||
def set_default_executor(self, executor):
|
||||
self._default_executor = executor
|
||||
|
|
|
@ -277,7 +277,7 @@ class AbstractEventLoop:
|
|||
def call_soon_threadsafe(self, callback, *args):
|
||||
raise NotImplementedError
|
||||
|
||||
def run_in_executor(self, executor, callback, *args):
|
||||
def run_in_executor(self, executor, func, *args):
|
||||
raise NotImplementedError
|
||||
|
||||
def set_default_executor(self, executor):
|
||||
|
@ -438,6 +438,14 @@ class AbstractEventLoop:
|
|||
def remove_signal_handler(self, sig):
|
||||
raise NotImplementedError
|
||||
|
||||
# Task factory.
|
||||
|
||||
def set_task_factory(self, factory):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_task_factory(self):
|
||||
raise NotImplementedError
|
||||
|
||||
# Error handlers.
|
||||
|
||||
def set_exception_handler(self, handler):
|
||||
|
|
|
@ -16,10 +16,15 @@ from asyncio import constants
|
|||
from asyncio import test_utils
|
||||
try:
|
||||
from test import support
|
||||
from test.script_helper import assert_python_ok
|
||||
except ImportError:
|
||||
from asyncio import test_support as support
|
||||
from asyncio.test_support import assert_python_ok
|
||||
try:
|
||||
from test.support.script_helper import assert_python_ok
|
||||
except ImportError:
|
||||
try:
|
||||
from test.script_helper import assert_python_ok
|
||||
except ImportError:
|
||||
from asyncio.test_support import assert_python_ok
|
||||
|
||||
|
||||
MOCK_ANY = mock.ANY
|
||||
|
@ -623,6 +628,42 @@ class BaseEventLoopTests(test_utils.TestCase):
|
|||
self.assertIs(type(_context['context']['exception']),
|
||||
ZeroDivisionError)
|
||||
|
||||
def test_set_task_factory_invalid(self):
|
||||
with self.assertRaisesRegex(
|
||||
TypeError, 'task factory must be a callable or None'):
|
||||
|
||||
self.loop.set_task_factory(1)
|
||||
|
||||
self.assertIsNone(self.loop.get_task_factory())
|
||||
|
||||
def test_set_task_factory(self):
|
||||
self.loop._process_events = mock.Mock()
|
||||
|
||||
class MyTask(asyncio.Task):
|
||||
pass
|
||||
|
||||
@asyncio.coroutine
|
||||
def coro():
|
||||
pass
|
||||
|
||||
factory = lambda loop, coro: MyTask(coro, loop=loop)
|
||||
|
||||
self.assertIsNone(self.loop.get_task_factory())
|
||||
self.loop.set_task_factory(factory)
|
||||
self.assertIs(self.loop.get_task_factory(), factory)
|
||||
|
||||
task = self.loop.create_task(coro())
|
||||
self.assertTrue(isinstance(task, MyTask))
|
||||
self.loop.run_until_complete(task)
|
||||
|
||||
self.loop.set_task_factory(None)
|
||||
self.assertIsNone(self.loop.get_task_factory())
|
||||
|
||||
task = self.loop.create_task(coro())
|
||||
self.assertTrue(isinstance(task, asyncio.Task))
|
||||
self.assertFalse(isinstance(task, MyTask))
|
||||
self.loop.run_until_complete(task)
|
||||
|
||||
def test_env_var_debug(self):
|
||||
code = '\n'.join((
|
||||
'import asyncio',
|
||||
|
|
|
@ -15,10 +15,15 @@ from asyncio import coroutines
|
|||
from asyncio import test_utils
|
||||
try:
|
||||
from test import support
|
||||
from test.script_helper import assert_python_ok
|
||||
except ImportError:
|
||||
from asyncio import test_support as support
|
||||
from asyncio.test_support import assert_python_ok
|
||||
try:
|
||||
from test.support.script_helper import assert_python_ok
|
||||
except ImportError:
|
||||
try:
|
||||
from test.script_helper import assert_python_ok
|
||||
except ImportError:
|
||||
from asyncio.test_support import assert_python_ok
|
||||
|
||||
|
||||
PY34 = (sys.version_info >= (3, 4))
|
||||
|
|
Loading…
Reference in New Issue