@@ -16,7 +16,7 @@ Abstract
1616
1717`Emscripten <https://emscripten.org/ >`__ is a complete open source compiler
1818toolchain which compiles C/C++ code into WebAssembly/JavaScript executables that
19- run in JavaScript runtimes including browsers and Node.
19+ run in JavaScript runtimes including browsers and Node.js.
2020
2121This PEP formalizes the addition of Tier 3 for Emscripten support in Python 3.14
2222which `was approved by the steering council on October 25, 2024
@@ -27,8 +27,8 @@ Pyodide wheels to be uploaded to PyPI.
2727Motivation
2828==========
2929
30- A web browser is a universal computing platform, available on Windows, Mac ,
31- Linux, and every smart phone .
30+ A web browser is a universal computing platform, available on Windows, macOS ,
31+ Linux, and every smartphone .
3232
3333`The Pyodide project <https://pyodide.org/ >`__ has for years supported
3434Emscripten Python. Hundreds of thousands of students have learned Python through
@@ -39,7 +39,7 @@ is also increasingly being used by Python packages to provide interactive
3939documentation. This demonstrates both the importance and the maturity of the
4040Emscripten platform.
4141
42- Emscripten and wasi are also the only supported platforms that offer any
42+ Emscripten and WASI are also the only supported platforms that offer any
4343meaningful sandboxing.
4444
4545=====
@@ -69,8 +69,8 @@ Packaging Goals
6969
70701. To describe Pyodide's packaging tooling
71712. To describe Pyodide's wheel abi to a similar level of detail as the manylinux
72- peps
73- 3. To request that Pyodide wheels be allowed for upload to pypi
72+ PEPs
73+ 3. To request that Pyodide wheels be allowed for upload to PyPI
7474
7575
7676===============================
@@ -93,12 +93,12 @@ specified here:
9393* https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md
9494
9595The ``emcc `` compiler is a wrapper around ``clang ``. The ``emcc `` linker is a
96- wrapper around ``wasm-ld `` (also part of the llvm toolchain).
96+ wrapper around ``wasm-ld `` (also part of the LLVM toolchain).
9797
9898Emscripten support for portable C/C++ code source compatibility with Linux is
9999fairly comprehensive, with certain expected exceptions to be spelled out.
100100CPython already supports compilation to Emscripten, and it only requires a very
101- modest number of modifications to the normal linux target.
101+ modest number of modifications to the normal Linux target.
102102
103103----------------
104104POSIX Compliance
@@ -113,15 +113,15 @@ support for ``fork()``. See `Emscripten Portability Guidelines
113113Emscripten executables can be linked with threading support, however, it comes
114114with several limitations:
115115
116- Enabling threading requires websites to be served with special security headers
117- that indicate acceptance of the possibility of spectre-style information
118- leakage. These headers are a usability hazard for users who are not intimately
119- familiar with the web platform.
116+ * Enabling threading requires websites to be served with special security headers
117+ that indicate acceptance of the possibility of spectre-style information
118+ leakage. These headers are a usability hazard for users who are not intimately
119+ familiar with the web platform.
120120
121- If an executable is linked with both threading and a dynamic loader, Emscripten
122- prints a warning that using dynamic loading and pthreads together is
123- experimental. It may cause performance problems or crashes. These problems may
124- require WebAssembly standards work to resolve.
121+ * If an executable is linked with both threading and a dynamic loader, Emscripten
122+ prints a warning that using dynamic loading and pthreads together is
123+ experimental. It may cause performance problems or crashes. These problems may
124+ require WebAssembly standards work to resolve.
125125
126126Because of these limitations, Pyodide standardizes a no-pthreads build of
127127Python. We will start with support for no-pthreads builds. If there is
@@ -162,27 +162,27 @@ macOS. Upstream tools:
162162* emcc is a C and C++ compiler, linker, and a sysroot with headers for the
163163 system libraries. The system libraries themselves are generated on the fly
164164 based on the ABI requested.
165- * NodeJS can be used as an "emulator" to run Emscripten programs from the
166- command line. This emulation behaves best on Linux with Mac as a runner up.
167- Node is the most convenient way to test Emscripten programs.
165+ * Node.js can be used as an "emulator" to run Emscripten programs from the
166+ command line. This emulation behaves best on Linux with macOS as a runner up.
167+ Node.js is the most convenient way to test Emscripten programs.
168168* It is possible to run Emscripten programs inside of any web browser. Browser
169169 automation tools like selenium, playwright, or pupeeteer can be used to test
170170 features that are browser-only.
171171
172172Pyodide's tools:
173173
174174* ``pyodide build `` can be used to cross compile Python packages to run on
175- Emscripten. Cross compilation works best on Linux, sometimes on Macs , and is
175+ Emscripten. Cross compilation works best on Linux, sometimes on macOS , and is
176176 unsupported on Windows.
177177* ``pyodide venv `` can make a virtual environment that runs in Pyodide.
178- * ``pytest-pyodide `` can test Python code against various JS runtimes.
178+ * ``pytest-pyodide `` can test Python code against various JavaScript runtimes.
179179
180180cibuildwheel supports building wheels to target Emscripten using ``pyodide build ``.
181181
182182In the short term, Pyodide's packaging tooling will stay in the Pyodide
183183repository. It is an open question where Pyodide's packaging tooling should live
184184in the long term. Two sensible options would be for it to remain under the
185- ``pyodide `` organization or be moved into the ``pypa `` organization.
185+ ``pyodide `` organization or be moved into the ``pypa `` organization on GitHub .
186186
187187
188188--------------------------------
@@ -240,7 +240,7 @@ Emscripten file system. There are several possible approaches to this:
240240 embeds the files into a custom archive format that cannot be processed with
241241 standard tooling.
242242
243- * For Node, use the NODEFS to mount a native directory with the files into the
243+ * For Node.js , use the NODEFS to mount a native directory with the files into the
244244 Emscripten file system. This is the most efficient option but is Node only. It
245245 is closely analogous to what wasi does.
246246
@@ -278,21 +278,21 @@ replace them in a ``preRun`` hook.
278278
279279Making ``stdin `` work correctly in the browser poses an additional challenge
280280because it is not allowed to block for user input in the main thread of the
281- browser. If Emscripten is run in a webworker and served with the shared memory
281+ browser. If Emscripten is run in a web worker and served with the shared memory
282282headers, it is possible to receive input using shared memory and atomics. It is
283283also possible for a ``stdin `` device to block in a simpler and more efficient
284284manner using stack switching using the experimental JavaScript Promise
285285Integration API.
286286
287287Pyodide replaces the standard I/O devices in order to fix the line buffering
288- behavior. When Pyodide is run in node , ``stdin ``, ``stdout ``, and ``stderr `` are
288+ behavior. When Pyodide is run in Node.js , ``stdin ``, ``stdout ``, and ``stderr `` are
289289by default connected to ``process.stdin ``, ``process.stdout ``, and
290290``process.stderr `` and so the standard streams work as a tty out of the box.
291291Pyodide also ensures that ``shutil.get_terminal_size `` returns results
292292consistent with ``process.stdout.rows `` and ``process.stdout.columns ``. Pyodide
293293currently has no support for stack switching ``stdin ``.
294294
295- Currently, the Emscripten Python node runner uses the default I/O that
295+ Currently, the Emscripten Python Node.js runner uses the default I/O that
296296Emscripten provides. The web example uses ``Atomics `` for ``stdin `` and has
297297custom ``stdout `` and ``stderr `` handlers, but they exhibit the undesirable line
298298buffering behavior. We will upstream the standard streams behaviors from
@@ -311,7 +311,7 @@ Main Thread Synchronous Loading Limit
311311
312312In the main browser thread, a dynamic library can only be loaded synchronously
313313if it is at most 4 kilobytes. This excludes most nontrivial dynamic libraries.
314- This limit is not present in Node and can be avoided by using a web worker. If
314+ This limit is not present in Node.js and can be avoided by using a web worker. If
315315stack switching is available, then it is possible to make ``dlopen() `` stack
316316switch in order to instantiate a dynamic library synchronously.
317317
@@ -394,12 +394,12 @@ very useful. Compiling and linking with ``-g2`` (or a higher debug setting)
394394ensures that WebAssembly symbols are included and they will appear in the
395395traceback.
396396
397- Because Emscripten Python currently has no JS API and no foreign function
398- interface, the situation is much simpler. The Python node runner wraps the call
397+ Because Emscripten Python currently has no JavaScript API and no foreign function
398+ interface, the situation is much simpler. The Python Node.js runner wraps the call
399399to ``bootstrapEmscriptenExecutable() `` in a try/catch block. If an exception is
400400caught, it displays the JavaScript exception and calls ``_Py_DumpTraceback() ``.
401401It then exits with code 1. We will stick with this approach until we add either
402- a JS API or foreign function interface, which is out of scope for this PEP.
402+ a JavaScript API or foreign function interface, which is out of scope for this PEP.
403403
404404=============
405405Specification
@@ -448,15 +448,14 @@ Removed Modules
448448---------------
449449
450450The following modules are removed from the standard library to reduce download
451- size and since they currently wouldn't work in the WebAssembly VM,
451+ size and since they currently wouldn't work in the WebAssembly VM.
452452
453453- curses
454454- dbm
455455- ensurepip
456456- fcntl
457457- grp
458458- idlelib
459- - lib2to3
460459- msvcrt
461460- pwd
462461- resource
@@ -496,7 +495,7 @@ name is justified. This is consistent with the return value from ``os.uname()``.
496495
497496There is also ``sys._emscripten_info `` which includes the Emscripten version and
498497the runtime (either ``navigator.userAgent `` in a browser or ``"Node js" +
499- process.version `` in Node).
498+ process.version `` in Node.js ).
500499
501500---------------
502501Signals Support
@@ -508,7 +507,7 @@ so it is impossible for any thread capable of seeing an interrupt to write to
508507the eval breaker while the Python interpreter is running code. To work around
509508this, there are two possible solutions:
510509
511- * If Emscripten is run in a webworker and served with the shared memory headers,
510+ * If Emscripten is run in a web worker and served with the shared memory headers,
512511 it is possible to use shared memory outside of the WebAssembly address space
513512 as a signal buffer. A signal handling UI thread can write the desired signal
514513 into the signal buffer. The interpreter can periodically check the state of
@@ -596,7 +595,7 @@ CI Resources
596595------------
597596
598597Pyodide can be built and tested on any Linux with a reasonably recent version of
599- Node. Anaconda has offered to provide physical hardware to run Android
598+ Node.js. Anaconda has offered to provide physical hardware to run Emscripten
600599buildbots, maintained by Russell Keith-Magee.
601600
602601CPython does not currently test Tier 3 platforms on GitHub Actions, but if this
@@ -610,12 +609,12 @@ Existing Package Support
610609========================
611610
612611Pyodide currently maintains ports of 255 different packages at the time of this
613- writing, including major scientific Python packages like numpy, scipy , pandas,
614- polars , scikit-learn, opencv, pyarrow , and Pillow as well as general purpose
615- packages like aiohttp, requests, pydantic , cryptography, and orjson.
612+ writing, including major scientific Python packages like NumPy, SciPy , pandas,
613+ Polars , scikit-learn, OpenCV, PyArrow , and Pillow as well as general purpose
614+ packages like aiohttp, Requests, Pydantic , cryptography, and orjson.
616615
617- About 60 packages are also testing against Pyodide in their CI, including numpy ,
618- pandas, awkward-cpp, scikit-image, statsmodels, pyarrow, hypothesis , and PyO3.
616+ About 60 packages are also testing against Pyodide in their CI, including NumPy ,
617+ pandas, awkward-cpp, scikit-image, statsmodels, PyArrow, Hypothesis , and PyO3.
619618
620619Emscripten Wheel Format
621620=======================
@@ -650,19 +649,18 @@ Pyodide ABI, it is not necessary to use the Pyodide distribution itself.
650649The ``pyodide build `` tool knows how to create wheels that match our ABI. As an
651650alternative,
652651`the auditwheel-emscripten tool <https://github.com/ryanking13/auditwheel-emscripten >`__
653-
654652is capable of performing basic compatibility checks, vendoring shared libraries,
655653and retagging the wheel from ``emscripten_<version> `` to ``pyodide_<abi> ``. Unlike
656- with manylinux, there is no need for a docker container to build the
654+ with manylinux, there is no need for a Docker container to build the
657655``pyodide_<abi> `` wheels. All that is needed is a Linux machine and appropriate
658- versions of Python, node , and Emscripten.
656+ versions of Python, Node.js , and Emscripten.
659657
660658
661659------
662660PEP 11
663661------
664662
665- PEP 11 will be updated to indicate that Emscripten is supported. Specifically
663+ :pep: ` 11 ` will be updated to indicate that Emscripten is supported. Specifically
666664the triples ``wasm32-unknown-emscripten_xx_xx_xx ``.
667665
668666Russell Keith-Magee will serve as the initial core team contact for these ABIs.
@@ -676,7 +674,7 @@ Future Work
676674Improving Cross Builds in the Packaging Ecosystem
677675-------------------------------------------------
678676
679- Python now supports four non-self-hosting platforms: iOS, Android, wasi , and
677+ Python now supports four non-self-hosting platforms: iOS, Android, WASI , and
680678Emscripten. All of them will need to build packages via cross builds. Currently,
681679``pyodide-build `` allows building a very large number of Python packages for
682680Emscripten, but it relies on a giant pile of hacks. In the long run, we would
@@ -695,7 +693,7 @@ JavaScript API for Bootstrapping
695693================================
696694
697695Currently we offer no stable API for bootstrapping Python. Instead, we use one
698- collection of settings for the Node cli entrypoint and a separate collection of
696+ collection of settings for the Node.js CLI entrypoint and a separate collection of
699697settings for the browser demo.
700698https://github.com/python/cpython/tree/98fa4a49fecbac3c990a25ce5d300592dad31be0/Tools/wasm/emscripten/node_entry.mjs
701699https://github.com/python/cpython/blob/98fa4a49fecbac3c990a25ce5d300592dad31be0/Tools/wasm/emscripten/web_example/python.worker.mjs
@@ -719,7 +717,7 @@ mapping between the JavaScript object model and the Python object model and a
719717calling convention that allows high level bidirectional integration.
720718
721719Asyncio
722- ========
720+ =======
723721
724722Most JavaScript primitives are asynchronous. The JavaScript thread that Python
725723runs in already has an event loop. It it not too difficult to implement a Python
0 commit comments