












until I turn it back on




<py> icon?









Discord Server and not Discord Channel as this is a server and within server we have channels

pyscript-dev channel or similar, so we have a place for questions/convos related to developing PyScript, vs questions about using PyScriptjest, which feels a little out of place in the pyscript-help channel


pyscript-general and pyscript-dev would be enough, considering the very low traffic that we have, wouldn't them?














py-repl mentions exec-id and root, but they are internal-use only and they should not be documented IMHO







Hello world!













userError haha I misunderstood what you said, I thought you were suggesting that instead of us doing showError("blah") we would do raise UserError and then the withUserErrorHandler should allow the code to keep going. Buuuut.... I clearly misunderstood and tried to do the impossible? showError we just want to stop execution, but in others not like the case where the user passes multiple <py-config> (this should probably be a warning)
raise UserError("my messsage")showWarning("my message")
of course, we also need someone to catch UserError and display the appropriate message on the page. withUserErrorHandler is just a convenience, but you could also do it manuallyshowError is a real error, but then I had to manually use return to stop the execution.
The second showError is actually a warning

showError and the throw. With the new logic, you could just do throw UserError(message), and then the logic to actually display (or not) the error to the user will be handled elsewhere (and it will be configurable)










addToProject CI job fails suddenly: https://github.com/pyscript/pyscript/actions/runs/3379019433 












node when running jest tests 



<py-terminal> tag, implemented as a Plugin (edited)
/pyscriptjs/plugins or /pyscriptjs/src/plugins), new repo (like /pyscript/plugins) or.... ? 

ffmpeg under WASM/WASI, which also explains (although a bit too shortly) the differences between WASI and emscripten:
https://runno.dev/articles/ffmpeg


(module
(import "console" "log" (func $log (param i32)))
(func (export "logIt")
i32.const 13
call $log))
this imports console.log as $log, then creates a function logIt that calls it.
links: https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format
wabt: https://github.com/WebAssembly/wabt






(module
(import "console" "log" (func $log (param i32)))
(func (export "logIt")
i32.const 13
call $log))
this imports console.log as $log, then creates a function logIt that calls it.
links: https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format
wabt: https://github.com/WebAssembly/wabt 





#include <Python.h>) or it's a plan C library and you call it using ctypes/cffi. (I'm not sure that ctypes/cffi works for WASM but in principle they should).
For MicroPython, I have no idea, but the first step is to understand whether it has support for extension modules independently of WASM

import numpy in pyodide dlopen() a library only if if were compiled with the very same version of emscripten that you are using



int32 and doublejs module does in Pyodide



js module. You can try to do it again, but you would quickly end up reimplementing the same thing

js module would take several months, and probably we would introduce other quirks. This always happen when you try to map features of language A onto language B













(module
(import "js" "import1" (func $i1))
(import "js" "import2" (func $i2))
(func $main (call $i1))
(start $main)
(func (export "f") (call $i2))
)
const importObject = {
js: {
import1: () => console.log("hello,"),
import2: () => console.log("world!")
}
};
const wasmInstance = new WebAssembly.Instance( wasmModule, importObject );
const { f } = wasmInstance.exports;
f()








to_file parameter.

to_file parameter. 





if mystring in ('foo', 'bar', baz')?
array.indexOf(search) >= 0 is more efficient according to StackOverflow

<py-repl> widget but with different runtimes (first MicroPython, then Pyodide) - in MicroPyScript.

showWarning or maybe just create the error banner when we call handleFetchError, the test is failing because the page never stops loading - the fetch raises the error so we never call the logic to hide the loading screen.
Also since we get a list of paths in fetch Paths, would it make sense to show the warning and keep trying other paths? 



showWarning or maybe just create the error banner when we call handleFetchError, the test is failing because the page never stops loading - the fetch raises the error so we never call the logic to hide the loading screen.
Also since we get a list of paths in fetch Paths, would it make sense to show the warning and keep trying other paths? pyscript_run in support.py: it takes a param wait_for_pyscript=True which does exactly what you needtest_invalid_toml_config in test_py_config.py, it seems very similar to what you needImportError (if the failed file was a .py file) or a FileNotFoundError later.Errors should never pass silently
(from the Zen of Python) (edited)

py.test tests/integration/test_whatever.py -k the_name_of_your_test -s --dev
--dev is needed to be able to debug the typescript files from the dev tools. Maybe this is useful to understand what's going on


--dev flag haha

--dev removes the loading screen, but no banner still or log messages so yeah something odd going on haha



ImportError (if the failed file was a .py file) or a FileNotFoundError later. 




display() and py-config [[fetch]])

display() and py-config [[fetch]]) 
self.page.locator('py-loader') to find it, but theoretically, if the startup is very fast, it could be already gone by the time my test code runs.
What is the playwright best practice to test such a case?









test_py_config.py::test_paths_that_do_not_exist fails on my machinethis.afterRuntimeLoad(this.runtime); is not wrapped into a withUserErrorHandler
_createBanner in handleFetchError.
If you do --headed does the splash screen disappear from the page? Also what failure are you seeing? 

_createBanner in handleFetchError.
If you do --headed does the splash screen disappear from the page? Also what failure are you seeing? 

await runtime.loadFromFile(paths[i], fetchPaths[i]);
I can see a 404, but it doesn't raise any exception--headed it works, with --dev it doesn't 

--dev uses a real web server
--dev flag runs a server right? So the expected test would fail anyway since it expects to see the "run webserver" error

















/captcha start


































squash&merge. I started my more-plugins branch on top of py-terminal, but now that py-terminal is merged to main, when I do git merge origin/main I get tons of conflict, because from the point of view of git the commit which merged py-terminal has nothing to do with the original branch 

squash&merge. I started my more-plugins branch on top of py-terminal, but now that py-terminal is merged to main, when I do git merge origin/main I get tons of conflict, because from the point of view of git the commit which merged py-terminal has nothing to do with the original branch git rebase --onto=main antocuni/py-terminal antocuni/more-plugins
which basically means "take all the commits which starts from py-terminal (excluded) to more-plugins (included) and rebase them on main (edited)

<script> tag to the <head>: once it's loaded, loadPyodide will be available as a JS global function
https://github.com/pyscript/pyscript/blob/3c3dffd5ede31aaee868e4260379eac86b7e27a2/pyscriptjs/src/main.ts#L139-L144
2. typescript doesn't know about this of course. The typing comes from the npm installed pyodide package, which is not necessarily the same as the one which we load at runtime of course. AFAIK, the local pyodide package is used only for this and to run jest tests:
https://github.com/pyscript/pyscript/blob/3c3dffd5ede31aaee868e4260379eac86b7e27a2/pyscriptjs/src/pyodide.ts#L4-L11
3. I think that "someone, at some point, in some place" (sorry, I don't remember more details) mentioned the fact that we could load pyodide dynamically as a ES module instead of using a <script> tag. It sounds a better solution to me, and maybe it also helps typing (but I don't really know)
custom-typings.d.ts and do something like:
export declare type "Pyodide" { blah}
But that didn't work, although my terrible workaround seems to be okay(ish) , I'm creating an interface like this just to support the extra methods that the Pyodide typing doesn't have
export declare interface PyProxy extends PyProxy {
connect(): void;
get(value: string): function | object;
set(id: string, proxy: PyProxyClass): void;
}
Although the get return is pretty bad 
runtime.run and runtime.globals.get are good examples of this: they can return "whatever", so their return type is just any.
Trying to type them is "static typing for the sake of static typing" IMHO





get specifically even with these types we still need to write a type for the thing we are getting like Display for example.
I might have been a bit too eager to kill all warnings 

eslint-disable on my branch since I’m seeing some weird behaviour where TS has the types but eslint is complaining that the typing is any
let foo
vs
let foo: number | null = nulltsconfig.json set...
"compilerOptions": {
"strict": false
} (edited)npm run tsc you will see the error list in full.
npm run lint thinking that this was the issues that strict mode would complain about 



:wq 

:wq vim suddenly looks like a very reasonable choice 



















stdout of a <py-script> tag on a tag-by-tag basis?
Similar to how <py-script std-out="..."> prior to the introduction of display()?

stdout of a <py-script> tag on a tag-by-tag basis?
Similar to how <py-script std-out="..."> prior to the introduction of display()? 

<py-script> to print() to two different output streams?

