def _remove(name: FFI.CData, env: FFI.CData, inherits) -> FFI.CData:
    rlib = openrlib.rlib
    with memorymanagement.rmemory() as rmemory:
        internal = rmemory.protect(
            rlib.Rf_install(conversion._str_to_cchar('.Internal')))
        remove = rmemory.protect(
            rlib.Rf_install(conversion._str_to_cchar('remove')))
        args = rmemory.protect(rlib.Rf_lang4(remove, name, env, inherits))
        call = rmemory.protect(rlib.Rf_lang2(internal, args))
        # TODO: use tryEval instead and catch errors.
        res = rlib.Rf_eval(call, rlib.R_GlobalEnv)
    return res
Beispiel #2
0
 def do_slot_assign(self, name: str, value) -> None:
     _rinterface._assert_valid_slotname(name)
     cchar = conversion._str_to_cchar(name)
     with memorymanagement.rmemory() as rmemory:
         name_r = rmemory.protect(openrlib.rlib.Rf_install(cchar))
         cdata = rmemory.protect(conversion._get_cdata(value))
         openrlib.rlib.R_do_slot_assign(self.__sexp__._cdata, name_r, cdata)
Beispiel #3
0
    def find(self, key: str, wantfun: int = False) -> Sexp:
        """Find an item, starting with this R environment.

        Raises a `KeyError` is the key cannot be found."""

        if not isinstance(key, str):
            raise TypeError('The key must be a non-empty string.')
        elif not len(key):
            raise ValueError('The key must be a non-empty string.')
        with memorymanagement.rmemory() as rmemory:
            symbol = rmemory.protect(
                openrlib.rlib.Rf_install(conversion._str_to_cchar(key)))
            if wantfun:
                # One would expect this to be like
                #   res = _rinterface._findfun(symbol, self.__sexp__._cdata)
                # but R's findfun will segfault if the symbol is not in
                # the environment. :/
                rho = self
                while rho.rid != emptyenv.rid:
                    res = _rinterface._findVarInFrame(symbol,
                                                      rho.__sexp__._cdata)
                    if _rinterface._TYPEOF(res) in (openrlib.rlib.CLOSXP,
                                                    openrlib.rlib.BUILTINSXP):
                        break
                    # TODO: move check of R_UnboundValue to _rinterface ?
                    res = openrlib.rlib.R_UnboundValue
                    rho = rho.enclos
            else:
                res = _rinterface._findvar(symbol, self.__sexp__._cdata)
        # TODO: move check of R_UnboundValue to _rinterface ?
        if res == openrlib.rlib.R_UnboundValue:
            raise KeyError("'%s' not found" % key)
        return res
Beispiel #4
0
 def do_slot(self, name: str) -> None:
     _rinterface._assert_valid_slotname(name)
     cchar = conversion._str_to_cchar(name)
     with memorymanagement.rmemory() as rmemory:
         name_r = rmemory.protect(openrlib.rlib.Rf_install(cchar))
         if not _rinterface._has_slot(self.__sexp__._cdata, name_r):
             raise LookupError(name)
         res = openrlib.rlib.R_do_slot(self.__sexp__._cdata, name_r)
     return res
def _geterrmessage() -> str:
    rlib = openrlib.rlib
    # TODO: use isString and installTrChar
    with memorymanagement.rmemory() as rmemory:
        symbol = rmemory.protect(
            rlib.Rf_install(conversion._str_to_cchar('geterrmessage')))
        geterrmessage = _findvar(symbol, rlib.R_GlobalEnv)
        call_r = rlib.Rf_lang1(geterrmessage)
        res = rmemory.protect(rlib.Rf_eval(call_r, rlib.R_GlobalEnv))
        res = _string_getitem(res, 0)
    return res
Beispiel #6
0
 def __getitem__(self, key: str) -> typing.Any:
     if not (isinstance(key, str) and len(key)):
         raise ValueError('The key must be a non-empty string.')
     with memorymanagement.rmemory() as rmemory:
         symbol = rmemory.protect(
             openrlib.rlib.Rf_install(conversion._str_to_cchar(key)))
         res = _rinterface._findVarInFrame(symbol, self.__sexp__._cdata)
     # TODO: move check of R_UnboundValue to _rinterface
     if res == openrlib.rlib.R_UnboundValue:
         raise KeyError("'%s' not found" % key)
     return res
def _choosefile(new, buf, n: int) -> int:
    try:
        res = choosefile(new)
    except Exception as e:
        logger.error(_CHOOSEFILE_EXCEPTION_LOG, str(e))
        res = None

    if res is None:
        return 0

    res_cdata = conversion._str_to_cchar(res)
    openrlib.ffi.memmove(buf, res_cdata, len(res_cdata))
    return len(res_cdata)
Beispiel #8
0
 def __setitem__(self, key: str, value) -> None:
     # TODO: move body to _rinterface-level function
     if not (isinstance(key, str) and len(key)):
         raise ValueError('The key must be a non-empty string.')
     if (self.__sexp__._cdata == openrlib.rlib.R_BaseEnv) or \
        (self.__sexp__._cdata == openrlib.rlib.R_EmptyEnv):
         raise ValueError('Cannot remove variables from the base or '
                          'empty environments.')
     # TODO: call to Rf_duplicate needed ?
     with memorymanagement.rmemory() as rmemory:
         symbol = rmemory.protect(
             openrlib.rlib.Rf_install(conversion._str_to_cchar(key)))
         cdata = rmemory.protect(conversion._get_cdata(value))
         cdata_copy = rmemory.protect(openrlib.rlib.Rf_duplicate(cdata))
         openrlib.rlib.Rf_defineVar(symbol, cdata_copy,
                                    self.__sexp__._cdata)
Beispiel #9
0
    def __getitem__(self, key: str) -> typing.Any:
        if not isinstance(key, str):
            raise TypeError('The key must be a non-empty string.')
        elif not len(key):
            raise ValueError('The key must be a non-empty string.')
        with memorymanagement.rmemory() as rmemory:
            key_cchar = conversion._str_to_cchar(key)
            symbol = rmemory.protect(openrlib.rlib.Rf_install(key_cchar))
            res = rmemory.protect(
                _rinterface.findvar_in_frame_wrap(self.__sexp__._cdata,
                                                  symbol))

        # TODO: move check of R_UnboundValue to _rinterface
        if res == openrlib.rlib.R_UnboundValue:
            raise KeyError("'%s' not found" % key)
        return res
Beispiel #10
0
    def find(self,
             key: str,
             wantfun: bool = False) -> Sexp:
        """Find an item, starting with this R environment.

        Raises a `KeyError` if the key cannot be found.

        This method is called `find` because it is somewhat different
        from the method :meth:`get` in Python mappings such :class:`dict`.
        This is looking for a key across enclosing environments, returning
        the first key found."""

        if not isinstance(key, str):
            raise TypeError('The key must be a non-empty string.')
        elif not len(key):
            raise ValueError('The key must be a non-empty string.')
        with memorymanagement.rmemory() as rmemory:
            key_cchar = conversion._str_to_cchar(key, 'utf-8')
            symbol = rmemory.protect(
                openrlib.rlib.Rf_install(key_cchar)
            )
            if wantfun:
                # One would expect this to be like
                #   res = _rinterface._findfun(symbol, self.__sexp__._cdata)
                # but R's findfun will segfault if the symbol is not in
                # the environment. :/
                rho = self
                while rho.rid != emptyenv.rid:
                    res = rmemory.protect(
                        _rinterface.findvar_in_frame_wrap(
                            rho.__sexp__._cdata, symbol
                        )
                    )
                    if _rinterface._TYPEOF(res) in (openrlib.rlib.CLOSXP,
                                                    openrlib.rlib.BUILTINSXP):
                        break
                    # TODO: move check of R_UnboundValue to _rinterface ?
                    res = openrlib.rlib.R_UnboundValue
                    rho = rho.enclos
            else:
                res = _rinterface._findvar(symbol, self.__sexp__._cdata)
        # TODO: move check of R_UnboundValue to _rinterface ?
        if res == openrlib.rlib.R_UnboundValue:
            raise KeyError("'%s' not found" % key)
        return res
Beispiel #11
0
    def __delitem__(self, key: str) -> None:
        # Testing that key is a non-empty string is implicitly
        # performed when checking that the key is in the environment.
        if key not in self:
            raise KeyError("'%s' not found" % key)

        if self.__sexp__ == baseenv.__sexp__:
            raise ValueError('Values from the R base environment '
                             'cannot be removed.')
        # TODO: also check it is not R_EmpyEnv or R_BaseNamespace
        if self.is_locked():
            ValueError('Cannot remove an item from a locked ' 'environment.')

        with memorymanagement.rmemory() as rmemory:
            key_cdata = rmemory.protect(
                openrlib.rlib.Rf_mkString(conversion._str_to_cchar(key)))
            _rinterface._remove(
                key_cdata, self.__sexp__._cdata,
                openrlib.rlib.Rf_ScalarLogical(openrlib.rlib.FALSE))
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
def build_rcall(rfunction, args=[], kwargs=[]):
    rlib = openrlib.rlib
    with memorymanagement.rmemory() as rmemory:
        rcall = rmemory.protect(rlib.Rf_allocList(len(args) + len(kwargs) + 1))
        _SET_TYPEOF(rcall, rlib.LANGSXP)
        rlib.SETCAR(rcall, rfunction)
        item = rlib.CDR(rcall)
        for val in args:
            cdata = rmemory.protect(conversion._get_cdata(val))
            rlib.SETCAR(item, cdata)
            item = rlib.CDR(item)
        for key, val in kwargs:
            if key is not None:
                _assert_valid_slotname(key)
                rlib.SET_TAG(item,
                             rlib.Rf_install(conversion._str_to_cchar(key)))
            cdata = rmemory.protect(conversion._get_cdata(val))
            rlib.SETCAR(item, cdata)
            item = rlib.CDR(item)
    return rcall