objects (for example when catching an exception and storing its
traceback for later use).
- :exc:`RuntimeError` is raised if the frame is currently executing.
+ :exc:`RuntimeError` is raised if the frame is currently executing
+ or suspended.
.. versionadded:: 3.4
+ .. versionchanged:: 3.13
+ Attempting to clear a suspended frame raises :exc:`RuntimeError`
+ (as has always been the case for executing frames).
+
.. _traceback-objects:
and methods that consider plural forms even if the translation was not found.
(Contributed by Serhiy Storchaka in :gh:`88434`.)
+* Calling :meth:`frame.clear` on a suspended frame raises :exc:`RuntimeError`
+ (as has always been the case for an executing frame).
+ (Contributed by Irit Katriel in :gh:`79932`.)
+
Pending Removal in Python 3.14
------------------------------
gen = g()
next(gen)
self.assertFalse(endly)
- # Clearing the frame closes the generator
- gen.gi_frame.clear()
- self.assertTrue(endly)
+
+ # Cannot clear a suspended frame
+ with self.assertRaisesRegex(RuntimeError, r'suspended frame'):
+ gen.gi_frame.clear()
+ self.assertFalse(endly)
def test_clear_executing(self):
# Attempting to clear an executing frame is forbidden.
gen = g()
f = next(gen)
self.assertFalse(endly)
- # Clearing the frame closes the generator
- f.clear()
- self.assertTrue(endly)
+ # Cannot clear a suspended frame
+ with self.assertRaisesRegex(RuntimeError, 'suspended frame'):
+ f.clear()
+ self.assertFalse(endly)
def test_lineno_with_tracing(self):
def record_line():
--- /dev/null
+Raise exception if :meth:`frame.clear` is called on a suspended frame.
if (gen->gi_frame_state == FRAME_EXECUTING) {
goto running;
}
+ if (FRAME_STATE_SUSPENDED(gen->gi_frame_state)) {
+ goto suspended;
+ }
_PyGen_Finalize((PyObject *)gen);
}
else if (f->f_frame->owner == FRAME_OWNED_BY_THREAD) {
PyErr_SetString(PyExc_RuntimeError,
"cannot clear an executing frame");
return NULL;
+suspended:
+ PyErr_SetString(PyExc_RuntimeError,
+ "cannot clear a suspended frame");
+ return NULL;
}
PyDoc_STRVAR(clear__doc__,