Reference cycle on the module dict (globals())

Hi, While working on my FAT Python optimizer project, I found an annoying bug in my code. When at least one guard is created with a reference to the global namespace (globals(), the module dictionary), objects of the module are no more removed at exit. Example: --- import sys class MessageAtExit: def __del__(self): print('__del__ called') # display a message at exit, when message_at_exit is removed message_at_exit = MessageAtExit() # create a reference cycle: # module -> module dict -> Guard -> module dict guard = sys.Guard(globals()) --- (the code is adapted from a test of test_gc) Apply attached patch to Python 3.6 to get the sys.Guard object. It's a minimalist object to keep a strong reference to an object. I expected the garbage collector to break such (simple?) reference cycle. The Guard object implements a traverse module, but it is never called. Did I miss something obvious, or is it a known issue of the garbage collector on modules? Victor

On 01/19/2016 10:42 AM, Victor Stinner wrote:
The default type flags are for objects that don't store references. Since you're creating a mutable container, you need to set Py_TPFLAGS_HAVE_GC. See https://docs.python.org/3/c-api/gcsupport.html for all the details.

Hi, 2016-01-19 11:39 GMT+01:00 Petr Viktorin <encukou@gmail.com>:
Ok, so I missed this important flag :-) Thanks! I had to fight against the C API to fix all my bugs, but now it works well: a guard keeps a strong reference to the global namespace, but objects are still destroyed when the module is unloaded! FYI I updated my PEP 510 patch to track guards with the garbage collector, and my fat project to fix bugs related to GC: - https://bugs.python.org/issue26098 - https://github.com/haypo/fat Victor

On 01/19/2016 10:42 AM, Victor Stinner wrote:
The default type flags are for objects that don't store references. Since you're creating a mutable container, you need to set Py_TPFLAGS_HAVE_GC. See https://docs.python.org/3/c-api/gcsupport.html for all the details.

Hi, 2016-01-19 11:39 GMT+01:00 Petr Viktorin <encukou@gmail.com>:
Ok, so I missed this important flag :-) Thanks! I had to fight against the C API to fix all my bugs, but now it works well: a guard keeps a strong reference to the global namespace, but objects are still destroyed when the module is unloaded! FYI I updated my PEP 510 patch to track guards with the garbage collector, and my fat project to fix bugs related to GC: - https://bugs.python.org/issue26098 - https://github.com/haypo/fat Victor
participants (2)
-
Petr Viktorin
-
Victor Stinner