[pypy-commit] pypy default: merge heads
arigo
noreply at buildbot.pypy.org
Fri May 13 15:01:06 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r44125:0e2cc89acbea
Date: 2011-05-13 15:09 +0200
http://bitbucket.org/pypy/pypy/changeset/0e2cc89acbea/
Log: merge heads
diff --git a/pypy/module/cpyext/__init__.py b/pypy/module/cpyext/__init__.py
--- a/pypy/module/cpyext/__init__.py
+++ b/pypy/module/cpyext/__init__.py
@@ -12,9 +12,21 @@
appleveldefs = {
}
+ atexit_funcs = []
+
def startup(self, space):
space.fromcache(State).startup(space)
+ def register_atexit(self, function):
+ if len(self.atexit_funcs) >= 32:
+ raise ValueError("cannot register more than 32 atexit functions")
+ self.atexit_funcs.append(function)
+
+ def shutdown(self, space):
+ for func in self.atexit_funcs:
+ func()
+
+
# import these modules to register api functions by side-effect
import pypy.module.cpyext.thread
import pypy.module.cpyext.pyobject
diff --git a/pypy/module/cpyext/pythonrun.py b/pypy/module/cpyext/pythonrun.py
--- a/pypy/module/cpyext/pythonrun.py
+++ b/pypy/module/cpyext/pythonrun.py
@@ -14,3 +14,21 @@
value."""
return space.fromcache(State).get_programname()
+ at cpython_api([lltype.Ptr(lltype.FuncType([], lltype.Void))], rffi.INT_real, error=-1)
+def Py_AtExit(space, func_ptr):
+ """Register a cleanup function to be called by Py_Finalize(). The cleanup
+ function will be called with no arguments and should return no value. At
+ most 32 cleanup functions can be registered. When the registration is
+ successful, Py_AtExit() returns 0; on failure, it returns -1. The cleanup
+ function registered last is called first. Each cleanup function will be
+ called at most once. Since Python's internal finalization will have
+ completed before the cleanup function, no Python APIs should be called by
+ func."""
+ from pypy.module import cpyext
+ w_module = space.getbuiltinmodule('cpyext')
+ module = space.interp_w(cpyext.Module, w_module)
+ try:
+ module.register_atexit(func_ptr)
+ except ValueError:
+ return -1
+ return 0
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -2274,18 +2274,6 @@
standard C library function exit(status)."""
raise NotImplementedError
- at cpython_api([rffi.VOIDP], rffi.INT_real, error=-1)
-def Py_AtExit(space, func):
- """Register a cleanup function to be called by Py_Finalize(). The cleanup
- function will be called with no arguments and should return no value. At
- most 32 cleanup functions can be registered. When the registration is
- successful, Py_AtExit() returns 0; on failure, it returns -1. The cleanup
- function registered last is called first. Each cleanup function will be
- called at most once. Since Python's internal finalization will have
- completed before the cleanup function, no Python APIs should be called by
- func."""
- raise NotImplementedError
-
@cpython_api([PyObject, Py_ssize_t, Py_ssize_t], PyObject)
def PyTuple_GetSlice(space, p, low, high):
"""Take a slice of the tuple pointed to by p from low to high and return it
diff --git a/pypy/module/cpyext/test/test_eval.py b/pypy/module/cpyext/test/test_eval.py
--- a/pypy/module/cpyext/test/test_eval.py
+++ b/pypy/module/cpyext/test/test_eval.py
@@ -166,6 +166,15 @@
lltype.free(pi, flavor='raw')
+ def test_atexit(self, space, api):
+ lst = []
+ def func():
+ lst.append(42)
+ api.Py_AtExit(func)
+ cpyext = space.getbuiltinmodule('cpyext')
+ cpyext.shutdown(space) # simulate shutdown
+ assert lst == [42]
+
class AppTestCall(AppTestCpythonExtensionBase):
def test_CallFunction(self):
module = self.import_extension('foo', [
More information about the pypy-commit
mailing list