Pyodide tracing example

HTML

<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/pyodide/v0.18.1/full/pyodide.js"></script>

<button id='stepButton'>
Step
</button>

JavaScript

async function main() {
    const pyodide = await loadPyodide({
        indexURL: "https://cdn.jsdelivr.net/pyodide/v0.18.1/full/"
    });

    pyodide.runPythonAsync(`
import js
import sys
print = lambda *a: js.console.log(' '.join(map(str, a)))

# This is the function we're tracing
def f():
    a, b = 0, 1
    for _ in range(5):
        a, b = b, a + b
    return a

# Tracer function
def tf(frame, event, args):
    if event == 'call':
        frame.f_trace_opcodes = True
    if event != 'opcode': return tf
    # Here we want to stop and wait for the user to press the button
    ...
    print('Executed opcode at offset', frame.f_lasti)
    return tf
    
# Do something to step the tracer function forward one instruction
js.window.stepButton.onclick = lambda e: ...

sys.settrace(tf)
f()
sys.settrace(None)
`);
}
main();