From 5b4b2da55dbc2a439235e8e969309c143320f4fc Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 15 Dec 2011 14:15:31 +0100 Subject: [PATCH] Fix the fix for issue #12149: it was incorrect, although it had the side effect of appearing to resolve the issue. Thanks to Mark Shannon for noticing. --- Misc/NEWS | 4 ++++ Objects/typeobject.c | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index c96321d186..8e7465c0a3 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -9,6 +9,10 @@ What's New in Python 2.7.3? Core and Builtins ----------------- +- Fix the fix for issue #12149: it was incorrect, although it had the side + effect of appearing to resolve the issue. Thanks to Mark Shannon for + noticing. + - Issue #13546: Fixed an overflow issue that could crash the intepreter when calling sys.setrecursionlimit((1<<31)-1). diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e5042cc239..3db02edaed 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1013,8 +1013,6 @@ subtype_dealloc(PyObject *self) assert(basedealloc); basedealloc(self); - PyType_Modified(type); - /* Can't reference self beyond this point */ Py_DECREF(type); @@ -2707,15 +2705,16 @@ type_clear(PyTypeObject *type) for heaptypes. */ assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE); - /* The only field we need to clear is tp_mro, which is part of a - hard cycle (its first element is the class itself) that won't - be broken otherwise (it's a tuple and tuples don't have a + /* We need to invalidate the method cache carefully before clearing + the dict, so that other objects caught in a reference cycle + don't start calling destroyed methods. + + Otherwise, the only field we need to clear is tp_mro, which is + part of a hard cycle (its first element is the class itself) that + won't be broken otherwise (it's a tuple and tuples don't have a tp_clear handler). None of the other fields need to be cleared, and here's why: - tp_dict: - It is a dict, so the collector will call its tp_clear. - tp_cache: Not used; if it were, it would be a dict. @@ -2732,6 +2731,9 @@ type_clear(PyTypeObject *type) A tuple of strings can't be part of a cycle. */ + PyType_Modified(type); + if (type->tp_dict) + PyDict_Clear(type->tp_dict); Py_CLEAR(type->tp_mro); return 0; -- 2.50.1