[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