FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Pathfinding pool test by clayote · Pull Request #2432 · pyscript/pyscript · GitHub

Pathfinding pool test - #2432

Open
clayote wants to merge 118 commits into
pyscript:mainfrom
clayote:networkx
Open

Pathfinding pool test#2432
clayote wants to merge 118 commits into
pyscript:mainfrom
clayote:networkx

Conversation

clayote commented Jan 21, 2026
edited
Loading

Copy link
Copy Markdown

Description

Here's a test I wrote that should, in principle, verify that

  • pyscript's web workers can really do computation in parallel
  • they can sync pretty complex state

I can't get it to run, though. Opening index.html directly gets me CORS errors; running npx mini-coi -p 8000 tests/ in the core directory gets me

Loading module from “http://localhost:8000/dist/core.js” was blocked because of a disallowed MIME type (“”)

in the Firefox console when I go to localhost:8000. In Chromium, I at least see the page to navigate to specific tests, but when I click the bottom option, python, I get an empty page with some 404 errors in the console. (I ran make build beforehand. Those files, core.css and core.js, ought to be there.)

Changes

Checklist

  • I have checked make build works locally.
  • I have created / updated documentation for this change (if applicable).

clayote force-pushed the networkx branch 2 times, most recently from 18b49a8 to d074327 Compare January 21, 2026 08:01

Copy link
Copy Markdown
Contributor

Loading module from “http://localhost:8000/dist/core.js” was blocked because of a disallowed MIME type (“”)

that's out of tree because you start mini-coi with tests/ as root ... npx mini-coi -p 8000 ./ is all you need then reach the http://localhost:8000/tests/ URL

Comment thread core/tests/python/worker_functions.py Outdated

__export__ = ["add", "multiply", "get_message"]
def dijkstra_path(g, a, b):
from networkx import from_dict_of_dicts, dijkstra_path

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

in MicroPython and PyScript, this cannot be just part of the requirements.txt, it has to be a Pure Python package MicroPython can import and run without issues and I believe that's not the case ... or is it?

otherwise I think you meant to use Pyodide py as type instead, but I am guessing at this point ... still that package needs to be available for each worker, if not part of the stdlib each runtime has.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

NetworkX is in fact a pure Python package.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

The fact that the virtual filesystem is unique per-interpreter is surprising. The documentation should call attention to that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

it's in WASM memory and shared with the environment that bootstraps it, no surprise there but also no way to have a unique shared VFS because these runtimes bundles Emscripten VFS anyway and each of them also has a different logic/tree per VFS (Pyodide VS MicroPython VS ... any other PL, where /tmp or /packages might or might not make any sense, together with symlinks and whatnot).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Well, it's surprising when I'm coming from desktop Python, where subprocesses don't share live objects but do share the filesystem. And I think a lot of your users will be coming from desktop Python.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

No need to apologise - any feedback on docs is very welcome and thank you for the suggestions. Honestly, if folks like you (actual real users!) don't tell people like me (the dude who wrote the docs!) what's missing in the docs then things won't improve. If in doubt, just give feedback, it'll always be welcome! 🚀

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Workers have separate memory spaces. Each worker has its own memory, and you cannot share objects between workers or with the main thread. All communication happens via function calls with serialised data.

This paragraph also describes the situation with multiprocess parallelism on desktop, which misled me into thinking I could assume it was like multiprocessing in other ways; in particular, that I could use files to communicate between workers. Perhaps this would be better:

Each worker is a separate Python interpreter, in a separate memory space, with a separate filesystem. You cannot share objects between workers, nor with the main thread. All communication between them happens via function calls with serialised data.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I'm doing some docs revisions today. I'll incorporate this clarification. Thank you!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

FWIW @clayote - if you ever want a "live" technical discussion we have a fortnightly community technical call in which we chat about deeply technical things. The details are in the "events" section of our PyScript discord server (and we use discord as the platform for the call). Feel free to add an item to the agenda when I announce it in the #chat channel.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I'm in New Zealand, where your technical calls happen at 4am. I don't think I can make it very often...

Comment thread requirements.txt Outdated
pre-commit==3.7.1
python-minifier==3.1.0
setuptools==72.1.0
networkx~=3.6

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

this does not affect Pyodide or MicroPython runtimes, you need to specify a config with a packages=['networkx'] for both runtimes, or even JSON, but it has to be usable from both Pyodide and MicroPython and I am not sure the latter would understand networkx package

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

i.e.

await create_named_worker(src="./worker_functions.py", name="mpy-worker0", type="py", config='{"packages":["networkx"]}')

note I've changed mpy to py too as I think MicroPython doesn't have the ability to run networkx while Pyodide does

Copy link
Copy Markdown
Contributor

there's a fundamental misconception of how dependencies work in PyScript and its used runtimes ... indeed:

Please read my comments in this MR to change mpy to py and explicitly include dependencies per each worker, thanks.

clayote commented Jan 21, 2026

Copy link
Copy Markdown
Author

there's a fundamental misconception of how dependencies work in PyScript and its used runtimes ... indeed:

Then, when I tried this approach in pyscript.com, this error is the JSON it's failing to load? I used only Pyodide there.

Please read my comments in this MR to change mpy to py and explicitly include dependencies per each worker, thanks.

clayote commented Jan 21, 2026

Copy link
Copy Markdown
Author

Well, whatever, I'll switch to Pyodide workers for the time being, and add another, similar micropython test later.

I can run the pure-Python tests now! I guess it's just a documentation issue, and a regrettably misleading error message.

However...

================================= FAILURES =================================
Failed: ./tests/test_workers.py::test_find_path_networkx_parallel_pyodide
Traceback (most recent call last):
  File "upytest.py", line 182, in run
  File "tests/test_workers.py", line 120, in test_find_path_networkx_parallel_pyodide
ImportError: can't import name Random

I put in an explicit dependency on the random stdlib package in settings_py.json to be safe. No dice.

WebReflection commented Jan 21, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

I'm afraid https://packages.pyscript.net/package/?package=random is not available ??? is that a native Python thing? if so, shouldn't it be random (lowercase) instead?

to clarify, non Python stdlib things should be in packages, packages that are in stdlib should not be part of packages ... they are not dependencies, they are core.

Copy link
Copy Markdown
Contributor

we are here: https://pyscript.com/@agiammarchi/parallel-pathfinding-bare-coroutines-str-copy/latest?files=main.py,worker.py,pyscript.toml,index.html

You need to pass config to each worker ... each worker is a runtime/world a part ... but now there is another error, although all imports are just fine, all workers run, everything is fine except the code that is expecting something else ... not sure what.

Turns out, requirements.txt has nothing to do with what gets installed in PyScript

clayote commented Jan 21, 2026

Copy link
Copy Markdown
Author

I'm afraid https://packages.pyscript.net/package/?package=random is not available ??? is that a native Python thing? if so, shouldn't it be random (lowercase) instead?

random.Random is the randomizer class, which you can instantiate if you want to have your own pseudorandomizer with a different state from the global one in the random module. I imported it as from random import Random, which should work, but doesn't.

There wasn't really a reason for me to use my own, just habit

It's weird that I can't `from random import Random` though...

clayote commented Jan 21, 2026

Copy link
Copy Markdown
Author

Oh, I think we may have stumbled into a compatibility issue between PyScript and Firefox, as well, because the output of your code on Firefox is different:

(PY0409) JSON.parse: unexpected character at line 1 column 8 of the JSON data for <script type="py" src="./worker.py" config="./pyscript.toml" worker="" name="worker0"></script>(PY0409) JSON.parse: unexpected character at line 1 column 8 of the JSON data for <script type="py" src="./worker.py" config="./pyscript.toml" worker="" name="worker2"></script>(PY0409) JSON.parse: unexpected character at line 1 column 8 of the JSON data for <script type="py" src="./worker.py" config="./pyscript.toml" worker="" name="worker1"></script>(PY0409) JSON.parse: unexpected character at line 1 column 8 of the JSON data for <script type="py" src="./worker.py" config="./pyscript.toml" worker="" name="worker3"></script>generated barbell_graph
here we go
1. we want a path 3→2
we submitted a request to find 3→2
2. we want a path 5→4
we submitted a request to find 5→4
3. we want a path 0→1
we submitted a request to find 0→1
4. we want a path 6→7
we submitted a request to find 6→7

And then it hangs forever.

clayote commented Jan 21, 2026

Copy link
Copy Markdown
Author

And I'm also getting different output from you when I fork your fork of parallel-pathfinding in Chromium!

(PY0409) Unexpected token ']', "[ "s1",]" is not valid JSON for <script type="py" src="./worker.py" config="./pyscript.toml" worker="" name="worker0"></script>(PY0409) Unexpected token ']', "[ "s1",]" is not valid JSON for <script type="py" src="./worker.py" config="./pyscript.toml" worker="" name="worker1"></script>(PY0409) Unexpected token ']', "[ "s1",]" is not valid JSON for <script type="py" src="./worker.py" config="./pyscript.toml" worker="" name="worker2"></script>(PY0409) Unexpected token ']', "[ "s1",]" is not valid JSON for <script type="py" src="./worker.py" config="./pyscript.toml" worker="" name="worker3"></script>generated barbell_graph
here we go
1. we want a path 5→7
we submitted a request to find 5→7
2. we want a path 6→3
we submitted a request to find 6→3
3. we want a path 9→0
we submitted a request to find 9→0
4. we want a path 4→2
we submitted a request to find 4→2
5. we want a path 1→8
we submitted a request to find 1→8

It's the Linux Mint build of Chromium, which has some customizations, I suppose...

clayote force-pushed the networkx branch 3 times, most recently from d56f8a3 to 25ca75a Compare January 21, 2026 22:10
Well, it will, once I get the package.json right...

clayote commented Jan 21, 2026

Copy link
Copy Markdown
Author

I think I've gotten networkx to install in micropython? At least, now the test hangs, rather than giving me an error in mip...

clayote commented Jan 21, 2026

Copy link
Copy Markdown
Author

When I forked your project on pyscript.com, it resulted in this project that, when run, gives me different output, though I haven't changed the code at all. Not sure what that's about.

clayote commented Jan 21, 2026

Copy link
Copy Markdown
Author

I think I've gotten networkx to install in micropython? At least, now the test hangs, rather than giving me an error in mip...

Oh, it didn't hang! It just took longer than I expected to grab all those files. Here's the new failure I'm looking at:

Failed: ./tests/test_workers.py::test_find_path_networkx_parallel_pyodide
Traceback (most recent call last):
  File "upytest.py", line 182, in run
  File "tests/test_workers.py", line 124, in test_find_path_networkx_parallel_pyodide
  File "/lib/networkx/__init__.py", line 15, in <module>
  File "/lib/networkx/lazy_imports.py", line 1, in <module>
ImportError: no module named 'importlib'

I probably have to add that dependency in the package.json somehow...or patch networkx not to need it?

clayote commented Jun 26, 2026

Copy link
Copy Markdown
Author

There was an issue with my test data generation code. I fixed it by running the test function outside of upytest, with plentiful prints.

Now I'm stuck here

        coros = []
        nodepairs = []
        # then submit nodes for them to find paths between
        for worker in our_workers:
            a = nodes.pop()

            nodes.insert(0, a)
            b = nodes.pop()

            nodes.insert(0, b)
            nodepairs.append((a, b))

            coros.append(worker.dijkstra_path(graph_d, a, b))
        for coro, (a, b), expected in zip(coros, nodepairs, expectations[name]):
            print(f"will await {coro} to find path {a}->{b}")
            the_path = await coro
            print(f"{coro} got path {the_path}")

            assert the_path == expected, (
                f"The path from {a} to {b} in {name} should be {expected}; instead, got {the_path}"
            )

It's the last part of test_find_path_parallel, and none of those coroutine-like objects ever seem to yield anything. I've run the exact same code in the main thread by this point. It generated the test data.

Where do I go from here?

clayote commented Jun 26, 2026

Copy link
Copy Markdown
Author

I have verified that code is at least running in the workers. They're having some trouble returning the result.

Copy link
Copy Markdown
Contributor

every worker bootstraps a new Pyodide environment ... meaning, every worker will add 1 up to 3+ seconds to bootstrap, depending on the config.

I don't know if this is anyhow meaningful, but this example is not minimal, it's complex, and the more complex it gets, the least "easy-to-solve" becomes ... can you reduce your test case to a single entity and tell us if that still fails?

Copy link
Copy Markdown
Contributor

in case it's not clear, if we have a single line example (that's enough to track issues) that shows what is failing, we might help ... if you keep changing tests and this PR because your tests were failing or anything, that does not help us.

unfortunately our time to tackle issues are extremely tight, so that every update I read about this topic to me is like "see? good thing you haven't wasted time around that issue yet".

I want a stable, consistent, precise thing I can read with ease and replicate/debug, otherwise this can keep going for a very long time without resolution ... I want to solve this, if there's anything we're doing wrong, I am not playing the "long time bug keeps getting updates around its tests" game, with all due respect I want to appreciate in here around your effort around this topic too!

Thanks for your understanding!

clayote commented Jun 26, 2026

Copy link
Copy Markdown
Author

There's something preventing me from sending a graph's worth of data to a worker. I don't think the data is especially large.

https://pyscript.com/@clayote/cheating-dijkstra/latest

Traceback (most recent call last):
  File "/lib/python313.zip/_pyodide/_base.py", line 597, in eval_code_async
    await CodeRunner(
    ...<9 lines>...
    .run_async(globals, locals)
  File "/lib/python313.zip/_pyodide/_base.py", line 413, in run_async
    await coroutine
  File "<exec>", line 11, in <module>
pyodide.ffi.JsException: Error: This borrowed proxy was automatically destroyed when an iterator was exhausted.
For more information about the cause of this error, use `pyodide.setDebug(true)

clayote added 3 commits July 2, 2026 13:28
Incidentally fixes a bad use of `js.Promise.all`
that's maybe more like a PyScript bug:
https://github.com/pyscript/pyscript/issues/2479

We now only send cheats in the tests they'll be used for.
clayote and others added 7 commits July 10, 2026 04:20
Perhaps I'll make another PR for those
* PyEditor - Fixed thrown error on output removal

* published to npm

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

clayote commented Jul 10, 2026

Copy link
Copy Markdown
Author

The pathfinding pool tests all pass now. Some of the others in the same file have regressed, but I didn't change them, apart from running ruff format.

clayote commented Jul 11, 2026

Copy link
Copy Markdown
Author

This should probably be a squash merge.

clayote commented Jul 11, 2026

Copy link
Copy Markdown
Author

The pathfinding pool tests all pass now. Some of the others in the same file have regressed, but I didn't change them, apart from running ruff format.

This was not actually true. I deleted the worker functions the old math tests used, for reasons I no longer remember. I've put them back.

clayote commented Aug 3, 2026

Copy link
Copy Markdown
Author

I realize I have little credibility left, but these tests pass on Chromium and Firefox.

Copy link
Copy Markdown
Contributor

@clayote gonna be honest, I am not sure what we're trying to achieve in here or how important this is ... considering how many changes you made, I am not willing (mostly because I have zero extra capacity) to maintain so many changes for an example so I suggest you put your demo on pyscript.com and you have full ownership of its latest state? If that's really convincing we could feature it in our https://pyscript.net/community/ dedicated page but please bear with me I have 99 problems to solve right now and checking examples is not really a priority to me, I am afraid.

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants


Back | FazBrowse Home | New Git URL