-
(I'm using pyo3 0.13.2, Rust 1.48, Python 3.7, on Linux) I'm embedding Python as a scripting interface within an application. There's an input where the user can enter some code, and it'll run it with a few additional globals present. I have things mostly working - but when actually running the users code with pyo3's fn main() {
use pyo3::{
prelude::*,
types::{PyBytes, PyDict},
};
let gil = pyo3::Python::acquire_gil();
let py = gil.python();
let locals = PyDict::new(py);
locals.set_item("dummy_api", 123);
py.run(
r#"
print(dummy_api)
eg = 'Confusing!'
def func():
print(eg)
func()
"#,
None,
Some(locals),
)
.map_err(|e| e.print_and_set_sys_last_vars(py))
.unwrap();
} This executes but results in a confusing Traceback (most recent call last):
File "<string>", line 6, in <module>
File "<string>", line 5, in func
NameError: name 'eg' is not defined Eventually I noticed this sentence in the Python docs about eval:
So the above Rust code is identical to doing either of these: exec(open("test.py").read(), None, {'a': 123})
exec(open("test.py").read(), globals(), {'a': 123}) Fair enough, all is well so far. The problemWhat I actually want to do is the equivalent to this Python: exec(code_snippet, {'dummy_api': 123}, None) however if I do this in pyo3, it cannot find builtins like
Whereas pyo3 does not automatically insert the builtins in globals My questionsThis is all a very long way of asking two things:
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Ah, can get let exec_globals = [
("__builtins__", py.import("__main__")?.getattr("__builtins__")?),
("dummy_api", ...),
]
.into_py_dict(py);
py.run(&code_string, Some(&exec_globals), None)?; |
Beta Was this translation helpful? Give feedback.
-
Yeah, you need to import |
Beta Was this translation helpful? Give feedback.
Yeah, you need to import
__main__
to do so.Maybe it's beneficial to note that in the FAQ section of the guide.