[pypy-commit] pypy default: Simplify the unwrapper_raise/unwrapper_catch mess a little

rlamy pypy.commits at gmail.com
Wed Dec 14 12:26:54 EST 2016


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: 
Changeset: r89061:c36941f291c3
Date: 2016-12-14 17:26 +0000
http://bitbucket.org/pypy/pypy/changeset/c36941f291c3/

Log:	Simplify the unwrapper_raise/unwrapper_catch mess a little

diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -379,103 +379,97 @@
         if error is _NOT_SPECIFIED:
             raise ValueError("function %s has no return value for exceptions"
                              % func)
-        def make_unwrapper(catch_exception):
-            # ZZZ is this whole logic really needed???  It seems to be only
-            # for RPython code calling PyXxx() functions directly.  I would
-            # think that usually directly calling the function is clean
-            # enough now
-            names = api_function.argnames
-            types_names_enum_ui = unrolling_iterable(enumerate(
-                zip(api_function.argtypes,
-                    [tp_name.startswith("w_") for tp_name in names])))
+        names = api_function.argnames
+        types_names_enum_ui = unrolling_iterable(enumerate(
+            zip(api_function.argtypes,
+                [tp_name.startswith("w_") for tp_name in names])))
 
-            @specialize.ll()
-            def unwrapper(space, *args):
-                from pypy.module.cpyext.pyobject import Py_DecRef, is_pyobj
-                from pypy.module.cpyext.pyobject import from_ref, as_pyobj
-                newargs = ()
-                keepalives = ()
-                assert len(args) == len(api_function.argtypes)
-                for i, (ARG, is_wrapped) in types_names_enum_ui:
-                    input_arg = args[i]
-                    if is_PyObject(ARG) and not is_wrapped:
-                        # build a 'PyObject *' (not holding a reference)
-                        if not is_pyobj(input_arg):
-                            keepalives += (input_arg,)
-                            arg = rffi.cast(ARG, as_pyobj(space, input_arg))
-                        else:
-                            arg = rffi.cast(ARG, input_arg)
-                    elif ARG == rffi.VOIDP and not is_wrapped:
-                        # unlike is_PyObject case above, we allow any kind of
-                        # argument -- just, if it's an object, we assume the
-                        # caller meant for it to become a PyObject*.
-                        if input_arg is None or isinstance(input_arg, W_Root):
-                            keepalives += (input_arg,)
-                            arg = rffi.cast(ARG, as_pyobj(space, input_arg))
-                        else:
-                            arg = rffi.cast(ARG, input_arg)
-                    elif (is_PyObject(ARG) or ARG == rffi.VOIDP) and is_wrapped:
-                        # build a W_Root, possibly from a 'PyObject *'
-                        if is_pyobj(input_arg):
-                            arg = from_ref(space, input_arg)
-                        else:
-                            arg = input_arg
+        @specialize.ll()
+        def unwrapper(space, *args):
+            from pypy.module.cpyext.pyobject import Py_DecRef, is_pyobj
+            from pypy.module.cpyext.pyobject import from_ref, as_pyobj
+            newargs = ()
+            keepalives = ()
+            assert len(args) == len(api_function.argtypes)
+            for i, (ARG, is_wrapped) in types_names_enum_ui:
+                input_arg = args[i]
+                if is_PyObject(ARG) and not is_wrapped:
+                    # build a 'PyObject *' (not holding a reference)
+                    if not is_pyobj(input_arg):
+                        keepalives += (input_arg,)
+                        arg = rffi.cast(ARG, as_pyobj(space, input_arg))
+                    else:
+                        arg = rffi.cast(ARG, input_arg)
+                elif ARG == rffi.VOIDP and not is_wrapped:
+                    # unlike is_PyObject case above, we allow any kind of
+                    # argument -- just, if it's an object, we assume the
+                    # caller meant for it to become a PyObject*.
+                    if input_arg is None or isinstance(input_arg, W_Root):
+                        keepalives += (input_arg,)
+                        arg = rffi.cast(ARG, as_pyobj(space, input_arg))
+                    else:
+                        arg = rffi.cast(ARG, input_arg)
+                elif (is_PyObject(ARG) or ARG == rffi.VOIDP) and is_wrapped:
+                    # build a W_Root, possibly from a 'PyObject *'
+                    if is_pyobj(input_arg):
+                        arg = from_ref(space, input_arg)
+                    else:
+                        arg = input_arg
 