sys.stdout and redirect it somewhere else, similar to the old OutputManagerCtx
stdout should be sent to such-and-such HTML element" (or, more powerfully, handled by such-and-such function) and that's not currently something that we can do, unless I've missed something. But yes, something like what was possible with the old OutputManagerCtx and <py-script std-out> (edited)StdioMultiplexer from your Plugin implementation @antocuni ?
StdioMultiplexer doesdisplay()OutputManagerCtx was half-broken 
print() works:
<p>This print() function in Python is how we print things to the terminal</p>
{{ displaycode helloworld.py" }}
<py-script src="helloworld.py" std-out="first-example"></py-script>
<div id="first-example"></div>
<p>print() can be used to print just about any object:</p>
{{ displaycode print_list.py }}
<py-script src="print_list.py" std-out="second-example"></py-script>
<div id="second-example"></div>
#helloworld.py
print("Hello, world"!)
#print_list.py
print([1,2,3,4]) (edited)src="...", but it's mostly used here for brevity. I use it here to emphasize that having the displayed-code and the executed code be the same is really, really useful for ensuring that the examples do what they claim they're going to (edited)
print("Hello, world")
and having to use the following as source:
<py-script>
with ContextManager_RedirectStdoutToElemWithID("first-example"):
print("hello, world")
</py-script> (edited)
<py-script std-out="xxx">
print("what's your name?")
name = input()
</py-script>
Where does the input come FROM?
print() in Python. To make it possible to use PyScript to better illustrate Python concepts in a way that doesn't expose the reader to any additional PyScript machinery (edited)
before-py-script and after-py-script which are executed before and after the execution of each <py-script> tagStdioMultiplexer to redirect each py-script to its own py-terminal


more-plugins PR is almost ready




























pytest -s --dev the experience is not too bad, since you don't have to switch to the browser, pytest takes case of starting one for you




<my-counter> https://github.com/pauleveritt/pyodide-components/blob/main/src/pyodide_components/counter.py#L6



<my-counter> https://github.com/pauleveritt/pyodide-components/blob/main/src/pyodide_components/counter.py#L6 
















<pyscript src="app.py"></py-script>
<pyscript worker="one" src="worker.py"></py-script>

<pyscript src="app.py"></py-script>
<pyscript worker="one" src="worker.py"></py-script> 



from pyscript import Worker
worker = Worker("one") # talk to worker by id
await worker.foo(1,2,3)

//@vitest-environment happy-dom
import { it, expect } from "vitest";
import { loadPyodide } from "../src/pyodide_components/pyodide/pyodide.mjs";
it("should calculate some Python", async () => {
const pyodide = await loadPyodide();
const result = await pyodide.runPythonAsync("1+1");
expect(result).to.equal(2);
});





<py-script async src="async-src.py"></py-script>
<py-script scope="foo" src="foo-src.py"></py-script>
<py-script scope="bar" src="bar-src.py"></py-script>
<py-script worker="one" src="worker-src.py"></py-script>
<py-script>
i = 0
while i<10:
print(i)
# ooops, forgot i+=1
# the UI freezes and the user has to reload the page
</py-script>







numpy.operation_that_takes_very_long(), (i.e., something implemented in C) the UI freezes completely and we cannot do anything until it completes



pydom.document.body.innerHTML = "<div>Foo</div>
My point is that we need to have a Pythonic DOM API anyway. And our hypotetical pydom can have two different backends, one which updates the DOM with real JS calls (for the main thread) and one which can do it with message passing (for workers). And the user won't even noticepydom.document.body is something like this:
class PyNode:
...
def set_inner_html(self, val):
self.postMessage("update", self.id, "innerHTML", val)
innerHTML = property(get_inner_html, set_inner_html)


pydom.document.body is something like this:
class PyNode:
...
def set_inner_html(self, val):
self.postMessage("update", self.id, "innerHTML", val)
innerHTML = property(get_inner_html, set_inner_html) 














chat channel?



chat channel? 







pyconfig we are iterating over each parameter and calling validateParamInConfig if the parameter isnt in the config we just ignore it, should we throw an exception instead? 




pyconfig we are iterating over each parameter and calling validateParamInConfig if the parameter isnt in the config we just ignore it, should we throw an exception instead? Plugin.configure hook
5. each plugin is responsible to read and mark all its settings in its .configure()
6. after the hook, we check whether there are still settings which have never been read. If there are, we emit an error/warning (edited)


Plugin.configure hook
5. each plugin is responsible to read and mark all its settings in its .configure()
6. after the hook, we check whether there are still settings which have never been read. If there are, we emit an error/warning (edited)<py-config>
packages = ['numpy']
[plugins.py-terminal]
auto = true
[plugins.splashscreen]
autoclose = false
</py-config>
I think the process is essentially still the same as you outlined, but except list of top-level keys in py-config is fixed (and includes the 'plugins' table).
plugins. part. E.g. for the splashscreen I've used:
[splashscreen]
autoclose = true
plugins table lets us distinguish misspelled settings from misspelled packages
Like if we parse py-config and it has a top-level key futch, is that a misspelling of [[fetch]] or trying to identify settings for a plugin called futch (or fitch)?[plugin-settings.py-terminal]
auto = true
etc (edited)


Plugin.configure hook
5. each plugin is responsible to read and mark all its settings in its .configure()
6. after the hook, we check whether there are still settings which have never been read. If there are, we emit an error/warning (edited)

plugins table lets us distinguish misspelled settings from misspelled packages
Like if we parse py-config and it has a top-level key futch, is that a misspelling of [[fetch]] or trying to identify settings for a plugin called futch (or fitch)? [plugin.splashscreen] and [splashscreen], apart that the user has to type more: we can easily detect whether there is an "unexpected section" in both cases.




A higher-level is intentional: there might be multiple. And you're plugging into that thing, not to PyScript.
I think this is Ted's view.

[plugin.splashscreen] and [splashscreen], apart that the user has to type more: we can easily detect whether there is an "unexpected section" in both cases. packages = ['numpy']
[splashscreen]
autoclose = true
[py-terminal]
auto = true
{
"packages": [
"numpy"
],
"py-terminal": {
"auto": true
},
"splashscreen": {
"autoclose": true
}
}
VS:
packages = ['numpy']
[plugin.splashscreen]
autoclose = true
[plugin.py-terminal]
auto = true
{
"packages": [
"numpy"
],
"plugin": {
"py-terminal": {
"auto": true
},
"splashscreen": {
"autoclose": true
}
}
}
config.keys() have been used or not, each plugin gets its own object of settings.

A higher-level is intentional: there might be multiple. And you're plugging into that thing, not to PyScript.
I think this is Ted's view. 

config.keys() have been used or not, each plugin gets its own object of settings. plugins.* sections: if someone writes [plugins.py-treminal] I want to make sure to inform them about the typo





packages = ['numpy']
[splashscreen]
autoclose = true
[py-terminal]
auto = true
{
"packages": [
"numpy"
],
"py-terminal": {
"auto": true
},
"splashscreen": {
"autoclose": true
}
}
VS:
packages = ['numpy']
[plugin.splashscreen]
autoclose = true
[plugin.py-terminal]
auto = true
{
"packages": [
"numpy"
],
"plugin": {
"py-terminal": {
"auto": true
},
"splashscreen": {
"autoclose": true
}
}
} 


<py-config>
plugins = ["foo", "bar", "http://..../baz.js"]
</py-config>
where foo and bar are downloaded from some kind of Official PyScript Plugin Store, and baz is downloaded from a custom URL


<py-config>
plugins = ["foo", "bar", "http://..../baz.js"]
</py-config>
where foo and bar are downloaded from some kind of Official PyScript Plugin Store, and baz is downloaded from a custom URL 



collections.deque doesn't support indexing but only push and pop


MemoryError. So he wanted to manually implement a deque using a fixed-size list, and I suggested using collection.deque which seemed perfect for his use case










beforeSetup hook if you call it after the setup? 

beforeSetup hook if you call it after the setup? 


beforeAAA, beforeBBB and beforeCCC hooks instead of afterDDD since they will be fired all together anyway?



beforeAAA, beforeBBB and beforeCCC hooks instead of afterDDD since they will be fired all together anyway? 


beforeExecute I am certain that all beforeSetup hooks were called, because that's the only way to ensure that the setup has been done.
Else, we are just encouraging a mess
Promise.all([list of awaiting events]).then( dispatch "SetupComplete") (pseudo code) to achieve this end.




Promise.all([list of awaiting events]).then( dispatch "SetupComplete") (pseudo code) to achieve this end. 


Promise.all(foo) ensures that a single event is dispatched when they all are finished.



Promise.all(foo) ensures that a single event is dispatched when they all are finished. 




afterSetup hook/event it's because I'm sure that the virtualenv setup has been completed. It's a very explicit sync point
syncing
In my mind, synchronization == 2 ways (either 2 things are aligned or communicating with each other). Events == 1 way (I am notified of an event). Plugins don't send anything back and don't synchronize with anything.. they just receive events in time (via hooks) and do something with it.
CCC hook I am sure that all the plugins have completed the BBB hook (i.e., basically the same logic which @ntoll mentioned in its Promise.all() code above) (edited)beforeSetup hook which can be used e.g. to implement [[fetch]] files = [...] and packages = [...], i.e. to make sure that the python virtualenv is ready and complete.
Then there is a beforeExecute hook which has the invariant that the setup phase has been completed, i.e. I'm sure that I can import all the python packages which I expect

beforeSetup and afterSetup and do a diff and raise an error /warning if I see any weird stuff.
There's no reason why I need to do this synchronously... if we store the config the moment we passed it to beforeSetup hooks and lazy fire the event when the Python Plugins are ready we allow the authors of plugins like this to do something. Rather than saying, you have no future, go write TypeScript
plugin1.afterSetup is called before plugin2.beforeSetup, and this completely breaks your use case.


plugin1.afterSetup is called before plugin2.beforeSetup, and this completely breaks your use case. 
beforePythonIsReady event: you cannot call it in python because this is obviously happening after the interpreter is ready


beforePythonIsReady event: you cannot call it in python because this is obviously happening after the interpreter is ready beforePytonIsReady then, you have no luck in a Python plugin but if your goal is to just read the state of things at that point in time, then it's still useful to have that event be passed to a Python plugin, so you can know the state at that point in time anyway.





pyscript-collective ? If that's too long, ps-collective ?







/latest in all our docs and official examples: people will just copy&paste the <script> tag and the result is that we are involuntary encouraging to publish pyscript apps which will break after 30 days


/releases/2022.09.1/.... exists. Personally, I wanted to use it at some point and I couldn't find the exact url in the docs /latest altogether. I cannot think of any reasonable use case in which you want to use it (unlike /unstable, which is useful if you want to use a feature which hasn't been released yet)
latest will be feasible, but not soon.
/latest been widespread for a couple versions since versioning was first announced, maybe need to find a way to deprecate it. A warning banner at the top of the page saying you should be linking to a pinned release? Not sure exactly how that would work from a deployment standpoint, but could even be something that gets done "manually" (changed, rebuilt, uploaded to /latest resource on AWS)


/latest been widespread for a couple versions since versioning was first announced, maybe need to find a way to deprecate it. A warning banner at the top of the page saying you should be linking to a pinned release? Not sure exactly how that would work from a deployment standpoint, but could even be something that gets done "manually" (changed, rebuilt, uploaded to /latest resource on AWS) /latest to the current release. IMHO it's better to keep apps working+warning than broken+warning

backlog tag to our valid issues, otherwise they'll be automatically close by the bot! 



backlog tag to our valid issues, otherwise they'll be automatically close by the bot! backlog? 







/latest been widespread for a couple versions since versioning was first announced, maybe need to find a way to deprecate it. A warning banner at the top of the page saying you should be linking to a pinned release? Not sure exactly how that would work from a deployment standpoint, but could even be something that gets done "manually" (changed, rebuilt, uploaded to /latest resource on AWS) alpha . (Just adding that as a data point)







sys.stdin.read(). I didn't see the VS code thing, but I guess that their debugging work by putting some blocking call inside a trace function installed using sys.settrace


pdb by faking user input.
I'm a bit surprised, I assumed they would use bdb which is made exactly for this
(basically: bdb implements the core functionality, and pdb adds a terminal-based UI on top of it)/$debug/input, which seems to be implemented here:
https://github.com/microsoft/vscode-python-web-wasm/blob/78bd69365bbf53957ca16f9b1ab87fba5dfe34b3/src/common/debugFileSystem.ts#L186-L188
but then it forwards to apiClient.byteSource.read(), which is most likely the blocking call



/$debug/input, which seems to be implemented here:
https://github.com/microsoft/vscode-python-web-wasm/blob/78bd69365bbf53957ca16f9b1ab87fba5dfe34b3/src/common/debugFileSystem.ts#L186-L188
but then it forwards to apiClient.byteSource.read(), which is most likely the blocking call apiClient.byteSource.read() returns a promise (see: https://github.com/microsoft/vscode-python-web-wasm/blob/78bd69365bbf53957ca16f9b1ab87fba5dfe34b3/src/common/debugCharacterDeviceDriver.ts#L45) I'm not at all clear what the const disposable does to cause waiting for user input. I have no idea what the .dispose() method does, for instance (it's not something in the "standard" Promises API AFAICT)
import { CharacterDeviceDriver, FileDescriptorDescription, RAL as SyncRal } from '@vscode/sync-api-service';
I don't know exactly how it's implemented, but it seems to be explicitly a sync api





runtime into interpreter.
Probably at some point we should do the renaming, although probably it's better to wait for the next release.
(And personally, I'd also like to make it a single entry and not a list... we support only a single interpreter anyway).


runtime into interpreter.
Probably at some point we should do the renaming, although probably it's better to wait for the next release.
(And personally, I'd also like to make it a single entry and not a list... we support only a single interpreter anyway). 

runtime into interpreter.
Probably at some point we should do the renaming, although probably it's better to wait for the next release.
(And personally, I'd also like to make it a single entry and not a list... we support only a single interpreter anyway). 







+ icon as you usually do to insert a comment

+ icon as you usually do to insert a comment 










make tests parallel throw different failures (Fabio noticed this last week (was it last week or this one?)) (edited)



make tests parallel throw different failures (Fabio noticed this last week (was it last week or this one?)) (edited)make tests-parallel just run pytest -n under the hood.
-n activates the pytest-xdist plugin, which is responsible for the actual parallelization
So, it's not pytest vs make, it's pytest vs pytest+xdist.
According to my experience, it's very likely that it's a bug in our testsuite (e.g., a common mistake is to have multiple tests trying to write/read to the same file in parallel, so you have a race condition).
What is the exact error?































paths_from_pacakges fails with this (as written) as the pyscript:
import js
from pkg.a import x
js.console.log(x)
but this passes
import os
import js
from pkg.a import x
js.console.log(x)pkg" (edited)



pyodide.create_proxy is now pyodide.ffi.create_proxy in v21, and the presence of Pyodide's deprecation warning is throwing off the tests





await somewhere), I would be surprised if it has anything to do with xdist.
If you see that the single test passes with xdist fails, it is very likely that running in parallel makes each test slightly slower, meaning that JS has more time to complete some fetch.

await somewhere), I would be surprised if it has anything to do with xdist.
If you see that the single test passes with xdist fails, it is very likely that running in parallel makes each test slightly slower, meaning that JS has more time to complete some fetch. 



<py-script> tag before execution and save the sources in a different div

<py-script> tag before execution and save the sources in a different div py-plot plugin that would use matplotlib under the hood to create things (but havent thought much about how it would work haha)




plugins = ["py-plot"] and we automatically know where and what to download.
When you do pip install foo you don't have to tell pip the complete lists of files to download 

output in for this release if possible 

plugins = ["py-plot"] and we automatically know where and what to download.
When you do pip install foo you don't have to tell pip the complete lists of files to download foo-plugin folder that has a bunch of python files, we would do plugins = ['foo-plugin'] and would import the whole folder? I like that 

output in for this release if possible 

foo-plugin folder that has a bunch of python files, we would do plugins = ['foo-plugin'] and would import the whole folder? I like that 






pyscript.write and do Element().write or display right? 
pyscript.runtime.interpreter.runPython("1+2")pyscript the instance vs PyScript the class in pyscript.py




pyscript.write and do Element().write or display right? pyscript and import pyscript are two different things is enough to block.
We should try to slowly clean the mess, not introducing new one 
import pyscript isn't possible at all until #961 is merged; that PR is now doing several things at once

pyscript and import pyscript are two different things is enough to block.
We should try to slowly clean the mess, not introducing new one 

import pyscript isn't possible at all until #961 is merged; that PR is now doing several things at once 




git merge it works out of the box, and it doesn't make much different at the end because we do squash&merge anyway























pyimport to find them... will post an issue with a minimal reproduction and some notes. Edit: it's possible it's just an odd interaction with the live-refresh dev server... hopefully a false alarm (edited)





















git bisect and find the PR which introduced the flakyness? Although I suspect it's #961 (python plugins)

pyscript.runtime.interpreter.FS.open("pkg/a.py") worked

test_paths_from_packages as my guinea pig 
ImportError in test_zz_examples









ModuleNotFoundError: No module named 'first_plugin'python3 -m http.server, VS Code Live server....




sys.meta_path cache invalidation; going to open a WIP PR to test against CI, but passing locally 10 times in a row

sys.meta_path cache invalidation; going to open a WIP PR to test against CI, but passing locally 10 times in a row 







runtime.run instead?

runtime.run instead? 
interpreter unless absolutely necessary
runtime.invalidate_import_cache() so it's not 4 copy-pastes of the same thing; I think both are a nice idea










self.element.source seems to be underfined

self.element.source seems to be underfined 
micropip.install, if they are executed before we finish to write things to the FS


Element long term, or if we want something better

Element long term, or if we want something better Element to be a nice way to interact with the elements in the page, do you have any ideas of alternatives?
Element.
Or, said in a different but more or less equivalent way: we could tweak/change/expand Element to be more complete

Element("foo") current APIpage.foopydom.page.foopydocument.fooapp.fooapp.elements.fooapp.elements.get('foo')
LocalStorage to interact with the browser's local storage in a python way, what do you think?Element("foo") is nice and short 



Element("foo") is nice and short Element("foo") is the bestElement interacts badly with iframes, because it assumes you want to access the global document.
This might or might not be enough to change it, but we need to think


Element("foo") current APIpage.foopydom.page.foopydocument.fooapp.fooapp.elements.fooapp.elements.get('foo')













jasmine @ntoll ? just curious 





spec folder. They're BDD style.















import pyxmastree
pyxmastree.on()


pyscript-rpi channel for this sub-project?

pyscript-gpio












n to run it multiple times:
@pytest.mark.parametrize('n', range(20))
def test_paths_from_packages(self, n):
...
And then use pytest -v --tb=no for a nice summary:

pytest-repeat that does a similar thing, you can use --count to run the same test n times



importlib.invalidate_cache 



def test_importlib1(self):
self.pyscript_run(
"""
<py-script>
with open('bar.py', 'w') as f:
f.write("x = 42")
import bar
print(bar.x)
</py-script>
"""
)
def test_importlib2(self):
self.pyscript_run(
"""
<script>
function onClick() {
pyscript.runtime.interpreter.FS.writeFile('bar.py', "x = 42");
printBar();
}
</script>
<py-script>
import js
def printBar():
print("hello from Python")
import bar
print(bar.x)
js.printBar = printBar
</py-script>
<button onclick="onClick()">click me</button>
"""
)
They both "work", in the sense that you can immediately do import bar after having written the file to the FS











importlib.invalidate_cache loadPyodide calls runPython internally: https://github.com/pyodide/pyodide/blob/e002c19af8906fd3b9199aa4bad6fe727d0b0451/src/js/pyodide.ts#L374
importlib.invalidate_caches doesn't actually solve the problem, but it just adds enough delay that the problem is hidden

importlib perspective..
We should definitely add the big file one though (edited)
test_importlib2 passes reliably on my machine, it doesn't seem flaky. Which seems to confirm that `pyodide.FS.writeFile() followed by a python import should just work

importlib.invalidate_caches() with a busy-wait, and it becomes flaky again







invalidate_module_path_cache(): void {
function busyWait(ms) {
console.log("busy wait start", ms);
let start = new Date().valueOf();
while( (new Date()).valueOf() - start < ms)
;
console.log("busy wait end");
}
busyWait(100);
// const importlib = this.interpreter.pyimport("importlib")
// importlib.invalidate_caches()
}
i.e., a busy loop instead of actual calling invalidate_caches().
With busyWait(1000) test_paths_from_packages passes reliably. With busyWait(100) it's still flaky



pyodide.asm.js has been prettier'd so you can modify the JavaScript code in place to add extra console.warn s and other debug stuff without rebuilding Pyodide.Date object with a mock object that replays the time stamps from the native session and see how the behavior changes. Though this would be a bit complicated to get right (edited)

output option in <py-repl>?<py-repl> to behave like before (output contextual to the cell I execute)?

Date object with a mock object that replays the time stamps from the native session and see how the behavior changes. Though this would be a bit complicated to get right (edited)


<py-repl> to behave like before (output contextual to the cell I execute)? 

<py-repl> flow is so weird

output is gone for py-script tags... is it also gone for repl?














output just not working at all




output just not working at all output now only affects the values returned from expressions; it has no affect on where your stdout goes



output now only affects the values returned from expressions; it has no affect on where your stdout goes 

print for instance?import this and I'd like it to output on a div of choice.

print for instance? <py-repl id="my-repl" auto-generate="true" output="my-output"> </py-repl>
<div style="background-color: #f0ab3c; height: 12rem;" id="my-output"></div>
Then putting the following in the repl should put "42" into the orange div:
>>> x = 42
>>> x
But this will put it in a <py-terminal>
>>> x = 42
>>> print(x)


import this and I'd like it to output on a div of choice. import this in a div of your choice


antigravity working on your branch?
AttributeError: module 'antigravity' has no attribute 'fly'
Traceback (most recent call last):
File "/lib/python3.10/site-packages/_pyodide/_base.py", line 435, in eval_code
.run(globals, locals)
File "/lib/python3.10/site-packages/_pyodide/_base.py", line 304, in run
coroutine = eval(self.code, globals, locals)
File "<exec>", line 1, in <module>
File "/home/pyodide/antigravity.py", line 44, in <module>
_auto = Antigravity(append=True)
File "/home/pyodide/antigravity.py", line 14, in __init__
target = target or sys.stdout._out
AttributeError: '_io.TextIOWrapper' object has no attribute '_out'




output attr. to be able to have notebook behaviour
that happens by default with auto-generate enabled
x = 42; x.... but if you do print(x) it goes somewhere else entirely (a <py-terminal>)
output attr is because I was already using it for one example. Since it doesn't work, I wanted to use the notebook behaviour... none of them work atm so I have 0 options really
npm run build
for some reason, it didn't work on my ongoing npm run dev
these two behave differently and I think they shouldn't? (but not sure what are the typescript norms)
npm run dev was running? That's I think where mine threw up... I had to kill and restart the build. Not sure if that was the culprit...
dev picks up on the different branches...
I'm not sure what's up


stdout should go to the same location as the results of expressions, which are placed according to display() rules (next-sibling of current element)
Which seems reasonable - it means either bypassing or rethinking the stdiomultiplixer from @antocuni 's #917.
Apologies if this got too in-the-weeds too fast - I've spent a lot of time in the commit history prepping the release blog post (5300 words and counting)



stdout should go to the same location as the results of expressions, which are placed according to display() rules (next-sibling of current element)
Which seems reasonable - it means either bypassing or rethinking the stdiomultiplixer from @antocuni 's #917.
Apologies if this got too in-the-weeds too fast - I've spent a lot of time in the commit history prepping the release blog post (5300 words and counting) 





display() and rethought stdout) would break them 

display() and rethought stdout) would break them 






2022-12-01 Y&T or 01 Dec Status Update, or something like that




Kalendis Decembribus MMXXII A.D.



[[fetch]] section in the draft blog post, the snippet for
Multiple Fetch Configs
has with open('data.csv', 'rb') as fp: while it should be sensordata.csv (edited)


so display(<br>) prints the literal characters: it's missing quotes around <br>, should be display("<br>")for loop

so display(<br>) prints the literal characters: it's missing quotes around <br>, should be display("<br>")for loop



const { loadPyodide } = require("pyodide");
function busyWait(ms) {
let start = new Date().valueOf();
while( (new Date()).valueOf() - start < ms)
;
}
async function main() {
let pyodide = await loadPyodide({
indexURL: "./node_modules/pyodide",
});
console.log("Pyodide version: ", pyodide.version);
try {
pyodide.FS.writeFile('bar0.py', 'x = 0');
pyodide.runPython('import bar0; print(bar0.x)');
// if you uncomment EITHER line, it works
//pyodide.runPython('import importlib; importlib.invalidate_caches()');
//busyWait(1000);
pyodide.FS.writeFile('bar1.py', 'x = 1');
pyodide.runPython('import bar1; print(bar1.x)');
}
catch(e) {
console.log(e);
}
}
main(); (edited)busyWait(1000) it works; with busyWait(100) is fails

const { loadPyodide } = require("pyodide");
function busyWait(ms) {
let start = new Date().valueOf();
while( (new Date()).valueOf() - start < ms)
;
}
async function main() {
let pyodide = await loadPyodide({
indexURL: "./node_modules/pyodide",
});
console.log("Pyodide version: ", pyodide.version);
try {
pyodide.FS.writeFile('bar0.py', 'x = 0');
pyodide.runPython('import bar0; print(bar0.x)');
// if you uncomment EITHER line, it works
//pyodide.runPython('import importlib; importlib.invalidate_caches()');
//busyWait(1000);
pyodide.FS.writeFile('bar1.py', 'x = 1');
pyodide.runPython('import bar1; print(bar1.x)');
}
catch(e) {
console.log(e);
}
}
main(); (edited)



runtime.invalidate_module_path_cache() is a proper and reliable workaround /me ==> dinner







<!DOCTYPE html>
<html>
<body>
<?php
$x = "Hello world!";
echo $x;
?>
</body>
</html>






















const { loadPyodide } = require("pyodide");
function busyWait(ms) {
let start = new Date().valueOf();
while( (new Date()).valueOf() - start < ms)
;
}
async function main() {
let pyodide = await loadPyodide({
indexURL: "./node_modules/pyodide",
});
console.log("Pyodide version: ", pyodide.version);
try {
pyodide.FS.writeFile('bar0.py', 'x = 0');
pyodide.runPython('import bar0; print(bar0.x)');
// if you uncomment EITHER line, it works
//pyodide.runPython('import importlib; importlib.invalidate_caches()');
//busyWait(1000);
pyodide.FS.writeFile('bar1.py', 'x = 1');
pyodide.runPython('import bar1; print(bar1.x)');
}
catch(e) {
console.log(e);
}
}
main(); (edited)



















python -m http server locally requires two refreshes to load code changes.
4. requests in pyscript(via pyfetch/open_url)






debugger line in a Jest test and stop there in dev tools?
tests/integration/*.py, they don't use jest.
I agree that jest is horrible 




debugger works.
I run tests individually using a command like this:
py.test test_01_basic.py -k test_pyscript_hello -s --dev







fetch docs 






























































plt.show and using AGG underneath isn't really needed so I have closed the associated PR i.e. https://github.com/pyscript/pyscript/pull/1023
I have commented on the original issue i.e. https://github.com/pyscript/pyscript/issues/983 on how to use display correctly.
If someone else can confirm that my proposed way works, we can close https://github.com/pyscript/pyscript/issues/983
CCing @FabioRosado since he reviewed https://github.com/pyscript/pyscript/pull/1023 originallyplt.show, I can re-open the PR
but I support using display for all purposes. Hence, I closed the PR for the patch


display correctly with matplotlib



display thing to the docs
and then we should be good to go?





display with matplotlib in the meanwhile.











py-config





make test-integration, I get a consistent failure in TestConfig.test_runtime_config
FileNotFoundError: [Errno 2] No such file or directory: '/var/folders/c1/br776hbd0llfk_l01ckngqvm0000gp/T/tmp92ipi5ml/pyodide-build-0.20.0.tar.bz2'

make test-integration, I get a consistent failure in TestConfig.test_runtime_config
FileNotFoundError: [Errno 2] No such file or directory: '/var/folders/c1/br776hbd0llfk_l01ckngqvm0000gp/T/tmp92ipi5ml/pyodide-build-0.20.0.tar.bz2' 


/lib/python3.10/site-packages/pyodide/__init__.py:74: FutureWarning: pyodide.to_js has been moved to pyodide.ffi.to_js Accessing it through the pyodide module is deprecated.
warn(

make test-integration, I get a consistent failure in TestConfig.test_runtime_config
FileNotFoundError: [Errno 2] No such file or directory: '/var/folders/c1/br776hbd0llfk_l01ckngqvm0000gp/T/tmp92ipi5ml/pyodide-build-0.20.0.tar.bz2' pytest cachepyodide 0.20 for subsequent runs, so that it's not downloaded each time for that test





rm -rf .pytest_cache/ inside pyscriptjs directory


stdout from MicroPython emits JSON, and polyplug is listening.


polyplug but need to integrate it into the work I did in MicroPyScript.





import json
def output(content):
print(json.dumps({"type": "stdout", "content": content}))
As you can see, it's very simple. But this will soon get built out and improved to cater to all the message types polyplug understands (updating DOM elements, registering events etc...)


panel from 13.1 -> 14.1) is up for a quick review: https://github.com/pyscript/pyscript/pull/1032

panel from 13.1 -> 14.1) is up for a quick review: https://github.com/pyscript/pyscript/pull/1032 













matplotlib in pyscript vs jupyterlite and consequences of merging these two approaches. And this also touches on switching to AGG (this discussion will come up when we start talking about web-workers) : https://github.com/pyscript/pyscript/issues/983#issuecomment-1343948823
just mentioning here 








dom manipulation/interaction API, what tools/libraries/APIs would you take inspiration from? I.e., I think playwright api to navigate and access elements is pretty nice...































dom manipulation/interaction API, what tools/libraries/APIs would you take inspiration from? I.e., I think playwright api to navigate and access elements is pretty nice... 

dom manipulation/interaction API, what tools/libraries/APIs would you take inspiration from? I.e., I think playwright api to navigate and access elements is pretty nice... 

dom manipulation/interaction API, what tools/libraries/APIs would you take inspiration from? I.e., I think playwright api to navigate and access elements is pretty nice... 

lxml in the past quite a bit. Some aspects are 
nodeType (in the world of the web) vs. node_type if we use the Pythonic naming conventions... or element.attributes.class (i.e. <div class="myCssClass"> in HTML) vs. element.attributes.class (causing a SyntaxError because of the use of the keyword "class") in Python. (edited)

npx python-wasm@latest
























































PongBall widget with a property pos and you use this property in the UI file. When you update pos in the code, the UI is automatically updated
https://kivy.org/doc/stable/tutorials/pong.html#pongball-class


PongBall widget with a property pos and you use this property in the UI file. When you update pos in the code, the UI is automatically updated
https://kivy.org/doc/stable/tutorials/pong.html#pongball-class 







<form id="inputForm">
<label for="english">Translate English 🇬 🇧 to Pirate speak 🏴<200d>☠️:</label>
<input type="text" name="english" id="english"
placeholder="Type English here..." />
<input type="submit" value="Translate"/>
<div id="output"></div>
</form>
<py-script>
import arrr
from polyplug import plug, update, receive
@plug("#inputForm", "submit")
def handle_form(event):
"""
Take the English input from the form, turn it into Pirate talk and update
the DOM with the result.
"""
english = event.target.find("#english").value
pirate_text = arrr.translate(english)
output = event.target.find("#output")
output.innerHTML = f"<p>{pirate_text}</p>"
update("#output", output)
</py-script>
<div id="arrr"/>
We get....event.target)#id, .classes and other cool things.










PyTutor plugin that basically automates the "show code" feature we have in our examples..
I'm trying to check but we didn't have any tests for that feature, did we?

PyTutor plugin that basically automates the "show code" feature we have in our examples..
I'm trying to check but we didn't have any tests for that feature, did we? 



zipimport2 branch, which distribute the stdlib as .pyc files instead of .py. IIRC, when I tried to use it under node.js in Paris, it showed a 2x speedup on startup time def test_default(self):
self.pyscript_run(
"""
<py-script>
print('hello pyscript')
</py-script>
"""
)
def test_gh_pages_0_21_3(self):
self.pyscript_run(
"""
<py-config>
[[runtimes]]
name = "pyodide-0.21.3"
src = "https://antocuni.github.io/files/pyodide/0.21.3/pyodide.js"
lang = "python"
</py-config>
<py-script>
print('hello pyscript')
</py-script>
"""
)
def test_gh_pages_zipimport2(self):
self.pyscript_run(
"""
<py-config>
[[runtimes]]
name = "pyodide-0.22.0.dev0-zipimport2"
src = "https://antocuni.github.io/files/pyodide/0.22.0.dev0/zipimport2/pyodide.js"
lang = "python"
</py-config>
<py-script>
print('hello pyscript')
</py-script>
"""
)hello pyscript on the console:
$ py.test tests/integration/test_01_basic.py -k test_default -s --no-fake-server
[...]
[ 7.12 console.log ] hello pyscript--no-fake-server is needed, else the fake server caches the requests (and part of the speedup should come by the fact that .pyc are smaller)test_default: 5.29 seconds
test_gh_pages_0_21_3: 6.40 seconds
test_gh_pages_zipimport2: 4.30 seconds
But I have a very unstable 4g connection, so I don't know how real these numbers are



plugins to fetch a python plugin, they get loaded correctly because we are using the same fetch logic as py-config 

test_default: 5.29 seconds
test_gh_pages_0_21_3: 6.40 seconds
test_gh_pages_zipimport2: 4.30 seconds
But I have a very unstable 4g connection, so I don't know how real these numbers are test_default: 2.52s (without --no-fake-server between 3-4s)
test_gh_pages_0_21_3: 2.51 ( without --no-fake-server 3.9-4s)
test_gh_pages_zipimport2: 2-3s (without --no-fake-server 2.88s)

test_default: 2.52s (without --no-fake-server between 3-4s)
test_gh_pages_0_21_3: 2.51 ( without --no-fake-server 3.9-4s)
test_gh_pages_zipimport2: 2-3s (without --no-fake-server 2.88s) 
--no-fake-server


--no-fake-server 































async import which solved a lot of problems. The javascript plugin will have to look like any Plugin and contain the same shape, but currently only afterSetup is being called.
We also can't do extend Plugin since the module has no notion of pyscript.plugin.Plugin. There's a lot of rough edges, but at least the code that fetches the plugin isn't too ugly 





print('hello world'):
https://antocuni.github.io/files/pyodide/misc/benchmark_pyodide_startup.html

async import which solved a lot of problems. The javascript plugin will have to look like any Plugin and contain the same shape, but currently only afterSetup is being called.
We also can't do extend Plugin since the module has no notion of pyscript.plugin.Plugin. There's a lot of rough edges, but at least the code that fetches the plugin isn't too ugly 


pyscript.plugin.Plugin above got me confused (not sure why because we don't have that on the Python namespace anyway lol
pyscriptjs/plugin.Plugin













runtimes.ts? I'm renaming 'runtimes' to 'interpreter' and I wonder if perhaps it should move to main instead?



runtimes.ts? I'm renaming 'runtimes' to 'interpreter' and I wonder if perhaps it should move to main instead? 













create_proxy deprecation warning. Will investigate and get a follow-up PR in.
[project] , where we move all the configs that we allow on root now? Or we are happy with the current status?
I personally feel like it'd be a positive change that would be more aligned with the standard in Python-land and also keep things more organized... but don't have a super strong opinion about it.
Thoughts?


name = "Bla"
instead of
[project]
name = "Bla

[project] , where we move all the configs that we allow on root now? Or we are happy with the current status?
I personally feel like it'd be a positive change that would be more aligned with the standard in Python-land and also keep things more organized... but don't have a super strong opinion about it.
Thoughts? 

create_proxy deprecation warning. Will investigate and get a follow-up PR in. 


























































sys.stdout)







print already goes to both, and js.console.log is so explicitly a JS concept it feels odd to override it
f'<div id={el_id!r}>'
Instead of:
f'<div id="{el_id}">'
I've opened up https://github.com/pyscript/pyscript/pull/1121 to simply ignore this recommendation mostly because I think the second versions is more explicit.
if we all agree with this change, we need to merge it soon so we can merge other PRs.
Otherwise we can always update all the f-strings to use the !r




Warning:
PackagesNotFoundError: The following packages are not available from current channels:
- python=3.11.1
Current channels:
- https://conda.anaconda.org/conda-forge/linux-64
- https://conda.anaconda.org/conda-forge/noarch
- https://repo.anaconda.com/pkgs/main/linux-64
- https://repo.anaconda.com/pkgs/main/noarch
- https://repo.anaconda.com/pkgs/r/linux-64
- https://repo.anaconda.com/pkgs/r/noarch



















globalThis.someFunc = someFunc


globalThis.xxx = 42 and window.xxx = 42 in the browser?
Or it's just that globalThis works also in node?








-sASYNCIFY=2 generates a module that requires JSPI. Maybe we can work with emscripten to provide a mode with a fallback for non supporting runtimes.
ASYNCIFY=2 doesn't do a fallback if it's missing but code is structured in a way that would make it a fairly simple change
.pyc files, but we can easily preprocess a pyscript page to pre-compile all the tags and files




























output attribute for REPLs) is finally ready for review. Sorry it took an age, obviously no rush to get it integrated 
















AttributeError: 'TestExamples' object has no attribute '_js_errors'
when I try to run it with pytest -vv tests/integration/ --log-cli-level=warning
but! the funny thing is, if I try to run with make test
everything works perfectly
anyone reproducing it or seeing similar?


AttributeError: 'TestExamples' object has no attribute '_js_errors'
when I try to run it with pytest -vv tests/integration/ --log-cli-level=warning
but! the funny thing is, if I try to run with make test
everything works perfectly
anyone reproducing it or seeing similar? 

AttributeError: 'TestExamples' object has no attribute '_js_errors'
when I try to run it with pytest -vv tests/integration/ --log-cli-level=warning
but! the funny thing is, if I try to run with make test
everything works perfectly
anyone reproducing it or seeing similar? 4c30359 (i.e., the latest commit in main as of now) and they seem to work finepytest command line invokes the right python?
What happens if you do python -m pytest instead of pytest?
python -m pytest throws some craazy numpy errors i've never seen before (edited)E ImportError:
E
E IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!
E
E Importing the numpy C-extensions failed. This error can happen for
E many reasons, often due to issues with your setup or how NumPy was
E installed.
E
E We have compiled some common reasons and troubleshooting tips at:
E
E https://numpy.org/devdocs/user/troubleshooting-importerror.html
E
E Please note and check the following:
E
E * The Python version is: Python3.10 from "/Users/mariana/miniconda3/envs/pyscript/bin/python"
E * The NumPy version is: "1.23.5"
E
E and make sure that they are the versions you expect.
E Please carefully study the documentation linked above for further help.
E
E Original error was: No module named 'numpy.core._multiarray_umath'
pytest-playwright and that was the problem
opening a PR with docs on how to install the test env 





Interpreter class: we need to make it "webworker-friendly", which means (at least):
1. kill interpreter.globals
2. kill all the usages of pyimport
3. make interpreter.run async again 












npm install













asyncio.gather etc and don't have to reimplement these ourselves.
If we had a syncifying decorator we can always do dispatch with await and then call the function synchronously outside:
@syncify
async def do_the_thing(selector, new_value):
await main_thread.querySelector(".blah").setattr("innerHTML", new_value)
await main_thread.fetch("a thing")
def g():
do_the_thing(".blah1", "blah_value")
do_the_thing(".blah2", "blah_value")
The definition of syncify would look like:
def syncify(func):
def wrapper(*args):
orig_loop = asyncio.get_event_loop()
asyncio.set_event_loop(MainThreadDispatchLoop())
try:
return asyncio.run(func(*args))
finally:
asyncio.set_event_loop(orig_loop)
return wrapper (edited)

asyncio.gather etc and don't have to reimplement these ourselves.
If we had a syncifying decorator we can always do dispatch with await and then call the function synchronously outside:
@syncify
async def do_the_thing(selector, new_value):
await main_thread.querySelector(".blah").setattr("innerHTML", new_value)
await main_thread.fetch("a thing")
def g():
do_the_thing(".blah1", "blah_value")
do_the_thing(".blah2", "blah_value")
The definition of syncify would look like:
def syncify(func):
def wrapper(*args):
orig_loop = asyncio.get_event_loop()
asyncio.set_event_loop(MainThreadDispatchLoop())
try:
return asyncio.run(func(*args))
finally:
asyncio.set_event_loop(orig_loop)
return wrapper (edited)








plt.show().
We should fix it

plt.show(), it should either -- ehm -- show it or raise an error if it cannot be shown


plt.show() calls display(plt).
Or maybe we could add a new "pyscript backend" to matplotlib, so that .show() calls display() automatically


.setattr() syntax. Maybe it's possible to achieve something like this:
from js import document # this is "sync" be default
async def myfunc():
doc = Lazy(document)
foo = doc.getElementById("foo")
foo.innerHTML = "hello"
await foo
# or maybe await doc; I guess they probably would be equivalent

.setattr() syntax. Maybe it's possible to achieve something like this:
from js import document # this is "sync" be default
async def myfunc():
doc = Lazy(document)
foo = doc.getElementById("foo")
foo.innerHTML = "hello"
await foo
# or maybe await doc; I guess they probably would be equivalent Lazy(some_js_object) returns an object which records all the operations done on it (and on the results of these ops) and then sends them to the main thread when you do await

plt.show() calls display(plt).
Or maybe we could add a new "pyscript backend" to matplotlib, so that .show() calls display() automatically 

Lazy(some_js_object) returns an object which records all the operations done on it (and on the results of these ops) and then sends them to the main thread when you do await await foo was more expressive. I think it's not immediate to a noob user what they are waiting for... Maybe being more explicit and awaiting a sync method is more expressive even if a level deeper?


.setattr() syntax. Maybe it's possible to achieve something like this:
from js import document # this is "sync" be default
async def myfunc():
doc = Lazy(document)
foo = doc.getElementById("foo")
foo.innerHTML = "hello"
await foo
# or maybe await doc; I guess they probably would be equivalent 
foo = await doc.getElementById("foo")
await doc.someFunc(foo)
2. Your proposal, perfectly possible to implement afaict
foo = doc.getElementById("foo")
foo.someAttr = "blah"
await foo # returns a proxy for foo,
# also assigns someAttr as a side effect
3. I'm not sure what this would do:
foo = doc.getElementById("foo")
await doc,someFunc(foo)
await foo
Does it execute document.getElementById twice? Once? If only once, how does that work? Do the objects foo and doc.someFunc(foo) know they are tied together in some way? (edited)foo object can't be used as an argument to a function, but it can have attributes / items assigned to them? I guess if 3 raises an error saying "please await foo first!" maybe that's clear enough.foo has to be mutable, whereas I would really prefer the "Synclink proxies" to be immutable or else things are kind of spookydoc.getElementById("foo").someAttr = "blah" and they don't hold onto the foo to await it, nothing will happen... but this is also a problem in general. Maybe we can print something like RuntimeWarning: coroutine 'f' was never awaited in the destructor.

foo = await doc.getElementById("foo")
await doc.someFunc(foo)
2. Your proposal, perfectly possible to implement afaict
foo = doc.getElementById("foo")
foo.someAttr = "blah"
await foo # returns a proxy for foo,
# also assigns someAttr as a side effect
3. I'm not sure what this would do:
foo = doc.getElementById("foo")
await doc,someFunc(foo)
await foo
Does it execute document.getElementById twice? Once? If only once, how does that work? Do the objects foo and doc.someFunc(foo) know they are tied together in some way? (edited)await it twice.
E.g., if you start with Lazy(document), you can do all operations that you want, and they would be executed only when you use await. Once you have done that, you cannot call await on it (or on any other intermediate object) again.
That said, I'm not sure it's a good idea, I'm mostly thinking aloud










SyncLink proxies and PyProxys 
RemoteInterpreter into a SyncLink proxy: is the code available somewhere?
synclink branch and builds on top of split-interpreter branch. (edited)
split-interpreter branch is ready to a final review/merge, or it's still WIP?
split-interpreter has a PR open, and it should be ready I guess -- https://github.com/pyscript/pyscript/pull/1218 (edited)

split-interpreter has a PR open, and it should be ready I guess -- https://github.com/pyscript/pyscript/pull/1218 (edited)
test_asyncio_gather is passing locally but failing in CI? The resulting list should be [3,2,1] but is coming out as [3, 2, 1]... but only in CI? I see the split interpreter class PR has a quick fix (stripping the result of spaces) but I'd still like to know why it started failing all of a sudden (edited)







CONTRIBUTING file:
Contributors are invited to be maintainers of the project by demonstrating good decision making in their contributions, a commitment to the goals of the project, and consistent adherence to the code of conduct. New maintainers are invited by a 3/4 vote of the existing maintainers.
So, let's vote! I'm obviously +1



.ts file to the project, it gets bundled with the all the rest inside pyscript.js, but for workers I want the typescript compiler to output it to another file.
A quick google doesn't find anything relevant



pyscriptjs/rollup.config.js. It looks like a harmless file but it has a pretty significant impact on the way the app works...api.ts, pyodide.ts, and pyodide.umd.ts so we export a list of three configs.
https://github.com/pyodide/pyodide/blob/main/src/js/rollup.config.mjs


pyscript.js with all the "main" code and worker_interpreter.js with the (very minimal so far) worker codeworker_interpreter.tsantocuni/play-with-workers branch on GH:
https://github.com/pyscript/pyscript/commit/3c928e796f27ca8adaded620333264f088398163src/workers/worker_interpreter.ts: from that file, I try to import { add } from './foo';, which is a file next to it

RemoteInterpreter from one directory up








pys-onClick should be removed not in the next version of pyscript, but the one the comes next
because we're adding the deprecation warnings right now? (they weren't there in the 2022.12.1 version)
correct @FabioRosado ? (edited)

pys-onClick should be removed not in the next version of pyscript, but the one the comes next
because we're adding the deprecation warnings right now? (they weren't there in the 2022.12.1 version)
correct @FabioRosado ? (edited)



















test_pyscript_hello passes.
It's very likely that this branch will never be merged and that I'll have to re-do it on top of the synclink branch once it's done, but it's cool to see that it actually works.
https://github.com/pyscript/pyscript/tree/antocuni/play-with-workers







<py-script> tags dynamically (or, equivalently, that if you do they are not executed).
Originally I introduced that test because it was easy to implement and mimics the behaviour of <script>, but I'm not 100% of what are good use cases for it


<py-script> tags dynamically (or, equivalently, that if you do they are not executed).
Originally I introduced that test because it was easy to implement and mimics the behaviour of <script>, but I'm not 100% of what are good use cases for it 

<py-script> tags in the DOM.
I see two scenarios:
1. I want to execute python code from JS: currently you can add a <py-script> tag, but we can imagine providing an API to just call a python function or a snippet of python code. Something like pyscript.runPython("....").
2. I want to execute python code from python: in that case, just call a function and/or import a module.
Am I missing anything? (edited)
js has a localStorage attribute when I:
import js
print(dir(js))
But when I try to:
from js import localStorage
I get:
ImportError: cannot import name 'localStorage' from 'js' (unknown location)
Help!!?!?!
js "namespace" work:
from js import alert
alert("hi")


What's New section isn't finished, obviously, will need to put a button on that tonight

What's New section isn't finished, obviously, will need to put a button on that tonight 

py-repl on the synclink branch since they are flaky and have lots of timing issues.
owing to that, I randomly tried a test called test_run_clears_previous_output
according it the title, there should be only 1 cell, since we clear the previous one and run it again
but using the --dev, it seems like there are 2 cells
This can also be seen in other related tests like test_python_exception_after_previous_output and test_hide_previous_error_after_successful_run
Let me know if this is expected aka I am interpreting this incorrectly OR if the test itself is incorrect?


<script> tag to the DOM?
I tried this:
let mod = await import("https://cdn.jsdelivr.net/pyodide/v0.22.1/full/pyodide.js");
However, the resulting mod seems to be empty:
> mod
Module {Symbol(Symbol.toStringTag): 'Module'}

<script> tag to the DOM?
I tried this:
let mod = await import("https://cdn.jsdelivr.net/pyodide/v0.22.1/full/pyodide.js");
However, the resulting mod seems to be empty:
> mod
Module {Symbol(Symbol.toStringTag): 'Module'} await import() the mod is empty, but loadPyodide is available in the global namespace. Is this expected? 




https://pyscript.net/snapshots/2023.03.1.RC2/pyscript.js) and the all were working fine.
Ship it ?








<script> tag to the DOM?
I tried this:
let mod = await import("https://cdn.jsdelivr.net/pyodide/v0.22.1/full/pyodide.js");
However, the resulting mod seems to be empty:
> mod
Module {Symbol(Symbol.toStringTag): 'Module'} mod = await import("https://cdn.jsdelivr.net/pyodide/v0.22.1/full/pyodide.mjs");mod.loadPyodide will be the loadPyodide function and

















synclink branch, a lot of examples fail due to not being able to create an instance of py-tutor plugin. Will push some more changes though. And will collaborate with @hood again today....


synclink branch, a lot of examples fail due to not being able to create an instance of py-tutor plugin. Will push some more changes though. And will collaborate with @hood again today.... 








{
"interpreters": [{
"src": "https://cdn.jsdelivr.net/pyodide/v0.22.1/full/pyodide.js",
"name": "pyodide-0.22.1",
"lang": "python"
}],
"plugins": [{
"src": "./pyvizzu.py"
}],
"fetch": [{
"files": ["./ab.py"]
}]
}
Is this how the json file should look?
plugins is just a list aka
plugins = [
"https://pyscript.net/latest/plugins/python/py_markdown.py",
"https://pyscript.net/latest/plugins/python/py_tutor.py"
]
should work for a TOML based config
[[interpreters]] is correct since that is a list of dictionary
fetch is also a list of dictionaries so you have to use [[fetch]] when using it via TOML
[[fetch]] adds a table (dictionary) to the array “fetch”; similarly with [[interpreters]]. https://toml.io/en/v1.0.0#array-of-tables

Uncaught (in promise) TypeError: singleFile.endsWith is not a function
and when I use the equivalent code in toml, the plugin is just successfully imported

Uncaught (in promise) TypeError: singleFile.endsWith is not a function
and when I use the equivalent code in toml, the plugin is just successfully imported singleFile.src.endsWith should work in that case, if I understand what's happening there (edited)"plugins": [{
"src": "./pyvizzu.py"
}],typeof singleFile === 'string' it's a type of object so the parser could be smart, otherwise you should write just "./pyvizzu.py" instead, not {"src": "./pyvizzy.py"} (edited)

runButton id and it doesn't need a label element around that doesn't necessarily point at that button neither ... thoughts? P.S. within ShadowDOM IDs can be unique (in there) but because we're not placing stuff within SD but also we're appending clones multiple times, I suggest we just move the label to the button and call it a day

.js file to orchestrate that so that we have one command to watch and serve examples, as npm run dev does now? For the time being I am just using npm run server which is a python -m http.server and a npm run esbuild-dev which watches files ... beside having dependencies simplified, it takes ~50ms to build either minified or not with source maps (edited)

.js file to orchestrate that so that we have one command to watch and serve examples, as npm run dev does now? For the time being I am just using npm run server which is a python -m http.server and a npm run esbuild-dev which watches files ... beside having dependencies simplified, it takes ~50ms to build either minified or not with source maps (edited)

.js file to orchestrate that so that we have one command to watch and serve examples, as npm run dev does now? For the time being I am just using npm run server which is a python -m http.server and a npm run esbuild-dev which watches files ... beside having dependencies simplified, it takes ~50ms to build either minified or not with source maps (edited)






cp or any common *nix operations within npm scripts and call it a day ... to which I'd be OK as I don't think Windows users would ever use Makefile anyway, or better this doesn't seem to be a concern until now, but WSL for Windows would still work perfectly fine.

cp or any common *nix operations within npm scripts and call it a day ... to which I'd be OK as I don't think Windows users would ever use Makefile anyway, or better this doesn't seem to be a concern until now, but WSL for Windows would still work perfectly fine. 

npm run esbuild or npm run esbuild-dev to measure locally differences ... I think just the fact we'll need one dependency instead of dozens is a pros, but maybe not everyone is experiencing the same speed improvement (and CI is not using it right now so I don't know about that neither)

npm run esbuild or npm run esbuild-dev to measure locally differences ... I think just the fact we'll need one dependency instead of dozens is a pros, but maybe not everyone is experiencing the same speed improvement (and CI is not using it right now so I don't know about that neither) 





.ts files inside the build folder as they are (even with rollup) ... not sure those files are usable in the wild ... any insight to share?
py_function.__call__()?
in the js side? (edited)
t = pyodide.runPython(`
class T:
def __call__(self, x):
print("called T with arg", x)
return x + 1
T()
`);
t(3)
t.__call__(3) (edited)
__call__ in the obj that should have a call method)
I'm executing code using eval though
which I get from the interpreter const pyEval = interpreter.globals.get('eval')
which is ultimately doing what you did up there ^ (edited)
add_event_listener from pyodide
not sure why but every time I use it, I can't use callable to figure out if something is callable
but every time I don't, works normally
so I don't think it's related to the eval stuff
callable returns a false positive / negative, that is a bug so it would be good to get a reproduction

synclink branch, basically, apart from the 4 integration tests that fail -- which @hood is picking up, there is also an issue with a unit test -- aka jest related issues.
This can be seen by executing make test-ts
My hunch is that it is really related to setting up jest.config etc.
Basically, I remember using the following snippet before:
import { TextEncoder, TextDecoder } from 'util';
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;
in pyodide.test.ts
But with the synclink integration, we get
ReferenceError: TextDecoder is not defined again
Also, this is a very common issue it seems -- https://stackoverflow.com/questions/68468203/why-am-i-getting-textencoder-is-not-defined-in-jest
In any case, my commit which accommodates the unit test with synclink is present here: https://github.com/pyscript/pyscript/pull/1258/commits/6fe6f11679a49cebb3efa91bdff6b5a7585cadd9








input()pdb.set_trace()




pyscript-write group so you both have wr rights once you accept :).




pyscript-write group so you both have wr rights once you accept :). 


py-repl based tests

eslint, we need to define the type of proxyClass basically
I remember @hood changed it to any while there were issues with keeping it as PyProxyCallable
Further, it seems like it doesn't allow us to use @ts-ignore which we do for the line:
this.globals = this._remote.globals as PyProxyDict;
Fixing these 2 should be enough I guess
@ts-ignore, I think we should disable that eslint rule. It doesn't make sense to complain about it (if we decide that it's fine to explicitly ignore typescript types for the next line, it means that we know what we are doing and eslint should just agree with us)
@ts-ignore rule is really dumbPyProxyCallable
PyProxyCallable is that it is inaccurate so even if it doesn't result in any type errors it is still nonsense. Same issue with this.globals = this._remote.globals as PyProxyDict.SynclinkProxy<PyProxyCallable>SynclinkProxy<PyProxyDict>
any?py_*, r_* and rpy_* (with or without the underscore, I don't care).
beforePyReplExec and afterPyReplExec plugin hooks should be optional for js plugins to implement or not https://github.com/pyscript/pyscript/pull/1310






beforePyReplExec and afterPyReplExec plugin hooks should be optional for js plugins to implement or not https://github.com/pyscript/pyscript/pull/1310 


src related to custom elements? 'cause I've just read about other src problems and I am not sure any ot these two is related

src related to custom elements? 'cause I've just read about other src problems and I am not sure any ot these two is related 







Yesterday & Today thread? 

Yesterday & Today thread? 












pyscript/__init__.py into multiple files: one thing which I would really like is to have a pyscript._internal (or a similar name) for all the things which are needed by pyscript itself but should not be called by the users (e.g. the new _run_python). If we put them inside _internal, we can probably even remove the leading underscore from the individual functions


<rant>
I hate squash&merge. It makes it very hard to develop a PR on top of another one, because when you merge it git creates a completely unrelated commit and you are no longer able to just git merge main
</rant>
RemoteInterpreter 
pyodide.registerComLink(Synclink) even if I am on the main thread? Does it have any negative consequences?

<rant>
I hate squash&merge. It makes it very hard to develop a PR on top of another one, because when you merge it git creates a completely unrelated commit and you are no longer able to just git merge main
</rant> 

reply on the wrong message? Else it doesn't make sense 

registerComlink has no test coverage in Pyodide so there's a few broken code paths
const worker_initialize: any = Synclink.wrap(worker);worker_initialize
Synclink.expose(t: T) then it should be Synclink.Remote<T>
Synctlink.expose is the following:
async function worker_initialize(cfg) {
...
}
export type worker_initializeexport type { worker_initialize}import type { worker_initialize } from "worker.ts"

export type worker_initialize worker_initialize lives in a completely separate file which is not even seen by the main bundle of pyscript

tsconfig (because of various reasons, but in particular tsc doesn't like it because it's not a module)







any


3 @typescript-eslint/no-unsafe-member-access
1 @typescript-eslint/no-unsafe-call/* eslint-disable @typescript-eslint/no-unused-vars */
const xPyRepl = customElements.define('py-repl', PyRepl);


/* eslint-disable @typescript-eslint/no-unused-vars */
const xPyRepl = customElements.define('py-repl', PyRepl); 

customElements.get('py-repl') would indeed return that if defined, nothing otherwise, but most importantly we have the PyRepl class right there in the scope so that xPyRepl should go indeed.















grid is taken for a module to reuse in more than a project ... so I ended up with greedily but I don't like it too much neither 







grid is taken for a module to reuse in more than a project ... so I ended up with greedily but I don't like it too much neither 













itsybitsyteenyweenyyellowpolkadot-grid is also free on npm 




npm i gridzilla. There are no other projects in the npm registry using gridzilla.


<script type="module"> 




<script> to bootstrap discussion ... if nothing else to add we have bugs coming due current situation https://github.com/pyscript/pyscript/discussions/1326#discussioncomment-5492789

<script> to bootstrap discussion ... if nothing else to add we have bugs coming due current situation https://github.com/pyscript/pyscript/discussions/1326#discussioncomment-5492789 
















main branch, seems like I cannot build pyscript
Specifically, I get this:
file:///Users/madhur/Desktop/Anaconda/pyscript/pyscriptjs/esbuild.mjs:5
import { cp, lstat, readdir } from 'fs/promises';
^^
SyntaxError: The requested module 'fs/promises' does not provide an export named 'cp'
at ModuleJob._instantiate (internal/modules/esm/module_job.js:124:21)
at async ModuleJob.run (internal/modules/esm/module_job.js:179:5)
at async Loader.import (internal/modules/esm/loader.js:178:24)
at async Object.loadESM (internal/process/esm_loader.js:68:5) (edited)

main branch, seems like I cannot build pyscript
Specifically, I get this:
file:///Users/madhur/Desktop/Anaconda/pyscript/pyscriptjs/esbuild.mjs:5
import { cp, lstat, readdir } from 'fs/promises';
^^
SyntaxError: The requested module 'fs/promises' does not provide an export named 'cp'
at ModuleJob._instantiate (internal/modules/esm/module_job.js:124:21)
at async ModuleJob.run (internal/modules/esm/module_job.js:179:5)
at async Loader.import (internal/modules/esm/loader.js:178:24)
at async Object.loadESM (internal/process/esm_loader.js:68:5) (edited)

v18.11.0 for node and 8.19.2 for npm
And now it's stuck at idealTree:pyscriptjs: sill idealTree buildDeps when I do npm install

v18.11.0 for node and 8.19.2 for npm
And now it's stuck at idealTree:pyscriptjs: sill idealTree buildDeps when I do npm install node_modules folders and then you do an npm ci

node_modules folders and then you do an npm ci 

npm i (install) the ci uses the package-lock.json file to ensure everyone uses actually the very same modules and very same modules versions ... or at least that's the idea, while npm i might grab patches without asking ... worth checking out if next version of some dev/dependency might break our builds (not today though)
<script type="py"> instead of <py-script> (worth it to me, but not for everyone to follow?), among all the details and improvements already shared, there is this particular reason that alone should make everyone think we did a mistake to use a layout element to define code data blocks ... maybe it helps as summary with demo you can test, images as results, and why that happens: https://github.com/pyscript/pyscript/discussions/1326#discussioncomment-5509027









View raw logs I see the following.
I think it means that for some reason github did not even start my job, not that the tests themselves are stuck. Am I right?Cancel workflow, the rest of the logs appeared. So it was a "genuine" hanging... good to know
typeof SharedArrayBuffer === "undefined"


antocuni/webworker-support branch, just after merging origin/main

pyscript.js and worker.js
Test Reporter stuff which was added by @hood recently it's awesome test_zz_examples.py::TestExamples::test_bokeh seems to be broken on main my machine.
I get these CORS errors:cdn.bokeh.org?



cdn.bokeh.org is returning different HTTP headers?




make examples I think
$ ls examples/bokeh*
examples/bokeh.html examples/bokeh_interactive.html
$ pytest tests/integration/ -k bokeh --dev
==> browser window with "Error code: 404 Message: File not found."cdn.bokeh.org it needs to set
Cross-Origin-Resource-Policy: cross-origin
bokeh.html? That's very weird, we should understand why and fix that





--dev, I discovered an unrelated problem with CORS headers.
On main, the problem manifests itself only with --dev, but as soon as we merge #1333 (webworkers) we will have the same problems also on main.
I have opened an issue:
https://github.com/pyscript/pyscript/issues/1365 (edited)

--dev, I discovered an unrelated problem with CORS headers.
On main, the problem manifests itself only with --dev, but as soon as we merge #1333 (webworkers) we will have the same problems also on main.
I have opened an issue:
https://github.com/pyscript/pyscript/issues/1365 (edited)

wait_for_pyscript for each test
2. a timeout argument to wait_for_pyscript so that we can change it on a test-by-test basis
3. an increased timeout for the problematic tests
Hopefully this should improve the situation: we will hopefully be able to set a smaller default timeout (because the current 30s is way too much for the vast majority of tests) and a higher one only for the tests which actually need it














































def _repr_svg_(self):
return (
# careful here, can't use less than sign!
f'##svg height="{self.r*2}" width="{self.r*2}">' +
f'##circle cx="{self.r}" cy="{self.r}" r="{self.r}" fill="red" />##/svg>'
).replace('##', chr(60)) # 60 is less than (edited)



<py-script> tag literally exactly what I would expect and explained when I've suggested to use <script type="py"> instead ... but of course we can ask everyone to use different chars to represent HTML and we could escape those chars on our side ... no other ideas beside using inverted tags for HTML/SVG content ... example:
def _repr_svg_(self):
return (
f'>svg height="{self.r*2}" width="{self.r*2}"<' +
f'>circle cx="{self.r}" cy="{self.r}" r="{self.r}" fill="red" /<>/svg<'
)
<py-script> tags then .. (this is a horrible idea anyway). (edited)

<py-script> tag literally exactly what I would expect and explained when I've suggested to use <script type="py"> instead ... but of course we can ask everyone to use different chars to represent HTML and we could escape those chars on our side ... no other ideas beside using inverted tags for HTML/SVG content ... example:
def _repr_svg_(self):
return (
f'>svg height="{self.r*2}" width="{self.r*2}"<' +
f'>circle cx="{self.r}" cy="{self.r}" r="{self.r}" fill="red" /<>/svg<'
)
<py-script> tags then .. (this is a horrible idea anyway). (edited)<!tag ... /!> which should not bother the parser as that's an invalid tag name ... <[tag ... /]> might do too as long as those chars don't interfere with both the HTML parser and Python ... the alternative is to use <script> and stop this "madness" sooner than later 

attachShadow({mode: 'open'}) automatically augment the custom element with a shadowRoot property making our own shadow property redundant -> https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#parameters ... as you're all busy at the PyCon, do you mind if I suggest a "chore" PR that removes such redundant property from our custom elements? 

make test and I think that's friction for contributors, specially since we ask if all tests passed locally whenever a PR is filed ... should we tackle this after the conf? I find this issue quite problematic 

make test and I think that's friction for contributors, specially since we ask if all tests passed locally whenever a PR is filed ... should we tackle this after the conf? I find this issue quite problematic 





















connectedCallback there, and that triggers any time the node is moved around the DOM. I've mentioned that at the end of the description of my PR.


connectedCallback there, and that triggers any time the node is moved around the DOM. I've mentioned that at the end of the description of my PR. 













shadowRoot and so on ... all doable on the surface but it requires some refactoring (edited)

PyWidget since we don't seem to use it anywhere?
Any thoughts? CC: @Fabio @Jeff Glass ?

PyWidget since we don't seem to use it anywhere?
Any thoughts? CC: @Fabio @Jeff Glass ? 




PyWidget also renders the function createWidget as useless since we don't use it anywhere. Do we potentially see it being used? Or perhaps we can remove this too? Basically, we can delete the full file i.e. pyscriptjs/src/components/pywidget.ts
<py-register-widget> in the wild.

PyWidget since we don't seem to use it anywhere?
Any thoughts? CC: @Fabio @Jeff Glass ? 














main branch so you're invited to run npm i inside the pyscript/pyscriptjs folder otherwise tests won't be able to run locallyWeakSet or WeakMap are not iterable, but since the FinalizationRegistry arrived on every browser it is possible to make these iterable (without retaining entries for longer than needed) (edited)

tests/integration/test_zz_examples.py::TestExamples::test_panel_kmeans is kinda broken and fails with ValueError: brush parameter was not found in list of parameters of class Selection

tests/integration/test_zz_examples.py::TestExamples::test_panel_kmeans is kinda broken and fails with ValueError: brush parameter was not found in list of parameters of class Selection 
test_panel_kmeans 









main.ts 


main


















@when, like we discussed this morning. https://github.com/pyscript/pyscript/discussions/1484@when - we talked about being able to remove listeners. I thought what I heard was that the api would be calling remove_when() (or something) on the function, ie:
@when('click', 'button')
def foo():
print("fOO!")
... # later
foo.remove_when(...)
Leaving aside the specifics of the API for that function - is this what we want? (edited)

@when - we talked about being able to remove listeners. I thought what I heard was that the api would be calling remove_when() (or something) on the function, ie:
@when('click', 'button')
def foo():
print("fOO!")
... # later
foo.remove_when(...)
Leaving aside the specifics of the API for that function - is this what we want? (edited)







pyscript --sw-proxy ./project-folder and we place a service worker (or we augment the present one) with all the logic ... something a bit "magic" like vite or other web dev oriented CLI tools do, nothing too articulated as a thought





The Salt Lake BBQ
























pyscript.core: if you check out pyscript-next and run npm run build, it fails with:
Error: ENOENT: no such file or directory, stat 'cjs'
I manually run mkdir cjs and now it builds fine

pyscript.core: if you check out pyscript-next and run npm run build, it fails with:
Error: ENOENT: no such file or directory, stat 'cjs'
I manually run mkdir cjs and now it builds fine .gitignore in that folder doesn't work ... I need to bring it into the parent folder ... which is annoying ... if we could have a whole pyscript-core repository instead it'd be much easier to setup that folder but not sure what others think about thisascjs module to create the foler if not there ... that seems like more sensible ... maybe ...)

