New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Review CPython patches / tests and contribute upstream #2000
Comments
|
Hi, I took some inspiration from your patch set. :)
|
|
I've created a repo with my build scripts to build CPython (for now for emscripten but I hope to add work on WASI eventually...): https://github.com/ethanhs/python-wasm (based on @tiran's config.site and my own attempts). I am happy to say I've successfully gotten CPython master running in the browser with emscripten! The main trick up my sleeve is Lots of things don't work though, like |
|
My hope is we eventually centralize all of this WASM build knowledge somewhere so that Pyodide can focus more on the "build the scientific stack" bit and the "build CPython for WASM/WASI" becomes a shared problem. But obviously getting this all working upstream is the first step. |
|
Sounds great @tiran ! Thanks for writing this summary.
It was added when the project started in 2018, with little documentation, difficult to determine exactly why now. Currently removing it works fine #2003 so it's probably something that was necessary for previous versions of Emecripten or CPython.
Great work @ethanhs ! |
Looking forward to this @brettcannon ! For information, currently, we are not necessarily focusing only on scientific computing. Other areas which constitute most of the Pyodide code base, are:
Some of those topics would likely be relevant for anyone trying to run CPython in the browser, and we can certainly try to make these parts more modular and independent so that they can be more easily re-used or adapted. |
|
@rth My comment about focusing on the "build the scientific stack" was meant to imply all the work you do for general building; sorry if it came off as me shortchanging all the work you have done! One thing we will have to discuss is where is the line in terms of what CPython can/will provide out-of-the-box and what will be left to projects like Pyodide to provide themselves? For instance, packaging is not a CPython core team concern; that's left to the community. And so all of your bullet points about Pyodide's work on packaging and building extensions definitely hold as something important this project provides. As for the JS FFI and trying to make more parts of the stdlib work via web APIs, that's an open question as to where that work would be best to live (and we should probably not try to answer until we decide how serious we all are about centralizing this work and where the centralized location should be). |
|
Thanks for starting this discussion @brettcannon !
Certainly.
Right now the JS/Python type translations is at the core of Pyodide. A good part of our API for Python and Javascript either exposes it or has a very strong coupling with it. Indeed, accessing JS from Python is a pre-requisite for finding workarounds for some of the stdlib modules. Such as using the browser event loop for asyncio or possibly in the future using WebWorkers for multiprocessing. It does make sense that better wasm support is done upstream, but as for the JS/Python type conversion API it's very specific to emscripten and the version used for the build and I imagine it would not be integrated into CPython? Even if it could, it's still actively developed, there are edge cases that need frequent fixes, and having a separate package, with faster iteration and the lighter process would still be preferable IMO. Now if it is a separate package, one can access it as, # from Python
from pyodide import jsor # From JS
pyodide.runPython(...)as part of the Pyodide Python and JS packages. We have talked about it with @hoodmane and we don't really see the point of moving the JS/Python type translation code into a different project. It would pretty much mean renaming the Pyodide package to something else. Particularly in the context where it's very likely there will an effort in 2022 to add WASM builds based on the conda-forge infrastructure, where they could take CPython and the Pyodide core package and build it with a conda build setup. We are very open to making things more modular in Pyodide #2014, or anything else that could facilitate the work you are doing though. |
Probably not. It's more of a question of whether it would be a Pyodide sort of thing or some common project we all contribute to. I basically don't know where everyone wants to draw the line on where Pyodide starts/stops compared to CPython itself and compared to some hypothetical project could sit between Pyodide and CPython.
Is that being discussed anywhere publicly? I'm curious how that would look due to some conda packages sometimes requiring arbitrary shell script execution in an activated conda environment which isn't exactly a browser feature. |
Might there instead be the possibility of having designated wasm wheel build targets? https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/ And then have that wasm build target supported within something like the following: https://github.com/pypa/cibuildwheel A lot of the ecosystem is using [Edit] Personally as a package maintainer, having to support both pypi distribution and conda-forge distribution can be quite the headache. So as such I dropped conda-forge distribution of my scientific library quite some time ago |
I agree it's good to have this discussion and if you want we can organize a call to talk about it.
It's been an ongoing subject for a while at conda/conda#7619 but @SylvainCorlay might have more recent information.
Definitely, these efforts are not mutually exclusive. We are currently exploring that possibility #655, pypi/warehouse#10416 and at present, it seems likely that we might use it, at least to replace the emscripten package format. Wheels do have limitations, particularly for packaging non Python dependencies, but on the conda for WASM packaging side there are also open questions #795 |
Sure! Probably @ethanhs and @tiran would be good to have from the CPython side as well as me.
As the author of |
|
We can and should use the A binary wheel for wasm32-emscripten could have a tag like |
I agree with this. I am working on moving Pyodide over to using wheels here:
I would be happy to author or coauthor the PEP. Not sure whether I have the technical knowledge yet, but I may be the closest to having it.
Yes, I think the platform ought to be versioned. But I am thinking about having a modified ABI for dealing with function pointer casting by adding a custom llvm pass. I think this ABI will have to change occasionally in a way that is backwards but not forwards compatible (old wheels work with new interpreter, new wheels don't work with old interpreter).
I think we should keep But if some platform is completely compatible with emscripten, it could just use the emscripten platform tag or accept emscripten-tagged wheels. In any case, I think it will be a while before e.g., WASI would ever be able to load emscripten wheels. And why wouldn't they just build separate WASI wheels? |
|
How are the compiler runtime libraries (like |
|
libc and libc++ are dynamically linked by emscripten. |
|
We can also package dynamic dependencies, for instance we do this with CLAPACK. |
Yes, QuantStack will start working on making emscripten-built conda/mamba packages in January. |
+1 for this as well. It is my understanding that Emscripten does not have a stable ABI, but I don't know about WASI-libc. If they don't have a stable ABI, may I recommend that we tie Emscripten/WASI version to Python version somewhat like is done on Windows?
I would suggest reading over the manylinux specs, which I probably should do too :) I think those are probably the closest to what we want.
+1 on this, emscripten and WASI are not compatible. WASI in particular isn't even meant to be POSIX.
I'm not sure if this will ever happen as I don't expect WASI to support dynamic linking (though I guess you could build on top of WASI to add this). |
They are absolutely planning support for dynamic linking: |
Aha, I forgot about that proposal. But that method looks to be incompatible with Emscripten's method of dynamic linking (well Emscripten kinda has 2, but whatever). Maybe some day Emscripten will transition to that, but I am also not sure how module linking would work with threads etc. |
That might complicate things as that would be introducing a new ABI for CPython in wheels (if I'm understanding correctly). That might necessitate a change in interpreter types, but honestly no one has proposed a new ABI since wheels were created. And is the custom pass just for building the interpreter, or would everyone have to use that custom pass to be compatible (and thus how to make sure everyone building a wheel had that custom pass)? |
I don't think it should -- the compiler will take care of it using existing source code.
It is not yet clear because I haven't gotten the design far enough. My hope would be that we could upstream this into llvm or failing that into emscripten so that everyone would use it. It will be a significant improvement to the wasm ABI I think -- at least in the Python ecosystem we have major trouble with fpcasts. The main issue is that we would encode extra signature information into the upper bits of function pointers, so those bits need to be masked out before calling the function pointer. If a wheel is receiving a function pointer from the CPython or a wheel built with this fpcast API and it wants to call that function pointer, the pointer needs to have its signature bits cleared first. This could be fixed up with a binaryen pass on the completed wasm binary, so if a wheel was built without the ABI and needs to be used with it, it's not necessary to rebuild the wheel, sort of like the way |
|
On the other hand, wheels with the fpcast ABI just won't work with interpreters built without it. But interpreters built without the fpcast ABI are going to have worse capabilities in general than ones with it. |
|
@SylvainCorlay do you have more details somewhere about what packages you are planning to build and how you are going about this? |
@brettcannon OK, maybe let's try to setup a call in early January to talk about how we could collaborate? |
|
I'm not seeing this in 3.11.0a6. I have to manually remove pwd from Setup.bootstrap. |
python/cpython#32224 will fix
I might have landed the change after 3.11.0a6. It's in HEAD of main. In the mean time you can disable the pwd module in |
When I tried that in the past, it looked like disabling a module in a |
|
I'll add a branch building against the alpha so we can have a better reference point for this conversation. |
It's a new feature, https://bugs.python.org/issue46023 |
|
What if I want to disable a bunch of things? Do I put disabled over each? e.g. |
|
Or it looks like I only have to put disabled once? |
just once is sufficient |
|
For reference, I pushed my 3.11.0a6 branch here: |
|
You should be able to replace |
|
Emscripten builds have test modules disabled. You can enable the test modules with The build system is opinionated. So far we have two build flavors |
|
We want to target both browser and node at the same time -- in practice this doesn't seem too hard, though there is some tricky runtime feature detection required. We want to build the test modules and |
How do we override |
|
You could copy the file into your project, make adjustments, and we merge your fixes back into CPython later. Most |
|
I've been meaning to review which of the features we actually need to be disabling. But there are just so many things to do... Thanks for checking. |
|
In the core test suite I'm hitting failures from File "/lib/python3.11/test/libregrtest/main.py", line 662, in main
faulthandler.dump_traceback_later(EXIT_TIMEOUT, exit=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: unable to start watchdog thread |
|
Can fix with: import faulthandler
faulthandler.dump_traceback_later = lambda *args, **kwargs: None |
Does python/cpython#32243 solve your problem? |
|
I suspect so. |
|
python/cpython#32253 is an attempt to add dynamic linking for WASM: |
|
I'm getting compile errors on tot from: Parser/tokenizer.c:2093:5: error: use of undeclared identifier 'cookie_io_functions_t'
cookie_io_functions_t io_cb = {borrow_read, NULL, NULL, NULL};
^
Parser/tokenizer.c:2095:12: error: implicit declaration of function 'fopencookie' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
return fopencookie(b.cookie, "r", io_cb);
^
Parser/tokenizer.c:2095:39: error: use of undeclared identifier 'io_cb'
return fopencookie(b.cookie, "r", io_cb);Note also that Emscripten's |
|
Probably emscripten added |
|
Fixed in python/cpython#32266 |
|
On tip of tree the majority of tests that we had to manually xfail or filter out are now automatically being filtered. Thanks guys! The following are a list of tests that we want to skip / xfail / filter out that still aren't being filtered on the cpython main branch: can't start new threadTons of failures
SocketsMost sockets tests automatically are skipped now but not all. These tests fail on
Missing bytecode
Missing modules:A lot of problems with missing dbm.
Miscunittest.test.test_break.TestBreakSignalIgnored.testTwoResults fails with os.kill(os.getpid(), signal.SIGINT)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PermissionError: [Errno 63] Operation not permitted |
|
|
Thanks!
Yeah that's a reasonable solution. I'm not sure why |
|
Agreed. Closing. Thanks, everyone for the discussion and your work on this! |

rth commentedNov 26, 2021
•
edited
There is currently an active effort for adding wasm as the build target to CPython in https://bugs.python.org/issue40280 by Christian Heimes. So it would be an ideal timing to review again our CPython patches and failing tests and re-evaluate what could be contributed upstream.
(Other things were already proposed upstream when possible).
The text was updated successfully, but these errors were encountered: