mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	bpo-30508: Don't log exceptions if Task/Future "cancel()" method called (#2050)
This commit is contained in:
		
							parent
							
								
									36ff451eba
								
							
						
					
					
						commit
						7ce1c6fb57
					
				
					 6 changed files with 49 additions and 1 deletions
				
			
		|  | @ -107,6 +107,7 @@ def cancel(self): | ||||||
|         change the future's state to cancelled, schedule the callbacks and |         change the future's state to cancelled, schedule the callbacks and | ||||||
|         return True. |         return True. | ||||||
|         """ |         """ | ||||||
|  |         self._log_traceback = False | ||||||
|         if self._state != _PENDING: |         if self._state != _PENDING: | ||||||
|             return False |             return False | ||||||
|         self._state = _CANCELLED |         self._state = _CANCELLED | ||||||
|  |  | ||||||
|  | @ -144,6 +144,7 @@ def cancel(self): | ||||||
|         terminates with a CancelledError exception (even if cancel() |         terminates with a CancelledError exception (even if cancel() | ||||||
|         was not called). |         was not called). | ||||||
|         """ |         """ | ||||||
|  |         self._log_traceback = False | ||||||
|         if self.done(): |         if self.done(): | ||||||
|             return False |             return False | ||||||
|         if self._fut_waiter is not None: |         if self._fut_waiter is not None: | ||||||
|  |  | ||||||
|  | @ -318,6 +318,14 @@ def test_tb_logger_abandoned(self, m_log): | ||||||
|         del fut |         del fut | ||||||
|         self.assertFalse(m_log.error.called) |         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') |     @mock.patch('asyncio.base_events.logger') | ||||||
|     def test_tb_logger_result_unretrieved(self, m_log): |     def test_tb_logger_result_unretrieved(self, m_log): | ||||||
|         fut = self._new_future(loop=self.loop) |         fut = self._new_future(loop=self.loop) | ||||||
|  |  | ||||||
|  | @ -1864,6 +1864,25 @@ def kill_me(loop): | ||||||
|         }) |         }) | ||||||
|         mock_handler.reset_mock() |         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') |     @mock.patch('asyncio.coroutines.logger') | ||||||
|     def test_coroutine_never_yielded(self, m_log): |     def test_coroutine_never_yielded(self, m_log): | ||||||
|         with set_coroutine_debug(True): |         with set_coroutine_debug(True): | ||||||
|  |  | ||||||
|  | @ -359,6 +359,9 @@ Extension Modules | ||||||
| Library | Library | ||||||
| ------- | ------- | ||||||
| 
 | 
 | ||||||
|  | - bpo-30508: Don't log exceptions if Task/Future "cancel()" method was | ||||||
|  |   called. | ||||||
|  | 
 | ||||||
| - bpo-11822: The dis.dis() function now is able to disassemble nested | - bpo-11822: The dis.dis() function now is able to disassemble nested | ||||||
|   code objects. |   code objects. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -306,6 +306,8 @@ future_add_done_callback(FutureObj *fut, PyObject *arg) | ||||||
| static PyObject * | static PyObject * | ||||||
| future_cancel(FutureObj *fut) | future_cancel(FutureObj *fut) | ||||||
| { | { | ||||||
|  |     fut->fut_log_tb = 0; | ||||||
|  | 
 | ||||||
|     if (fut->fut_state != STATE_PENDING) { |     if (fut->fut_state != STATE_PENDING) { | ||||||
|         Py_RETURN_FALSE; |         Py_RETURN_FALSE; | ||||||
|     } |     } | ||||||
|  | @ -639,6 +641,17 @@ FutureObj_get_log_traceback(FutureObj *fut) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 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 * | static PyObject * | ||||||
| FutureObj_get_loop(FutureObj *fut) | FutureObj_get_loop(FutureObj *fut) | ||||||
| { | { | ||||||
|  | @ -883,7 +896,8 @@ static PyMethodDef FutureType_methods[] = { | ||||||
|     {"_callbacks", (getter)FutureObj_get_callbacks, NULL, NULL},              \ |     {"_callbacks", (getter)FutureObj_get_callbacks, NULL, NULL},              \ | ||||||
|     {"_result", (getter)FutureObj_get_result, NULL, NULL},                    \ |     {"_result", (getter)FutureObj_get_result, NULL, NULL},                    \ | ||||||
|     {"_exception", (getter)FutureObj_get_exception, 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}, |     {"_source_traceback", (getter)FutureObj_get_source_traceback, NULL, NULL}, | ||||||
| 
 | 
 | ||||||
| static PyGetSetDef FutureType_getsetlist[] = { | static PyGetSetDef FutureType_getsetlist[] = { | ||||||
|  | @ -1569,6 +1583,8 @@ static PyObject * | ||||||
| _asyncio_Task_cancel_impl(TaskObj *self) | _asyncio_Task_cancel_impl(TaskObj *self) | ||||||
| /*[clinic end generated code: output=6bfc0479da9d5757 input=13f9bf496695cb52]*/ | /*[clinic end generated code: output=6bfc0479da9d5757 input=13f9bf496695cb52]*/ | ||||||
| { | { | ||||||
|  |     self->task_log_tb = 0; | ||||||
|  | 
 | ||||||
|     if (self->task_state != STATE_PENDING) { |     if (self->task_state != STATE_PENDING) { | ||||||
|         Py_RETURN_FALSE; |         Py_RETURN_FALSE; | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Yury Selivanov
						Yury Selivanov