PyOxidizer
PyOxidizer copied to clipboard
Segmentation fault
Issue
Like a few others before me, I was getting a segmentation fault when trying to embed python within rust. But the Rust compiler was not catching the error.
Discussion
After a lot of debugging, I believe the issue was the lifetime for the Result<PyAny, PyError>.
The easiest solution I came to was to keep the config, the interpreter, and the consumer all within the same function.
I had tried defining the lifetimes of variables, but that didn't work.
async fn runner(input: &str) -> String {
let mut config: OxidizedPythonInterpreterConfig<'_> = OxidizedPythonInterpreterConfig::default();
config.interpreter_config.isolated = Some(true);
config.interpreter_config.filesystem_encoding = Some("utf-8".to_string());
config.set_missing_path_configuration = false;
config.interpreter_config.parse_argv = Some(false);
config.argv = Some(vec!["python".into()]);
config.interpreter_config.executable = Some("python".into());
let embeded_python = MainPythonInterpreter::new(config).unwrap();
let py_ai: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/python/ai.py"));
let from_python: Result<Py<PyAny>, PyErr> = embeded_python.with_gil(|py: Python<'_>| -> PyResult<Py<PyAny>> {
let app: Py<PyAny> = PyModule::from_code(py, py_ai, "", "")?
.getattr("run")?.into();
app.call1(py, (input,))
});
match from_python {
Ok(result) => {
return result.to_string();
},
Err(err) => {
eprintln!("Error: {:?}", err);
return String::new();
}
}
}
NOTE The above configs worked for me. The official docs do not provide any examples of working configs.
Recommendation
Learn from my folly. Hopefully this helps others who are trying to embed python but do not have example configurations.