pyscript.core: if you check out pyscript-next and run npm run build, it fails with:
Error: ENOENT: no such file or directory, stat 'cjs'
I manually run mkdir cjs and now it builds fine 
Cannot destructure property 'runtime' of 'runtimes.get(...)'
<py-config> (or equivalent), or it's required to use an external config file?


[next] as prefix ... the rest is the same

<py-config> (or equivalent), or it's required to use an external config file? py-script plugin to do so, otherwise yes

py-script plugin to do so, otherwise yes 











2023.01.01 (it was 2023.03.1) https://github.com/pyscript/pyscript/pull/1546 update Merged, thanks @FabioRosado ! (edited)

pyscript org called plugins where we collect all the pyscript plugins maintainer by the community (that include but is not limited to the ones we create and maintain). It's important to understand here that this does not mean that ALL plugins go there. For instance, we may want to keep a few core plugins that are shipped by default into core



@pyscript/core documentation https://github.com/pyscript/pyscript/blob/a3bf2881e42592d4360eff132118446af426e5eb/pyscript.core/docs/README.md (edited)

@pyscript/core documentation https://github.com/pyscript/pyscript/blob/a3bf2881e42592d4360eff132118446af426e5eb/pyscript.core/docs/README.md (edited)






Pyodide and Micropython interpreters, as possible Python interpreters, this Tech Preview also adds support for 2 new experimental Interpreters: wasmoon, an interpreter that runs Lua on the browser and that, among the previous two interpreters, is fully compatible with all core features; and ruby-wasm-wasi an interpreter that adds Ruby to the list of programming languages currently supported :).
Multiple Interpreter Support: PyScript now supports the utilization of multiple interpreters simultaneously. This means you can take advantage of different languages (or Python versions) or configurations within a single application, opening up a world of possibilities for experimentation and optimization.
Enhanced Compatibility: We have diligently worked on improving PyScript's compatibility with a wider range of Python code and libraries. The re-written core incorporates extensive compatibility optimizations, enabling seamless execution of complex Python applications and libraries in the browser, especially when it comes to supporting blocking calls and other aspects now available through the execution on Web Workers. This also includes the possibility of better debugging capabilities.
We invite you to give the tech preview a spin, build something amazing and share your feedback with us. Your participation in the project is at the heart of what we do, and essential for guaranteeing PyScript allows you to build the amazing things you want and fulfills its potential for everyone.
To get started, visit the Tech Preview showcase, where you can find detailed documentation and examples!
Have fun and build cool stuff.
Happy coding!
The PyScript Team (edited)










wasmtime a desired interpreter for us? something that would enable proof of concepts out there?@pyscript/core@0.0.8 has been published and it comes with the following breaking changes (for good!):
runEvent interpreter helper, and these can only represent context methods or namespaced version of it ... that is py-click="method" or py-script="some.namespace.method" without the (event) part, just the pointer for that event and it will receive the event out of the boxxworker module but so far you need to import XWorker from xworker on the page and import xworker from xworker on the Worker/thread[next] as prefix and we'll look into it ASAP!



wasm-snip 
with set_value(a_dict, "key", value):
# in the body of the with block, a_dict["key"] is value
# after exiting the state of the key is restored, including whether it is present or not
I think the best way to do it is:
@contextmanager
def set_value(d, key, value):
orig = d.get(key, _sentinel)
d[key] = value
try:
yield
finally:
if orig == _sentinel:
d.pop(key, None)
else:
d[key] = orig
but this is a bit cumbersome
.a files 



polyscript thing, not sure). So would be good to have an extra pair of eyes on it 

















@pyscript/core on npm 































time.sleep in workers 




newdocs/README.md file.


pydom under pyweb as a namespace package (idea here is that other 3rd party packages can augment the namespace package. (At least that's the idea that Antonio and I were entertaining...)
Honestly, I feel like the way pydom is currently organized is not great... Ideas?
Another question: We currently don't have @when and HTML. This PR somehow introduce them back but.... where do you think they should belong? pyscript module? pyweb?


pydom and testing the release... the more a couple of things felt off (specially the naming and namespace of pydom). I've pairined with @tedpatrick and @Martin yesterday and today and we capture out thoughts in this discussion https://github.com/pyscript/pyscript/discussions/1687
Please check it out and let's discuss before we release. (I know it's a bit of last minute but I'd rather take a few more days than make a big mess 

<script type="py"> doesn't support the version tag like Polyscript



import pydom become from pyscript import dom? 








Classic tag to issues the PyScript repo that relate purely to bugs or implementation details in PyScript Classic. These would be good candidates for re-examination or closure once we release.


Classic tag to issues the PyScript repo that relate purely to bugs or implementation details in PyScript Classic. These would be good candidates for re-examination or closure once we release. 







PyScript ready 











env attribute is not available in PyScript, yes? Or rather, is always set to the same value across all tags by this line?https://github.com/pyscript/pyscript/blob/287d0fa1afb2d395f9382147054c9fd7656a8e43/pyscript.core/src/core.js#L144

env attribute is not available in PyScript, yes? Or rather, is always set to the same value across all tags by this line?https://github.com/pyscript/pyscript/blob/287d0fa1afb2d395f9382147054c9fd7656a8e43/pyscript.core/src/core.js#L144 env is the most unique identifier we have and py-script is our env in polyscript, yes ... it's not exposed though, but no example or use case required otherwise ... we could expose it but I am not sure what's the purpose so that maybe we can do better?env should be out of the discussion in PyScript .... if you specify a different env it means you want a new pyodide bootstrap and we don't have any mechanism to map a <py-config> element to that desire needed ... please keep env out of the explanation as that's really more like a polyscript internal feature, exposed by need, rather than by usefulness, thanks!

env should be out of the discussion in PyScript .... if you specify a different env it means you want a new pyodide bootstrap and we don't have any mechanism to map a <py-config> element to that desire needed ... please keep env out of the explanation as that's really more like a polyscript internal feature, exposed by need, rather than by usefulness, thanks! 
<script type="mpy"> now for MicroPython, and Lua and Ruby don't need to be mentioned ... so don't mention polyscript at all feels like the natural consequence of current state. (edited)<mpy-script>)
async src , worker, and config attributes in PyScript, and I think I had mistakenly remembered that env was also available in PyScript. Clearly I was wrong - thanks for confirming!








<mpy-config> and <py-config> work as expected ... don't these? I wasn't aware of any revert there ...



CTRL-C, which Python is supposed to intercept and raise KeyboardInterrupt.
E.g., try to go to my console demo and press CTRL-C: you can see that KeyboardInterrupt is not raised:
https://antocuni.pyscriptapps.com/pyterminal-poc/latest/?console/ (edited)

CTRL-C, which Python is supposed to intercept and raise KeyboardInterrupt.
E.g., try to go to my console demo and press CTRL-C: you can see that KeyboardInterrupt is not raised:
https://antocuni.pyscriptapps.com/pyterminal-poc/latest/?console/ (edited)^C though which seems ... OK? is not that we can exit the terminal ... or should we? 

^C though which seems ... OK? is not that we can exit the terminal ... or should we? 


KeyboardInterrupt. That's what Python folk expect. If you want to copy something from the "terminal" with out using CTRL-C the convention is SHIFT-CTRL-C for "copy".

files configuration option:
https://github.com/pyscript/pyscript/discussions/1755


coincident internals to judge whether this can be implemented without changes, so I guess it's better to wait for @hood input



chat or announcements as well when you get details, in case there are community members that can come
1

chat or announcements as well when you get details, in case there are community members that can come 








coincident internals to judge whether this can be implemented without changes, so I guess it's better to wait for @hood input Atomics.wait and blocks all activity. This has to be changed instead to have a timeout and periodically check for a keyboard interrupt.






KeyboardInterrupt 








skip on the main thread: https://github.com/pyscript/pyscript/issues/1761
(I'll do a similar one for workers soon)
test_report workflow not running 


on_click) with Python functions using MicroPython ?













display to show a matplotlib figure (i.e. image?) + append=False
inside an event-handler!
It seems that inside an handler function (regardless how you’ve programmed it, namely via explicit addEventListener + create_proxy combination or using @when) the display freezes and doesn’t work anymore.
Everything works as expected when used outside the event_handler function.
Since it’s quite niche, and difficult to explain I have it demonstrated here: https://pyscript.com/@leriomaggio/rough-bar/latest
To replicate: (see also the console.log messages proving event handlers are actually working.
1) the display with text & matplotlib.plot work as expected when called during the main-thread execution.
2) if you click on display text button, display(..., append=False) works as expected with textual content
3) if you click on display plot it should be displaying a plt.plt on a randomly generated range every time you click (see also console.log msgs) instead only the first is shown, and others won't be displayed at all! (edited)
polyscript
1

polyscript 

.wasm files but we don't have yet a use case for that, so I won't spend time on it 


pyscript-next display function (cc/ @antocuni @Jeff Glass ): https://github.com/pyscript/pyscript/pull/1784




Makefile in the PyScript repo... that's another "classic" that needs updating. 





Makefile 

































<py-script>
print("content on the page")
</py-script>
pyscript build command (to run on your desktop) which takes an HTML page and turns it into an optimized one (e.g. by automatically byte-compiling all the things)
<script type="pyc"> ... I see 















from string import Template throws in MicroPython ... please add this to the list of questions whenever you have some time .. you really missed out on today demos and no, nobody recorded, Hood was in the house too 


from string import Template throws in MicroPython ... please add this to the list of questions whenever you have some time .. you really missed out on today demos and no, nobody recorded, Hood was in the house too Template https://github.com/JeffersGlass/mp-templates (edited)Template class your demo got today Andrea
src of an mpy tag 
Template for MicroPython, we should send it upstream and help out. Also, the "unix" port of MicroPython is the most "maximalist" version, and may already have a solution we need.

cache and still the result was like there was a cache ... well, I've learned yesterday evening that in Python [1, 2] in list or (1, 2) in list don't check by reference so my counter-cache was producing True even if the tutle was always a new one ... this is super interesting and I believe it helps avoiding duplicated lists of the same kind or with the same value, unless I am completely misunderstanding the feature, but basically the code was fine, the in operator was guarding upfront regrdless.tag`This is ${"some"} ${"value"}!`
passes to the tag function a template, which is an immutable array like a tuple in Python, and one or more interpolated values ... as in tag(template, ...interpolations) and most UI libraries using this feature expects that signature to work, as it is for uhtml or lit-html too.




py-terminal (https://github.com/pyscript/pyscript/pull/1801) we should do a new release of PyScript next, and assuming after a few days of exercising it "in the wild" promote that version to final - et voila, we have finally released PyScript next. Thoughts and feedback in a 

py-terminal (https://github.com/pyscript/pyscript/pull/1801) we should do a new release of PyScript next, and assuming after a few days of exercising it "in the wild" promote that version to final - et voila, we have finally released PyScript next. Thoughts and feedback in a <py-terminal> Custom Element stuff works in the terminal ... is this OK or should I actually implement the terminal attribute instead? To me the current terminal works and it doesn't require to "change the world" around polyscript neither plus it's explicit when it runs from a worker and when it doesn't ... should we move forward with it?
terminal attribute myself (thus avoiding the need for a custom element). But others may disagree, and as you say, the outcome is lost in a forest of comments.
I think @Jeff Glass 's terminal attribute suggestion was welcomed. Not sure what the status of a custom element <py-terminal> is.
<script type="py" worker terminal> with eventually in the future the async attribute too or it's just terminal with no way to make it work on main?























make setup which will do npm install, install Python deps and playwright install




make setup should just install playwright, right..?

make setup should just install playwright, right..? pyscript.core folder too ... playwright doesn't check upper instals, it's weird there ... it doesn't work like npm packages do
make setup installation for playwright because "reasons" so the quickest solution is probably to cd pyscript.core && npx playwright install && npm run build
playwright install thing only inside pyscript.core and move into that folder the current Python integration

make setup installation for playwright because "reasons" so the quickest solution is probably to cd pyscript.core && npx playwright install && npm run build playwright install at the moment, one is an off-by-one folder.






3








[RC3]










autogenerate from classic) that we could add as well, but I think we should try to nail down the core behaviors before we layer more features in.

autogenerate from classic) that we could add as well, but I think we should try to nail down the core behaviors before we layer more features in. 





pydom section in the docs has been added and just need to be deployed. +1 on the plugin section, which I think we already have some content in the many READMEs around ( @Andrea Giammarchi would you mind taking care of this tomorrow? ) but the docs are decouple from the release itself so we can also correct after.


pydom section in the docs has been added and just need to be deployed. +1 on the plugin section, which I think we already have some content in the many READMEs around ( @Andrea Giammarchi would you mind taking care of this tomorrow? ) but the docs are decouple from the release itself so we can also correct after.








README.md still says to link to /latest... we can update that to recommend the most recent actual version as soon as we release @ntoll

README.md still says to link to /latest... we can update that to recommend the most recent actual version as soon as we release @ntoll docs/changelog.md ? 









/latest . That PR wasn't merged before the release....
I don't think it's a big deal but it is a missed opportunity 




when as we agreed

















/snapshots and non-RC under /releases. They should all go under /releases









import { hooks } from "<path_to_pyscript>/core.js"; come from? I looked at existing docs also did a github search and there are no such example that shows me how I get path_to_pyscript. Also it's unclear to me, is it only part of javascript modules? I would prefer something as close to working code as possible. (edited)


import { hooks } from "<path_to_pyscript>/core.js"; come from? I looked at existing docs also did a github search and there are no such example that shows me how I get path_to_pyscript. Also it's unclear to me, is it only part of javascript modules? I would prefer something as close to working code as possible. (edited)<script type="module" src="//cdn/@pyscript/core">
in your page, you can just refactor that as:
<script type="module">
import { hooks } from "//cdn/@pyscript/core";
</script>
that's it?




import { hooks } from "<path_to_pyscript>/core.js"; come from? I looked at existing docs also did a github search and there are no such example that shows me how I get path_to_pyscript. Also it's unclear to me, is it only part of javascript modules? I would prefer something as close to working code as possible. (edited)






























/latest as an interesting topic https://jeff.glass/post/whats-new-pyscript-2023-11-2/



/latest as an interesting topic https://jeff.glass/post/whats-new-pyscript-2023-11-2/ 



env, very clean and will be helpful





[notice] A new release of pip is available: 23.2.1 -> 23.3.1



python -m pip install --upgrade pip
To upgrade pip in your venv.








examples folder being removed from the main repo. I'd like to add a note like "To see current examples, go to _______". What should I put there these days?


examples folder being removed from the main repo. I'd like to add a note like "To see current examples, go to _______". What should I put there these days? 










audio side of it?



main.py that is really the whole code for the app. Looking forward for feedback on the pydom and pyweb.media APIs.!






MediaRecorder object's onstop is called before we call Python's await rec.audio() if we're using Pyodide. Yet this isn't the case in MicroPython... hence I had to add an event listener for stop in the promise returned by result.audio which resolves when (if using MicroPython) the stop event is dispatched. This feels smelly, and is one of the more esoteric things I want to chat about with Damien, so Pyodide and MicroPython don't work so differently in this respect.





























document.currentScript behavior: https://github.com/pyscript/pyscript/discussions/1930
























__terminal__ landed in here as discussed with both @Jeff Glass and @ntoll https://github.com/pyscript/pyscript/pull/1947 ... if it's green and approved and merged, I am confident we could release today or tomorrow.worker attribute, and still throw an error if multiple main terminals are used. I am not sure for this release we want to rush this but ... hey ... it was worth mentioning the current state.


__terminal__ discussion ... but it needs __terminal__ in first.

__terminal__ together (edited)
create_proxy because I think it might be interesting for either Hood or Damien. It shows my earlier examples in practice, thanks! /cc @ntoll (edited)









npm run server then reach http://localhost:8080/test/py-terminals.html and hack away npm run build before being able to see it)
pydom and cleaning all the current mess. Got it working (at least somehow pydom and the when decorator) but there's a ton to do still. Initial work here https://github.com/pyscript/pyscript/pull/1954 .
create_proxy = "auto" in the TOML it would be experimental_create_proxy = "auto" ... is anyone against that? It does nothing if such flag is not enabled, it changes A LOT if it is.

experimental as you are suggesting @Andrea Giammarchi . I think the benefits are prettu clear....
Now... there are some concerns for instance, like @antocuni mentioned earlier this week, this could create a code portability problem but I thnk it's a good bet right now










npx mini-coi ./ would start a server that does what npx static-handler --coi ./ does now, maybe helping further users and developers to have one module that does it all for testing purposes ... thoughts?

npx mini-coi ./ would start a server that does what npx static-handler --coi ./ does now, maybe helping further users and developers to have one module that does it all for testing purposes ... thoughts? 







sync_main_only flag to workaround missing SharedArrayBuffer cases: https://github.com/pyscript/pyscript/pull/1967













PyWorker/MPyWorker? Using the worker attribute on a pyscript tag without the right CORS headers still throws up on me about SharedArrayBuffer not being available in an insecure environment.
EDIT: OH! I missed that adding the sync_main_only = True param to the config was necessary. Please disregard. (edited)


PyWorker/MPyWorker? Using the worker attribute on a pyscript tag without the right CORS headers still throws up on me about SharedArrayBuffer not being available in an insecure environment.
EDIT: OH! I missed that adding the sync_main_only = True param to the config was necessary. Please disregard. (edited)sync_main_only was a requirement for these use cases:
await when it calls sync operations from the worker ... accordingly, if you expose utilities form the worker and you await these on the main, SAB is not needed, you add that flag to the config, and you can delegate to the worker anything you like.

sync_main_only removes the ability from the worker to run DOM APIs (and others from main) synchronously ... I need to double check though if that means nothing can be used, but I think your example and message is clearhttps://cdn.jsdelivr.net/npm/@pyscript/core@0.4.11/+esm I would suggest using the https://pyscript.net/releases/2024.3.2/core.js onefetch example is spot-on but I would add the following:async attribute within the script if top-level await is desiredawait pyscript.fetch("https://reqres.in/api/users/2").text() directly, which fails if the response was not ok (not in the 200-299 range).json() which is not mentioned ... the fetch API returns proper Python dictionaries when .json() is used, instead of JS proxies ....bytearray() which returns a Python result too ... as a matter of fact, all fetch methods in PyScript namespace return Pythonic references instead of JS proxies ... I think that might be interesting/important to mention

sync_main_only removes the ability from the worker to run DOM APIs (and others from main) synchronously ... I need to double check though if that means nothing can be used, but I think your example and message is clearhttps://cdn.jsdelivr.net/npm/@pyscript/core@0.4.11/+esm I would suggest using the https://pyscript.net/releases/2024.3.2/core.js onefetch example is spot-on but I would add the following:async attribute within the script if top-level await is desiredawait pyscript.fetch("https://reqres.in/api/users/2").text() directly, which fails if the response was not ok (not in the 200-299 range).json() which is not mentioned ... the fetch API returns proper Python dictionaries when .json() is used, instead of JS proxies ....bytearray() which returns a Python result too ... as a matter of fact, all fetch methods in PyScript namespace return Pythonic references instead of JS proxies ... I think that might be interesting/important to mention

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MicroPython Terminal</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.12/dist/core.css">
<script type="module" src="https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.12/dist/core.js"></script>
<style>.xterm { padding: .5rem; }</style>
</head>
<body>
<script type="mpy" worker terminal>
import code
code.interact()
</script>
</body>
</html>
it's been already published to npm so it's possible to try it already. This version fixes lazy terminal (or runtime) initialization and allows MicroPython too.worker attribute to work properly, as the input is mandatory/needed in here, you need to enable COOP and headers to allow SharedArrayBuffer. npx mini-coi ./ would do ... save that code as index.html in any folder you like, go into that folder and run that command ... you should be in a REPL like this one:


elements.py seems to really make MicroPython unhappy (triggers a memory access out of bounds exception). Think this is probably upstream..

elements.py seems to really make MicroPython unhappy (triggers a memory access out of bounds exception). Think this is probably upstream.. 
ltk to the pyscript github org.


elements.py seems to really make MicroPython unhappy (triggers a memory access out of bounds exception). Think this is probably upstream.. 





runPython, not as vFS content to parse ... maybe this is the difference Damien wasn't thinking about. It's generated out of @Fabio branch and as soon as I drop one file there everything is fine. It might as well be a path issue but I always get just memory out of bound so I can reproduce that every single time. The file we run as code is attached.



.zip folder of our stdlib and produce a base64 based artifact that would unpack in the FS the whole content, as opposite of manually creating a huge string with all our current and future stdlib in there as single runPython command. However, this not only would need quite some time to be implemented, it won't solve the underlying issue that MicroPython runPython (and I believe runPythonAsync too) is incapable of handling biggfer inputs so I'd rather go to fix that and think about improvements later on. After all, our files behind the CDN get already compressed, and compressing the compression feels off to me.

.zip folder of our stdlib and produce a base64 based artifact that would unpack in the FS the whole content, as opposite of manually creating a huge string with all our current and future stdlib in there as single runPython command. However, this not only would need quite some time to be implemented, it won't solve the underlying issue that MicroPython runPython (and I believe runPythonAsync too) is incapable of handling biggfer inputs so I'd rather go to fix that and think about improvements later on. After all, our files behind the CDN get already compressed, and compressing the compression feels off to me. 






File.new([blob])) so it's possible to create downloads from the virtual FS too ... plus other fixes landed these days ... please feel free to test it via https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.31/dist/core.js and https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.31/dist/core.css respective JS and CSS urls, thank you!
asyncio native support now.

py-editor is always showing an error in the new release (2024.5.1): https://github.com/pyscript/pyscript/issues/2056






pyweb.ui.elements . I'll add a couple of quick PRs to change and bring pyweb.ui.elements to pyweb.elements and avoid too deep nesting. There are also a couple of small improvements in the interface that I'll land tomorrow as well. Rest will be adding docs.

pyweb.ui.elements . I'll add a couple of quick PRs to change and bring pyweb.ui.elements to pyweb.elements and avoid too deep nesting. There are also a couple of small improvements in the interface that I'll land tomorrow as well. Rest will be adding docs. 




pyscript.web tests and latest media but I've fixed much more and this is the current state when SharedArrayBuffer is enabled:
https://youtu.be/jz7CX8xgRNA