[pypy-commit] pypy default: implement Py_AtExit (without test case)

Timo Paulssen noreply at buildbot.pypy.org
Fri May 13 14:39:27 CEST 2011


Author: Timo Paulssen <timonator at perpetuum-immobile.de>
Branch: 
Changeset: r44122:86db0a1b82c4
Date: 2011-05-12 10:36 +0200
http://bitbucket.org/pypy/pypy/changeset/86db0a1b82c4/

Log:	implement Py_AtExit (without test case)

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


More information about the pypy-commit mailing list