Skip to content

Commit 9beb442

Browse files
committed
Add examples showcasing how to embed RustPython in Rust applications
1 parent bc121d7 commit 9beb442

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ cargo build --release --target wasm32-wasi --features="freeze-stdlib"
7272

7373
> Note: we use the `freeze-stdlib` to include the standard library inside the binary.
7474
75+
76+
## Embedding RustPython into your Rust Applications
77+
78+
Interested in exposing Python scripting in an application written in Rust,
79+
perhaps to allow quickly tweaking logic where Rust's compile times would be inhibitive?
80+
Then `examples/hello_embed.rs` and `examples/mini_repl.rs` may be of some assistance.
81+
7582
## Disclaimer
7683

7784
RustPython is in a development phase and should not be used in production or a

examples/hello_embed.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use rustpython_compiler::compile;
2+
use rustpython_vm::{pyobject::PyResult, PySettings, VirtualMachine};
3+
4+
fn main() -> PyResult<()> {
5+
let vm = VirtualMachine::new(PySettings::default());
6+
7+
let scope = vm.new_scope_with_builtins();
8+
9+
let code_obj = vm
10+
.compile(
11+
r#"print("Hello World!")"#,
12+
compile::Mode::Exec,
13+
"<embedded>".to_string(),
14+
)
15+
.map_err(|err| vm.new_syntax_error(&err))?;
16+
17+
vm.run_code_obj(code_obj, scope)?;
18+
19+
Ok(())
20+
}

examples/mini_repl.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
///! This example show cases a very simple REPL.
2+
///! While a much better REPL can be found in ../src/shell,
3+
///! This much smaller REPL is still a useful example because it showcases inserting
4+
///! values and functions into the Python runtime's scope, and showcases use
5+
///! of the compilation mode "Single".
6+
///! Note that in particular this REPL does a horrible job of showing users their errors
7+
///! (instead it simply crashes).
8+
use rustpython_compiler::compile;
9+
use rustpython_vm::{pyobject::PyResult, PySettings, VirtualMachine};
10+
// this needs to be in scope in order to insert things into scope.globals
11+
use rustpython_vm::pyobject::ItemProtocol;
12+
13+
fn main() -> PyResult<()> {
14+
let mut on = true;
15+
16+
let mut input = String::with_capacity(50);
17+
let stdin = std::io::stdin();
18+
19+
let vm = VirtualMachine::new(PySettings::default());
20+
let scope = vm.new_scope_with_builtins();
21+
22+
// typing `quit()` is too long, let's make `on(False)` work instead.
23+
scope
24+
.globals
25+
.set_item(
26+
"on",
27+
vm.context().new_rustfunc({
28+
let on: *mut bool = &mut on;
29+
move |b: bool, _: &VirtualMachine| unsafe { *on = b }
30+
}),
31+
&vm,
32+
)
33+
.unwrap();
34+
35+
while on {
36+
input.clear();
37+
stdin.read_line(&mut input).unwrap();
38+
39+
let code_obj = vm
40+
.compile(&input, compile::Mode::Single, "<embedded>".to_string())
41+
.map_err(|err| vm.new_syntax_error(&err))?;
42+
43+
// this line also automatically prints the output
44+
let output = vm.run_code_obj(code_obj, scope.clone())?;
45+
46+
// store the last value in the "last" variable
47+
if !vm.is_none(&output) {
48+
scope.globals.set_item("last", output, &vm).unwrap();
49+
}
50+
}
51+
52+
Ok(())
53+
}

0 commit comments

Comments
 (0)