summaryrefslogtreecommitdiffstats
path: root/Objects/typeobject.c
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2011-12-15 13:17:36 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2011-12-15 13:17:36 (GMT)
commitd73a9acb633883a713fe63dbe67b36b3bddec902 (patch)
tree26fedb768d21152bd2a19c72258efe85827702a1 /Objects/typeobject.c
parent96ff0840b68a9568d859a7bef2f59e851f811ae3 (diff)
parent2e872082f620e2fa96fe37dc6a5c3cb5b55bdcbd (diff)
downloadcpython-d73a9acb633883a713fe63dbe67b36b3bddec902.zip
cpython-d73a9acb633883a713fe63dbe67b36b3bddec902.tar.gz
cpython-d73a9acb633883a713fe63dbe67b36b3bddec902.tar.bz2
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.
Diffstat (limited to 'Objects/typeobject.c')
-rw-r--r--Objects/typeobject.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 5383eee..02999d6 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -999,8 +999,6 @@ subtype_dealloc(PyObject *self)
assert(basedealloc);
basedealloc(self);
- PyType_Modified(type);
-
/* Can't reference self beyond this point */
Py_DECREF(type);
@@ -2776,15 +2774,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.
@@ -2801,6 +2800,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;