]> granicus.if.org Git - python/commitdiff
Fix the fix for issue #12149: it was incorrect, although it had the side
authorAntoine Pitrou <solipsis@pitrou.net>
Thu, 15 Dec 2011 13:15:31 +0000 (14:15 +0100)
committerAntoine Pitrou <solipsis@pitrou.net>
Thu, 15 Dec 2011 13:15:31 +0000 (14:15 +0100)
effect of appearing to resolve the issue.  Thanks to Mark Shannon for
noticing.

Misc/NEWS
Objects/typeobject.c

index c96321d186d9babb532f37251015890ec68782c2..8e7465c0a32186afc4e72eac0356d4cc69ddbcaa 100644 (file)
--- 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).
 
index e5042cc239df9e2d395af4f3c6618f41577afc5c..3db02edaed1ed4dcc442dda2def760b11f63972e 100644 (file)
@@ -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;