Module gets garbage collected; its globals become None

Steven Taschuk staschuk at telusplanet.net
Fri May 23 23:39:50 EDT 2003


Under CPython 2.2.2 and 2.3 (and earlier versions, I suspect):

    $ cat snee.py
    import sys
    print sys
    del sys.modules['__main__']
    print sys

    $ python snee.py
    <module 'sys' (built-in)>
    None

Since sys.modules has the only reference to __main__ here, the del
causes the module to be garbage collected.  The module's __dict__
is not collected (since the running code itself retains a
reference to that dict), but the collection of the module mutates
the dict, setting all its values to None, with the result shown
above.  (See Objects/moduleobject.c:/^_PyModule_Clear, which is
called by module_dealloc.)

So much for *how* this occurs.  What I'm curious about is why --
why do the dict's values have to be cleared when the module is
collected?  Why not just let the dict, and hence its values, get
collected in its turn?

Is it, as a comment in moduleobject.c suggests, to "make the
execution order of destructors for global objects a bit more
predictable"?  And if so, couldn't this equally as well be done by
giving modules' dicts their own tp_dealloc, one which clears them
in the desired order?  Such an approach would ensure that the dict
is not destructively mutated until nobody cares.

(If you find it bizarre that I want to delete entries from
sys.modules, be assured that I don't.  I ran into this behaviour
while writing a script which loaded modules dynamically, did not
register them in sys.modules, and retained only references to
objects defined in the modules, not references to the modules
themselves.  Those objects then broke spectacularly, in an
unusually mysterious way -- variables made None without any
obvious reason.)

-- 
Steven Taschuk                            staschuk at telusplanet.net
"Our analysis begins with two outrageous benchmarks."
  -- "Implementation strategies for continuations", Clinger et al.





More information about the Python-list mailing list