Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e0aef4f

Browse files
authored
bpo-31721: Allow Future._log_traceback to only be set to False (#5009)
1 parent 3070b71 commit e0aef4f

5 files changed

Lines changed: 37 additions & 6 deletions

File tree

Lib/asyncio/futures.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class Future:
6565
# `yield Future()` (incorrect).
6666
_asyncio_future_blocking = False
6767

68-
_log_traceback = False
68+
__log_traceback = False
6969

7070
def __init__(self, *, loop=None):
7171
"""Initialize the future.
@@ -90,7 +90,7 @@ def __repr__(self):
9090
' '.join(self._repr_info()))
9191

9292
def __del__(self):
93-
if not self._log_traceback:
93+
if not self.__log_traceback:
9494
# set_exception() was not called, or result() or exception()
9595
# has consumed the exception
9696
return
@@ -105,6 +105,16 @@ def __del__(self):
105105
context['source_traceback'] = self._source_traceback
106106
self._loop.call_exception_handler(context)
107107

108+
@property
109+
def _log_traceback(self):
110+
return self.__log_traceback
111+
112+
@_log_traceback.setter
113+
def _log_traceback(self, val):
114+
if bool(val):
115+
raise ValueError('_log_traceback can only be set to False')
116+
self.__log_traceback = False
117+
108118
def get_loop(self):
109119
"""Return the event loop the Future is bound to."""
110120
return self._loop
@@ -116,7 +126,7 @@ def cancel(self):
116126
change the future's state to cancelled, schedule the callbacks and
117127
return True.
118128
"""
119-
self._log_traceback = False
129+
self.__log_traceback = False
120130
if self._state != _PENDING:
121131
return False
122132
self._state = _CANCELLED
@@ -162,7 +172,7 @@ def result(self):
162172
raise CancelledError
163173
if self._state != _FINISHED:
164174
raise InvalidStateError('Result is not ready.')
165-
self._log_traceback = False
175+
self.__log_traceback = False
166176
if self._exception is not None:
167177
raise self._exception
168178
return self._result
@@ -179,7 +189,7 @@ def exception(self):
179189
raise CancelledError
180190
if self._state != _FINISHED:
181191
raise InvalidStateError('Exception is not set.')
182-
self._log_traceback = False
192+
self.__log_traceback = False
183193
return self._exception
184194

185195
def add_done_callback(self, fn):
@@ -237,7 +247,7 @@ def set_exception(self, exception):
237247
self._exception = exception
238248
self._state = _FINISHED
239249
self._schedule_callbacks()
240-
self._log_traceback = True
250+
self.__log_traceback = True
241251

242252
def __await__(self):
243253
if not self.done():

Lib/test/test_asyncio/test_futures.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,11 @@ def test():
374374
test()
375375
fut.cancel()
376376

377+
def test_log_traceback(self):
378+
fut = self._new_future(loop=self.loop)
379+
with self.assertRaisesRegex(ValueError, 'can only be set to False'):
380+
fut._log_traceback = True
381+
377382
@mock.patch('asyncio.base_events.logger')
378383
def test_tb_logger_abandoned(self, m_log):
379384
fut = self._new_future(loop=self.loop)

Lib/test/test_asyncio/test_tasks.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,15 @@ async def task():
623623
t.cancel()
624624
self.assertRaises(asyncio.CancelledError, loop.run_until_complete, t)
625625

626+
def test_log_traceback(self):
627+
async def coro():
628+
pass
629+
630+
task = self.new_task(self.loop, coro())
631+
with self.assertRaisesRegex(ValueError, 'can only be set to False'):
632+
task._log_traceback = True
633+
self.loop.run_until_complete(task)
634+
626635
def test_wait_for_timeout_less_then_0_or_0_future_done(self):
627636
def gen():
628637
when = yield
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Prevent Python crash from happening when Future._log_traceback is set to
2+
True manually. Now it can only be set to False, or a ValueError is raised.

Modules/_asynciomodule.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,11 @@ FutureObj_set_log_traceback(FutureObj *fut, PyObject *val)
10581058
if (is_true < 0) {
10591059
return -1;
10601060
}
1061+
if (is_true) {
1062+
PyErr_SetString(PyExc_ValueError,
1063+
"_log_traceback can only be set to False");
1064+
return -1;
1065+
}
10611066
fut->fut_log_tb = is_true;
10621067
return 0;
10631068
}

0 commit comments

Comments
 (0)