@@ -56,6 +56,7 @@ CPythonManager g_PythonManager;
5656// Forward declarations.
5757// ---------------------------------------------------------------------------------
5858void InitConverters ();
59+ void EnableDictTraversal ();
5960
6061
6162// ---------------------------------------------------------------------------------
@@ -168,6 +169,9 @@ bool CPythonManager::Initialize( void )
168169 // And of course, the plugins directory for script imports.
169170 AddToSysPath (" /plugins" );
170171
172+ // Enable circular references traversal
173+ EnableDictTraversal ();
174+
171175 // Initialize all converters
172176 InitConverters ();
173177
@@ -262,6 +266,39 @@ bool CPythonManager::Shutdown( void )
262266}
263267
264268
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+
265302// ---------------------------------------------------------------------------------
266303// Converters
267304// ---------------------------------------------------------------------------------
0 commit comments