@@ -56,6 +56,7 @@ CPythonManager g_PythonManager;
56
56
// Forward declarations.
57
57
// ---------------------------------------------------------------------------------
58
58
void InitConverters ();
59
+ void EnableDictTraversal ();
59
60
60
61
61
62
// ---------------------------------------------------------------------------------
@@ -168,6 +169,9 @@ bool CPythonManager::Initialize( void )
168
169
// And of course, the plugins directory for script imports.
169
170
AddToSysPath (" /plugins" );
170
171
172
+ // Enable circular references traversal
173
+ EnableDictTraversal ();
174
+
171
175
// Initialize all converters
172
176
InitConverters ();
173
177
@@ -262,6 +266,39 @@ bool CPythonManager::Shutdown( void )
262
266
}
263
267
264
268
269
+ // ---------------------------------------------------------------------------------
270
+ // Circular references traversal
271
+ // ---------------------------------------------------------------------------------
272
+ struct dict_traversal
273
+ {
274
+ static int is_gc (PyObject *self)
275
+ {
276
+ return !!downcast<objects::instance<> >(self)->dict ;
277
+ }
278
+
279
+ static int traverse (PyObject *self, visitproc visit, void *arg)
280
+ {
281
+ Py_VISIT (downcast<objects::instance<> >(self)->dict );
282
+ return 0 ;
283
+ }
284
+
285
+ static int clear (PyObject *self)
286
+ {
287
+ Py_CLEAR (downcast<objects::instance<> >(self)->dict );
288
+ return 0 ;
289
+ }
290
+ };
291
+
292
+ void EnableDictTraversal ()
293
+ {
294
+ PyTypeObject *type = objects::class_type ().get ();
295
+ type->tp_flags |= Py_TPFLAGS_HAVE_GC;
296
+ type->tp_is_gc = dict_traversal::is_gc;
297
+ type->tp_traverse = dict_traversal::traverse;
298
+ type->tp_clear = dict_traversal::clear;
299
+ }
300
+
301
+
265
302
// ---------------------------------------------------------------------------------
266
303
// Converters
267
304
// ---------------------------------------------------------------------------------
0 commit comments