This creates a new `pyodide.ffi` submodule and adds a bunch of new subclasses of
`PyProxy` to it.
There are three stages in which we are concerned with the behavior of the
objects we define:
1. at time of static typechecks
2. at execution time
3. when generating docs
Prior to this PR, the subtypes of PyProxy only work well for static type checks,
they work acceptably at runtime (just don't let the user access them), and the
docs don't look that great. This PR is primarily intended to improve the docs
for PyProxy, but they also make execution time checks work better: you can now
say `obj instanceof pyodide.ffi.PyCallable` instead of `obj.isCallable()` which
I is easier to understand and to cross reference against the documentation. I am
marking `isCallable` as deprecated.
I also made a bunch of edits and improvements to the docs.
I have deprecated `PyProxyCallable` in favor of `pyodide.ffi.PyCallable` and
`PyProxy.isCallable` in favor of `obj instanceof pyodide.ffi.PyCallable`.
`PyBuffer` has been renamed to `pyodide.ffi.PyBufferView` and a new `PyBuffer`
has been created which is a subtype of `PyProxy`.
This leads to more consistent rendering (functions and methods get parens after
them) and reduces chances of warnings about getting the wrong link. It is also
possible to use `~fully.quallified.name` to just show `name` if we use a specific
reference type, but it doesn't work with `any` for some reason.
* Don't destroy roundtrip PyProxies automatically
There's a bunch of places where we want to destroy a `PyProxy` if it is being
handed back into Python. This way, if the user wants to keep the proxy around
they can return a copy() of it (whereas otherwise they would have no way to
destroy it after the JavaScript execution is ended).
```js
function new_dict(){
const dict = pyodide.globals.get("dict");
const result = dict([[1,2],[3,4]]);
return result;
// Proxy is destroyed after it is returned!
}
```
If the `PyProxy` has roundtrip set, however, it is generally a bad idea to
destroy it in these cases. In many cases, this means that the object returned
to Python is actually unusable (because we get a destroyed double proxy).
One slightly annoying question is how to deal with the case where (1) we
want the return value NOT to be destroyed and (2) it may or may not be roundtrip
```
function f(px){
// We don't want px to be destroyed so we have to return a copy (the copy
// gets destroyed instead). But if px is roundtrip then the copy is also
// roundtrip and neither gets destroyed so there is a leak. What to do???
return px.copy();
}
Old usage is still accepted but causes a deprecation warning, saying
we will remove it in v0.21. Similar to #2300. I am planning to add
an option to do wasm compilation in a subsequent PR.
I also did some cleanup from #2300 and added tests for the deprecation
warnings.