[Duncan Booth]
> No, Python doesn't run the garbage collector when it is exiting.

Actually, it does.  What it doesn't do is call the garbage collector
twice when it exits, although it used to ;-)

> What it does is to delete all the globals from each module in turn. So:

Yup.  The code is in function Py_Finalize().  Here's the relevant snippet:

        ...
        PyGC_Collect();

        /* Destroy all modules */
        PyImport_Cleanup();

        /* Collect final garbage.  This disposes of cycles created by
         * new-style class definitions, for example.
         * XXX This is disabled because it caused too many problems.  If
         * XXX a __del__ or weakref callback triggers here, Python code has
         * XXX a hard time running, because even the sys module has been
         * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc).
         * XXX One symptom is a sequence of information-free messages
         * XXX coming from threads (if a __del__ or callback is invoked,
         * XXX other threads can execute too, and any exception they encounter
         * XXX triggers a comedy of errors as subsystem after subsystem
         * XXX fails to find what it *expects* to find in sys to help report
         * XXX the exception and consequent unexpected failures).  I've also
         * XXX seen segfaults then, after adding print statements to the
         * XXX Python code getting called.
         */
#if 0
        PyGC_Collect();
#endif

The first PyGC_Collect() runs, then what you described runs ("destroy
all modules"), and then  PyGC_Collect() _doesn't_ run again.  As the
comment says, it's the second run of PyGC_Collect() that _would_ get
rid of dead module-level new-style classes, were it to run.

Alas, as the XXX comments say, too much of the interpreter has been
destroyed by PyImport_Cleanup() for __del__ and weakref callbacks to
execute sanely, so we have to skip it.  And, of course, module-level
objects _aren't_ trash before PyImport_Cleanup() runs.  Therefore
module-level objects involved in reference cycles never trigger
__del__ or weakref callbacks as a side effect of Python exiting, and
new-style classes are (as you said) always involved in reference
cycles.
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to