Repository: pyscript/pyscript (language: python)

Issue:
`script_element.process()` function not working
### Checklist

- [X] I added a descriptive title
- [X] I searched for other issues and couldn't find a solution or duplication
- [X] I already searched in Google and didn't find any good information or help

### What happened?

I'm trying to programmatically execute code in a `<py-editor>` using [the documentation for `editor.process(code)`](https://docs.pyscript.net/2024.8.2/user-guide/editor/#read-write-execute).

I get the following error when executing `editor.process(editor.code)`:
```
pyodide.asm.js:10
Unable to use `window` or `document` -> https://docs.pyscript.net/latest/faq/#sharedarraybuffer
```
### mre.html
```html
<!doctype html>
<html>
	<head>
		<link
			rel="stylesheet"
			href="https://pyscript.net/releases/2024.8.2/core.css"
		/>
		<script
			type="module"
			src="https://pyscript.net/releases/2024.8.2/core.js"
		></script>
	</head>
	<body>
		<script type="py-editor" id="editor">
			import sys
			print(sys.version)
		</script>
		<script type="py" src="mre.py"></script>
		<button py-click="submit">Submit</button>
	</body>
</html>
```
### mre.py
```python
from pyscript import document


def submit(event):
    editor = document.querySelector('#editor')
    editor.process(editor.code)
```
I've tried making the `submit` function `async` and `await`ing `editor.process(editor.code)`. I've also tried using micropython instead of pyodide. I've even tried `process`ing the editor's code from JavaScript according to #2053 :
```javascript
<script>
addEventListener('mpy-editor', async (event) => {
    // the script is the target of this event
    const { target: script } = event
    // it can process any Python code
    await script.process('print("hello")')
})
</script>
```
Everything results in the same error message above.

### What browsers are you seeing the problem on? (if applicable)

Chrome

### Console info

```shell
pyodide.asm.js:10
Unable to use `window` or `document` -> https://docs.pyscript.net/latest/faq/#sharedarraybuffer
```


### Additional Context

_No response_


Discussion / hints:
that's a **warning** about the fact you are not enabling *SharedArrayBuffer* and the link showed in such warning should provide all the details you need: https://docs.pyscript.net/latest/faq/#sharedarraybuffer

Unless you are sure you are enabling all headers needed to have 100% PyScript working, I am going to close this. If you do, feel free to re-open or comment so I'll take a look, thanks.
I was able to satisfy that warning by using the [mini-coi](https://github.com/WebReflection/mini-coi#readme) project and also by adding the `service-worker` attribute to the `py-editor` `script` and pointing it to the [sabayan Service Worker](https://raw.githubusercontent.com/WebReflection/sabayon/main/dist/sw.js).

In both cases, while the warning went away, nothing was output to the output `div` or to the console. I would've expected that the output `div` would be updated. Python error stacktraces are also not output anywhere I could find.

The Python code in the `py-editor` does get run, because I was able to update the DOM:
```python
from pyscript.web import page, div

page.append(div('hello'))
```
Is the expectation for `script_element.process()` that we override all output functions, like `print`, and intercept exceptions?
> The Python code in the py-editor does get run, because I was able to update the DOM:

great, so if your example works, that was the issue, missing headers to allow main thread access from workers.

> Is the expectation for script_element.process() that we override all output functions, like print, and intercept exceptions?

the py-editor lives in a worker to avoid blocking your main thread if you write an infinite loop, as example, plus other things ... the expectation of evaluating its content is the same as pressing the *Run* button except it doesn't need an explicit user intent. This is (or better, *should*) be documented in our docs and it's also tested and used in production already so it'd be surprising if something is not working as I know projects using that quite a lot.

So, assuming you understand how the PyEditor works, and yes ... it does take over the `print` and shows its things on its related target, created by default if not available, what is it that is surprising you?

Any **minimal** reproducible example might help me to understand and help you fix that ... or me fixing what's broken, thanks.
> what is it that is surprising you?

My MRE is posted above. If you click the green _run_ button, the following is printed in the div below the editor:
```
3.12.1 (main, Jul 26 2024, 14:03:47) [Clang 19.0.0git (https:/github.com/llvm/llvm-project 0a8cd1ed1f4f35905df318015b
```
If, instead of clicking the green _run_ button, you click the Submit button (which calls `editor.process(editor.code)`, nothing is printed anywhere (neither in the output div nor in the console).
is the submit reloading the page or you are doing `event.preventDefault()` in its listener/related form?
The page is not being reloaded, a button outside a form wouldn't cause a reload, as seen in Chrome dev tools. Also, any print statements before and after `editor.process(editor.code)` are shown and remain in the console. In any event, I also added the following code and I still get the same issue:
```javascript
document
    .querySelector('button')
    .addEventListener('click', (event) => event.preventDefault())
```
For convenience, I've attached the MRE zip containing 2 files (`mre.html` and `mre.py`), including `<script src="/mini-coi.js"></script>` and the `event.preventDefault()` code above.
[mre.zip](https://github.com/user-attachments/files/17000035/mre.zip)

Essentially, nothing is `print`ed in the output `div` as expected (nor is anything printed anywhere else). Should this issue be reopened?
Reopening to have deeper investigation
@samueller OK, I had a look ... the current status of `editor.process(code)` is that it puts the `editor` in a `setup` like mode while evaluating the code.

This was a requirement by the time I've implemented it and it was the desired behavior, meaning:

  * a setup node has no side-effects on the page when `print` statements execute because setup nodes don't have a target and are supposed to silently bootstrap indeed
  * errors within a setup node are visible on the page because setup nodes have no target ... you won't see the error in the DOM within your target for the editor, you'll see a notification error which is something else
  * ... also ...
  * it's been asked more than once how to easily invoke the *Run* button and the workaround is to use *CSS* selectors but I see an opportunity here to instead change the `process(code)` signature to `process(code, asRunButtonAction = false)` where if that second argument is `true` instead (or `True` in Python) then it will just click on behalf of the user the *Run* and the flow is exactly the same as clicking manually *Run* which is apparently what you expect here.

Would this work as solution? I have already a working patch for it but I want to be sure that's what you are asking: a way to run the editor without the user needing to reach the editor *Run* button ... correct?

If not, please explain what you expect from `execute` as either it runs in *setup mode* or it runs through the button and the usual orchestration with the visible target on the DOM, thanks.
@samueller ? 🤔
This is great @WebReflection, thank you. `process(code, asRunButtonAction = false)` would solve our use case. We're trying to create an education platform, teaching Python. So, in addition to a Run button, we need a Submit button that runs tests against student code.

Fix patch:
diff --git a/pyscript.core/package-lock.json b/pyscript.core/package-lock.json
index 1eae2889472..f70fafe25da 100644
--- a/pyscript.core/package-lock.json
+++ b/pyscript.core/package-lock.json
@@ -19,9 +19,9 @@
                 "type-checked-collections": "^0.1.7"
             },
             "devDependencies": {
-                "@codemirror/commands": "^6.6.1",
+                "@codemirror/commands": "^6.6.2",
                 "@codemirror/lang-python": "^6.1.6",
-                "@codemirror/language": "^6.10.2",
+                "@codemirror/language": "^6.10.3",
                 "@codemirror/state": "^6.4.1",
                 "@codemirror/view": "^6.33.0",
                 "@playwright/test": "1.45.3",
@@ -31,13 +31,13 @@
                 "@webreflection/toml-j0.4": "^1.1.3",
                 "@xterm/addon-fit": "^0.10.0",
                 "@xterm/addon-web-links": "^0.11.0",
-                "bun": "^1.1.27",
+                "bun": "^1.1.29",
                 "chokidar": "^4.0.0",
                 "codedent": "^0.1.2",
                 "codemirror": "^6.0.1",
                 "eslint": "^9.10.0",
                 "flatted": "^3.3.1",
-                "rollup": "^4.21.3",
+                "rollup": "^4.22.2",
                 "rollup-plugin-postcss": "^4.0.2",
                 "rollup-plugin-string": "^3.0.0",
                 "static-handler": "^0.5.3",
@@ -66,9 +66,9 @@
             }
         },
         "node_modules/@codemirror/commands": {
-            "version": "6.6.1",
-            "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.6.1.tgz",
-            "integrity": "sha512-iBfKbyIoXS1FGdsKcZmnrxmbc8VcbMrSgD7AVrsnX+WyAYjmUDWvE93dt5D874qS4CCVu4O1JpbagHdXbbLiOw==",
+            "version": "6.6.2",
+            "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.6.2.tgz",
+            "integrity": "sha512-Fq7eWOl1Rcbrfn6jD8FPCj9Auaxdm5nIK5RYOeW7ughnd/rY5AmPg6b+CfsG39ZHdwiwe8lde3q8uR7CF5S0yQ==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
@@ -93,9 +93,9 @@
             }
         },
         "node_modules/@codemirror/language": {
-            "version": "6.10.2",
-            "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.2.tgz",
-            "integrity": "sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==",
+            "version": "6.10.3",
+            "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.3.tgz",
+            "integrity": "sha512-kDqEU5sCP55Oabl6E7m5N+vZRoc0iWqgDVhEKifcHzPzjqCegcO4amfrYVL9PmPZpl4G0yjkpTpUO/Ui8CzO8A==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
@@ -478,9 +478,9 @@
             }
         },
         "node_modules/@oven/bun-darwin-aarch64": {
-            "version": "1.1.27",
-            "resolved": "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-1.1.27.tgz",
-            "integrity": "sha512-h5Mf2+AESEtHHGRdSDQgDU7TY2vMPMeAuwkf/XPMDpaS+EoIUFayj1CXShB25gT16uw/ww/Pl3LaN0sN0tcWhQ==",
+            "version": "1.1.29",
+            "resolved": "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-1.1.29.tgz",
+            "integrity": "sha512-Z8WnrXoAXg6ENU6z+Mil94oipMBMliJIj4XWWqjNC33/ZGPqMdPT5MbFQjbdHjxe5bRBW/aHaMU3G35fGx9Seg==",
             "cpu": [
                 "arm64"
             ],
@@ -492,9 +492,9 @@
             ]
         },
         "node_modules/@oven/bun-darwin-x64": {
-            "version": "1.1.27",
-            "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64/-/bun-darwin-x64-1.1.27.tgz",
-            "integrity": "sha512-l+uAcE0kh4+c2VUwKvSpsHFQbzR2eLxGKhONa4AJBNVW4UXIpSdH12Qj9fG4Xqgq7s26zs32jPsl2C2NQsmRag==",
+            "version": "1.1.29",
+            "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64/-/bun-darwin-x64-1.1.29.tgz",
+            "integrity": "sha512-tDHDR+OWLCKEP0xE8IGCWRxSsxO5tr3rvyrSzy6CXYkoWPz66kODbtbGfWl8HSwunrQxJKnE2L9LWX2Eiz3Cpw==",
             "cpu": [
                 "x64"
             ],
@@ -506,9 +506,9 @@
             ]
         },
         "node_modules/@oven/bun-darwin-x64-baseline": {
-            "version": "1.1.27",
-            "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64-baseline/-/bun-darwin-x64-baseline-1.1.27.tgz",
-            "integrity": "sha512-Ld+FBW3VUzGOI9QhsQKnaiYinGcOQg83NpagoeyMASozFJEMyDEr/jxA5KxoSEJRChQrGZowq/7IfoPIcJZIUA==",
+            "version": "1.1.29",
+            "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64-baseline/-/bun-darwin-x64-baseline-1.1.29.tgz",
+            "integrity": "sha512-B+zKlJR+3ANPDU+vNjvXaqgB63hYcCk16/k45hiInvIsDXfSdDn4+LMHwZTFdfUWTCGbNMFg9u4bZCtK0nhMDw==",
             "cpu": [
                 "x64"
             ],
@@ -520,9 +520,9 @@
             ]
         },
         "node_modules/@oven/bun-linux-aarch64": {
-            "version": "1.1.27",
-            "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.1.27.tgz",
-            "integrity": "sha512-4oaNlx07SFxhO26Lm2cfRjozEQX/qRoWFhnz+EFLlGPUPLB2cNmXCVMtmXJep0u4Jub5pGK9yISwNT1voZ6KMg==",
+            "version": "1.1.29",
+            "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.1.29.tgz",
+            "integrity": "sha512-BuV2Gni+FaMo1r7+3vLjefQYtQcWE01zJJ4zCjyzikP1L4r6PUaLeJyKXbqF6sIR0cLjG6LWj66EGskakDyvWA==",
             "cpu": [
                 "arm64"
             ],
@@ -534,9 +534,9 @@
             ]
         },
         "node_modules/@oven/bun-linux-x64": {
-            "version": "1.1.27",
-            "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-1.1.27.tgz",
-            "integrity": "sha512-ktplW245+ke0GIKdBEzZisZ4mwAqdPYmW3RzhDPGB7193jVmaAE1YVUscrWkTAdfl6YMGb99IXThrhcXSddeAw==",
+            "version": "1.1.29",
+            "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-1.1.29.tgz",
+            "integrity": "sha512-JVLiTafybuOFIeC80mZEzHdkOCCzlOtOV5zCbvYAIb7D3SM64fNBwrR0dvDkJTQtsjbwt8YeVFN2YRSI/wlFkw==",
             "cpu": [
                 "x64"
             ],
@@ -548,9 +548,9 @@
             ]
         },
         "node_modules/@oven/bun-linux-x64-baseline": {
-            "version": "1.1.27",
-            "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-1.1.27.tgz",
-            "integrity": "sha512-495DOwgzpr/0ta/AaSRYb7EJeAEAf38cBOUO6oJzCxT5NdWRbZeAo5bmqcrBke1AexnKPA7RUN9Z5+t1TvqjtQ==",
+            "version": "1.1.29",
+            "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-1.1.29.tgz",
+            "integrity": "sha512-tQhm1SDyymBvc2L3zIN7FI+sI3g9gxavDYuvL/Lz17nEk1oqP5DFE2lF9QWJMDdQL3XQKH/drI27yNpfPHgAPw==",
             "cpu": [
                 "x64"
             ],
@@ -562,9 +562,9 @@
             ]
         },
         "node_modules/@oven/bun-windows-x64": {
-            "version": "1.1.27",
-            "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64/-/bun-windows-x64-1.1.27.tgz",
-            "integrity": "sha512-LIZRqlyLpMEkmbsA+d/GmQnEdJzMGlFRlVtdQnyjTskW+uMv+lBHmWu7CkdcCCVPtf6wRDYgdkjpQOAw1wle5g==",
+            "version": "1.1.29",
+            "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64/-/bun-windows-x64-1.1.29.tgz",
+            "integrity": "sha512-d930+pSkNVHPJJBryIh1gsAKk7lp1HzcktFe0bfxwmpHwjj4BiVfMjU1YaCnsdWKNs2Nv1Y1PLVDNyUCQVfo0Q==",
             "cpu": [
                 "x64"
             ],
@@ -576,9 +576,9 @@
             ]
         },
         "node_modules/@oven/bun-windows-x64-baseline": {
-            "version": "1.1.27",
-            "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64-baseline/-/bun-windows-x64-baseline-1.1.27.tgz",
-            "integrity": "sha512-Qfn80kb9eDZaecCVVVxFpNfuHvo7h4yQlh278u9Vs0vSrHTYG4dxoH4SWkZSzHa44ZwKRpa1TmMfDVhX/HE+mA==",
+            "version": "1.1.29",
+            "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64-baseline/-/bun-windows-x64-baseline-1.1.29.tgz",
+            "integrity": "sha512-+QWT8Kp+3Sl54QUa6uBsDzQlX11thMMVAw+yUwSRU4Y5FVSN8RPuxhN8ijJ1QGm1KOYA2sCI6V+3lyNMNmRvAA==",
             "cpu": [
                 "x64"
             ],
@@ -715,9 +715,9 @@
             }
         },
         "node_modules/@rollup/rollup-android-arm-eabi": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.3.tgz",
-            "integrity": "sha512-MmKSfaB9GX+zXl6E8z4koOr/xU63AMVleLEa64v7R0QF/ZloMs5vcD1sHgM64GXXS1csaJutG+ddtzcueI/BLg==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.2.tgz",
+            "integrity": "sha512-8Ao+EDmTPjZ1ZBABc1ohN7Ylx7UIYcjReZinigedTOnGFhIctyGPxY2II+hJ6gD2/vkDKZTyQ0e7++kwv6wDrw==",
             "cpu": [
                 "arm"
             ],
@@ -729,9 +729,9 @@
             ]
         },
         "node_modules/@rollup/rollup-android-arm64": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.3.tgz",
-            "integrity": "sha512-zrt8ecH07PE3sB4jPOggweBjJMzI1JG5xI2DIsUbkA+7K+Gkjys6eV7i9pOenNSDJH3eOr/jLb/PzqtmdwDq5g==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.2.tgz",
+            "integrity": "sha512-I+B1v0a4iqdS9DvYt1RJZ3W+Oh9EVWjbY6gp79aAYipIbxSLEoQtFQlZEnUuwhDXCqMxJ3hluxKAdPD+GiluFQ==",
             "cpu": [
                 "arm64"
             ],
@@ -743,9 +743,9 @@
             ]
         },
         "node_modules/@rollup/rollup-darwin-arm64": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.3.tgz",
-            "integrity": "sha512-P0UxIOrKNBFTQaXTxOH4RxuEBVCgEA5UTNV6Yz7z9QHnUJ7eLX9reOd/NYMO3+XZO2cco19mXTxDMXxit4R/eQ==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.2.tgz",
+            "integrity": "sha512-BTHO7rR+LC67OP7I8N8GvdvnQqzFujJYWo7qCQ8fGdQcb8Gn6EQY+K1P+daQLnDCuWKbZ+gHAQZuKiQkXkqIYg==",
             "cpu": [
                 "arm64"
             ],
@@ -757,9 +757,9 @@
             ]
         },
         "node_modules/@rollup/rollup-darwin-x64": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.3.tgz",
-            "integrity": "sha512-L1M0vKGO5ASKntqtsFEjTq/fD91vAqnzeaF6sfNAy55aD+Hi2pBI5DKwCO+UNDQHWsDViJLqshxOahXyLSh3EA==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.2.tgz",
+            "integrity": "sha512-1esGwDNFe2lov4I6GsEeYaAMHwkqk0IbuGH7gXGdBmd/EP9QddJJvTtTF/jv+7R8ZTYPqwcdLpMTxK8ytP6k6Q==",
             "cpu": [
                 "x64"
             ],
@@ -771,9 +771,9 @@
             ]
         },
         "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.3.tgz",
-            "integrity": "sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.2.tgz",
+            "integrity": "sha512-GBHuY07x96OTEM3OQLNaUSUwrOhdMea/LDmlFHi/HMonrgF6jcFrrFFwJhhe84XtA1oK/Qh4yFS+VMREf6dobg==",
             "cpu": [
                 "arm"
             ],
@@ -785,9 +785,9 @@
             ]
         },
         "node_modules/@rollup/rollup-linux-arm-musleabihf": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.3.tgz",
-            "integrity": "sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.2.tgz",
+            "integrity": "sha512-Dbfa9Sc1G1lWxop0gNguXOfGhaXQWAGhZUcqA0Vs6CnJq8JW/YOw/KvyGtQFmz4yDr0H4v9X248SM7bizYj4yQ==",
             "cpu": [
                 "arm"
             ],
@@ -799,9 +799,9 @@
             ]
         },
         "node_modules/@rollup/rollup-linux-arm64-gnu": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.3.tgz",
-            "integrity": "sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.2.tgz",
+            "integrity": "sha512-Z1YpgBvFYhZIyBW5BoopwSg+t7yqEhs5HCei4JbsaXnhz/eZehT18DaXl957aaE9QK7TRGFryCAtStZywcQe1A==",
             "cpu": [
                 "arm64"
             ],
@@ -813,9 +813,9 @@
             ]
         },
         "node_modules/@rollup/rollup-linux-arm64-musl": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.3.tgz",
-            "integrity": "sha512-MnvSPGO8KJXIMGlQDYfvYS3IosFN2rKsvxRpPO2l2cum+Z3exiExLwVU+GExL96pn8IP+GdH8Tz70EpBhO0sIQ==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.2.tgz",
+            "integrity": "sha512-66Zszr7i/JaQ0u/lefcfaAw16wh3oT72vSqubIMQqWzOg85bGCPhoeykG/cC5uvMzH80DQa2L539IqKht6twVA==",
             "cpu": [
                 "arm64"
             ],
@@ -827,9 +827,9 @@
             ]
         },
         "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.3.tgz",
-            "integrity": "sha512-+W+p/9QNDr2vE2AXU0qIy0qQE75E8RTwTwgqS2G5CRQ11vzq0tbnfBd6brWhS9bCRjAjepJe2fvvkvS3dno+iw==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.2.tgz",
+            "integrity": "sha512-HpJCMnlMTfEhwo19bajvdraQMcAq3FX08QDx3OfQgb+414xZhKNf3jNvLFYKbbDSGBBrQh5yNwWZrdK0g0pokg==",
             "cpu": [
                 "ppc64"
             ],
@@ -841,9 +841,9 @@
             ]
         },
         "node_modules/@rollup/rollup-linux-riscv64-gnu": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.3.tgz",
-            "integrity": "sha512-yXH6K6KfqGXaxHrtr+Uoy+JpNlUlI46BKVyonGiaD74ravdnF9BUNC+vV+SIuB96hUMGShhKV693rF9QDfO6nQ==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.2.tgz",
+            "integrity": "sha512-/egzQzbOSRef2vYCINKITGrlwkzP7uXRnL+xU2j75kDVp3iPdcF0TIlfwTRF8woBZllhk3QaxNOEj2Ogh3t9hg==",
             "cpu": [
                 "riscv64"
             ],
@@ -855,9 +855,9 @@
             ]
         },
         "node_modules/@rollup/rollup-linux-s390x-gnu": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.3.tgz",
-            "integrity": "sha512-R8cwY9wcnApN/KDYWTH4gV/ypvy9yZUHlbJvfaiXSB48JO3KpwSpjOGqO4jnGkLDSk1hgjYkTbTt6Q7uvPf8eg==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.2.tgz",
+            "integrity": "sha512-qgYbOEbrPfEkH/OnUJd1/q4s89FvNJQIUldx8X2F/UM5sEbtkqZpf2s0yly2jSCKr1zUUOY1hnTP2J1WOzMAdA==",
             "cpu": [
                 "s390x"
             ],
@@ -869,9 +869,9 @@
             ]
         },
         "node_modules/@rollup/rollup-linux-x64-gnu": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.3.tgz",
-            "integrity": "sha512-kZPbX/NOPh0vhS5sI+dR8L1bU2cSO9FgxwM8r7wHzGydzfSjLRCFAT87GR5U9scj2rhzN3JPYVC7NoBbl4FZ0g==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.2.tgz",
+            "integrity": "sha512-a0lkvNhFLhf+w7A95XeBqGQaG0KfS3hPFJnz1uraSdUe/XImkp/Psq0Ca0/UdD5IEAGoENVmnYrzSC9Y2a2uKQ==",
             "cpu": [
                 "x64"
             ],
@@ -883,9 +883,9 @@
             ]
         },
         "node_modules/@rollup/rollup-linux-x64-musl": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.3.tgz",
-            "integrity": "sha512-S0Yq+xA1VEH66uiMNhijsWAafffydd2X5b77eLHfRmfLsRSpbiAWiRHV6DEpz6aOToPsgid7TI9rGd6zB1rhbg==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.2.tgz",
+            "integrity": "sha512-sSWBVZgzwtsuG9Dxi9kjYOUu/wKW+jrbzj4Cclabqnfkot8Z3VEHcIgyenA3lLn/Fu11uDviWjhctulkhEO60g==",
             "cpu": [
                 "x64"
             ],
@@ -897,9 +897,9 @@
             ]
         },
         "node_modules/@rollup/rollup-win32-arm64-msvc": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.3.tgz",
-            "integrity": "sha512-9isNzeL34yquCPyerog+IMCNxKR8XYmGd0tHSV+OVx0TmE0aJOo9uw4fZfUuk2qxobP5sug6vNdZR6u7Mw7Q+Q==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.2.tgz",
+            "integrity": "sha512-t/YgCbZ638R/r7IKb9yCM6nAek1RUvyNdfU0SHMDLOf6GFe/VG1wdiUAsxTWHKqjyzkRGg897ZfCpdo1bsCSsA==",
             "cpu": [
                 "arm64"
             ],
@@ -911,9 +911,9 @@
             ]
         },
         "node_modules/@rollup/rollup-win32-ia32-msvc": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.3.tgz",
-            "integrity": "sha512-nMIdKnfZfzn1Vsk+RuOvl43ONTZXoAPUUxgcU0tXooqg4YrAqzfKzVenqqk2g5efWh46/D28cKFrOzDSW28gTA==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.2.tgz",
+            "integrity": "sha512-kTmX5uGs3WYOA+gYDgI6ITkZng9SP71FEMoHNkn+cnmb9Zuyyay8pf0oO5twtTwSjNGy1jlaWooTIr+Dw4tIbw==",
             "cpu": [
                 "ia32"
             ],
@@ -925,9 +925,9 @@
             ]
         },
         "node_modules/@rollup/rollup-win32-x64-msvc": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.3.tgz",
-            "integrity": "sha512-fOvu7PCQjAj4eWDEuD8Xz5gpzFqXzGlxHZozHP4b9Jxv9APtdxL6STqztDzMLuRXEc4UpXGGhx029Xgm91QBeA==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.2.tgz",
+            "integrity": "sha512-Yy8So+SoRz8I3NS4Bjh91BICPOSVgdompTIPYTByUqU66AXSIOgmW3Lv1ke3NORPqxdF+RdrZET+8vYai6f4aA==",
             "cpu": [
                 "x64"
             ],
@@ -1178,9 +1178,9 @@
             }
         },
         "node_modules/bun": {
-            "version": "1.1.27",
-            "resolved": "https://registry.npmjs.org/bun/-/bun-1.1.27.tgz",
-            "integrity": "sha512-FLnMaOuVVuhjPIfmlRtAE42B2x+oSWO6jW8MZ/Ss179qokN//nzIhuj/07bdA016U6d11HyLvvGb6eaH0HKhBQ==",
+            "version": "1.1.29",
+            "resolved": "https://registry.npmjs.org/bun/-/bun-1.1.29.tgz",
+            "integrity": "sha512-SKhpyKNZtgxrVel9ec9xon3LDv8mgpiuFhARgcJo1YIbggY2PBrKHRNiwQ6Qlb+x3ivmRurfuwWgwGexjpgBRg==",
             "cpu": [
                 "arm64",
                 "x64"
@@ -1198,14 +1198,14 @@
                 "bunx": "bin/bun.exe"
             },
             "optionalDependencies": {
-                "@oven/bun-darwin-aarch64": "1.1.27",
-                "@oven/bun-darwin-x64": "1.1.27",
-                "@oven/bun-darwin-x64-baseline": "1.1.27",
-                "@oven/bun-linux-aarch64": "1.1.27",
-                "@oven/bun-linux-x64": "1.1.27",
-                "@oven/bun-linux-x64-baseline": "1.1.27",
-                "@oven/bun-windows-x64": "1.1.27",
-                "@oven/bun-windows-x64-baseline": "1.1.27"
+                "@oven/bun-darwin-aarch64": "1.1.29",
+                "@oven/bun-darwin-x64": "1.1.29",
+                "@oven/bun-darwin-x64-baseline": "1.1.29",
+                "@oven/bun-linux-aarch64": "1.1.29",
+                "@oven/bun-linux-x64": "1.1.29",
+                "@oven/bun-linux-x64-baseline": "1.1.29",
+                "@oven/bun-windows-x64": "1.1.29",
+                "@oven/bun-windows-x64-baseline": "1.1.29"
             }
         },
         "node_modules/callsites": {
@@ -3546,9 +3546,9 @@
             }
         },
         "node_modules/rollup": {
-            "version": "4.21.3",
-            "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.3.tgz",
-            "integrity": "sha512-7sqRtBNnEbcBtMeRVc6VRsJMmpI+JU1z9VTvW8D4gXIYQFz0aLcsE6rRkyghZkLfEgUZgVvOG7A5CVz/VW5GIA==",
+            "version": "4.22.2",
+            "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.2.tgz",
+            "integrity": "sha512-JWWpTrZmqQGQWt16xvNn6KVIUz16VtZwl984TKw0dfqqRpFwtLJYYk1/4BTgplndMQKWUk/yB4uOShYmMzA2Vg==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
@@ -3562,22 +3562,22 @@
                 "npm": ">=8.0.0"
             },
             "optionalDependencies": {
-                "@rollup/rollup-android-arm-eabi": "4.21.3",
-                "@rollup/rollup-android-arm64": "4.21.3",
-                "@rollup/rollup-darwin-arm64": "4.21.3",
-                "@rollup/rollup-darwin-x64": "4.21.3",
-                "@rollup/rollup-linux-arm-gnueabihf": "4.21.3",
-                "@rollup/rollup-linux-arm-musleabihf": "4.21.3",
-                "@rollup/rollup-linux-arm64-gnu": "4.21.3",
-                "@rollup/rollup-linux-arm64-musl": "4.21.3",
-                "@rollup/rollup-linux-powerpc64le-gnu": "4.21.3",
-                "@rollup/rollup-linux-riscv64-gnu": "4.21.3",
-                "@rollup/rollup-linux-s390x-gnu": "4.21.3",
-                "@rollup/rollup-linux-x64-gnu": "4.21.3",
-                "@rollup/rollup-linux-x64-musl": "4.21.3",
-                "@rollup/rollup-win32-arm64-msvc": "4.21.3",
-                "@rollup/rollup-win32-ia32-msvc": "4.21.3",
-                "@rollup/rollup-win32-x64-msvc": "4.21.3",
+                "@rollup/rollup-android-arm-eabi": "4.22.2",
+                "@rollup/rollup-android-arm64": "4.22.2",
+                "@rollup/rollup-darwin-arm64": "4.22.2",
+                "@rollup/rollup-darwin-x64": "4.22.2",
+                "@rollup/rollup-linux-arm-gnueabihf": "4.22.2",
+                "@rollup/rollup-linux-arm-musleabihf": "4.22.2",
+                "@rollup/rollup-linux-arm64-gnu": "4.22.2",
+                "@rollup/rollup-linux-arm64-musl": "4.22.2",
+                "@rollup/rollup-linux-powerpc64le-gnu": "4.22.2",
+                "@rollup/rollup-linux-riscv64-gnu": "4.22.2",
+                "@rollup/rollup-linux-s390x-gnu": "4.22.2",
+                "@rollup/rollup-linux-x64-gnu": "4.22.2",
+                "@rollup/rollup-linux-x64-musl": "4.22.2",
+                "@rollup/rollup-win32-arm64-msvc": "4.22.2",
+                "@rollup/rollup-win32-ia32-msvc": "4.22.2",
+                "@rollup/rollup-win32-x64-msvc": "4.22.2",
                 "fsevents": "~2.3.2"
             }
         },
