[Python-Dev] Reference cycle on the module dict (globals())

Petr Viktorin encukou at gmail.com
Tue Jan 19 05:39:28 EST 2016


On 01/19/2016 10:42 AM, Victor Stinner wrote:
> 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?

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.


More information about the Python-Dev mailing list