# The reference was released by .clear()
self.assertIs(None, wr())
+ def test_clear_does_not_clear_specials(self):
+ class C:
+ pass
+ c = C()
+ exc = self.outer(c=c)
+ del c
+ f = exc.__traceback__.tb_frame
+ f.clear()
+ self.assertIsNot(f.f_code, None)
+ self.assertIsNot(f.f_locals, None)
+ self.assertIsNot(f.f_builtins, None)
+ self.assertIsNot(f.f_globals, None)
+
def test_clear_generator(self):
endly = False
def g():
Py_TRASHCAN_SAFE_BEGIN(f)
PyCodeObject *co = f->f_code;
- /* Kill all local variables */
+ /* Kill all local variables including specials. */
if (f->f_localsptr) {
for (int i = 0; i < co->co_nlocalsplus+FRAME_SPECIALS_SIZE; i++) {
Py_CLEAR(f->f_localsptr[i]);
f->f_state = FRAME_CLEARED;
Py_CLEAR(f->f_trace);
-
+ PyCodeObject *co = f->f_code;
/* locals */
- PyObject **localsplus = f->f_localsptr;
- for (Py_ssize_t i = frame_nslots(f); --i >= 0; ++localsplus) {
- Py_CLEAR(*localsplus);
+ for (int i = 0; i < co->co_nlocalsplus; i++) {
+ Py_CLEAR(f->f_localsptr[i]);
}
/* stack */