[pypy-commit] pypy default: merge

fijal noreply at buildbot.pypy.org
Tue May 5 11:01:38 CEST 2015


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: 
Changeset: r77144:5bb7b9003046
Date: 2015-05-05 11:01 +0200
http://bitbucket.org/pypy/pypy/changeset/5bb7b9003046/

Log:	merge

diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -276,7 +276,11 @@
             if argtypes:
                 args = [argtype._CData_retval(argtype.from_address(arg)._buffer)
                         for argtype, arg in zip(argtypes, args)]
-            return to_call(*args)
+            try:
+                return to_call(*args)
+            except SystemExit, e:
+                handle_system_exit(e)
+                raise
         return f
 
     def __call__(self, *args, **kwargs):
@@ -305,11 +309,13 @@
             except (UnicodeError, TypeError, ValueError), e:
                 raise ArgumentError(str(e))
             try:
-                res = self.callable(*newargs)
+                try:
+                    res = self.callable(*newargs)
+                except SystemExit, e:
+                    handle_system_exit(e)
+                    raise
             except:
                 exc_info = sys.exc_info()
-                if issubclass(exc_info[0], SystemExit):
-                    exc_info = handle_system_exit(exc_info)
                 traceback.print_tb(exc_info[2], file=sys.stderr)
                 print >>sys.stderr, "%s: %s" % (exc_info[0].__name__, exc_info[1])
                 return 0
@@ -719,14 +725,13 @@
 make_fastpath_subclass.memo = {}
 
 
-def handle_system_exit(exc_info):
+def handle_system_exit(e):
     # issue #1194: if we get SystemExit here, then exit the interpreter.
     # Highly obscure imho but some people seem to depend on it.
-    try:
-        if sys.flags.inspect:
-            return exc_info   # Don't exit if -i flag was given.
-
-        code = exc_info[1].code
+    if sys.flags.inspect:
+        return   # Don't exit if -i flag was given.
+    else:
+        code = e.code
         if isinstance(code, int):
             exitcode = code
         else:
@@ -737,6 +742,3 @@
             exitcode = 1
 
         _rawffi.exit(exitcode)
-
-    except:
-        return sys.exc_info()
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_callback_traceback.py b/pypy/module/test_lib_pypy/ctypes_tests/test_callback_traceback.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_callback_traceback.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_callback_traceback.py
@@ -55,3 +55,26 @@
                              "TypeError: "
                              "unsupported operand type(s) for")
 
+    def test_SystemExit(self):
+        import _rawffi
+        if sys.flags.inspect:
+            skip("requires sys.flags.inspect == 0")
+        def callback_func(arg):
+            raise SystemExit(42)
+        def custom_exit(value):
+            raise Exception("<<<exit(%r)>>>" % (value,))
+        original_exit = _rawffi.exit
+        try:
+            _rawffi.exit = custom_exit
+            #
+            cb = CFUNCTYPE(c_int, c_int)(callback_func)
+            cb2 = cast(cast(cb, c_void_p), CFUNCTYPE(c_int, c_int))
+            out = self.capture_stderr(cb2, 0)
+            assert out.splitlines()[-1] == "Exception: <<<exit(42)>>>"
+            #
+            cb = CFUNCTYPE(c_int, c_int)(callback_func)
+            out = self.capture_stderr(cb, 0)
+            assert out.splitlines()[-1] == "Exception: <<<exit(42)>>>"
+            #
+        finally:
+            _rawffi.exit = original_exit


More information about the pypy-commit mailing list