def prase_text_complete(text): status = ffi.new("ParseStatus[1]") s = rstring_p(text) orig_stderr = sys.stderr sys.stderr = None with protected(s): lib.R_ParseVector(s, -1, status, lib.R_NilValue) sys.stderr = orig_stderr return status[0] != 2
def setup_rstart(rhome, args): rstart = ffi.new("Rstart") _protected["rstart"] = rstart SA_NORESTORE = 0 SA_RESTORE = 1 # SA_DEFAULT = 2 SA_NOSAVE = 3 SA_SAVE = 4 SA_SAVEASK = 5 # SA_SUICIDE = 6 lib.R_DefParams(rstart) rstart.R_Quiet = "--quiet" in args rstart.R_Slave = "--slave" in args rstart.R_Interactive = 1 rstart.R_Verbose = "--verbose" in args rstart.LoadSiteFile = "--no-site-file" not in args rstart.LoadInitFile = "--no-init-file" not in args if "--no-restore" in args: rstart.RestoreAction = SA_NORESTORE else: rstart.RestoreAction = SA_RESTORE if "--no-save" in args: rstart.SaveAction = SA_NOSAVE elif "--save" in args: rstart.SaveAction = SA_SAVE else: rstart.SaveAction = SA_SAVEASK rhome = ffi.new("char[]", rhome.encode("utf-8")) _protected["rhome"] = rhome rstart.rhome = rhome home = ffi.new("char[]", ffi.string(lib.getRUser())) _protected["home"] = home rstart.home = home rstart._ReadConsole = ffi.addressof(lib, "cb_read_console_interruptible") rstart._WriteConsole = ffi.NULL rstart.CallBack = ffi.addressof(lib, "cb_polled_events_interruptible") rstart.ShowMessage = ffi.addressof(lib, "cb_show_message") rstart.YesNoCancel = ffi.addressof(lib, "cb_yes_no_cancel") rstart.Busy = ffi.addressof(lib, "cb_busy") # we cannot get it to RGui, otherwise `do_system` will clear the standard handlers rstart.CharacterMode = 1 # RTerm rstart.WriteConsoleEx = ffi.addressof(lib, "cb_write_console_capturable") lib.R_SetParams(rstart)
def rparse_p(s): ensure_initialized() status = ffi.new("ParseStatus[1]") s = lib.Rf_mkString(utf8tosystem(s)) with protected(s): with capture_console(): # need to capture stderr ret = lib.R_ParseVector(s, -1, status, lib.R_NilValue) if status[0] != lib.PARSE_OK: err = read_stderr().strip() or "Error" raise RuntimeError("{}".format(err)) return ret
def test_yes_no_cancel_exceptions(mocker, gctorture): count = [0] def throw_on_first_run(_): if count[0] == 0: count[0] += 1 raise Exception() else: return "y" mocker.patch("rchitect.setup.ask_input", side_effect=throw_on_first_run) ret = lib.cb_yes_no_cancel(ffi.new("char[10]", b"> ")) assert ret == 1 mocker.patch("rchitect.setup.ask_input", side_effect=EOFError()) ret = lib.cb_yes_no_cancel(ffi.new("char[10]", b"> ")) assert ret == 0 mocker.patch("rchitect.setup.ask_input", side_effect=KeyboardInterrupt()) ret = lib.cb_yes_no_cancel(ffi.new("char[10]", b"> ")) assert ret == 0
def reval_p(s, envir=None): ensure_initialized() with protected(s): if envir: # `sys.frame()` doesn't work with R_tryEval as it doesn't create R stacks, # we use `base::eval` instead. ret = rcall_p(("base", "eval"), s, _envir=envir) else: ret = lib.R_NilValue status = ffi.new("int[1]") with capture_console(): # need to capture stderr for i in range(0, lib.Rf_length(s)): ret = lib.R_tryEval(lib.VECTOR_ELT(s, i), lib.R_GlobalEnv, status) if status[0] != 0: err = read_stderr().strip() or "Error" raise RuntimeError("{}".format(err)) return ret
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
def rcall_p(f, *args, **kwargs): ensure_initialized() _envir = extract(kwargs, "_envir") _asis = extract(kwargs, "_asis") if _envir: _envir = unbox(_envir) else: _envir = lib.R_GlobalEnv with protected(f, _envir): with sexp_args(args, kwargs, _asis) as (a, k): with capture_console(): # need to capture stderr status = ffi.new("int[1]") lang = rlang_p(f, *a, **k) with protected(lang): val = lib.R_tryEval(lang, _envir, status) if status[0] != 0: err = read_stderr().strip() or "Error" raise RuntimeError("{}".format(err)) return val
def test_yes_no_cancel(mocker, gctorture): for (a, v) in [('y', 1), ('n', 2), ('c', 0)]: mocker.patch("rchitect.setup.ask_input", return_value=a) ret = lib.cb_yes_no_cancel(ffi.new("char[10]", b"> ")) assert ret == v mocker.resetall()
def init(args=None, register_signal_handlers=None): if not args: args = ["rchitect", "--quiet", "--no-save"] if register_signal_handlers is None: register_signal_handlers = os.environ.get( "RCHITECT_REGISTER_SIGNAL_HANDLERS", "1") == "1" rhome = Rhome() # microsoft python doesn't load DLL's from PATH # we will need to open the DLL's directly in _libR_load ensure_path(rhome) libR_loaded = lib.Rf_initialize_R != ffi.NULL if not libR_loaded: # `system2utf8` may not work before `Rf_initialize_R` because locale may not be set if not lib._libR_load(rhome.encode("utf-8")): raise Exception(load_lib_error()) if not lib._libR_load_symbols(): raise Exception(load_symbol_error()) # _libR_is_initialized only works after _libR_load is run. if not lib._libR_is_initialized(): _argv = [ffi.new("char[]", a.encode("utf-8")) for a in args] argv = ffi.new("char *[]", _argv) if sys.platform.startswith("win"): if register_signal_handlers: lib.Rf_initialize_R(len(argv), argv) setup_rstart(rhome, args) else: # Rf_initialize_R will set handler for SIGINT # we need to workaround it lib.R_SignalHandlers_t[0] = 0 setup_rstart(rhome, args) lib.R_set_command_line_arguments(len(argv), argv) lib.GA_initapp(0, ffi.NULL) lib.setup_Rmainloop() # require R 4.0 if lib.EmitEmbeddedUTF8_t != ffi.NULL: lib.EmitEmbeddedUTF8_t[0] = 1 else: lib.R_SignalHandlers_t[0] = register_signal_handlers lib.Rf_initialize_R(len(argv), argv) setup_unix_callbacks() lib.setup_Rmainloop() if not libR_loaded: if not lib._libR_load_constants(): raise Exception(load_constant_error()) lib._libR_setup_xptr_callback() from rchitect.py_tools import inject_py_tools inject_py_tools() if os.environ.get("RCHITECT_RETICULATE_CONFIG", "1") != "0": from rchitect import reticulate reticulate.configure()
def sexp(_, s): # noqa c = ffi.new("Rcomplex*") c.r = s.real c.i = s.imag return lib.Rf_ScalarComplex(c[0])