mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Merge 3.5 (issue #28600)
This commit is contained in:
commit
a6fbcd19ac
5 changed files with 29 additions and 57 deletions
|
@ -532,12 +532,10 @@ class BaseEventLoop(events.AbstractEventLoop):
|
||||||
|
|
||||||
Absolute time corresponds to the event loop's time() method.
|
Absolute time corresponds to the event loop's time() method.
|
||||||
"""
|
"""
|
||||||
if (coroutines.iscoroutine(callback)
|
|
||||||
or coroutines.iscoroutinefunction(callback)):
|
|
||||||
raise TypeError("coroutines cannot be used with call_at()")
|
|
||||||
self._check_closed()
|
self._check_closed()
|
||||||
if self._debug:
|
if self._debug:
|
||||||
self._check_thread()
|
self._check_thread()
|
||||||
|
self._check_callback(callback, 'call_at')
|
||||||
timer = events.TimerHandle(when, callback, args, self)
|
timer = events.TimerHandle(when, callback, args, self)
|
||||||
if timer._source_traceback:
|
if timer._source_traceback:
|
||||||
del timer._source_traceback[-1]
|
del timer._source_traceback[-1]
|
||||||
|
@ -555,18 +553,27 @@ class BaseEventLoop(events.AbstractEventLoop):
|
||||||
Any positional arguments after the callback will be passed to
|
Any positional arguments after the callback will be passed to
|
||||||
the callback when it is called.
|
the callback when it is called.
|
||||||
"""
|
"""
|
||||||
|
self._check_closed()
|
||||||
if self._debug:
|
if self._debug:
|
||||||
self._check_thread()
|
self._check_thread()
|
||||||
|
self._check_callback(callback, 'call_soon')
|
||||||
handle = self._call_soon(callback, args)
|
handle = self._call_soon(callback, args)
|
||||||
if handle._source_traceback:
|
if handle._source_traceback:
|
||||||
del handle._source_traceback[-1]
|
del handle._source_traceback[-1]
|
||||||
return handle
|
return handle
|
||||||
|
|
||||||
|
def _check_callback(self, callback, method):
|
||||||
|
if (coroutines.iscoroutine(callback) or
|
||||||
|
coroutines.iscoroutinefunction(callback)):
|
||||||
|
raise TypeError(
|
||||||
|
"coroutines cannot be used with {}()".format(method))
|
||||||
|
if not callable(callback):
|
||||||
|
raise TypeError(
|
||||||
|
'a callable object was expected by {}(), got {!r}'.format(
|
||||||
|
method, callback))
|
||||||
|
|
||||||
|
|
||||||
def _call_soon(self, callback, args):
|
def _call_soon(self, callback, args):
|
||||||
if (coroutines.iscoroutine(callback)
|
|
||||||
or coroutines.iscoroutinefunction(callback)):
|
|
||||||
raise TypeError("coroutines cannot be used with call_soon()")
|
|
||||||
self._check_closed()
|
|
||||||
handle = events.Handle(callback, args, self)
|
handle = events.Handle(callback, args, self)
|
||||||
if handle._source_traceback:
|
if handle._source_traceback:
|
||||||
del handle._source_traceback[-1]
|
del handle._source_traceback[-1]
|
||||||
|
@ -592,6 +599,9 @@ class BaseEventLoop(events.AbstractEventLoop):
|
||||||
|
|
||||||
def call_soon_threadsafe(self, callback, *args):
|
def call_soon_threadsafe(self, callback, *args):
|
||||||
"""Like call_soon(), but thread-safe."""
|
"""Like call_soon(), but thread-safe."""
|
||||||
|
self._check_closed()
|
||||||
|
if self._debug:
|
||||||
|
self._check_callback(callback, 'call_soon_threadsafe')
|
||||||
handle = self._call_soon(callback, args)
|
handle = self._call_soon(callback, args)
|
||||||
if handle._source_traceback:
|
if handle._source_traceback:
|
||||||
del handle._source_traceback[-1]
|
del handle._source_traceback[-1]
|
||||||
|
@ -599,21 +609,9 @@ class BaseEventLoop(events.AbstractEventLoop):
|
||||||
return handle
|
return handle
|
||||||
|
|
||||||
def run_in_executor(self, executor, func, *args):
|
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()
|
self._check_closed()
|
||||||
if isinstance(func, events.Handle):
|
if self._debug:
|
||||||
assert not args
|
self._check_callback(func, 'run_in_executor')
|
||||||
assert not isinstance(func, events.TimerHandle)
|
|
||||||
warnings.warn(
|
|
||||||
"Passing Handle to loop.run_in_executor() is deprecated",
|
|
||||||
DeprecationWarning)
|
|
||||||
if func._cancelled:
|
|
||||||
f = self.create_future()
|
|
||||||
f.set_result(None)
|
|
||||||
return f
|
|
||||||
func, args = func._callback, func._args
|
|
||||||
if executor is None:
|
if executor is None:
|
||||||
executor = self._default_executor
|
executor = self._default_executor
|
||||||
if executor is None:
|
if executor is None:
|
||||||
|
|
|
@ -82,7 +82,6 @@ class Handle:
|
||||||
'_source_traceback', '_repr', '__weakref__')
|
'_source_traceback', '_repr', '__weakref__')
|
||||||
|
|
||||||
def __init__(self, callback, args, loop):
|
def __init__(self, callback, args, loop):
|
||||||
assert not isinstance(callback, Handle), 'A Handle is not a callback'
|
|
||||||
self._loop = loop
|
self._loop = loop
|
||||||
self._callback = callback
|
self._callback = callback
|
||||||
self._args = args
|
self._args = args
|
||||||
|
|
|
@ -235,6 +235,11 @@ class BaseEventLoopTests(test_utils.TestCase):
|
||||||
self.assertIsInstance(h, asyncio.Handle)
|
self.assertIsInstance(h, asyncio.Handle)
|
||||||
self.assertIn(h, self.loop._ready)
|
self.assertIn(h, self.loop._ready)
|
||||||
|
|
||||||
|
def test_call_soon_non_callable(self):
|
||||||
|
self.loop.set_debug(True)
|
||||||
|
with self.assertRaisesRegex(TypeError, 'a callable object'):
|
||||||
|
self.loop.call_soon(1)
|
||||||
|
|
||||||
def test_call_later(self):
|
def test_call_later(self):
|
||||||
def cb():
|
def cb():
|
||||||
pass
|
pass
|
||||||
|
@ -341,47 +346,21 @@ class BaseEventLoopTests(test_utils.TestCase):
|
||||||
# check disabled if debug mode is disabled
|
# check disabled if debug mode is disabled
|
||||||
test_thread(self.loop, False, create_loop=True)
|
test_thread(self.loop, False, create_loop=True)
|
||||||
|
|
||||||
def test_run_once_in_executor_handle(self):
|
|
||||||
def cb():
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.assertRaises(
|
|
||||||
AssertionError, self.loop.run_in_executor,
|
|
||||||
None, asyncio.Handle(cb, (), self.loop), ('',))
|
|
||||||
self.assertRaises(
|
|
||||||
AssertionError, self.loop.run_in_executor,
|
|
||||||
None, asyncio.TimerHandle(10, cb, (), self.loop))
|
|
||||||
|
|
||||||
def test_run_once_in_executor_cancelled(self):
|
|
||||||
def cb():
|
|
||||||
pass
|
|
||||||
h = asyncio.Handle(cb, (), self.loop)
|
|
||||||
h.cancel()
|
|
||||||
|
|
||||||
with self.assertWarnsRegex(DeprecationWarning, "Passing Handle"):
|
|
||||||
f = self.loop.run_in_executor(None, h)
|
|
||||||
self.assertIsInstance(f, asyncio.Future)
|
|
||||||
self.assertTrue(f.done())
|
|
||||||
self.assertIsNone(f.result())
|
|
||||||
|
|
||||||
def test_run_once_in_executor_plain(self):
|
def test_run_once_in_executor_plain(self):
|
||||||
def cb():
|
def cb():
|
||||||
pass
|
pass
|
||||||
h = asyncio.Handle(cb, (), self.loop)
|
|
||||||
f = asyncio.Future(loop=self.loop)
|
f = asyncio.Future(loop=self.loop)
|
||||||
executor = mock.Mock()
|
executor = mock.Mock()
|
||||||
executor.submit.return_value = f
|
executor.submit.return_value = f
|
||||||
|
|
||||||
self.loop.set_default_executor(executor)
|
self.loop.set_default_executor(executor)
|
||||||
|
|
||||||
with self.assertWarnsRegex(DeprecationWarning, "Passing Handle"):
|
res = self.loop.run_in_executor(None, cb)
|
||||||
res = self.loop.run_in_executor(None, h)
|
|
||||||
self.assertIs(f, res)
|
self.assertIs(f, res)
|
||||||
|
|
||||||
executor = mock.Mock()
|
executor = mock.Mock()
|
||||||
executor.submit.return_value = f
|
executor.submit.return_value = f
|
||||||
with self.assertWarnsRegex(DeprecationWarning, "Passing Handle"):
|
res = self.loop.run_in_executor(executor, cb)
|
||||||
res = self.loop.run_in_executor(executor, h)
|
|
||||||
self.assertIs(f, res)
|
self.assertIs(f, res)
|
||||||
self.assertTrue(executor.submit.called)
|
self.assertTrue(executor.submit.called)
|
||||||
|
|
||||||
|
@ -1666,6 +1645,7 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
|
||||||
def simple_coroutine():
|
def simple_coroutine():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
self.loop.set_debug(True)
|
||||||
coro_func = simple_coroutine
|
coro_func = simple_coroutine
|
||||||
coro_obj = coro_func()
|
coro_obj = coro_func()
|
||||||
self.addCleanup(coro_obj.close)
|
self.addCleanup(coro_obj.close)
|
||||||
|
|
|
@ -2249,13 +2249,6 @@ class HandleTests(test_utils.TestCase):
|
||||||
h.cancel()
|
h.cancel()
|
||||||
self.assertTrue(h._cancelled)
|
self.assertTrue(h._cancelled)
|
||||||
|
|
||||||
def test_handle_from_handle(self):
|
|
||||||
def callback(*args):
|
|
||||||
return args
|
|
||||||
h1 = asyncio.Handle(callback, (), loop=self.loop)
|
|
||||||
self.assertRaises(
|
|
||||||
AssertionError, asyncio.Handle, h1, (), self.loop)
|
|
||||||
|
|
||||||
def test_callback_with_exception(self):
|
def test_callback_with_exception(self):
|
||||||
def callback():
|
def callback():
|
||||||
raise ValueError()
|
raise ValueError()
|
||||||
|
|
|
@ -20,6 +20,8 @@ Library
|
||||||
the garbage collector is invoked in other thread. Based on patch by
|
the garbage collector is invoked in other thread. Based on patch by
|
||||||
Sebastian Cufre.
|
Sebastian Cufre.
|
||||||
|
|
||||||
|
- Issue #28600: Optimize loop.call_soon.
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue