Ejemplo n.º 1
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
Ejemplo n.º 2
0
 def __getitem__(self, i: Union[int, slice]) -> Sexp:
     cdata = self.__sexp__._cdata
     rlib = openrlib.rlib
     if isinstance(i, int):
         # R-exts says that it is converted to a VECSXP when subsetted.
         i_c = _rinterface._python_index_to_c(cdata, i)
         item_cdata = rlib.Rf_nthcdr(cdata, i_c)
         with memorymanagement.rmemory() as rmemory:
             res_cdata = rmemory.protect(
                 rlib.Rf_allocVector(RTYPES.VECSXP, 1))
             rlib.SET_VECTOR_ELT(
                 res_cdata,
                 0,
                 rlib.CAR(
                     item_cdata
                 ))
             res_name = rmemory.protect(
                 rlib.Rf_allocVector(RTYPES.STRSXP, 1))
             item_cdata_name = rlib.PRINTNAME(rlib.TAG(item_cdata))
             if _rinterface._TYPEOF(item_cdata_name) != rlib.NILSXP:
                 rlib.SET_STRING_ELT(
                     res_name,
                     0,
                     item_cdata_name)
                 rlib.Rf_namesgets(res_cdata, res_name)
             res = conversion._cdata_to_rinterface(res_cdata)
     elif isinstance(i, slice):
         iter_indices = range(*i.indices(len(self)))
         n = len(iter_indices)
         with memorymanagement.rmemory() as rmemory:
             res_cdata = rmemory.protect(
                 rlib.Rf_allocVector(
                     self._R_TYPE, n)
             )
             iter_res_cdata = res_cdata
             prev_i = 0
             lst_cdata = self.__sexp__._cdata
             for i in iter_indices:
                 if i >= len(self):
                     raise IndexError('index out of range')
                 lst_cdata = rlib.Rf_nthcdr(lst_cdata, i - prev_i)
                 prev_i = i
                 rlib.SETCAR(iter_res_cdata,
                             rlib.CAR(lst_cdata))
                 rlib.SET_TAG(iter_res_cdata,
                              rlib.TAG(lst_cdata))
                 iter_res_cdata = rlib.CDR(iter_res_cdata)
             res = conversion._cdata_to_rinterface(res_cdata)
     else:
         raise TypeError(
             'Indices must be integers or slices, not %s' % type(i))
     return res
Ejemplo n.º 3
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
Ejemplo n.º 4
0
 def typeof(self) -> RTYPES:
     return RTYPES(_rinterface._TYPEOF(self.__sexp__._cdata))