Author: Amaury Forgeot d'Arc <[email protected]>
Branch: py3k
Changeset: r48022:fac760084b0d
Date: 2011-10-13 22:38 +0200
http://bitbucket.org/pypy/pypy/changeset/fac760084b0d/
Log: The atexit module now replaces sys.exitfunc.
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -18,7 +18,7 @@
default_modules = essential_modules.copy()
default_modules.update(dict.fromkeys(
- ["_codecs", "gc", "_weakref", "marshal", "errno", "imp",
+ ["_codecs", "atexit", "gc", "_weakref", "marshal", "errno", "imp",
"math", "cmath", "_sre", "_pickle_support", "operator",
"parser", "symbol", "token", "_ast", "_io", "_random", "__pypy__",
"_string", "_testing"]))
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -330,9 +330,8 @@
def finish(self):
self.wait_for_thread_shutdown()
- w_exitfunc = self.sys.getdictvalue(self, 'exitfunc')
- if w_exitfunc is not None:
- self.call_function(w_exitfunc)
+ w_atexit = self.getbuiltinmodule('atexit')
+ self.call_method(w_atexit, '_run_exitfuncs')
from pypy.interpreter.module import Module
for w_mod in self.builtin_modules.values():
mod = self.interpclass_w(w_mod)
diff --git a/pypy/interpreter/module.py b/pypy/interpreter/module.py
--- a/pypy/interpreter/module.py
+++ b/pypy/interpreter/module.py
@@ -57,7 +57,7 @@
def shutdown(self, space):
"""This is called when the space is shut down, just after
- sys.exitfunc(), if the module has been imported.
+ atexit functions, if the module has been imported.
"""
def getdict(self, space):
diff --git a/pypy/module/atexit/__init__.py b/pypy/module/atexit/__init__.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/atexit/__init__.py
@@ -0,0 +1,24 @@
+"""A _string module, to export formatter_parser and
+ formatter_field_name_split to the string.Formatter class
+ implemented in Python."""
+
+
+from pypy.interpreter.mixedmodule import MixedModule
+
+class Module(MixedModule):
+ """Allow programmer to define multiple exit functions to be
+ executed upon normal program termination.
+
+ Two public functions, register and unregister, are defined.
+ """
+
+ interpleveldefs = {
+ }
+
+ appleveldefs = {
+ 'register': 'app_atexit.register',
+ 'unregister': 'app_atexit.unregister',
+ '_clear': 'app_atexit.clear',
+ '_run_exitfuncs': 'app_atexit.run_exitfuncs',
+ }
+
diff --git a/pypy/module/atexit/app_atexit.py b/pypy/module/atexit/app_atexit.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/atexit/app_atexit.py
@@ -0,0 +1,48 @@
+atexit_callbacks = []
+
+def register(func, *args, **kwargs):
+ """Register a function to be executed upon normal program termination.
+
+ func - function to be called at exit
+ args - optional arguments to pass to func
+ kwargs - optional keyword arguments to pass to func
+
+ func is returned to facilitate usage as a decorator."""
+
+ if not callable(func):
+ raise TypeError("func must be callable")
+
+ atexit_callbacks.append((func, args, kwargs))
+ return func
+
+def run_exitfuncs():
+ "Run all registered exit functions."
+ # Maintain the last exception
+ last_exc, last_tb = None, None
+ for (func, args, kwargs) in atexit_callbacks:
+ if func is None:
+ # unregistered slot
+ continue
+ try:
+ func(*args, **kwargs)
+ except BaseException, e:
+ if not isinstance(e, SystemExit):
+ import traceback
+ last_type, last_exc, last_tb = sys.exc_info()
+ traceback.print_exception(last_type, last_exc, last_tb)
+
+ clear()
+
+ if last_exc is not None:
+ raise last_exc.with_traceback(last_tb)
+
+def clear():
+ "Clear the list of previously registered exit functions."
+ del atexit_callbacks[:]
+
+def unregister(func):
+ """Unregister a exit function which was previously registered using
+ atexit.register"""
+ for i, (f, _, _) in enumerate(atexit_callbacks):
+ if f == func:
+ atexit_callbacks[i] = (None, None, None)
diff --git a/pypy/module/sys/__init__.py b/pypy/module/sys/__init__.py
--- a/pypy/module/sys/__init__.py
+++ b/pypy/module/sys/__init__.py
@@ -94,7 +94,6 @@
'excepthook' : 'app.excepthook',
'__excepthook__' : 'app.excepthook',
'exit' : 'app.exit',
- 'exitfunc' : 'app.exitfunc',
'callstats' : 'app.callstats',
'copyright' : 'app.copyright_str',
'flags' : 'app.null_sysflags',
diff --git a/pypy/module/sys/app.py b/pypy/module/sys/app.py
--- a/pypy/module/sys/app.py
+++ b/pypy/module/sys/app.py
@@ -56,9 +56,6 @@
# in normalize_exception, which is exactly like CPython's.
raise SystemExit, exitcode
-def exitfunc():
- """Placeholder for sys.exitfunc(), which is called when PyPy exits."""
-
#import __builtin__
def callstats():
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit