summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'Objects')
-rw-r--r--Objects/typeobject.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 7da961e..de1e445 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -967,8 +967,6 @@ subtype_dealloc(PyObject *self)
assert(basedealloc);
basedealloc(self);
- PyType_Modified(type);
-
/* Can't reference self beyond this point */
Py_DECREF(type);
@@ -2645,15 +2643,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.
@@ -2670,6 +2669,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;