Expose PyEval_EvalCodeEx e.g. as Python::run_ex
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 16.2k
- Forks
- 1k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 66
Description
I have a use-case where I need to evaluate some code and set args. It would be possible by exposing PyEval_EvalCodeEx e.g. as a Python::run_ex method. Or perhaps call it run_with_args?
I am trying to implement it myself for contribution to pyo3, but I am a little stuck on the correct method signature and type conversions. Here is what I have so far. It is mostly just copied from Python::run_code:
fn run_code_ex(
self,
code: &str,
start: c_int,
globals: Option<&PyDict>,
locals: Option<&PyDict>,
args: Option<&PyTuple>,
kws: Option<&PyDict>,
defs: Option<&PyTuple>,
kwdefs: Option<&PyDict>,
closure: Option<&PyTuple> // TODO no idea what this is. docs say 'a closure tuple of cells.'
) -> PyResult<&'py PyAny> {
let code = CString::new(code)?;
unsafe {
let mptr = ffi::PyImport_AddModule("__main__\0".as_ptr() as *const _);
if mptr.is_null() {
return Err(PyErr::fetch(self));
}
let globals = globals
.map(AsPyPointer::as_ptr)
.unwrap_or_else(|| ffi::PyModule_GetDict(mptr));
let locals = locals.map(AsPyPointer::as_ptr).unwrap_or(globals);
let args = args.map(AsPyPointer::as_ptr).unwrap_or(std::ptr::null_mut());
let code_obj = ffi::Py_CompileString(code.as_ptr(), "<string>\0".as_ptr() as _, start);
if code_obj.is_null() {
return Err(PyErr::fetch(self));
}
let res_ptr = ffi::PyEval_EvalCodeEx(
code_obj,
globals,
locals,
args, // ERROR: expecting PyObject *const *args
0, // TODO
std::ptr::null_mut(), // TODO
0, // TODO
std::ptr::null_mut(), // TODO
0, // TODO
std::ptr::null_mut(), // TODO
std::ptr::null_mut(), // TODO
);
ffi::Py_DECREF(code_obj);
self.from_owned_ptr_or_err(res_ptr)
}
}
The error at the args line looks like this:
= note: expected raw pointer `*mut *mut pyo3_ffi::PyObject`
found raw pointer `*mut pyo3_ffi::PyObject`
It seems like I am passing a pointer to the tuple object, but the method is expecting an array of the tuple elements?
A bit of guidance would be appreciated :)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start from the existing Python::run_code implementation and the PyEval_EvalCodeEx documentation linked in the issue. Check the FFI signature and the conversions needed for the argument tuple, keyword arguments, defaults, keyword defaults, and closure; done means exposing the requested evaluation capability with a settled method signature.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust
- Domain
- api
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100