[Python-Dev] AtExit Functions

Tim Peters tim.one@comcast.net
Tue, 16 Jul 2002 01:24:23 -0400


[MAL, on Py_AtExit()]
> PyObject_Del() [must be avoided] as well ?

I don't think that one's a problem.  The Py{Object,Mem}_{Del,DEL,Free,FREE}
spellings have resolved to plain free().  Under pymalloc that's different,
but pymalloc never tears itself down so it's safe there too.


>> We have two sets of exit-function gimmicks, one that runs at
>> the very start of Py_Finalize(), and the other at the very end.
>> If you need to clean up Python objects, you have to get into
>> the first group.

> I suppose the first one is what the atexit module exposes
> in Python 2.0+, right ?

Yes, but do read Skip's message too.  atexit.py wraps a primitive gimmick
that was also in 1.5.2.  See the docs for sys.exitfunc at

    http://www.python.org/doc/1.5.2p2/lib/module-sys.html

The docs are pretty much the same now, except atexit.py provides a rational
way to register multiple exit functions now.  Hmm!  The logic in atexit.py
looks wrong if sys.exitfunc already exists:  then atexit appends it to the
module's own list of exit functions, but then forgets to do anything to
ensure that its own list gets run at the end.  I conclude that nobody has
tried mixing these gimmicks.

In any case, you can do something safe across all versions via:

import sys
try:
    inherited = sys.exitfunc
except AttributeError:
    def inherited():
        pass

def myexitfunc():
    clean_up_my_stuff()
    inherited()

sys.exitfunc = myexitfunc
del sys

You can get screwed then if somebody else sets sys.exitfunc later without
being as considerate of your hook as the code above is of a pre-existing
hook, but then that's why atexit.py was created and you should move to a
later Python if you want saner behavior <wink>.

> The problem with that approach is that there may still be some
> references to objects left in lists and dicts which are cleaned
> up after having called the atexit functions. This is not so
> much a problem in my cases, but something to watch out in other
> applications which use C level Python objects as globals.

I don't know specifically what you have in mind there, but I expect that it
would kick off another round of the every-18-months discussion of what kind
of module finalization protocol Python should start to support.  A PEP for
that is long overdue.

>>> Also, atexit.py is not present in Python 1.5.2.

>> What's that <wink>?

> That's the Python version which was brand new just 3 years
> ago. I know... in US terms that's for history books ;-)

Oh, 3 years ago is sooooo 20th century!  Goodness, they didn't even have
cellophane sleeping tubes back then.  May as well go back to worshipping
cats while you're at it.