[ python-Bugs-1052242 ] Attempt to run all atexit handlers

SourceForge.net noreply at sourceforge.net
Mon Nov 1 01:25:10 CET 2004


Bugs item #1052242, was opened at 2004-10-22 09:31
Message generated for change (Comment added) made by montanaro
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1052242&group_id=5470

Category: Python Library
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Greg Chapman (glchapman)
Assigned to: Skip Montanaro (montanaro)
Summary: Attempt to run all atexit handlers

Initial Comment:
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.


----------------------------------------------------------------------

>Comment By: Skip Montanaro (montanaro)
Date: 2004-10-31 18:25

Message:
Logged In: YES 
user_id=44345

Whoops, forgot to attach.  Just as well, I also have a small
doc fix to include...

----------------------------------------------------------------------

Comment By: Skip Montanaro (montanaro)
Date: 2004-10-31 18:16

Message:
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.


----------------------------------------------------------------------

Comment By: Raymond Hettinger (rhettinger)
Date: 2004-10-28 14:21

Message:
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.

----------------------------------------------------------------------

Comment By: Greg Chapman (glchapman)
Date: 2004-10-28 10:24

Message:
Logged In: YES 
user_id=86307

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

+1


----------------------------------------------------------------------

Comment By: Skip Montanaro (montanaro)
Date: 2004-10-28 06:28

Message:
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?




----------------------------------------------------------------------

Comment By: Skip Montanaro (montanaro)
Date: 2004-10-27 09:44

Message:
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.

----------------------------------------------------------------------

Comment By: Raymond Hettinger (rhettinger)
Date: 2004-10-27 00:46

Message:
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.

----------------------------------------------------------------------

Comment By: Skip Montanaro (montanaro)
Date: 2004-10-24 12:21

Message:
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.



----------------------------------------------------------------------

Comment By: Raymond Hettinger (rhettinger)
Date: 2004-10-23 19:56

Message:
Logged In: YES 
user_id=80475

This could be considered a bug.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1052242&group_id=5470


More information about the Python-bugs-list mailing list