From b35e7222fee6bcee76df64975b988be6c2e0655b Mon Sep 17 00:00:00 2001 From: Tomasz Kalinowski Date: Tue, 8 Oct 2024 10:45:06 -0400 Subject: [PATCH] rewrite `py_activate_virtualenv()` to run `activate_this.py` isolated Related: https://github.com/astral-sh/uv/pull/7978 --- src/python.cpp | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/python.cpp b/src/python.cpp index 31bd3f6b9..680a47a14 100644 --- a/src/python.cpp +++ b/src/python.cpp @@ -2725,30 +2725,28 @@ extern "C" PyObject* initializeRPYCall(void) { // [[Rcpp::export]] -void py_activate_virtualenv(const std::string& script) -{ +void py_activate_virtualenv(const std::string& script) { - // get main dict - PyObject* main = PyImport_AddModule("__main__"); - PyObject* mainDict = PyModule_GetDict(main); + // import runpy + PyObjectPtr runpy_module(PyImport_ImportModule("runpy")); + if (runpy_module.is_null()) + throw PythonException(py_fetch_error()); - // inject __file__ - PyObjectPtr file(as_python_str(script)); - int res = PyDict_SetItemString(mainDict, "__file__", file); - if (res != 0) + // get ref to runpy.run_path() + PyObjectPtr run_path_func(PyObject_GetAttrString(runpy_module, "run_path")); + if (run_path_func.is_null()) throw PythonException(py_fetch_error()); - // read the code in the script - std::ifstream ifs(script.c_str()); - if (!ifs) - stop("Unable to open file '%s' (does it exist?)", script); - std::string code((std::istreambuf_iterator(ifs)), - (std::istreambuf_iterator())); + // make a Python string of the script path + PyObjectPtr py_script_path(PyUnicode_FromString(script.c_str())); + if (py_script_path.is_null()) + throw PythonException(py_fetch_error()); - // run string - PyObjectPtr runRes(PyRun_StringFlags(code.c_str(), Py_file_input, mainDict, NULL, NULL)); - if (runRes.is_null()) + // Call runpy.run_path(script_path) function + PyObjectPtr result(PyObject_CallFunctionObjArgs(run_path_func, py_script_path.get(), NULL)); + if (result.is_null()) throw PythonException(py_fetch_error()); + } void trace_print(int threadId, PyFrameObject *frame) {