Author: Armin Rigo <ar...@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() +@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 -@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', [ _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit