mirror of https://github.com/pyodide/pyodide.git
DOCS Edits to Javascript API docs (#1427)
This commit is contained in:
parent
31d10d1705
commit
1781b8760f
|
@ -2,3 +2,7 @@
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-size: 100% !important;
|
||||||
|
}
|
||||||
|
|
|
@ -7,9 +7,10 @@ browser.
|
||||||
|
|
||||||
Pyodide brings the Python 3.8 runtime to the browser via WebAssembly, along with
|
Pyodide brings the Python 3.8 runtime to the browser via WebAssembly, along with
|
||||||
the Python scientific stack including NumPy, Pandas, Matplotlib, SciPy, and
|
the Python scientific stack including NumPy, Pandas, Matplotlib, SciPy, and
|
||||||
scikit-learn. The [packages directory](packages) lists over 75 packages which
|
scikit-learn. The [packages
|
||||||
are currently available. In addition it's possible to install pure Python wheels
|
directory](https://github.com/pyodide/pyodide/tree/master/packages) lists over
|
||||||
from PyPi.
|
75 packages which are currently available. In addition it's possible to install
|
||||||
|
pure Python wheels from PyPi.
|
||||||
|
|
||||||
Pyodide provides transparent conversion of objects between Javascript and
|
Pyodide provides transparent conversion of objects between Javascript and
|
||||||
Python. When used inside a browser, Python has full access to the Web APIs.
|
Python. When used inside a browser, Python has full access to the Web APIs.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.parsers.rst import Directive, Parser as RstParser
|
from docutils.parsers.rst import Directive, Parser as RstParser, directives
|
||||||
from docutils.statemachine import StringList
|
from docutils.statemachine import StringList
|
||||||
from docutils.utils import new_document
|
from docutils.utils import new_document
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ from sphinx import addnodes
|
||||||
from sphinx.util import rst
|
from sphinx.util import rst
|
||||||
from sphinx.util.docutils import switch_source_input
|
from sphinx.util.docutils import switch_source_input
|
||||||
from sphinx.ext.autosummary import autosummary_table, extract_summary
|
from sphinx.ext.autosummary import autosummary_table, extract_summary
|
||||||
|
from sphinx.domains.javascript import JSCallable, JavaScriptDomain
|
||||||
|
|
||||||
from sphinx_js.jsdoc import Analyzer as JsAnalyzer
|
from sphinx_js.jsdoc import Analyzer as JsAnalyzer
|
||||||
from sphinx_js.ir import Class, Function
|
from sphinx_js.ir import Class, Function
|
||||||
|
@ -21,6 +22,21 @@ from sphinx_js.renderers import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class JSFuncMaybeAsync(JSCallable):
|
||||||
|
option_spec = {
|
||||||
|
**JSCallable.option_spec,
|
||||||
|
"async": directives.flag,
|
||||||
|
}
|
||||||
|
|
||||||
|
def handle_signature(self, sig, signode):
|
||||||
|
if "async" in self.options:
|
||||||
|
self.display_prefix = "async"
|
||||||
|
return super().handle_signature(sig, signode)
|
||||||
|
|
||||||
|
|
||||||
|
JavaScriptDomain.directives["function"] = JSFuncMaybeAsync
|
||||||
|
|
||||||
|
|
||||||
class PyodideAnalyzer:
|
class PyodideAnalyzer:
|
||||||
"""JsDoc automatically instantiates the JsAnalyzer. Rather than subclassing
|
"""JsDoc automatically instantiates the JsAnalyzer. Rather than subclassing
|
||||||
or monkey patching it, we use composition (see getattr impl).
|
or monkey patching it, we use composition (see getattr impl).
|
||||||
|
@ -85,11 +101,14 @@ class PyodideAnalyzer:
|
||||||
if key[0] == "pyproxy.":
|
if key[0] == "pyproxy.":
|
||||||
items["PyProxy"] += group
|
items["PyProxy"] += group
|
||||||
|
|
||||||
|
from operator import itemgetter
|
||||||
|
|
||||||
for key, value in items.items():
|
for key, value in items.items():
|
||||||
for json in value:
|
for json in sorted(value, key=itemgetter("name")):
|
||||||
if json.get("access", None) == "private":
|
if json.get("access", None) == "private":
|
||||||
continue
|
continue
|
||||||
obj = self.get_object_from_json(json)
|
obj = self.get_object_from_json(json)
|
||||||
|
obj.async_ = json.get("async", False)
|
||||||
if isinstance(obj, Class):
|
if isinstance(obj, Class):
|
||||||
# sphinx-jsdoc messes up array types. Fix them.
|
# sphinx-jsdoc messes up array types. Fix them.
|
||||||
for x in obj.members:
|
for x in obj.members:
|
||||||
|
@ -121,9 +140,20 @@ def get_jsdoc_content_directive(app):
|
||||||
renderer = AutoClassRenderer
|
renderer = AutoClassRenderer
|
||||||
else:
|
else:
|
||||||
renderer = AutoAttributeRenderer
|
renderer = AutoAttributeRenderer
|
||||||
return renderer(
|
rst = renderer(
|
||||||
self, app, arguments=["dummy"], options={"members": ["*"]}
|
self, app, arguments=["dummy"], options={"members": ["*"]}
|
||||||
).rst([obj.name], obj, use_short_name=False)
|
).rst([obj.name], obj, use_short_name=False)
|
||||||
|
if obj.async_:
|
||||||
|
rst = self.add_async_option_to_rst(rst)
|
||||||
|
return rst
|
||||||
|
|
||||||
|
def add_async_option_to_rst(self, rst):
|
||||||
|
rst_lines = rst.split("\n")
|
||||||
|
for i, line in enumerate(rst_lines):
|
||||||
|
if line.startswith(".."):
|
||||||
|
break
|
||||||
|
rst_lines.insert(i + 1, " :async:")
|
||||||
|
return "\n".join(rst_lines)
|
||||||
|
|
||||||
def get_rst_for_group(self, objects):
|
def get_rst_for_group(self, objects):
|
||||||
return [self.get_rst(obj) for obj in objects]
|
return [self.get_rst(obj) for obj in objects]
|
||||||
|
@ -215,9 +245,10 @@ def get_jsdoc_summary_directive(app):
|
||||||
"""
|
"""
|
||||||
sig = self.get_sig(obj)
|
sig = self.get_sig(obj)
|
||||||
display_name = obj.name
|
display_name = obj.name
|
||||||
|
prefix = "*async* " if obj.async_ else ""
|
||||||
summary = self.extract_summary(obj.description)
|
summary = self.extract_summary(obj.description)
|
||||||
link_name = pkgname + "." + display_name
|
link_name = pkgname + "." + display_name
|
||||||
return (display_name, sig, summary, link_name)
|
return (prefix, display_name, sig, summary, link_name)
|
||||||
|
|
||||||
def get_summary_table(self, pkgname, group):
|
def get_summary_table(self, pkgname, group):
|
||||||
"""Get the data for a summary table. Return value is set up to be an
|
"""Get the data for a summary table. Return value is set up to be an
|
||||||
|
@ -266,17 +297,18 @@ def get_jsdoc_summary_directive(app):
|
||||||
row.append(nodes.entry("", node))
|
row.append(nodes.entry("", node))
|
||||||
body.append(row)
|
body.append(row)
|
||||||
|
|
||||||
for name, sig, summary, real_name in items:
|
for prefix, name, sig, summary, real_name in items:
|
||||||
qualifier = "any" # <== Only thing changed from autosummary version
|
qualifier = "any" # <== Only thing changed from autosummary version
|
||||||
if "nosignatures" not in self.options:
|
if "nosignatures" not in self.options:
|
||||||
col1 = ":%s:`%s <%s>`\\ %s" % (
|
col1 = "%s:%s:`%s <%s>`\\ %s" % (
|
||||||
|
prefix,
|
||||||
qualifier,
|
qualifier,
|
||||||
name,
|
name,
|
||||||
real_name,
|
real_name,
|
||||||
rst.escape(sig),
|
rst.escape(sig),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
col1 = ":%s:`%s <%s>`" % (qualifier, name, real_name)
|
col1 = "%s:%s:`%s <%s>`" % (prefix, qualifier, name, real_name)
|
||||||
col2 = summary
|
col2 = summary
|
||||||
append_row(col1, col2)
|
append_row(col1, col2)
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -119,6 +119,7 @@ def test_summary():
|
||||||
)
|
)
|
||||||
assert set(globals) == {
|
assert set(globals) == {
|
||||||
(
|
(
|
||||||
|
"",
|
||||||
"languagePluginLoader",
|
"languagePluginLoader",
|
||||||
"",
|
"",
|
||||||
"A promise that resolves to ``undefined`` when Pyodide is finished loading.",
|
"A promise that resolves to ``undefined`` when Pyodide is finished loading.",
|
||||||
|
@ -128,12 +129,14 @@ def test_summary():
|
||||||
assert set(attributes).issuperset(
|
assert set(attributes).issuperset(
|
||||||
{
|
{
|
||||||
(
|
(
|
||||||
|
"",
|
||||||
"loadedPackages",
|
"loadedPackages",
|
||||||
"",
|
"",
|
||||||
"The list of packages that Pyodide has loaded.",
|
"The list of packages that Pyodide has loaded.",
|
||||||
"pyodide.loadedPackages",
|
"pyodide.loadedPackages",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
"",
|
||||||
"pyodide_py",
|
"pyodide_py",
|
||||||
"",
|
"",
|
||||||
"An alias to the Python pyodide package.",
|
"An alias to the Python pyodide package.",
|
||||||
|
@ -141,15 +144,18 @@ def test_summary():
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
print(functions)
|
||||||
assert set(functions).issuperset(
|
assert set(functions).issuperset(
|
||||||
{
|
{
|
||||||
(
|
(
|
||||||
|
"*async* ",
|
||||||
"loadPackagesFromImports",
|
"loadPackagesFromImports",
|
||||||
"(code, messageCallback, errorCallback)",
|
"(code, messageCallback, errorCallback)",
|
||||||
"Inspect a Python code chunk and use :js:func:`pyodide.loadPackage` to load any known \npackages that the code chunk imports.",
|
"Inspect a Python code chunk and use :js:func:`pyodide.loadPackage` to load any known \npackages that the code chunk imports.",
|
||||||
"pyodide.loadPackagesFromImports",
|
"pyodide.loadPackagesFromImports",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
"",
|
||||||
"registerJsModule",
|
"registerJsModule",
|
||||||
"(name, module)",
|
"(name, module)",
|
||||||
"Registers the Js object ``module`` as a Js module with ``name``.",
|
"Registers the Js object ``module`` as a Js module with ``name``.",
|
||||||
|
|
|
@ -14,7 +14,7 @@ By default there are two Javascript modules. More can be added with
|
||||||
* - ``js``
|
* - ``js``
|
||||||
- The global Javascript scope.
|
- The global Javascript scope.
|
||||||
* - :js:mod:`pyodide_js <pyodide>`
|
* - :js:mod:`pyodide_js <pyodide>`
|
||||||
- The Javascript pyodide module.
|
- The Javascript Pyodide module.
|
||||||
```
|
```
|
||||||
|
|
||||||
```{eval-rst}
|
```{eval-rst}
|
||||||
|
|
|
@ -167,7 +167,7 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
/**
|
/**
|
||||||
* The length of the object.
|
* The length of the object.
|
||||||
*
|
*
|
||||||
* Present only if ``type(obj)`` has a `__len__` method.
|
* Present only if the proxied Python object has a ``__len__`` method.
|
||||||
*/
|
*/
|
||||||
get length() {
|
get length() {
|
||||||
let ptrobj = _getPtr(this);
|
let ptrobj = _getPtr(this);
|
||||||
|
@ -190,7 +190,7 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
/**
|
/**
|
||||||
* This translates to the Python code ``obj[key]``.
|
* This translates to the Python code ``obj[key]``.
|
||||||
*
|
*
|
||||||
* Present only if ``type(obj)`` has a ``__getitem__`` method.
|
* Present only if the proxied Python object has a ``__getitem__`` method.
|
||||||
*
|
*
|
||||||
* @param {any} key The key to look up.
|
* @param {any} key The key to look up.
|
||||||
* @returns The corresponding value.
|
* @returns The corresponding value.
|
||||||
|
@ -223,7 +223,7 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
/**
|
/**
|
||||||
* This translates to the Python code ``obj[key] = value``.
|
* This translates to the Python code ``obj[key] = value``.
|
||||||
*
|
*
|
||||||
* Present only if ``type(obj)`` has a ``__setitem__`` method.
|
* Present only if the proxied Python object has a ``__setitem__`` method.
|
||||||
*
|
*
|
||||||
* @param {any} key The key to set.
|
* @param {any} key The key to set.
|
||||||
* @param {any} value The value to set it to.
|
* @param {any} value The value to set it to.
|
||||||
|
@ -248,7 +248,7 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
/**
|
/**
|
||||||
* This translates to the Python code ``del obj[key]``.
|
* This translates to the Python code ``del obj[key]``.
|
||||||
*
|
*
|
||||||
* Present only if ``type(obj)`` has a ``__delitem__`` method.
|
* Present only if the proxied Python object has a ``__delitem__`` method.
|
||||||
*
|
*
|
||||||
* @param {any} key The key to delete.
|
* @param {any} key The key to delete.
|
||||||
*/
|
*/
|
||||||
|
@ -275,7 +275,7 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
/**
|
/**
|
||||||
* This translates to the Python code ``key in obj``.
|
* This translates to the Python code ``key in obj``.
|
||||||
*
|
*
|
||||||
* Present only if ``type(obj)`` has a ``__contains__`` method.
|
* Present only if the proxied Python object has a ``__contains__`` method.
|
||||||
*
|
*
|
||||||
* @param {*} key The key to check for.
|
* @param {*} key The key to check for.
|
||||||
* @returns {bool} Is ``key`` present?
|
* @returns {bool} Is ``key`` present?
|
||||||
|
@ -308,12 +308,12 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
* associated to the proxy. See the documentation for `Symbol.iterator
|
* associated to the proxy. See the documentation for `Symbol.iterator
|
||||||
* <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator>`_.
|
* <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator>`_.
|
||||||
*
|
*
|
||||||
* Present only if the Python object is iterable (i.e., ``type(obj)`` has an
|
* Present only if the proxied Python object is iterable (i.e., has an
|
||||||
* ``__iter__`` method).
|
* ``__iter__`` method).
|
||||||
*
|
*
|
||||||
* This will be used implicitly by ``for(let x of proxy){}``.
|
* This will be used implicitly by ``for(let x of proxy){}``.
|
||||||
*
|
*
|
||||||
* @returns {Iterator} An iterator for ``obj``.
|
* @returns {Iterator} An iterator for the proxied Python object.
|
||||||
*/
|
*/
|
||||||
[Symbol.iterator] : function*() {
|
[Symbol.iterator] : function*() {
|
||||||
let iterptr = _PyObject_GetIter(_getPtr(this));
|
let iterptr = _PyObject_GetIter(_getPtr(this));
|
||||||
|
@ -343,16 +343,16 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
*
|
*
|
||||||
* This will be used implicitly by ``for(let x of proxy){}``.
|
* This will be used implicitly by ``for(let x of proxy){}``.
|
||||||
*
|
*
|
||||||
* Present only if ``obj`` is a Python generator or iterator (i.e.,
|
* Present only if the proxied Python object is a generator or iterator
|
||||||
* ``type(obj)`` has an ``__iter__`` method).
|
* (i.e., has a ``send`` or ``__next__`` method).
|
||||||
*
|
*
|
||||||
* @param {*} value The value to send to the generator. The value will be
|
* @param {*} value The value to send to the generator. The value will be
|
||||||
* assigned as a result of a yield expression.
|
* assigned as a result of a yield expression.
|
||||||
* @returns {Object} An Object with two properties, ``done`` and ``value``.
|
* @returns {Object} An Object with two properties: ``done`` and ``value``.
|
||||||
* If the generator returned ``some_value``, will return ``{done : false,
|
* When the generator yields ``some_value``, ``next`` returns ``{done :
|
||||||
* value : some_value}``. If the Python generator raised a
|
* false, value : some_value}``. When the generator raises a
|
||||||
* ``StopIteration(result_value)`` exception, then we return ``{done : true,
|
* ``StopIteration(result_value)`` exception, ``next`` returns ``{done :
|
||||||
* value : result_value}``.
|
* true, value : result_value}``.
|
||||||
*/
|
*/
|
||||||
next : function(arg) {
|
next : function(arg) {
|
||||||
let idresult;
|
let idresult;
|
||||||
|
@ -599,7 +599,8 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
* `Promise.then
|
* `Promise.then
|
||||||
* <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then>`_
|
* <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then>`_
|
||||||
*
|
*
|
||||||
* Only present on awaitable Python objects.
|
* Present only if the proxied Python object is `awaitable
|
||||||
|
* <https://docs.python.org/3/library/asyncio-task.html?highlight=awaitable#awaitables>`_.
|
||||||
*
|
*
|
||||||
* @param {Function} onFulfilled A handler called with the result as an
|
* @param {Function} onFulfilled A handler called with the result as an
|
||||||
* argument if the awaitable succeeds.
|
* argument if the awaitable succeeds.
|
||||||
|
@ -619,7 +620,8 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
* `Promise.catch
|
* `Promise.catch
|
||||||
* <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch>`_.
|
* <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch>`_.
|
||||||
*
|
*
|
||||||
* Only present on awaitable Python objects.
|
* Present only if the proxied Python object is `awaitable
|
||||||
|
* <https://docs.python.org/3/library/asyncio-task.html?highlight=awaitable#awaitables>`_.
|
||||||
*
|
*
|
||||||
* @param {Function} onRejected A handler called with the error as an
|
* @param {Function} onRejected A handler called with the error as an
|
||||||
* argument if the awaitable fails.
|
* argument if the awaitable fails.
|
||||||
|
@ -637,9 +639,9 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
* `Promise.finally
|
* `Promise.finally
|
||||||
* <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally>`_.
|
* <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally>`_.
|
||||||
*
|
*
|
||||||
* Only present on `awaitable
|
* Present only if the proxied Python object is `awaitable
|
||||||
* <https://docs.python.org/3/library/asyncio-task.html?highlight=awaitable#awaitables>`_
|
* <https://docs.python.org/3/library/asyncio-task.html?highlight=awaitable#awaitables>`_.
|
||||||
* Python objects.
|
*
|
||||||
*
|
*
|
||||||
* @param {Function} onFinally A handler that is called with zero arguments
|
* @param {Function} onFinally A handler that is called with zero arguments
|
||||||
* when the awaitable resolves.
|
* when the awaitable resolves.
|
||||||
|
@ -681,18 +683,31 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
* Get a view of the buffer data which is usable from Javascript. No copy is
|
* Get a view of the buffer data which is usable from Javascript. No copy is
|
||||||
* ever performed.
|
* ever performed.
|
||||||
*
|
*
|
||||||
* The return value is a :any:`PyBuffer` object. See the documentation for
|
* Present only if the proxied Python object supports the `Python Buffer
|
||||||
* :any:`PyBuffer` for details on how to use it.
|
* Protocol <https://docs.python.org/3/c-api/buffer.html>`_.
|
||||||
*
|
*
|
||||||
* We do not support suboffsets, if the buffer requires suboffsets we will
|
* We do not support suboffsets, if the buffer requires suboffsets we will
|
||||||
* throw an error. Javascript nd array libraries can't handle suboffsets
|
* throw an error. Javascript nd array libraries can't handle suboffsets
|
||||||
* anyways. In this case, you should copy the buffer to one that doesn't use
|
* anyways. In this case, you should use the :any:`toJs` api or copy the
|
||||||
* suboffets (using e.g., ``np.ascontiguousarray``).
|
* buffer to one that doesn't use suboffets (using e.g.,
|
||||||
|
* `numpy.ascontiguousarray
|
||||||
|
* <https://numpy.org/doc/stable/reference/generated/numpy.ascontiguousarray.html>`_).
|
||||||
*
|
*
|
||||||
* @param {string} type The type of the desired output. Should be one of:
|
* If the buffer stores big endian data or half floats, this function will
|
||||||
* "i8", "u8", "u8clamped", "i16", "u16", "i32", "u32", "i32", "u32",
|
* fail without an explicit type argument. For big endian data you can use
|
||||||
* "i64", "u64", "f32", "f64, or "dataview".
|
* ``toJs``. `DataViews
|
||||||
* @returns PyBuffer
|
* <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView>`_
|
||||||
|
* have support for big endian data, so you might want to pass
|
||||||
|
* ``'dataview'`` as the type argument in that case.
|
||||||
|
*
|
||||||
|
* @param {string} [type] The type of :any:`PyBuffer.data` field in the
|
||||||
|
* output. Should be one of: ``"i8"``, ``"u8"``, ``"u8clamped"``, ``"i16"``,
|
||||||
|
* ``"u16"``, ``"i32"``, ``"u32"``, ``"i32"``, ``"u32"``, ``"i64"``,
|
||||||
|
* ``"u64"``, ``"f32"``, ``"f64``, or ``"dataview"``. This argument is
|
||||||
|
* optional, if absent ``getBuffer`` will try to determine the appropriate
|
||||||
|
* output type based on the buffer `format string
|
||||||
|
* <https://docs.python.org/3/library/struct.html#format-strings>`_.
|
||||||
|
* @returns :any:`PyBuffer`
|
||||||
*/
|
*/
|
||||||
getBuffer : function(type) {
|
getBuffer : function(type) {
|
||||||
let ArrayType = undefined;
|
let ArrayType = undefined;
|
||||||
|
@ -789,6 +804,7 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
/**
|
/**
|
||||||
* A class to allow access to a Python data buffers from Javascript. These are
|
* A class to allow access to a Python data buffers from Javascript. These are
|
||||||
* produced by :any:`PyProxy.getBuffer` and cannot be constructed directly.
|
* produced by :any:`PyProxy.getBuffer` and cannot be constructed directly.
|
||||||
|
@ -817,8 +833,7 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
* }
|
* }
|
||||||
* return idx;
|
* return idx;
|
||||||
* }
|
* }
|
||||||
* console.log("entry is", pybuff.data[multiIndexToIndex(pybuff, [2, 0,
|
* console.log("entry is", pybuff.data[multiIndexToIndex(pybuff, [2, 0, -1])]);
|
||||||
* -1])]);
|
|
||||||
*
|
*
|
||||||
* .. admonition:: Contiguity
|
* .. admonition:: Contiguity
|
||||||
* :class: warning
|
* :class: warning
|
||||||
|
@ -856,6 +871,7 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
* buffer.data.byteLength
|
* buffer.data.byteLength
|
||||||
* );
|
* );
|
||||||
*/
|
*/
|
||||||
|
// clang-format on
|
||||||
Module.PyBuffer = class PyBuffer {
|
Module.PyBuffer = class PyBuffer {
|
||||||
constructor() {
|
constructor() {
|
||||||
// FOR_JSDOC_ONLY is a macro that deletes its argument.
|
// FOR_JSDOC_ONLY is a macro that deletes its argument.
|
||||||
|
@ -923,6 +939,11 @@ JS_FILE(pyproxy_init_js, () => {0,0; /* Magic, see include_js_file.h */
|
||||||
/**
|
/**
|
||||||
* The actual data. A typed array of an appropriate size backed by a
|
* The actual data. A typed array of an appropriate size backed by a
|
||||||
* segment of the WASM memory.
|
* segment of the WASM memory.
|
||||||
|
*
|
||||||
|
* The ``type`` argument of :any:`getBuffer`
|
||||||
|
* determines which sort of `TypedArray` this is, by default
|
||||||
|
* :any:`getBuffer` will look at the format string to determine the most
|
||||||
|
* appropriate option.
|
||||||
* @type {TypedArray}
|
* @type {TypedArray}
|
||||||
*/
|
*/
|
||||||
this.data;
|
this.data;
|
||||||
|
|
|
@ -51,7 +51,7 @@ try:
|
||||||
"""The ``Promise.then`` API, wrapped to manage the lifetimes of the
|
"""The ``Promise.then`` API, wrapped to manage the lifetimes of the
|
||||||
handlers.
|
handlers.
|
||||||
|
|
||||||
Only available if the wrapped Javascript object has a "then" method.
|
Present only if the wrapped Javascript object has a "then" method.
|
||||||
Pyodide will automatically release the references to the handlers
|
Pyodide will automatically release the references to the handlers
|
||||||
when the promise resolves.
|
when the promise resolves.
|
||||||
"""
|
"""
|
||||||
|
@ -60,7 +60,7 @@ try:
|
||||||
"""The ``Promise.catch`` API, wrapped to manage the lifetimes of the
|
"""The ``Promise.catch`` API, wrapped to manage the lifetimes of the
|
||||||
handler.
|
handler.
|
||||||
|
|
||||||
Only available if the wrapped Javascript object has a "then" method.
|
Present only if the wrapped Javascript object has a "then" method.
|
||||||
Pyodide will automatically release the references to the handler
|
Pyodide will automatically release the references to the handler
|
||||||
when the promise resolves.
|
when the promise resolves.
|
||||||
"""
|
"""
|
||||||
|
@ -69,7 +69,7 @@ try:
|
||||||
"""The ``Promise.finally`` API, wrapped to manage the lifetimes of
|
"""The ``Promise.finally`` API, wrapped to manage the lifetimes of
|
||||||
the handler.
|
the handler.
|
||||||
|
|
||||||
Only available if the wrapped Javascript object has a "then" method.
|
Present only if the wrapped Javascript object has a "then" method.
|
||||||
Pyodide will automatically release the references to the handler
|
Pyodide will automatically release the references to the handler
|
||||||
when the promise resolves. Note the trailing underscore in the name;
|
when the promise resolves. Note the trailing underscore in the name;
|
||||||
this is needed because ``finally`` is a reserved keyword in Python.
|
this is needed because ``finally`` is a reserved keyword in Python.
|
||||||
|
|
126
src/pyodide.js
126
src/pyodide.js
|
@ -13,11 +13,11 @@ globalThis.pyodide = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the main Pyodide wasm module and initialize it. When finished stores the
|
* Load the main Pyodide wasm module and initialize it. When finished stores the
|
||||||
* pyodide module as a global object called ``pyodide``.
|
* Pyodide module as a global object called ``pyodide``.
|
||||||
* @async
|
|
||||||
* @param {string} config.indexURL - The URL from which Pyodide will load
|
* @param {string} config.indexURL - The URL from which Pyodide will load
|
||||||
* packages
|
* packages
|
||||||
* @returns The pyodide module.
|
* @returns The Pyodide module.
|
||||||
|
* @async
|
||||||
*/
|
*/
|
||||||
globalThis.loadPyodide = async function(config = {}) {
|
globalThis.loadPyodide = async function(config = {}) {
|
||||||
if (globalThis.__pyodideLoading) {
|
if (globalThis.__pyodideLoading) {
|
||||||
|
@ -273,18 +273,18 @@ globalThis.loadPyodide = async function(config = {}) {
|
||||||
Module.loadedPackages = {};
|
Module.loadedPackages = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a package or a list of packages over the network. This makes the files
|
* Load a package or a list of packages over the network. This installs the
|
||||||
* for the package available in the virtual filesystem. The package needs to
|
* package in the virtual filesystem. The package needs to be imported from
|
||||||
* be imported from Python before it can be used.
|
* Python before it can be used.
|
||||||
* @param {String | Array} names Package name or URL. Can be either a single
|
* @param {String | Array} names Either a single package name or URL or a list
|
||||||
* element, or an array. URLs can be absolute or relative. URLs must have
|
* of them. URLs can be absolute or relative. The URLs must have file name
|
||||||
* file name `<package-name>.js` and there must be a file called
|
* ``<package-name>.js`` and there must be a file called
|
||||||
* `<package-name>.data` in the same directory.
|
* ``<package-name>.data`` in the same directory.
|
||||||
* @param {function} messageCallback A callback, called with progress messages
|
* @param {function} messageCallback A callback, called with progress messages
|
||||||
* (optional)
|
* (optional)
|
||||||
* @param {function} errorCallback A callback, called with error/warning
|
* @param {function} errorCallback A callback, called with error/warning
|
||||||
* messages (optional)
|
* messages (optional)
|
||||||
* @returns {Promise} Resolves to ``undefined`` when loading is complete
|
* @async
|
||||||
*/
|
*/
|
||||||
Module.loadPackage = async function(names, messageCallback, errorCallback) {
|
Module.loadPackage = async function(names, messageCallback, errorCallback) {
|
||||||
if (!Array.isArray(names)) {
|
if (!Array.isArray(names)) {
|
||||||
|
@ -455,7 +455,10 @@ globalThis.loadPyodide = async function(config = {}) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An alias to the Python pyodide package.
|
* An alias to the Python :py:mod:`pyodide` package.
|
||||||
|
*
|
||||||
|
* You can use this to call functions defined in the Pyodide Python package
|
||||||
|
* from Javascript.
|
||||||
*
|
*
|
||||||
* @type {PyProxy}
|
* @type {PyProxy}
|
||||||
*/
|
*/
|
||||||
|
@ -465,9 +468,8 @@ globalThis.loadPyodide = async function(config = {}) {
|
||||||
*
|
*
|
||||||
* An alias to the global Python namespace.
|
* An alias to the global Python namespace.
|
||||||
*
|
*
|
||||||
* An object whose attributes are members of the Python global namespace.
|
* For example, to access a variable called ``foo`` in the Python global
|
||||||
* For example, to access the ``foo`` Python object from Javascript use
|
* scope, use ``pyodide.globals.get("foo")``
|
||||||
* ``pyodide.globals.get("foo")``
|
|
||||||
*
|
*
|
||||||
* @type {PyProxy}
|
* @type {PyProxy}
|
||||||
*/
|
*/
|
||||||
|
@ -487,11 +489,11 @@ globalThis.loadPyodide = async function(config = {}) {
|
||||||
* .. admonition:: Avoid Stack Frames
|
* .. admonition:: Avoid Stack Frames
|
||||||
* :class: warning
|
* :class: warning
|
||||||
*
|
*
|
||||||
* If you make a ``PyProxy`` of ``sys.last_value``, you should be
|
* If you make a :any:`PyProxy` of ``sys.last_value``, you should be
|
||||||
* especially careful to :any:`destroy() <PyProxy.destroy>`. You may leak a
|
* especially careful to :any:`destroy() <PyProxy.destroy>` it when you are
|
||||||
* large amount of memory including the local variables of all the stack
|
* done. You may leak a large amount of memory including the local
|
||||||
* frames in the traceback if you don't. The easiest way is to only handle
|
* variables of all the stack frames in the traceback if you don't. The
|
||||||
* the exception in Python.
|
* easiest way is to only handle the exception in Python.
|
||||||
*
|
*
|
||||||
* @class
|
* @class
|
||||||
*/
|
*/
|
||||||
|
@ -510,7 +512,7 @@ globalThis.loadPyodide = async function(config = {}) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* The pyodide version.
|
* The Pyodide version.
|
||||||
*
|
*
|
||||||
* It can be either the exact release version (e.g. ``0.1.0``), or
|
* It can be either the exact release version (e.g. ``0.1.0``), or
|
||||||
* the latest release version followed by the number of commits since, and
|
* the latest release version followed by the number of commits since, and
|
||||||
|
@ -531,7 +533,7 @@ globalThis.loadPyodide = async function(config = {}) {
|
||||||
* 1. `runPythonSimple` doesn't return anything (and so won't leak
|
* 1. `runPythonSimple` doesn't return anything (and so won't leak
|
||||||
* PyProxies)
|
* PyProxies)
|
||||||
* 2. `runPythonSimple` doesn't require access to any state on the
|
* 2. `runPythonSimple` doesn't require access to any state on the
|
||||||
* `pyodide_js` module.
|
* Javascript `pyodide` module.
|
||||||
* 3. `runPython` uses `pyodide.eval_code`, whereas `runPythonSimple` uses
|
* 3. `runPython` uses `pyodide.eval_code`, whereas `runPythonSimple` uses
|
||||||
* `PyRun_String` which is the C API for `eval` / `exec`.
|
* `PyRun_String` which is the C API for `eval` / `exec`.
|
||||||
* 4. `runPythonSimple` runs with `globals` a separate dict which is called
|
* 4. `runPythonSimple` runs with `globals` a separate dict which is called
|
||||||
|
@ -560,8 +562,10 @@ globalThis.loadPyodide = async function(config = {}) {
|
||||||
*
|
*
|
||||||
* @param {string} code Python code to evaluate
|
* @param {string} code Python code to evaluate
|
||||||
* @param {dict} globals An optional Python dictionary to use as the globals.
|
* @param {dict} globals An optional Python dictionary to use as the globals.
|
||||||
* Defaults to ``pyodide.globals``.
|
* Defaults to :any:`pyodide.globals`. Uses the Python API
|
||||||
* @returns The result of the python code converted to Javascript
|
* :any:`pyodide.eval_code` to evaluate the code.
|
||||||
|
* @returns The result of the Python code translated to Javascript. See the
|
||||||
|
* documentation for :any:`pyodide.eval_code` for more info.
|
||||||
*/
|
*/
|
||||||
Module.runPython = function(code, globals = Module.globals) {
|
Module.runPython = function(code, globals = Module.globals) {
|
||||||
return Module.pyodide_py.eval_code(code, globals);
|
return Module.pyodide_py.eval_code(code, globals);
|
||||||
|
@ -569,23 +573,25 @@ globalThis.loadPyodide = async function(config = {}) {
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
/**
|
/**
|
||||||
* Inspect a Python code chunk and use :js:func:`pyodide.loadPackage` to load any known
|
* Inspect a Python code chunk and use :js:func:`pyodide.loadPackage` to
|
||||||
* packages that the code chunk imports. Uses
|
* install any known packages that the code chunk imports. Uses the Python API
|
||||||
* :func:`pyodide_py.find_imports <pyodide.find\_imports>` to inspect the code.
|
* :func:`pyodide.find\_imports` to inspect the code.
|
||||||
*
|
*
|
||||||
* For example, given the following code as input
|
* For example, given the following code as input
|
||||||
*
|
*
|
||||||
* .. code-block:: python
|
* .. code-block:: python
|
||||||
*
|
*
|
||||||
* import numpy as np
|
* import numpy as np x = np.array([1, 2, 3])
|
||||||
* x = np.array([1, 2, 3])
|
|
||||||
*
|
*
|
||||||
* :js:func:`loadPackagesFromImports` will call ``pyodide.loadPackage(['numpy'])``.
|
* :js:func:`loadPackagesFromImports` will call
|
||||||
* See also :js:func:`runPythonAsync`.
|
* ``pyodide.loadPackage(['numpy'])``. See also :js:func:`runPythonAsync`.
|
||||||
*
|
*
|
||||||
* @param {*} code
|
* @param {string} code The code to inspect.
|
||||||
* @param {*} messageCallback
|
* @param {Function} messageCallback The ``messageCallback`` argument of
|
||||||
* @param {*} errorCallback
|
* :any:`pyodide.loadPackage` (optional).
|
||||||
|
* @param {Function} errorCallback The ``errorCallback`` argument of
|
||||||
|
* :any:`pyodide.loadPackage` (optional).
|
||||||
|
* @async
|
||||||
*/
|
*/
|
||||||
Module.loadPackagesFromImports = async function(code, messageCallback, errorCallback) {
|
Module.loadPackagesFromImports = async function(code, messageCallback, errorCallback) {
|
||||||
let imports = Module.pyodide_py.find_imports(code).toJs();
|
let imports = Module.pyodide_py.find_imports(code).toJs();
|
||||||
|
@ -610,13 +616,11 @@ globalThis.loadPyodide = async function(config = {}) {
|
||||||
/**
|
/**
|
||||||
* Access a Python object in the global namespace from Javascript.
|
* Access a Python object in the global namespace from Javascript.
|
||||||
*
|
*
|
||||||
* Note: this function is deprecated and will be removed in version 0.18.0.
|
* @deprecated This function will be removed in version 0.18.0. Use
|
||||||
* Use pyodide.globals.get('key') instead.
|
* :any:`pyodide.globals.get('key') <pyodide.globals>` instead.
|
||||||
*
|
*
|
||||||
* @param {string} name Python variable name
|
* @param {string} name Python variable name
|
||||||
* @returns If the Python object is an immutable type (string, number,
|
* @returns The Python object translated to Javascript.
|
||||||
* boolean), it is converted to Javascript and returned. For other types, a
|
|
||||||
* ``PyProxy`` object is returned.
|
|
||||||
*/
|
*/
|
||||||
Module.pyimport = name => {
|
Module.pyimport = name => {
|
||||||
console.warn(
|
console.warn(
|
||||||
|
@ -634,21 +638,35 @@ globalThis.loadPyodide = async function(config = {}) {
|
||||||
* import numpy as np
|
* import numpy as np
|
||||||
* x = np.array([1, 2, 3])
|
* x = np.array([1, 2, 3])
|
||||||
*
|
*
|
||||||
* pyodide will first call ``pyodide.loadPackage(['numpy'])``, and then run
|
* Pyodide will first call :any:`pyodide.loadPackage(['numpy'])
|
||||||
* the code, returning the result. Since package fetching must happen
|
* <pyodide.loadPackage>`, and then run the code using the Python API
|
||||||
* asynchronously, this function returns a `Promise` which resolves to the
|
* :any:`pyodide.eval_code_async`, returning the result. The code is compiled
|
||||||
* output. For example:
|
* with `PyCF_ALLOW_TOP_LEVEL_AWAIT
|
||||||
|
* <https://docs.python.org/3/library/ast.html?highlight=pycf_allow_top_level_await#ast.PyCF_ALLOW_TOP_LEVEL_AWAIT>`_.
|
||||||
*
|
*
|
||||||
* .. code-block:: javascript
|
* For example:
|
||||||
*
|
*
|
||||||
* pyodide.runPythonAsync(code, messageCallback)
|
* .. code-block:: pyodide
|
||||||
* .then((output) => handleOutput(output))
|
*
|
||||||
|
* let result = await pyodide.runPythonAsync(`
|
||||||
|
* # numpy will automatically be loaded by loadPackagesFromImports
|
||||||
|
* import numpy as np
|
||||||
|
* # we can use top level await
|
||||||
|
* from js import fetch
|
||||||
|
* response = await fetch("./packages.json")
|
||||||
|
* packages = await response.json()
|
||||||
|
* # If final statement is an expression, its value is returned to
|
||||||
|
* Javascript len(packages.dependencies.object_keys())
|
||||||
|
* `);
|
||||||
|
* console.log(result); // 72
|
||||||
*
|
*
|
||||||
* @param {string} code Python code to evaluate
|
* @param {string} code Python code to evaluate
|
||||||
* @param {Function} messageCallback A callback, called with progress
|
* @param {Function} messageCallback The ``messageCallback`` argument of
|
||||||
* messages. (optional)
|
* :any:`pyodide.loadPackage`.
|
||||||
* @param {Function} errorCallback A callback, called with error/warning
|
* @param {Function} errorCallback The ``errorCallback`` argument of
|
||||||
* messages. (optional)
|
* :any:`pyodide.loadPackage`.
|
||||||
|
* @returns The result of the Python code translated to Javascript.
|
||||||
|
* @async
|
||||||
*/
|
*/
|
||||||
Module.runPythonAsync = async function(code, messageCallback, errorCallback) {
|
Module.runPythonAsync = async function(code, messageCallback, errorCallback) {
|
||||||
await Module.loadPackagesFromImports(code, messageCallback, errorCallback);
|
await Module.loadPackagesFromImports(code, messageCallback, errorCallback);
|
||||||
|
@ -755,12 +773,12 @@ if (globalThis.languagePluginUrl) {
|
||||||
"instead use loadPyodide({ indexURL : <some_url>})");
|
"instead use loadPyodide({ indexURL : <some_url>})");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A deprecated parameter that specifies the Pyodide indexURL. If present,
|
* A deprecated parameter that specifies the Pyodide ``indexURL``. If present,
|
||||||
* Pyodide will automatically invoke
|
* Pyodide will automatically invoke
|
||||||
* ``initializePyodide({indexURL : languagePluginUrl})``
|
* ``loadPyodide({indexURL : languagePluginUrl})``
|
||||||
* and will store the resulting promise in
|
* and will store the resulting promise in
|
||||||
* :any:`globalThis.languagePluginLoader`. Instead, use :any:`loadPyodide`
|
* :any:`globalThis.languagePluginLoader`. Use :any:`loadPyodide`
|
||||||
* directly.
|
* directly instead of defining this.
|
||||||
*
|
*
|
||||||
* @type String
|
* @type String
|
||||||
* @deprecated Will be removed in version 0.18.0
|
* @deprecated Will be removed in version 0.18.0
|
||||||
|
|
Loading…
Reference in New Issue