Inconsistent JS–Python FFI behavior between Pyodide and MicroPython runtimes
0 reputation · 18 Aug 2023, 19:06 UTC
0 reputation · 18 Aug 2023, 19:06 UTC
When testing a PyScript integration that relies on the JS–Python FFI, the objective is to confirm that Python code can import a stub JavaScript module and invoke its functions without using production credentials, while ensuring the test passes regardless of whether the underlying runtime is Pyodide or MicroPython.
The two runtimes differ in standard‑library size, startup latency, and WebAssembly package support, which may affect the availability of the js module and the performance of asynchronous mocks. It remains unclear whether the FFI behaves identically across these runtimes or if additional configuration is required to achieve parity. Which runtime should be chosen as the default for reliable integration tests, and what configuration adjustments, if any, are needed to make the FFI behavior consistent between Pyodide and MicroPython?
31775 reputation · 18 Aug 2023, 20:52 UTC
Pyodide should be chosen as the default runtime for integration tests involving the JavaScript–Python Foreign Function Interface (FFI). Because Pyodide provides a more mature and comprehensive js module with robust proxying of JavaScript objects, it offers the highest reliability for confirming that Python code can interact with JS stubs without runtime-specific failures.
The inconsistency stems from the differing architectural goals of the two runtimes. Pyodide is designed as a full Python distribution for the browser, whereas MicroPython is optimized for a minimal footprint. This results in two primary discrepancies:
To achieve consistent behavior across both runtimes, avoid direct reliance on the js module's implicit behavior. Instead, implement a thin compatibility wrapper:
js module import, as the availability and behavior of the global scope can vary between runtimes.Detect the active runtime inside your test suite so conditional logic can be applied where parity cannot be reached through abstraction:
import sys
runtime = "pyodide" if "pyodide" in sys.modules else "micropython"
print(f"Testing FFI on: {runtime}")Run the same test suite twice, once with the PyScript configuration set to the Pyodide runtime and once with MicroPython, and compare the FFI output. Note that FFI capabilities are coupled to the underlying WebAssembly build, so record the exact runtime versions used in each pass.
To give a more specific configuration for the asynchronous mocks, clarify whether the Python side uses asyncio to await JS Promises or whether it relies on JS-side callbacks, since the parity strategy differs between those two patterns.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.