-                            ## ZZZ: for is_pyobj:
-                            ## try:
-                            ##     arg = from_ref(space,
-                            ##                rffi.cast(PyObject, input_arg))
-                            ## except TypeError, e:
-                            ##     err = oefmt(space.w_TypeError,
-                            ##                 "could not cast arg to PyObject")
-                            ##     if not catch_exception:
-                            ##         raise err
-                            ##     state = space.fromcache(State)
-                            ##     state.set_exception(err)
-                            ##     if is_PyObject(restype):
-                            ##         return None
-                            ##     else:
-                            ##         return api_function.error_value
-                    else:
-                        # arg is not declared as PyObject, no magic
-                        arg = input_arg
-                    newargs += (arg, )
-                if not catch_exception:
-                    try:
-                        res = func(space, *newargs)
-                    finally:
-                        keepalive_until_here(*keepalives)
+                        ## ZZZ: for is_pyobj:
+                        ## try:
+                        ##     arg = from_ref(space,
+                        ##                rffi.cast(PyObject, input_arg))
+                        ## except TypeError, e:
+                        ##     err = oefmt(space.w_TypeError,
+                        ##                 "could not cast arg to PyObject")
+                        ##     if not catch_exception:
+                        ##         raise err
+                        ##     state = space.fromcache(State)
+                        ##     state.set_exception(err)
+                        ##     if is_PyObject(restype):
+                        ##         return None
+                        ##     else:
+                        ##         return api_function.error_value
                 else:
-                    # non-rpython variant
-                    assert not we_are_translated()
-                    try:
-                        res = func(space, *newargs)
-                    except OperationError as e:
-                        if not hasattr(api_function, "error_value"):
-                            raise
-                        state = space.fromcache(State)
-                        state.set_exception(e)
-                        if is_PyObject(restype):
-                            return None
-                        else:
-                            return api_function.error_value
-                    # 'keepalives' is alive here (it's not rpython)
-                    got_integer = isinstance(res, (int, long, float))
-                    assert got_integer == expect_integer, (
-                        'got %r not integer' % (res,))
-                return res
-            unwrapper.func = func
-            unwrapper.api_func = api_function
-            return unwrapper
+                    # arg is not declared as PyObject, no magic
+                    arg = input_arg
+                newargs += (arg, )
+            try:
+                return func(space, *newargs)
+            finally:
+                keepalive_until_here(*keepalives)
 
-        unwrapper_catch = make_unwrapper(True)
-        unwrapper_raise = make_unwrapper(False)
+        unwrapper.func = func
+        unwrapper.api_func = api_function
+
+        # ZZZ is this whole logic really needed???  It seems to be only
+        # for RPython code calling PyXxx() functions directly.  I would
+        # think that usually directly calling the function is clean
+        # enough now
+        def unwrapper_catch(space, *args):
+            try:
+                res = unwrapper(space, *args)
+            except OperationError as e:
+                if not hasattr(api_function, "error_value"):
+                    raise
+                state = space.fromcache(State)
+                state.set_exception(e)
+                if is_PyObject(restype):
+                    return None
+                else:
+                    return api_function.error_value
+            got_integer = isinstance(res, (int, long, float))
+            assert got_integer == expect_integer, (
+                'got %r not integer' % (res,))
+            return res
+
         if header is not None:
             if header == DEFAULT_HEADER:
                 FUNCTIONS[func_name] = api_function
             FUNCTIONS_BY_HEADER.setdefault(header, {})[func_name] = api_function
-        INTERPLEVEL_API[func_name] = unwrapper_catch # used in tests
-        return unwrapper_raise # used in 'normal' RPython code.
+        INTERPLEVEL_API[func_name] = unwrapper_catch  # used in tests
+        return unwrapper  # used in 'normal' RPython code.
     return decorate
 
 def cpython_struct(name, fields, forward=None, level=1):


More information about the pypy-commit mailing list