diff options
| -rw-r--r-- | ports/webassembly/proxy_js.js | 17 | ||||
| -rw-r--r-- | tests/ports/webassembly/fun_py_callback_js.mjs | 31 | ||||
| -rw-r--r-- | tests/ports/webassembly/fun_py_callback_js.mjs.exp | 8 |
3 files changed, 55 insertions, 1 deletions
diff --git a/ports/webassembly/proxy_js.js b/ports/webassembly/proxy_js.js index 7a0a1bbe8..1f60bf41e 100644 --- a/ports/webassembly/proxy_js.js +++ b/ports/webassembly/proxy_js.js @@ -89,7 +89,22 @@ function proxy_call_python(target, argumentsList) { if (argumentsList.length > 0) { Module._free(args); } - return proxy_convert_mp_to_js_obj_jsside_with_free(value); + const ret = proxy_convert_mp_to_js_obj_jsside_with_free(value); + if (ret instanceof PyProxyThenable) { + // In Python when an async function is called it creates the + // corresponding "generator", which must then be executed at + // the top level by an asyncio-like scheduler. In JavaScript + // the semantics for async functions is that they are started + // immediately (their non-async prefix code is executed immediately) + // and only if they await do they return a Promise to delay the + // execution of the remainder of the function. + // + // Emulate the JavaScript behaviour here by resolving the Python + // async function. We assume that the caller who gets this + // return is JavaScript. + return Promise.resolve(ret); + } + return ret; } function proxy_convert_js_to_mp_obj_jsside(js_obj, out) { diff --git a/tests/ports/webassembly/fun_py_callback_js.mjs b/tests/ports/webassembly/fun_py_callback_js.mjs new file mode 100644 index 000000000..5541e7a46 --- /dev/null +++ b/tests/ports/webassembly/fun_py_callback_js.mjs @@ -0,0 +1,31 @@ +// Test using Python functions as JS callbacks. + +const mp = await (await import(process.argv[2])).loadMicroPython(); + +globalThis.asyncTimeout = (ms) => + new Promise((resolve) => setTimeout(resolve, ms)); + +mp.runPython(` +import js + +def f0(): + print("f0 run") + +async def f1(): + print("f1 run") + +async def f2(): + print("f2 start") + await js.asyncTimeout(0) + print("f2 end") + +async def f3(): + print("f3 start") + await f2() + print("f3 end") + +js.setTimeout(f0, 0) +js.setTimeout(f1, 50) +js.setTimeout(f2, 100) +js.setTimeout(f3, 150) +`); diff --git a/tests/ports/webassembly/fun_py_callback_js.mjs.exp b/tests/ports/webassembly/fun_py_callback_js.mjs.exp new file mode 100644 index 000000000..732062c84 --- /dev/null +++ b/tests/ports/webassembly/fun_py_callback_js.mjs.exp @@ -0,0 +1,8 @@ +f0 run +f1 run +f2 start +f2 end +f3 start +f2 start +f2 end +f3 end |