diff --git a/pyscript.core/package.json b/pyscript.core/package.json
index 2d9c7e128d6..b6865ffef57 100644
--- a/pyscript.core/package.json
+++ b/pyscript.core/package.json
@@ -65,9 +65,9 @@
         "type-checked-collections": "^0.1.7"
     },
     "devDependencies": {
-        "@codemirror/commands": "^6.6.1",
+        "@codemirror/commands": "^6.6.2",
         "@codemirror/lang-python": "^6.1.6",
-        "@codemirror/language": "^6.10.2",
+        "@codemirror/language": "^6.10.3",
         "@codemirror/state": "^6.4.1",
         "@codemirror/view": "^6.33.0",
         "@playwright/test": "1.45.3",
@@ -77,13 +77,13 @@
         "@webreflection/toml-j0.4": "^1.1.3",
         "@xterm/addon-fit": "^0.10.0",
         "@xterm/addon-web-links": "^0.11.0",
-        "bun": "^1.1.27",
+        "bun": "^1.1.29",
         "chokidar": "^4.0.0",
         "codedent": "^0.1.2",
         "codemirror": "^6.0.1",
         "eslint": "^9.10.0",
         "flatted": "^3.3.1",
-        "rollup": "^4.21.3",
+        "rollup": "^4.22.2",
         "rollup-plugin-postcss": "^4.0.2",
         "rollup-plugin-string": "^3.0.0",
         "static-handler": "^0.5.3",
diff --git a/pyscript.core/src/plugins/py-editor.js b/pyscript.core/src/plugins/py-editor.js
index ba4fdcb60b0..01293ae4d7f 100644
--- a/pyscript.core/src/plugins/py-editor.js
+++ b/pyscript.core/src/plugins/py-editor.js
@@ -290,9 +290,11 @@ const init = async (script, type, interpreter) => {
             /**
              * Simulate a setup node overriding the source to evaluate.
              * @param {string} code the Python code to evaluate.
+             * @param {boolean} asRunButtonAction invoke the `Run` button handler.
              * @returns {Promise<...>} fulfill once code has been evaluated.
              */
-            value(code) {
+            value(code, asRunButtonAction = false) {
+                if (asRunButtonAction) return listener();
                 const wasSetup = isSetup;
                 const wasSource = source;
                 isSetup = true;


Test patch:
diff --git a/pyscript.core/tests/index.html b/pyscript.core/tests/index.html
index 647df6ca159..c5bbbe2e986 100644
--- a/pyscript.core/tests/index.html
+++ b/pyscript.core/tests/index.html
@@ -14,5 +14,5 @@
             a:hover { opacity: 1; }
         </style>
     </head>
-    <body><ul><li><strong><a href="./config/index.html">config</a></strong><ul><li><a href="./config/ambiguous-config.html">ambiguous-config<small>.html</small></a></li><li><a href="./config/same-config.html">same-config<small>.html</small></a></li><li><a href="./config/too-many-config.html">too-many-config<small>.html</small></a></li><li><a href="./config/too-many-py-config.html">too-many-py-config<small>.html</small></a></li></ul></li><li><strong><a href="./issue-7015/index.html">issue-7015</a></strong></li><li><strong><span>js-integration</span></strong><ul><li><a href="./js-integration/async-listener.html">async-listener<small>.html</small></a></li><li><a href="./js-integration/config-url.html">config-url<small>.html</small></a></li><li><a href="./js-integration/config_type.html">config_type<small>.html</small></a></li><li><strong><a href="./js-integration/fetch/index.html">fetch</a></strong></li><li><a href="./js-integration/ffi.html">ffi<small>.html</small></a></li><li><a href="./js-integration/hooks.html">hooks<small>.html</small></a></li><li><strong><a href="./js-integration/issue-2093/index.html">issue-2093</a></strong></li><li><a href="./js-integration/js-storage.html">js-storage<small>.html</small></a></li><li><a href="./js-integration/js_modules.html">js_modules<small>.html</small></a></li><li><strong><a href="./js-integration/loader/index.html">loader</a></strong></li><li><a href="./js-integration/mpy.html">mpy<small>.html</small></a></li><li><a href="./js-integration/py-terminal-main.html">py-terminal-main<small>.html</small></a></li><li><a href="./js-integration/py-terminal-worker.html">py-terminal-worker<small>.html</small></a></li><li><a href="./js-integration/py-terminal.html">py-terminal<small>.html</small></a></li><li><a href="./js-integration/py-terminals.html">py-terminals<small>.html</small></a></li><li><a href="./js-integration/storage.html">storage<small>.html</small></a></li><li><strong><a href="./js-integration/workers/index.html">workers</a></strong><ul><li><a href="./js-integration/workers/named.html">named<small>.html</small></a></li></ul></li></ul></li><li><strong><a href="./manual/index.html">manual</a></strong><ul><li><a href="./manual/all-done.html">all-done<small>.html</small></a></li><li><a href="./manual/async.html">async<small>.html</small></a></li><li><a href="./manual/camera.html">camera<small>.html</small></a></li><li><a href="./manual/click.html">click<small>.html</small></a></li><li><a href="./manual/code-a-part.html">code-a-part<small>.html</small></a></li><li><a href="./manual/combo.html">combo<small>.html</small></a></li><li><a href="./manual/config.html">config<small>.html</small></a></li><li><a href="./manual/create-element.html">create-element<small>.html</small></a></li><li><a href="./manual/dialog.html">dialog<small>.html</small></a></li><li><a href="./manual/display.html">display<small>.html</small></a></li><li><a href="./manual/error.html">error<small>.html</small></a></li><li><a href="./manual/html-decode.html">html-decode<small>.html</small></a></li><li><a href="./manual/input.html">input<small>.html</small></a></li><li><a href="./manual/interpreter.html">interpreter<small>.html</small></a></li><li><a href="./manual/multi.html">multi<small>.html</small></a></li><li><a href="./manual/multiple-editors.html">multiple-editors<small>.html</small></a></li><li><a href="./manual/no-error.html">no-error<small>.html</small></a></li><li><a href="./manual/py-editor-failure.html">py-editor-failure<small>.html</small></a></li><li><a href="./manual/py-editor.html">py-editor<small>.html</small></a></li><li><a href="./manual/py_modules.html">py_modules<small>.html</small></a></li><li><a href="./manual/split-config.html">split-config<small>.html</small></a></li><li><a href="./manual/target.html">target<small>.html</small></a></li><li><a href="./manual/test_display_HTML.html">test_display_HTML<small>.html</small></a></li><li><a href="./manual/test_when.html">test_when<small>.html</small></a></li><li><a href="./manual/worker.html">worker<small>.html</small></a></li></ul></li><li><strong><a href="./no_sab/index.html">no_sab</a></strong></li><li><strong><a href="./piratical/index.html">piratical</a></strong></li><li><strong><a href="./py-editor/index.html">py-editor</a></strong><ul><li><a href="./py-editor/issue-2056.html">issue-2056<small>.html</small></a></li><li><a href="./py-editor/service-worker.html">service-worker<small>.html</small></a></li></ul></li><li><strong><a href="./py-terminals/index.html">py-terminals</a></strong><ul><li><a href="./py-terminals/no-repl.html">no-repl<small>.html</small></a></li><li><a href="./py-terminals/repl.html">repl<small>.html</small></a></li></ul></li><li><strong><a href="./pyscript_dom/index.html">pyscript_dom</a></strong></li><li><strong><a href="./service-worker/index.html">service-worker</a></strong></li><li><strong><a href="./ui/index.html">ui</a></strong><ul><li><a href="./ui/gallery.html">gallery<small>.html</small></a></li></ul></li></ul></body>
+    <body><ul><li><strong><a href="./config/index.html">config</a></strong><ul><li><a href="./config/ambiguous-config.html">ambiguous-config<small>.html</small></a></li><li><a href="./config/same-config.html">same-config<small>.html</small></a></li><li><a href="./config/too-many-config.html">too-many-config<small>.html</small></a></li><li><a href="./config/too-many-py-config.html">too-many-py-config<small>.html</small></a></li></ul></li><li><strong><a href="./issue-7015/index.html">issue-7015</a></strong></li><li><strong><span>js-integration</span></strong><ul><li><a href="./js-integration/async-listener.html">async-listener<small>.html</small></a></li><li><a href="./js-integration/config-url.html">config-url<small>.html</small></a></li><li><a href="./js-integration/config_type.html">config_type<small>.html</small></a></li><li><strong><a href="./js-integration/fetch/index.html">fetch</a></strong></li><li><a href="./js-integration/ffi.html">ffi<small>.html</small></a></li><li><a href="./js-integration/hooks.html">hooks<small>.html</small></a></li><li><strong><a href="./js-integration/issue-2093/index.html">issue-2093</a></strong></li><li><a href="./js-integration/js-storage.html">js-storage<small>.html</small></a></li><li><a href="./js-integration/js_modules.html">js_modules<small>.html</small></a></li><li><strong><a href="./js-integration/loader/index.html">loader</a></strong></li><li><a href="./js-integration/mpy.html">mpy<small>.html</small></a></li><li><a href="./js-integration/py-terminal-main.html">py-terminal-main<small>.html</small></a></li><li><a href="./js-integration/py-terminal-worker.html">py-terminal-worker<small>.html</small></a></li><li><a href="./js-integration/py-terminal.html">py-terminal<small>.html</small></a></li><li><a href="./js-integration/py-terminals.html">py-terminals<small>.html</small></a></li><li><a href="./js-integration/storage.html">storage<small>.html</small></a></li><li><strong><a href="./js-integration/workers/index.html">workers</a></strong><ul><li><a href="./js-integration/workers/named.html">named<small>.html</small></a></li></ul></li></ul></li><li><strong><a href="./manual/index.html">manual</a></strong><ul><li><a href="./manual/all-done.html">all-done<small>.html</small></a></li><li><a href="./manual/async.html">async<small>.html</small></a></li><li><a href="./manual/camera.html">camera<small>.html</small></a></li><li><a href="./manual/click.html">click<small>.html</small></a></li><li><a href="./manual/code-a-part.html">code-a-part<small>.html</small></a></li><li><a href="./manual/combo.html">combo<small>.html</small></a></li><li><a href="./manual/config.html">config<small>.html</small></a></li><li><a href="./manual/create-element.html">create-element<small>.html</small></a></li><li><a href="./manual/dialog.html">dialog<small>.html</small></a></li><li><a href="./manual/display.html">display<small>.html</small></a></li><li><a href="./manual/error.html">error<small>.html</small></a></li><li><a href="./manual/html-decode.html">html-decode<small>.html</small></a></li><li><a href="./manual/input.html">input<small>.html</small></a></li><li><a href="./manual/interpreter.html">interpreter<small>.html</small></a></li><li><a href="./manual/multi.html">multi<small>.html</small></a></li><li><a href="./manual/multiple-editors.html">multiple-editors<small>.html</small></a></li><li><a href="./manual/no-error.html">no-error<small>.html</small></a></li><li><a href="./manual/py-editor-failure.html">py-editor-failure<small>.html</small></a></li><li><a href="./manual/py-editor.html">py-editor<small>.html</small></a></li><li><a href="./manual/py_modules.html">py_modules<small>.html</small></a></li><li><a href="./manual/split-config.html">split-config<small>.html</small></a></li><li><a href="./manual/submit.html">submit<small>.html</small></a></li><li><a href="./manual/target.html">target<small>.html</small></a></li><li><a href="./manual/test_display_HTML.html">test_display_HTML<small>.html</small></a></li><li><a href="./manual/test_when.html">test_when<small>.html</small></a></li><li><a href="./manual/worker.html">worker<small>.html</small></a></li></ul></li><li><strong><a href="./no_sab/index.html">no_sab</a></strong></li><li><strong><a href="./piratical/index.html">piratical</a></strong></li><li><strong><a href="./py-editor/index.html">py-editor</a></strong><ul><li><a href="./py-editor/issue-2056.html">issue-2056<small>.html</small></a></li><li><a href="./py-editor/service-worker.html">service-worker<small>.html</small></a></li></ul></li><li><strong><a href="./py-terminals/index.html">py-terminals</a></strong><ul><li><a href="./py-terminals/no-repl.html">no-repl<small>.html</small></a></li><li><a href="./py-terminals/repl.html">repl<small>.html</small></a></li></ul></li><li><strong><a href="./pyscript_dom/index.html">pyscript_dom</a></strong></li><li><strong><a href="./service-worker/index.html">service-worker</a></strong></li><li><strong><a href="./ui/index.html">ui</a></strong><ul><li><a href="./ui/gallery.html">gallery<small>.html</small></a></li></ul></li></ul></body>
 </html>
diff --git a/pyscript.core/tests/manual/submit.html b/pyscript.core/tests/manual/submit.html
new file mode 100644
index 00000000000..65e68abd2a9
--- /dev/null
+++ b/pyscript.core/tests/manual/submit.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<html>
+  <head>
+    <link rel="stylesheet" href="../../dist/core.css">
+    <script type="module" src="../../dist/core.js"></script>
+  </head>
+  <body>
+    <script type="py-editor" id="editor">
+      import sys
+      print(sys.version)
+    </script>
+    <script type="py" src="submit.py"></script>
+    <button py-click="submit">Submit</button>
+  </body>
+</html>
diff --git a/pyscript.core/tests/manual/submit.py b/pyscript.core/tests/manual/submit.py
new file mode 100644
index 00000000000..e6136ee343d
--- /dev/null
+++ b/pyscript.core/tests/manual/submit.py
@@ -0,0 +1,6 @@
+from pyscript import document
+
+
+def submit(event):
+    editor = document.querySelector("#editor")
+    editor.process(editor.code, True)