# PEP 818: Adding the Core of the Pyodide Foreign Function Interface to Python (2)

**URL:** <https://discuss.python.org/t/pep-818-adding-the-core-of-the-pyodide-foreign-function-interface-to-python-2/109311>\
**Category:** PEPs\
**Created:** [October 1, 2026, 4:29pm UTC](https://discuss.python.org/t/pep-818-adding-the-core-of-the-pyodide-foreign-function-interface-to-python-2/109311 "2026-10-01T16:29:20Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![hoodmane](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/hoodmane/32/4037_2.png) [@hoodmane](https://discuss.python.org/u/hoodmane)\
**Post date:** [October 1, 2026, 4:29pm UTC](https://discuss.python.org/t/pep-818-adding-the-core-of-the-pyodide-foreign-function-interface-to-python-2/109311/1 "2026-10-01T16:29:20Z")

</div>

This is the second discuss thread for [PEP 818](https://peps.python.org/pep-0818/). The previous thread is [here](https://discuss.python.org/t/pep-818-adding-the-core-of-the-pyodide-foreign-function-interface-to-python/105530/22). I got the following feedback:

1. Various name changes were requested, which I implemented.
2. The PEP was too long, so I reduced the length by about half by removing implementation details from the spec section.

I also added support for proxying and conversion of buffers, and for asyncio including an event loop, conversion between Python and JavaScript awaitables, and deferred destruction for arguments to an asynchronous JavaScript function called from Python.

In terms of motivation, I got confirmation that the maintainers of Emscripten-forge (an alternate Emscripten Python runtime) strongly support the proposal. They don’t have an easy way to use Pyodide’s foreign function interface currently so they reimplement it. But they would much prefer to share code, and this proposal is the most direct way to do that.

---

<div class="post-metadata">

**Author:** ![davidbrochart](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/davidbrochart/32/32621_2.png) [@davidbrochart](https://discuss.python.org/u/davidbrochart)\
**Post date:** [October 1, 2026, 5:08pm UTC](https://discuss.python.org/t/pep-818-adding-the-core-of-the-pyodide-foreign-function-interface-to-python-2/109311/2 "2026-10-01T17:08:25Z")

</div>

Regarding the asyncio integration, I’m wondering if we could make it more generic to allow integration with other Python event loops (for instance, Trio). It seems the only asyncio-specific code is `ensure_future`, `add_done_callback` and `Future`.

Also IIUC promise cancellation doesn’t really exist in JavaScript (even with abort signals), so I’m wondering what implications this has on the Python side.

---

<div class="post-metadata">

**Author:** ![hoodmane](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/hoodmane/32/4037_2.png) [@hoodmane](https://discuss.python.org/u/hoodmane)\
**Post date:** [October 1, 2026, 6:24pm UTC](https://discuss.python.org/t/pep-818-adding-the-core-of-the-pyodide-foreign-function-interface-to-python-2/109311/3 "2026-10-01T18:24:46Z")

</div>

> if we could make it more generic to allow integration with other Python event loops

You mean something similar to `set_asyncgen_hooks`? I think it makes sense, I will add it.

> Also IIUC promise cancellation doesn’t really exist in JavaScript (even with abort signals), so I’m wondering what implications this has on the Python side.

Well abort signals allow cancellation of certain promises, in the sense that when used the promise will be rejected _and_ the IO work that the promise is waiting for also stops. But we don’t have any integration with Python cancellation and I don’t really know how to do such integration. For the most part the implication is that when a Python task is cancelled, the current IO that it’s waiting on keeps going. When it finishes, no further work will happen on the cancelled Python task. But the current IO job is not affected.

It would be possible to introduce some API like `CancellablePromise(promise, on_cancel)`. Then you could do

```python
controller = AbortController.new()
resp = fetch(some_url, signal=controller.signal)
wrapped = CancellablePromise(resp, controller.abort)

```

Annoyingly this essentially has to be done from user code. But I think it can be implemented downstream.

---

<div class="post-metadata">

**Author:** ![davidbrochart](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/davidbrochart/32/32621_2.png) [@davidbrochart](https://discuss.python.org/u/davidbrochart)\
**Post date:** [October 1, 2026, 9:26pm UTC](https://discuss.python.org/t/pep-818-adding-the-core-of-the-pyodide-foreign-function-interface-to-python-2/109311/4 "2026-10-01T21:26:41Z")

</div>

For integrating any Python event loop, I just meant that the Python code of the `WebLoop` should not depend directly on asyncio, but should use an API that could be implemented using asyncio or e.g. Trio. But given that AnyIO plays this role at the Python level, maybe this is not so important.

The way I see cancellation in JavaScript using abort signals is that the code has to be cooperative all the way down, and in general it is not. So a lot of IO work can be done even though it was cancelled on the Python side. There is an interesting blog post about that [here](https://frontside.com/blog/2023-12-11-await-event-horizon/).
