[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