This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Attempt to run all atexit handlers
Type: Stage:
Components: Library (Lib) Versions:
process
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: skip.montanaro Nosy List: glchapman, rhettinger, skip.montanaro
Priority: normal Keywords:

Created on 2004-10-22 14:31 by glchapman, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
atexit.diff skip.montanaro, 2004-11-01 00:25
Messages (11)
msg22818 - (view) Author: Greg Chapman (glchapman) Date: 2004-10-22 14:31
Currently, if an atexit handler raises an exception
during _run_exitfuncs, none of the remaining handlers
in the _exithandlers list gets run.  I would prefer it
if _run_exitfuncs did something like:

    while _exithandlers:
        func, targs, kargs = _exithandlers.pop()
        try:
            func(*targs, **kargs)
        except SystemExit:
            raise
        except:
            import sys, traceback
            print >> sys.stderr, "Error in sys.exitfunc:"
            traceback.print_exc()

The SystemExit except clause is there because it looks
like (given its special treatment in call_sys_exitfunc)
SystemExit is envisioned as a way of intentionally
breaking out of the exithandlers loop.
msg22819 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2004-10-24 00:56
Logged In: YES 
user_id=80475

This could be considered a bug.
msg22820 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2004-10-24 17:21
Logged In: YES 
user_id=44345

OTOH, since the ordering of the exit handlers is not guaranteed,
exiting after one exception is also reasonable behavior.  Attached
is a diff that does two things: adds a set_run_all function and
converts the functionality into an ExitHandler class to keep from
all the different bits of global state.

msg22821 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2004-10-27 05:46
Logged In: YES 
user_id=80475

I prefer the original proposal that leaves the API untouched.

Irrespective of ordering, my thought is that all exit
handlers are probably expected to run (needed for important
cleanup, resource freeing, etc) and may be independent of
one another.  So, all of them that can run, probably should.
msg22822 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2004-10-27 14:44
Logged In: YES 
user_id=44345

I agree with you in principle, but you'd change behavior and
possibly
break existing code that relies on the current implicit
semantics, hence
my suggestion to use a variable to control the behavior,
with it set to
preserve the current behavior by default.

I'll post a request to python-dev soliciting input.
msg22823 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2004-10-28 11:28
Logged In: YES 
user_id=44345

Okay, Guido has pronounced.  My idea for preserving compatibility
is out.  Now, I wonder about Greg's SystemExit behavior...
Should we defer it until the loop is complete and reraise it then?


msg22824 - (view) Author: Greg Chapman (glchapman) Date: 2004-10-28 15:24
Logged In: YES 
user_id=86307

> Should we defer it until the loop is complete and reraise it
> then?

+1
msg22825 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2004-10-28 19:21
Logged In: YES 
user_id=80475

This should probably also be kicked around on python-dev so
that we arrive at a clear expression of what it means to
raise SystemExit and how that differs from os._exit().

One school of thought is that Greg's initial version is
correct -- raising SystemExit means get out as fast as you
can but not as abruptly as os._exit() so that buffers can be
flushed, etc.
msg22826 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2004-11-01 00:16
Logged In: YES 
user_id=44345

Here's the next version of the patch.  It includes the
save-the-exception stuff and a rewrite of test_atexit.py using
unittest.  The only annoyance is that the traceback for the actually
raised exception will be printed twice.  One way around that might
be to wrap the last raise in something like

    stdout = sys.stdout
    stderr = sys.stderr
    sys.stdout = sys.stderr = open(os.devnull, "w")
    try:
        raise ...
    finally:
        sys.stdout = stdout
        sys.stderr = stderr

though I haven't tested the idea to see if it will actually work.
msg22827 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2004-11-01 00:25
Logged In: YES 
user_id=44345

Whoops, forgot to attach.  Just as well, I also have a small
doc fix to include...
msg22828 - (view) Author: Skip Montanaro (skip.montanaro) * (Python triager) Date: 2004-11-04 04:32
Logged In: YES 
user_id=44345

Lib/atexit.py v 1.8, Doc/lib/libatexit.tex v 1.9, Lib/test/
test_atexit.py v 1.11
History
Date User Action Args
2022-04-11 14:56:07adminsetgithub: 41062
2004-10-22 14:31:48glchapmancreate