Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
599bd5e1
Commit
599bd5e1
authored
Nov 04, 2004
by
Skip Montanaro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix bug 1052242. Also includes rewrite of test case using unittest and
avoiding use of popen.
parent
ed306292
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
117 additions
and
54 deletions
+117
-54
Doc/lib/libatexit.tex
Doc/lib/libatexit.tex
+6
-0
Lib/atexit.py
Lib/atexit.py
+14
-2
Lib/test/test_atexit.py
Lib/test/test_atexit.py
+86
-52
Misc/NEWS
Misc/NEWS
+11
-0
No files found.
Doc/lib/libatexit.tex
View file @
599bd5e1
...
...
@@ -39,6 +39,12 @@ completes), all functions registered are called in last in, first out
order. The assumption is that lower level modules will normally be
imported before higher level modules and thus must be cleaned up
later.
If an exception is raised during execution of the exit handlers, a traceback
is printed (unless SystemExit is raised) and the exception information is
saved. After all exit handlers have had a chance to run the last exception
to be raised is reraised.
\end{funcdesc}
...
...
Lib/atexit.py
View file @
599bd5e1
...
...
@@ -15,9 +15,22 @@ def _run_exitfuncs():
last in, first out.
"""
exc_info
=
None
while
_exithandlers
:
func
,
targs
,
kargs
=
_exithandlers
.
pop
()
func
(
*
targs
,
**
kargs
)
try
:
func
(
*
targs
,
**
kargs
)
except
SystemExit
:
exc_info
=
sys
.
exc_info
()
except
:
import
sys
,
traceback
print
>>
sys
.
stderr
,
"Error in atexit._run_exitfuncs:"
traceback
.
print_exc
()
exc_info
=
sys
.
exc_info
()
if
exc_info
is
not
None
:
raise
exc_info
[
0
],
exc_info
[
1
],
exc_info
[
2
]
def
register
(
func
,
*
targs
,
**
kargs
):
"""register a function to be executed upon normal program termination
...
...
@@ -33,7 +46,6 @@ if hasattr(sys, "exitfunc"):
# Assume it's another registered exit function - append it to our list
register
(
sys
.
exitfunc
)
sys
.
exitfunc
=
_run_exitfuncs
del
sys
if
__name__
==
"__main__"
:
...
...
Lib/test/test_atexit.py
View file @
599bd5e1
# Test the atexit module.
from
test.test_support
import
TESTFN
,
vereq
,
is_jython
import
atexit
from
os
import
popen
,
unlink
import
sys
executable
=
sys
.
executable
if
is_jython
:
executable
=
"jython"
input
=
"""
\
import
unittest
import
StringIO
import
atexit
from
test
import
test_support
def handler1():
print "handler1"
class
TestCase
(
unittest
.
TestCase
):
def
test_args
(
self
):
# be sure args are handled properly
s
=
StringIO
.
StringIO
()
sys
.
stdout
=
sys
.
stderr
=
s
save_handlers
=
atexit
.
_exithandlers
atexit
.
_exithandlers
=
[]
try
:
atexit
.
register
(
self
.
h1
)
atexit
.
register
(
self
.
h4
)
atexit
.
register
(
self
.
h4
,
4
,
kw
=
"abc"
)
atexit
.
_run_exitfuncs
()
finally
:
sys
.
stdout
=
sys
.
__stdout__
sys
.
stderr
=
sys
.
__stderr__
atexit
.
_exithandlers
=
save_handlers
self
.
assertEqual
(
s
.
getvalue
(),
"h4 (4,) {'kw': 'abc'}
\
n
h4 () {}
\
n
h1
\
n
"
)
def handler2(*args, **kargs):
print "handler2", args, kargs
def
test_order
(
self
):
# be sure handlers are executed in reverse order
s
=
StringIO
.
StringIO
()
sys
.
stdout
=
sys
.
stderr
=
s
save_handlers
=
atexit
.
_exithandlers
atexit
.
_exithandlers
=
[]
try
:
atexit
.
register
(
self
.
h1
)
atexit
.
register
(
self
.
h2
)
atexit
.
register
(
self
.
h3
)
atexit
.
_run_exitfuncs
()
finally
:
sys
.
stdout
=
sys
.
__stdout__
sys
.
stderr
=
sys
.
__stderr__
atexit
.
_exithandlers
=
save_handlers
self
.
assertEqual
(
s
.
getvalue
(),
"h3
\
n
h2
\
n
h1
\
n
"
)
atexit.register(handler1)
atexit.register(handler2)
atexit.register(handler2, 7, kw="abc")
"""
def
test_sys_override
(
self
):
# be sure a preset sys.exitfunc is handled properly
s
=
StringIO
.
StringIO
()
sys
.
stdout
=
sys
.
stderr
=
s
save_handlers
=
atexit
.
_exithandlers
atexit
.
_exithandlers
=
[]
exfunc
=
sys
.
exitfunc
sys
.
exitfunc
=
self
.
h1
reload
(
atexit
)
try
:
atexit
.
register
(
self
.
h2
)
atexit
.
_run_exitfuncs
()
finally
:
sys
.
stdout
=
sys
.
__stdout__
sys
.
stderr
=
sys
.
__stderr__
atexit
.
_exithandlers
=
save_handlers
sys
.
exitfunc
=
exfunc
self
.
assertEqual
(
s
.
getvalue
(),
"h2
\
n
h1
\
n
"
)
fname
=
TESTFN
+
".py"
f
=
file
(
fname
,
"w"
)
f
.
write
(
input
)
f
.
close
()
def
test_raise
(
self
):
# be sure raises are handled properly
s
=
StringIO
.
StringIO
()
sys
.
stdout
=
sys
.
stderr
=
s
save_handlers
=
atexit
.
_exithandlers
atexit
.
_exithandlers
=
[]
try
:
atexit
.
register
(
self
.
raise1
)
atexit
.
register
(
self
.
raise2
)
self
.
assertRaises
(
TypeError
,
atexit
.
_run_exitfuncs
)
finally
:
sys
.
stdout
=
sys
.
__stdout__
sys
.
stderr
=
sys
.
__stderr__
atexit
.
_exithandlers
=
save_handlers
### helpers
def
h1
(
self
):
print
"h1"
p
=
popen
(
'"%s" %s'
%
(
executable
,
fname
))
output
=
p
.
read
()
p
.
close
()
vereq
(
output
,
"""
\
handler2 (7,) {'kw': 'abc'}
handler2 () {}
handler1
"""
)
def
h2
(
self
):
print
"h2"
input
=
"""
\
def direct():
print "direct exit"
def
h3
(
self
):
print
"h3"
import sys
sys.exitfunc = direct
def
h4
(
self
,
*
args
,
**
kwargs
):
print
"h4"
,
args
,
kwargs
# Make sure atexit doesn't drop
def indirect():
print "indirect exit"
def
raise1
(
self
):
raise
TypeError
import atexit
atexit.register(indirect)
"""
def
raise2
(
self
):
raise
SystemError
f
=
file
(
fname
,
"w"
)
f
.
write
(
input
)
f
.
close
()
def
test_main
():
test_support
.
run_unittest
(
TestCase
)
p
=
popen
(
'"%s" %s'
%
(
executable
,
fname
))
output
=
p
.
read
()
p
.
close
()
vereq
(
output
,
"""
\
indirect exit
direct exit
"""
)
unlink
(
fname
)
if
__name__
==
"__main__"
:
test_main
()
Misc/NEWS
View file @
599bd5e1
...
...
@@ -2,6 +2,17 @@
Python
News
+++++++++++
What
's New in Python 2.4 release candidate 1?
=============================================
Library
-------
- Bug 1052242: If exceptions are raised by an atexit handler function an
attempt is made to execute the remaining handlers. The last exception
raised is re-raised.
(editors: check NEWS.help for information about editing NEWS using ReST.)
What'
s
New
in
Python
2.4
beta
2
?
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment