change the future's state to cancelled, schedule the callbacks and
return True.
"""
+ self._log_traceback = False
if self._state != _PENDING:
return False
self._state = _CANCELLED
terminates with a CancelledError exception (even if cancel()
was not called).
"""
+ self._log_traceback = False
if self.done():
return False
if self._fut_waiter is not None:
del fut
self.assertFalse(m_log.error.called)
+ @mock.patch('asyncio.base_events.logger')
+ def test_tb_logger_not_called_after_cancel(self, m_log):
+ fut = self._new_future(loop=self.loop)
+ fut.set_exception(Exception())
+ fut.cancel()
+ del fut
+ self.assertFalse(m_log.error.called)
+
@mock.patch('asyncio.base_events.logger')
def test_tb_logger_result_unretrieved(self, m_log):
fut = self._new_future(loop=self.loop)
})
mock_handler.reset_mock()
+ @mock.patch('asyncio.base_events.logger')
+ def test_tb_logger_not_called_after_cancel(self, m_log):
+ loop = asyncio.new_event_loop()
+ self.set_event_loop(loop)
+
+ @asyncio.coroutine
+ def coro():
+ raise TypeError
+
+ @asyncio.coroutine
+ def runner():
+ task = self.new_task(loop, coro())
+ yield from asyncio.sleep(0.05, loop=loop)
+ task.cancel()
+ task = None
+
+ loop.run_until_complete(runner())
+ self.assertFalse(m_log.error.called)
+
@mock.patch('asyncio.coroutines.logger')
def test_coroutine_never_yielded(self, m_log):
with set_coroutine_debug(True):
Library
-------
+- bpo-30508: Don't log exceptions if Task/Future "cancel()" method was
+ called.
+
- bpo-28556: Updates to typing module: Add generic AsyncContextManager, add
support for ContextManager on all versions. Original PRs by Jelle Zijlstra
and Ivan Levkivskyi
static PyObject *
future_cancel(FutureObj *fut)
{
+ fut->fut_log_tb = 0;
+
if (fut->fut_state != STATE_PENDING) {
Py_RETURN_FALSE;
}
}
}
+static int
+FutureObj_set_log_traceback(FutureObj *fut, PyObject *val)
+{
+ int is_true = PyObject_IsTrue(val);
+ if (is_true < 0) {
+ return -1;
+ }
+ fut->fut_log_tb = is_true;
+ return 0;
+}
+
static PyObject *
FutureObj_get_loop(FutureObj *fut)
{
{"_callbacks", (getter)FutureObj_get_callbacks, NULL, NULL}, \
{"_result", (getter)FutureObj_get_result, NULL, NULL}, \
{"_exception", (getter)FutureObj_get_exception, NULL, NULL}, \
- {"_log_traceback", (getter)FutureObj_get_log_traceback, NULL, NULL}, \
+ {"_log_traceback", (getter)FutureObj_get_log_traceback, \
+ (setter)FutureObj_set_log_traceback, NULL}, \
{"_source_traceback", (getter)FutureObj_get_source_traceback, NULL, NULL},
static PyGetSetDef FutureType_getsetlist[] = {
_asyncio_Task_cancel_impl(TaskObj *self)
/*[clinic end generated code: output=6bfc0479da9d5757 input=13f9bf496695cb52]*/
{
+ self->task_log_tb = 0;
+
if (self->task_state != STATE_PENDING) {
Py_RETURN_FALSE;
}