An interesting Python garbage collection bug

November 5, 2006

Derived from here:

import sys
x = 10
del sys.modules['__main__']
print x

If you execute this at the interpreter prompt, you get a NameError that x is not defined. If you execute it as a file (or if you put the sys.modules and print bit in a function and run the function), you get None printed.

The interpreter situation makes a certain amount of sense, once you discover that the interpreter is holding no references to anything from prompt to prompt. The del drops the reference count on the real __main__ to zero, causing it to be garbage collected, and you are left with no namespace at all.

(Technically what happens is that the interpreter recreates a new __main__ at the next line, but it is empty. You can't do much with this, since you can't successfully import __builtins__ to start reconstructing an environment.)

The function case makes sense once you think about cyclic garbage collection. While the executing function has a reference to __main__, __main__ also holds a reference to it, making it a cyclic reference and thus not enough to keep __main__ alive. The peculiar result is because of how CPython cleans up modules that are getting garbage collected; in order to help out destructors, it follows a complicated dance of setting module-level names to None (in two passes, and excluding __builtins__, so that destructors can still get at builtin objects), instead of actually deleting them outright.

I call this a bug because I believe that executing code should be considered to be holding an external reference to its module, and that the interpreter should similarly hold an external reference to __main__ in general. Python may be doing what you told it to here, but it's not anywhere near what I think most people would expect.

Written on 05 November 2006.
« Weekly spam summary on November 4th, 2006
HTML character sets »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Nov 5 21:55:08 2006
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.