Skip to content

Commit e77f223

Browse files
committed
Add documentation for eval_py() and update error message handling
Also, switch from iterating over the values of js_injections and serializing each of them individually to asserting it's an object and then just stringifying the whole thing.
1 parent a796b13 commit e77f223

File tree

3 files changed

+83
-71
lines changed

3 files changed

+83
-71
lines changed

wasm/app/index.html

+69-51
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,49 @@
11
<!DOCTYPE html>
22
<html>
3-
<head>
4-
<meta charset="utf-8" />
5-
<title>RustPython Demo</title>
6-
<style type="text/css" media="screen">
7-
textarea {
8-
font-family: monospace;
9-
}
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>RustPython Demo</title>
6+
<style type="text/css" media="screen">
7+
textarea {
8+
font-family: monospace;
9+
resize: vertical;
10+
}
1011

11-
#code {
12-
height: 35vh;
13-
width: 95vw;
14-
}
12+
#code {
13+
height: 35vh;
14+
width: 95vw;
15+
}
1516

16-
#console {
17-
height: 35vh;
18-
width: 95vw;
19-
}
17+
#console {
18+
height: 35vh;
19+
width: 95vw;
20+
}
2021

21-
#run-btn {
22-
width: 6em;
23-
height: 2em;
24-
font-size: 24px;
25-
}
22+
#run-btn {
23+
width: 6em;
24+
height: 2em;
25+
font-size: 24px;
26+
}
2627

27-
#error {
28-
color: tomato;
29-
margin-top: 10px;
30-
}
31-
</style>
32-
</head>
33-
<body>
34-
<h1>RustPython Demo</h1>
35-
<p>
36-
RustPython is a Python interpreter writter in Rust. This demo is compiled
37-
from Rust to WebAssembly so it runs in the browser
38-
</p>
39-
<p>Please input your python code below and click <kbd>Run</kbd>:</p>
40-
<p>
41-
Alternatively, open up your browser's devtools and play with
42-
<code>rp.eval_py('print("a")')</code>
43-
</p>
44-
<textarea id="code">
28+
#error {
29+
color: tomato;
30+
margin-top: 10px;
31+
font-family: monospace;
32+
}
33+
</style>
34+
</head>
35+
<body>
36+
<h1>RustPython Demo</h1>
37+
<p>
38+
RustPython is a Python interpreter writter in Rust. This demo is
39+
compiled from Rust to WebAssembly so it runs in the browser
40+
</p>
41+
<p>Please input your python code below and click <kbd>Run</kbd>:</p>
42+
<p>
43+
Alternatively, open up your browser's devtools and play with
44+
<code>rp.eval_py('print("a")')</code>
45+
</p>
46+
<textarea id="code">
4547
n1 = 0
4648
n2 = 1
4749
count = 0
@@ -54,18 +56,34 @@ <h1>RustPython Demo</h1>
5456
n1, n2 = n2, n1 + n2
5557
count += 1
5658

57-
</textarea>
58-
<button id="run-btn">Run &#9655;</button>
59-
<div id="error"></div>
60-
<script src="./bootstrap.js"></script>
61-
<h3>Standard Output</h3>
62-
<textarea id="console">Loading...</textarea>
59+
</textarea>
60+
<button id="run-btn">Run &#9655;</button>
61+
<div id="error"></div>
62+
<script src="./bootstrap.js"></script>
63+
<h3>Standard Output</h3>
64+
<textarea id="console">Loading...</textarea>
6365

64-
<a href="https://github.com/RustPython/RustPython"
65-
><img
66-
style="position: absolute; top: 0; right: 0; border: 0;"
67-
src="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png"
68-
alt="Fork me on GitHub"
69-
/></a>
70-
</body>
66+
<p>Here's some info regarding the <code>rp.eval_py()</code> function</p>
67+
<ul>
68+
<li>
69+
You can return variables from python and get them returned to
70+
JS, with the only requirement being that they're serializable
71+
with <code>json.dumps</code>.
72+
</li>
73+
<li>
74+
You can pass an object as the second argument to the function,
75+
and that will be available in python as the variable
76+
<code>js_vars</code>. Again, only values that can be serialized
77+
with <code>JSON.stringify()</code> will go through.
78+
</li>
79+
</ul>
80+
81+
<!-- "Fork me on GitHub" banner -->
82+
<a href="https://github.com/RustPython/RustPython"
83+
><img
84+
style="position: absolute; top: 0; right: 0; border: 0;"
85+
src="https://s3.amazonaws.com/github/ribbons/forkme_right_green_007200.png"
86+
alt="Fork me on GitHub"
87+
/></a>
88+
</body>
7189
</html>

wasm/app/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ window.rp = rp;
66
function runCodeFromTextarea(_) {
77
const consoleElement = document.getElementById('console');
88
const errorElement = document.getElementById('error');
9-
// Clean the console
9+
10+
// Clean the console and errors
1011
consoleElement.value = '';
12+
errorElement.textContent = '';
1113

1214
const code = document.getElementById('code').value;
1315
try {

wasm/src/lib.rs

+11-19
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ extern crate rustpython_vm;
55
extern crate wasm_bindgen;
66
extern crate web_sys;
77

8-
use js_sys::Reflect;
98
use rustpython_vm::compile;
109
use rustpython_vm::pyobject::{self, PyObjectRef, PyResult};
1110
use rustpython_vm::VirtualMachine;
@@ -77,6 +76,12 @@ where
7776

7877
#[wasm_bindgen]
7978
pub fn eval_py(source: &str, js_injections: Option<js_sys::Object>) -> Result<JsValue, JsValue> {
79+
if let Some(js_injections) = js_injections.clone() {
80+
if !js_injections.is_object() {
81+
return Err(js_sys::TypeError::new("The second argument must be an object").into());
82+
}
83+
}
84+
8085
let mut vm = VirtualMachine::new();
8186

8287
vm.ctx.set_attr(
@@ -87,24 +92,11 @@ pub fn eval_py(source: &str, js_injections: Option<js_sys::Object>) -> Result<Js
8792
);
8893

8994
let res = eval(&mut vm, source, |vm, vars| {
90-
let injections = vm.new_dict();
91-
92-
if let Some(js_injections) = js_injections.clone() {
93-
for pair in js_sys::try_iter(&js_sys::Object::entries(&js_injections))
94-
.unwrap()
95-
.unwrap()
96-
{
97-
let pair = pair.unwrap();
98-
let key = Reflect::get(&pair, &"0".into()).unwrap();
99-
let val = Reflect::get(&pair, &"1".into()).unwrap();
100-
let py_val = js_to_py(vm, val);
101-
vm.ctx.set_item(
102-
&injections,
103-
&String::from(js_sys::JsString::from(key)),
104-
py_val,
105-
);
106-
}
107-
}
95+
let injections = if let Some(js_injections) = js_injections.clone() {
96+
js_to_py(vm, js_injections.into())
97+
} else {
98+
vm.new_dict()
99+
};
108100

109101
vm.ctx.set_item(vars, "js_vars", injections);
110102
});

0 commit comments

Comments
 (0)