Author: Ronan Lamy <[email protected]>
Branch: api_func-refactor
Changeset: r89453:8d6b8422c3d2
Date: 2017-01-09 19:06 +0000
http://bitbucket.org/pypy/pypy/changeset/8d6b8422c3d2/
Log: Move unwrapper creation to a method of ApiFunction()
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
@@ -329,6 +329,53 @@
wrapper.c_name = cpyext_namespace.uniquename(self.c_name)
return wrapper
+ def get_unwrapper(self):
+ names = self.argnames
+ argtypesw = zip(self.argtypes,
+ [_name.startswith("w_") for _name in self.argnames])
+ types_names_enum_ui = unrolling_iterable(enumerate(argtypesw))
+
+ @specialize.ll()
+ def unwrapper(space, *args):
+ from pypy.module.cpyext.pyobject import is_pyobj
+ from pypy.module.cpyext.pyobject import from_ref, as_pyobj
+ newargs = ()
+ keepalives = ()
+ assert len(args) == len(self.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
+ else:
+ # arg is not declared as PyObject, no magic
+ arg = input_arg
+ newargs += (arg, )
+ try:
+ return self.callable(space, *newargs)
+ finally:
+ keepalive_until_here(*keepalives)
+ return unwrapper
+
def get_c_restype(self, c_writer):
return c_writer.gettype(self.restype).replace('@', '').strip()
@@ -452,67 +499,7 @@
c_name=c_name, gil=gil,
result_borrowed=result_borrowed,
result_is_ll=result_is_ll)
- 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
-
- ## 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, )
- try:
- return func(space, *newargs)
- finally:
- keepalive_until_here(*keepalives)
-
+ unwrapper = api_function.get_unwrapper()
unwrapper.func = func
unwrapper.api_func = api_function
return unwrapper
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit