def py_object(*args, **kwargs): if len(args) == 1: lib.Rf_protect(args[0]) try: with sexp_context(**kwargs): return robject("PyObject", rcopy(args[0])) finally: lib.Rf_unprotect(1) elif len(args) == 2: lib.Rf_protect(args[1]) try: with sexp_context(**kwargs): return robject("PyObject", rcopy(rcopy(object, args[0]), args[1])) finally: lib.Rf_unprotect(1)
def sexp_args(args, kwargs, asis=False): nprotect = 0 try: for a in args: if isinstance(a, SEXP): lib.Rf_protect(a) nprotect += 1 for _, v in kwargs.items(): if isinstance(v, SEXP): lib.Rf_protect(v) nprotect += 1 _args = [] for a in args: if not isinstance(a, SEXP): a = sexp_as_py_object(a) if asis else sexp(a) lib.Rf_protect(a) nprotect += 1 _args.append(a) _kwargs = {} for k, v in kwargs.items(): if not isinstance(v, SEXP): v = sexp_as_py_object(v) if asis else sexp(v) lib.Rf_protect(v) nprotect += 1 _kwargs[k] = v yield _args, _kwargs finally: lib.Rf_unprotect(nprotect)
def py_tuple(*args): narg = len(args) for a in args: lib.Rf_protect(a) try: return tuple([rcopy(a) for a in args]) finally: lib.Rf_unprotect(narg)
def py_dict(**kwargs): narg = len(kwargs) for key in kwargs: lib.Rf_protect(kwargs[key]) try: return {key: rcopy(kwargs[key]) for key in kwargs} finally: lib.Rf_unprotect(narg)
def new_xptr_p(x): h = ffi.new_handle(x) hp = ffi.cast("void*", h) _global_set[hp] = h s = lib.R_MakeExternalPtr(hp, lib.R_NilValue, lib.R_NilValue) lib.Rf_protect(s) lib.R_RegisterCFinalizerEx(s, ffi.addressof(lib, "xptr_finalizer"), 1) lib.Rf_unprotect(1) return s
def sexp(_, f): # noqa with sexp_context() as context: asis = context.get("asis", False) convert = context.get("convert", False) with sexp_context(asis=asis, convert=convert): p = sexp(RClass("function"), f) lib.Rf_protect(p) setclass(p, ["PyCallable", "PyObject"]) lib.Rf_unprotect(1) return p
def protected(*args): nprotect = 0 for a in args: if isinstance(a, SEXP): lib.Rf_protect(a) nprotect += 1 try: yield finally: lib.Rf_unprotect(nprotect)
def py_set_item(obj, key, value): lib.Rf_protect(obj) lib.Rf_protect(key) lib.Rf_protect(value) pyo = rcopy(object, obj) try: pyo[rcopy(key)] = rcopy(value) finally: lib.Rf_unprotect(3) return pyo
def py_set_attr(obj, key, value): lib.Rf_protect(obj) lib.Rf_protect(key) lib.Rf_protect(value) pyo = rcopy(object, obj) try: setattr(pyo, rcopy(key), rcopy(value)) finally: lib.Rf_unprotect(3) return pyo
def py_get_item2(robj, rkey): lib.Rf_protect(robj) lib.Rf_protect(rkey) nprotect = 2 try: obj = rcopy(robj) key = rcopy(rkey) convert_p = getattrib_p(robj, "convert") lib.Rf_protect(convert_p) nprotect += 1 convert = rcopy(convert_p) with sexp_context(convert=convert): val = py_get_item(obj, key) return sexp(val) if convert else sexp_as_py_object(val) finally: lib.Rf_unprotect(nprotect)
def sexp(_, f): # noqa if hasattr(f, "__robject__"): # R function wrapped by python function return unbox(f.__robject__) with sexp_context() as context: nprotect = 0 invisible = context.get('invisible', False) env = new_env_p() lib.Rf_protect(env) nprotect += 1 fp = new_xptr_p(f) lib.Rf_protect(fp) nprotect += 1 setclass(fp, "PyObject") lib.Rf_defineVar(rsym_p("pointer"), fp, env) dotlist = rlang("list", lib.R_DotsSymbol) xptr_callback = rstring_p("_libR_xptr_callback") lib.Rf_protect(xptr_callback) nprotect += 1 body = rlang_p(".Call", xptr_callback, rsym_p("pointer"), dotlist, rlogical(context.get("asis", False)), rlogical(context.get("convert", True))) lib.Rf_protect(body) nprotect += 1 if invisible: body = rlang_p("invisible", body) lib.Rf_protect(body) nprotect += 1 lang = rlang_p(rsym_p("function"), sexp_dots(), body) lib.Rf_protect(lang) nprotect += 1 status = ffi.new("int[1]") val = lib.R_tryEval(lang, env, status) lib.Rf_protect(val) nprotect += 1 setattrib(val, "py_object", fp) lib.Rf_unprotect(nprotect) return val