File tree Expand file tree Collapse file tree 2 files changed +12
-0
lines changed Expand file tree Collapse file tree 2 files changed +12
-0
lines changed Original file line number Diff line number Diff line change @@ -128,8 +128,13 @@ extern void _PyWeakref_ClearWeakRefsNoCallbacks(PyObject *obj);
128128
129129PyAPI_FUNC (int ) _PyWeakref_IsDead (PyObject * weakref );
130130
131+ // Create sentinel callback object for subclasses weakrefs
131132int _PyWeakref_InitSubclassSentinel (PyInterpreterState * interp );
133+
134+ // Create new PyWeakReference object with sentinel callback
132135PyObject * _PyWeakref_NewSubclassRef (PyObject * ob );
136+
137+ // Check if weakref has sentinel callback
133138int _PyWeakref_IsSubclassRef (PyWeakReference * weakref );
134139
135140#ifdef __cplusplus
Original file line number Diff line number Diff line change @@ -906,6 +906,8 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
906906 * reference cycle. If we don't clear the weakref, the callback
907907 * will run and potentially cause a crash. See bpo-38006 for
908908 * one example.
909+ *
910+ * If this is a subclass weakref we can safely ignore it's cleanup.
909911 */
910912 if (!_PyWeakref_IsSubclassRef ((PyWeakReference * )op )) {
911913 _PyWeakref_ClearRef ((PyWeakReference * )op );
@@ -935,6 +937,11 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
935937 PyGC_Head * wrasgc ; /* AS_GC(wr) */
936938
937939 wr_next = wr -> wr_next ;
940+
941+ /* If this is a subclass weakref we can safely ignore it's cleanup.
942+ * It has only sentinel callback (no-op) and we also can safely
943+ * not invoke them.
944+ */
938945 if (_PyWeakref_IsSubclassRef (wr ) == 1 ) {
939946 continue ;
940947 }
You can’t perform that action at this time.
0 commit comments