mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-23 22:00:25 -05:00
PyTerminal: use Pyodide instead of Python (#1833)
This commit is contained in:
committed by
GitHub
parent
aef028be6e
commit
3e2a67d434
@@ -81,26 +81,23 @@ const pyTerminal = async () => {
|
|||||||
const workerReady = ({ interpreter }, { sync }) => {
|
const workerReady = ({ interpreter }, { sync }) => {
|
||||||
sync.pyterminal_drop_hooks();
|
sync.pyterminal_drop_hooks();
|
||||||
const decoder = new TextDecoder();
|
const decoder = new TextDecoder();
|
||||||
|
let data = "";
|
||||||
const generic = {
|
const generic = {
|
||||||
isatty: true,
|
isatty: true,
|
||||||
write(buffer) {
|
write(buffer) {
|
||||||
sync.pyterminal_write(decoder.decode(buffer));
|
data = decoder.decode(buffer);
|
||||||
|
sync.pyterminal_write(data);
|
||||||
return buffer.length;
|
return buffer.length;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
interpreter.setStdout(generic);
|
interpreter.setStdout(generic);
|
||||||
interpreter.setStderr(generic);
|
interpreter.setStderr(generic);
|
||||||
|
interpreter.setStdin({
|
||||||
|
isatty: true,
|
||||||
|
stdin: () => sync.pyterminal_read(data),
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// run in python code able to replace builtins.input
|
|
||||||
// using the xworker.sync non blocking prompt
|
|
||||||
const codeBefore = `
|
|
||||||
import builtins
|
|
||||||
from pyscript import sync as _sync
|
|
||||||
|
|
||||||
builtins.input = lambda prompt: _sync.pyterminal_read(prompt)
|
|
||||||
`;
|
|
||||||
|
|
||||||
// at the end of the code, make the terminal interactive
|
// at the end of the code, make the terminal interactive
|
||||||
const codeAfter = `
|
const codeAfter = `
|
||||||
import code as _code
|
import code as _code
|
||||||
@@ -121,7 +118,6 @@ const pyTerminal = async () => {
|
|||||||
// allow a worker to drop main thread hooks ASAP
|
// allow a worker to drop main thread hooks ASAP
|
||||||
xworker.sync.pyterminal_drop_hooks = () => {
|
xworker.sync.pyterminal_drop_hooks = () => {
|
||||||
hooks.worker.onReady.delete(workerReady);
|
hooks.worker.onReady.delete(workerReady);
|
||||||
hooks.worker.codeBeforeRun.delete(codeBefore);
|
|
||||||
hooks.worker.codeAfterRun.delete(codeAfter);
|
hooks.worker.codeAfterRun.delete(codeAfter);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -129,7 +125,6 @@ const pyTerminal = async () => {
|
|||||||
// setup remote thread JS/Python code for whenever the
|
// setup remote thread JS/Python code for whenever the
|
||||||
// worker is ready to become a terminal
|
// worker is ready to become a terminal
|
||||||
hooks.worker.onReady.add(workerReady);
|
hooks.worker.onReady.add(workerReady);
|
||||||
hooks.worker.codeBeforeRun.add(codeBefore);
|
|
||||||
hooks.worker.codeAfterRun.add(codeAfter);
|
hooks.worker.codeAfterRun.add(codeAfter);
|
||||||
} else {
|
} else {
|
||||||
// in the main case, just bootstrap XTerm without
|
// in the main case, just bootstrap XTerm without
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
def greetings(event):
|
def greetings(event):
|
||||||
print('hello world')
|
print('hello world')
|
||||||
</script>
|
</script>
|
||||||
<py-script terminal>
|
<py-script worker terminal>
|
||||||
import sys
|
import sys
|
||||||
from pyscript import display
|
from pyscript import display
|
||||||
display("Hello", "PyScript Next - PyTerminal", append=False)
|
display("Hello", "PyScript Next - PyTerminal", append=False)
|
||||||
|
|||||||
@@ -40,6 +40,24 @@ class TestPyTerminal(PyScriptTest):
|
|||||||
self.page.keyboard.press("Enter")
|
self.page.keyboard.press("Enter")
|
||||||
self.page.get_by_text("the answer is 42").wait_for()
|
self.page.get_by_text("the answer is 42").wait_for()
|
||||||
|
|
||||||
|
@only_worker
|
||||||
|
def test_py_terminal_os_write(self):
|
||||||
|
"""
|
||||||
|
An `os.write("text")` should land in the terminal
|
||||||
|
"""
|
||||||
|
self.pyscript_run(
|
||||||
|
"""
|
||||||
|
<script type="py" terminal>
|
||||||
|
import os
|
||||||
|
os.write(1, str.encode("hello\\n"))
|
||||||
|
os.write(2, str.encode("world\\n"))
|
||||||
|
</script>
|
||||||
|
""",
|
||||||
|
wait_for_pyscript=False,
|
||||||
|
)
|
||||||
|
self.page.get_by_text("hello\n").wait_for()
|
||||||
|
self.page.get_by_text("world\n").wait_for()
|
||||||
|
|
||||||
def test_py_terminal(self):
|
def test_py_terminal(self):
|
||||||
"""
|
"""
|
||||||
1. <py-terminal> should redirect stdout and stderr to the DOM
|
1. <py-terminal> should redirect stdout and stderr to the DOM
|
||||||
|
|||||||
Reference in New Issue
Block a user