When we call a Python function from JavaScript, if the result is a coroutine
we have logic to automatically schedule it. This is so that a coroutine function
can be used as an event handler or otherwise as a drop in replacement for a JS
async function: when a JS async function is called, its execution is automatically
scheduled, whereas in Python an async function must be awaited or scheduled with
`create_task`. Contexts that expect JS async functions may not do any of these
things but still want the function to execute.
A confusing edge case that arises is when a coroutine is returned from a function
which is not a Python async function. This most often happens by accident, for example
with `eval_code`. It's perhaps slightly unexpected that we schedule it in this case.
This PR adjusts it so that if a non-async python is called and it returns a coroutine,
we no longer schedule it.
One edge case that's still here is that if an async function returns a coroutine, that
coroutine will get automatically scheduled:
```js
pyodide.runPython(`
async def f():
return g()
async def g():
print("This is executed")
`);
pyodide.globals.get("g")()
```
This is because we attach the coroutine to a JS promise and if a JS promise resolves to
a thenable, the thenable is automatically thened. If we were sufficiently upset about this,
we could use a custom thenable that doesn't have this flattening behavior.
Upgrades scipy to its latest release 1.11.1 (released 28 June 2023).
I ran the scipy test suite locally and I did not notice any problematic issues.
There are some additional test failures for some tests that were added between
scipy 1.10.1 and 1.11.1. Most are due to Pyodide limitations. There is also
`scipy.stats.tests.test_multivariate` `test_cdf_against_generic_integrators`
that seems to indicate that `scipy.integrate.tplquad` is not converging but that
seems to be the case in scipy 1.10.1 too.
The previous logic raised an OSError if a response returned a status code of 400
or greater but it is useful to be able to retrieve the bodies from such
responses as they often contain additional information about the error
This change allows users to customize where wheels are cached in Node.
This is important in the context of docker images and other cases where
the `node_modules` folder isn't writable.
This is a minor optimization in `JsObject_GetString`. We only need to check if `key in obj`
when `obj[key]` returns `undefined` to distinguish between missing and present but set
to `undefined`.
In C++
```
try {
some_func(arg1, arg2, ...);
} catch (SomeException e) {
// ...
}
```
generates code like:
```
invoke_sig(some_func_ptr, arg1, arg2, ...);
```
where invoke_sig is a JS trampoline that does a JS try/catch. So in particular, if some_func is declared with the wrong type but it is only called in try blocks, then it will work anyways. But if instead of js exceptions you use wasm exceptions then it's back to "null function or function signature mismatch".
Resolves#3924. Some code checks whether an object is callable with `instanceof Function`.
The correct way to check for callability is with `typeof x === "function"`, but ideally we want
to work with existing code that uses a less accurate callability check.
Make a copy of the PyProxy class which is a subclass of Function.
Since the difference between `PyProxy` and `PyProxyFunction` is an implementation
detail, we use `[Symbol.hasInstance]` to make them recognize the same set of objects
as their instances.
we also need some extra logic to filter out additional attributes that come from the
`Function` prototype.
This is some cleanup after #3883.
- Make the `PYODIDE_ROOT` be modified only inside the `init_environment` function.
- Removes `__LOADED_PYODIDE_ENV`. I think it is redundant as we use `PYODIDE_ROOT` for a similar purpose.
Prior to this commit:
```js
pyodide.registerJsModule("xx", {a: 2});
pyodide.runPython("from xx import *");
```
raises:
```
ImportError: from-import-* object has no __dict__ and no __all__
```
Afterwards, it behaves as expected (a variable called "a" is introduced into globals equal to 2).
This also updates the command line runner to pass in all ambient environment
variables except that `HOME` is set to the working directory.
`homedir` is now deprecated. I added handling for `homedir` and `env.HOME`:
if both are passed, raise an error, otherwise they mean the same thing.
Using `Py_SIZE` on `PyLongObject` is no longer allowed in Python 3.12. Less
importantly, we are minorly overestimating the size of very large numbers here
since each digit has only 30 bits, so a 16 "digit" number has 480 bits and fits
into 15 u32s.
Prior to this PR, internal Python code paths that use `PySequence_*` methods
directly would fail on JS Arrays. To fix this, we implement `sq_length`, `sq_item`
and (for mutable sequences) `sq_ass_item.` I also added implementations for
the rest of the sequence methods `sq_concat` and `sq_repeat`. Strangely
`sq_inplace_concat` already existed.