def wrap_next(space, w_self, w_args, func): from pypy.module.cpyext.api import generic_cpy_call_expect_null func_target = rffi.cast(iternextfunc, func) check_num_args(space, w_args, 0) w_res = generic_cpy_call_expect_null(space, func_target, w_self) if not w_res and not PyErr_Occurred(space): raise OperationError(space.w_StopIteration, space.w_None) return w_res
def call(self, space, w_self, __args__): from pypy.module.cpyext.api import generic_cpy_call_expect_null self.check_args(__args__, 0) func = self.get_func_to_call() func_target = rffi.cast(iternextfunc, func) w_res = generic_cpy_call_expect_null(space, func_target, w_self) if not w_res and not PyErr_Occurred(space): raise OperationError(space.w_StopIteration, space.w_None) return w_res
def generic_cpy_call(space, func, *args): boxed_args = () to_decref = [] assert len(args) == len(FT.ARGS) for i, ARG in unrolling_arg_types: arg = args[i] if is_PyObject(ARG): if arg is None: boxed_args += (lltype.nullptr(PyObject.TO),) elif isinstance(arg, W_Root): ref = make_ref(space, arg) boxed_args += (ref,) if decref_args: to_decref.append(ref) else: boxed_args += (arg,) else: boxed_args += (arg,) try: # create a new container for borrowed references state = space.fromcache(RefcountState) old_container = state.swap_borrow_container(None) try: # Call the function result = call_external_function(func, *boxed_args) finally: state.swap_borrow_container(old_container) if is_PyObject(RESULT_TYPE): if result is None: ret = result elif isinstance(result, W_Root): ret = result else: ret = from_ref(space, result) # The object reference returned from a C function # that is called from Python must be an owned reference # - ownership is transferred from the function to its caller. if result: Py_DecRef(space, result) # Check for exception consistency has_error = PyErr_Occurred(space) is not None has_result = ret is not None if has_error and has_result: raise OperationError(space.w_SystemError, space.wrap( "An exception was set, but function returned a value")) elif not expect_null and not has_error and not has_result: raise OperationError(space.w_SystemError, space.wrap( "Function returned a NULL result without setting an exception")) if has_error: state = space.fromcache(State) state.check_and_raise_exception() return ret return result finally: if decref_args: for ref in to_decref: Py_DecRef(space, ref)