예제 #1
0
    def rcall(self,
              keyvals,
              environment: typing.Optional[SexpEnvironment] = None):
        """Call/evaluate an R function.

        Args:
        - keyvals: a sequence of key/value (name/parameter) pairs. A
          name/parameter that is None will indicated an unnamed parameter.
          Like in R, keys/names do not have to be unique, partial matching
          can be used, and named/unnamed parameters can occur at any position
          in the sequence.
        - environment: an optional R environment to evaluate the function.
        """
        # TODO: check keyvals are pairs ?
        if environment is None:
            environment = _evaluation_context
        assert isinstance(environment, SexpEnvironment)
        error_occured = _rinterface.ffi.new('int *', 0)

        with memorymanagement.rmemory() as rmemory:
            call_r = rmemory.protect(
                _rinterface.build_rcall(self.__sexp__._cdata, [], keyvals))
            res = rmemory.protect(
                openrlib.rlib.R_tryEval(call_r, environment.__sexp__._cdata,
                                        error_occured))
            if error_occured[0]:
                raise embedded.RRuntimeError(_rinterface._geterrmessage())
        return res
def findvar_in_frame(rho, symbol):
    """Safer wrapper around Rf_findVarInFrame()

    Run the function Rf_findVarInFrame() in R's C-API through
    R_ToplevelExec().

    Note: All arguments, and the object returned, are C-level
    R objects.

    Args:
    - rho: An R environment.
    - symbol: An R symbol (as returned by Rf_install())
    Returns:
    The object found.
    """
    # One would expect this to be like
    #   res = _rinterface._findfun(symbol, self.__sexp__._cdata)
    # but R's findfun will segfault if an error occurs while
    # accessing the matching object in the environment.
    exec_data = ffi.new('struct RPY2_sym_env_data *',
                        [symbol, rho, openrlib.rlib.R_NilValue])
    _ = openrlib.rlib.R_ToplevelExec(openrlib.rlib._exec_findvar_in_frame,
                                     exec_data)
    if _ != openrlib.rlib.TRUE:
        raise embedded.RRuntimeError('R C-API Rf_findVarInFrame()')
    return exec_data.data
예제 #3
0
 def __call__(self, *args, **kwargs) -> Sexp:
     error_occured = _rinterface.ffi.new('int *', 0)
     with memorymanagement.rmemory() as rmemory:
         call_r = rmemory.protect(
             _rinterface.build_rcall(self.__sexp__._cdata, args,
                                     kwargs.items()))
         res = rmemory.protect(
             openrlib.rlib.R_tryEval(call_r, globalenv.__sexp__._cdata,
                                     error_occured))
         if error_occured[0]:
             raise embedded.RRuntimeError(_rinterface._geterrmessage())
     return res
예제 #4
0
 def rcall(self, keyvals, environment: SexpEnvironment):
     # TODO: check keyvals are pairs ?
     assert isinstance(environment, SexpEnvironment)
     error_occured = _rinterface.ffi.new('int *', 0)
     with memorymanagement.rmemory() as rmemory:
         call_r = rmemory.protect(
             _rinterface.build_rcall(self.__sexp__._cdata, [], keyvals))
         res = rmemory.protect(
             openrlib.rlib.R_tryEval(call_r, environment.__sexp__._cdata,
                                     error_occured))
         if error_occured[0]:
             raise embedded.RRuntimeError(_rinterface._geterrmessage())
     return res
def unserialize(cdata: FFI.CData, cdata_env: FFI.CData) -> FFI.CData:
    """Unserialize an R string to an R object.

    Note that the R object returned is *not* protected from
    the R garbage collection."""

    rlib = openrlib.rlib

    with memorymanagement.rmemory() as rmemory:
        sym_unserialize = rmemory.protect(
            rlib.Rf_install(conversion._str_to_cchar('unserialize')))
        func_unserialize = rmemory.protect(
            _findfun(sym_unserialize, rlib.R_BaseEnv))
        r_call = rmemory.protect(rlib.Rf_lang2(func_unserialize, cdata))
        error_occured = ffi.new('int *', 0)
        res = rlib.R_tryEval(r_call, cdata_env, error_occured)
        if error_occured[0]:
            raise embedded.RRuntimeError(_geterrmessage())

        return res