mirror of https://github.com/pyodide/pyodide.git
DOC Replace "Javascript" with "JavaScript" in documents and comments [skip ci] (#1860)
This commit is contained in:
parent
3c4199036a
commit
89682dabfe
|
@ -22,7 +22,7 @@ scikit-learn. The [packages directory](packages) lists over 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.
|
||||
|
||||
## Try Pyodide (no installation needed)
|
||||
|
|
|
@ -97,7 +97,7 @@ and try to make your tests match. If you are having trouble, we can help you get
|
|||
started on our test-writing journey.
|
||||
|
||||
All code submissions should pass `make lint`. Python is checked with the
|
||||
default settings of `flake8`. C and Javascript are checked against the Mozilla
|
||||
default settings of `flake8`. C and JavaScript are checked against the Mozilla
|
||||
style in `clang-format`.
|
||||
|
||||
### Contributing to the “core” C Code
|
||||
|
|
|
@ -6,26 +6,26 @@ This file is intended as guidelines to help contributors trying to modify the C
|
|||
|
||||
## What the files do
|
||||
|
||||
The primary purpose of `core` is to implement {ref}`type translations <type-translations>` between Python and Javascript. Here is a breakdown of the purposes of the files.
|
||||
The primary purpose of `core` is to implement {ref}`type translations <type-translations>` between Python and JavaScript. Here is a breakdown of the purposes of the files.
|
||||
|
||||
- `main` -- responsible for configuring and initializing the Python interpreter, initializing the other source files, and creating the `_pyodide_core` module which is used to expose Python objects to `pyodide_py`. `main.c` also tries to generate fatal initialization error messages to help with debugging when there is a mistake in the initialization code.
|
||||
- `keyboard_interrupt` -- This sets up the keyboard interrupts system for using Pyodide with a webworker.
|
||||
|
||||
### Backend utilities
|
||||
|
||||
- `hiwire` -- A helper framework. It is impossible for wasm to directly hold owning references to Javascript objects. The primary purpose of hiwire is to act as a surrogate owner for Javascript references by holding the references in a Javascript `Map`. `hiwire` also defines a wide variety of `EM_JS` helper functions to do Javascript operations on the held objects. The primary type that hiwire exports is `JsRef`. References are created with `Module.hiwire.new_value` (only can be done from Javascript) and must be destroyed from C with `hiwire_decref` or `hiwire_CLEAR`, or from Javascript with `Module.hiwire.decref`.
|
||||
- `error_handling` -- defines macros useful for error propagation and for adapting Javascript functions to the CPython calling convention. See more in the {ref}`error_handling_macros` section.
|
||||
- `hiwire` -- A helper framework. It is impossible for wasm to directly hold owning references to JavaScript objects. The primary purpose of hiwire is to act as a surrogate owner for JavaScript references by holding the references in a JavaScript `Map`. `hiwire` also defines a wide variety of `EM_JS` helper functions to do JavaScript operations on the held objects. The primary type that hiwire exports is `JsRef`. References are created with `Module.hiwire.new_value` (only can be done from JavaScript) and must be destroyed from C with `hiwire_decref` or `hiwire_CLEAR`, or from JavaScript with `Module.hiwire.decref`.
|
||||
- `error_handling` -- defines macros useful for error propagation and for adapting JavaScript functions to the CPython calling convention. See more in the {ref}`error_handling_macros` section.
|
||||
|
||||
### Type conversion from Javascript to Python
|
||||
### Type conversion from JavaScript to Python
|
||||
|
||||
- `js2python` -- Translates basic types from Javascript to Python, leaves more complicated stuff to jsproxy.
|
||||
- `jsproxy` -- Defines Python classes to proxy complex Javascript types into Python. A complex file responsible for many of the core behaviors of Pyodide.
|
||||
- `js2python` -- Translates basic types from JavaScript to Python, leaves more complicated stuff to jsproxy.
|
||||
- `jsproxy` -- Defines Python classes to proxy complex JavaScript types into Python. A complex file responsible for many of the core behaviors of Pyodide.
|
||||
|
||||
### Type conversion from Python to Javascript
|
||||
### Type conversion from Python to JavaScript
|
||||
|
||||
- `python2js` -- Translates types from types from Python to Javascript, implicitly converting basic types and creating pyproxies for others. It also implements explicity conversion from Python to Javascript (the `toJs` method).
|
||||
- `python2js_buffer` -- Attempts to convert Python objects that implement the Python [Buffer Protocol](https://docs.python.org/3/c-api/buffer.html). This includes `bytes` objects, `memoryview`s, `array.array` and a wide variety of types exposed by extension modules like `numpy`. If the data is a 1d array in a contiguous block it can be sliced directly out of the wasm heap to produce a Javascript `TypedArray`, but Javascript does not have native support for pointers so higher dimensional arrays are more complicated.
|
||||
- `pyproxy` -- Defines a Javascript `Proxy` object that passes calls through to a Python object. Another important core file, `PyProxy.apply` is the primary entrypoint into Python code. `pyproxy.c` is much simpler than `jsproxy.c` though.
|
||||
- `python2js` -- Translates types from types from Python to JavaScript, implicitly converting basic types and creating pyproxies for others. It also implements explicity conversion from Python to JavaScript (the `toJs` method).
|
||||
- `python2js_buffer` -- Attempts to convert Python objects that implement the Python [Buffer Protocol](https://docs.python.org/3/c-api/buffer.html). This includes `bytes` objects, `memoryview`s, `array.array` and a wide variety of types exposed by extension modules like `numpy`. If the data is a 1d array in a contiguous block it can be sliced directly out of the wasm heap to produce a JavaScript `TypedArray`, but JavaScript does not have native support for pointers so higher dimensional arrays are more complicated.
|
||||
- `pyproxy` -- Defines a JavaScript `Proxy` object that passes calls through to a Python object. Another important core file, `PyProxy.apply` is the primary entrypoint into Python code. `pyproxy.c` is much simpler than `jsproxy.c` though.
|
||||
|
||||
## CPython APIs
|
||||
|
||||
|
@ -71,9 +71,9 @@ They can only be used in a function with a `finally:` label which should handle
|
|||
- `FAIL_IF_ERR_OCCURRED()` -- `goto finally;` if the Python error indicator is set (in other words if `PyErr_Occurred()`).
|
||||
- `FAIL_IF_ERR_MATCHES(python_err_type)` -- `goto finally;` if `PyErr_ExceptionMatches(python_err_type)`, for example `FAIL_IF_ERR_MATCHES(PyExc_AttributeError);`
|
||||
|
||||
### Javascript to CPython calling convention adapators
|
||||
### JavaScript to CPython calling convention adapators
|
||||
|
||||
If we call a Javascript function from C and that Javascript function throws an error, it is impossible to catch it in C. We define two `EM_JS` adaptors to convert from the Javascript calling convention to the CPython calling convention. The point of this is to ensure that errors that occur in `EM_JS` functions can be handled in C code using the ` FAIL_*`` macros. When compiled with `DEBUG_F`, when a Javascript error is thrown a message will also be written to `console.error`. The wrappers do roughly the following:
|
||||
If we call a JavaScript function from C and that JavaScript function throws an error, it is impossible to catch it in C. We define two `EM_JS` adaptors to convert from the JavaScript calling convention to the CPython calling convention. The point of this is to ensure that errors that occur in `EM_JS` functions can be handled in C code using the ` FAIL_*`` macros. When compiled with `DEBUG_F`, when a JavaScript error is thrown a message will also be written to `console.error`. The wrappers do roughly the following:
|
||||
|
||||
```javascript
|
||||
try {
|
||||
|
@ -125,7 +125,7 @@ These wrappers enable the following sort of code:
|
|||
try:
|
||||
jsfunc()
|
||||
except JsException:
|
||||
print("Caught an exception thrown in Javascript!")
|
||||
print("Caught an exception thrown in JavaScript!")
|
||||
```
|
||||
|
||||
## Structure of functions
|
||||
|
|
|
@ -57,7 +57,7 @@ the latest release branch named `stable` (due to ReadTheDocs constraints).
|
|||
twine check dist/*X.Y.Z*
|
||||
twine upload dist/*X.Y.Z*
|
||||
```
|
||||
7. Release the Pyodide Javascript package,
|
||||
7. Release the Pyodide JavaScript package,
|
||||
|
||||
```bash
|
||||
cd src/js
|
||||
|
|
|
@ -81,7 +81,7 @@ make benchmark
|
|||
|
||||
## Linting
|
||||
|
||||
Python is linted with `flake8`. C and Javascript are linted with
|
||||
Python is linted with `flake8`. C and JavaScript are linted with
|
||||
`clang-format`.
|
||||
|
||||
To lint the code, run:
|
||||
|
|
|
@ -11,7 +11,7 @@ with the Python scientific stack including NumPy, Pandas, Matplotlib, SciPy, and
|
|||
scikit-learn. Over 75 packages 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.
|
||||
|
||||
Using Pyodide
|
||||
|
|
|
@ -12,7 +12,7 @@ directory](https://github.com/pyodide/pyodide/tree/main/packages) lists over
|
|||
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.
|
||||
|
||||
## History
|
||||
|
|
|
@ -19,7 +19,7 @@ substitutions:
|
|||
error, it will return an empty list instead of raising a `SyntaxError`.
|
||||
{pr}`1819`
|
||||
|
||||
### Javascript package
|
||||
### JavaScript package
|
||||
|
||||
- {{Fix}} {any}`loadPyodide <globalThis.loadPyodide>` no longer fails in the
|
||||
presence of a user-defined global named `process`.
|
||||
|
@ -27,7 +27,7 @@ substitutions:
|
|||
|
||||
### Python / JavaScript type conversions
|
||||
|
||||
- {{Enhancement}} Updated the calling convention when a Javascript function is
|
||||
- {{Enhancement}} Updated the calling convention when a JavaScript function is
|
||||
called from Python to improve memory management of PyProxies. PyProxy
|
||||
arguments and return values are automatically destroyed when the function is
|
||||
finished. {pr}`1573`
|
||||
|
@ -96,14 +96,14 @@ substitutions:
|
|||
- {{Fix}} Avoid circular references when runsource raises SyntaxError
|
||||
{pr}`1758`
|
||||
|
||||
### Javascript package
|
||||
### JavaScript package
|
||||
|
||||
- {{Fix}} The {any}`pyodide.setInterruptBuffer` command is now publicly exposed
|
||||
again, as it was in v0.17.0. {pr}`1797`
|
||||
|
||||
### Python / JavaScript type conversions
|
||||
|
||||
- {{Fix}} Conversion of very large strings from Javascript to Python works
|
||||
- {{Fix}} Conversion of very large strings from JavaScript to Python works
|
||||
again. {pr}`1806`
|
||||
|
||||
- {{Fix}} Fixed a use after free bug in the error handling code.
|
||||
|
@ -165,9 +165,9 @@ _August 3rd, 2021_
|
|||
- {{ Enhancement }} Added support for `ctypes`.
|
||||
{pr}`1656`
|
||||
|
||||
### Javascript package
|
||||
### JavaScript package
|
||||
|
||||
- {{ Enhancement }} The Pyodide Javascript package is released to npm under [npmjs.com/package/pyodide](https://www.npmjs.com/package/pyodide)
|
||||
- {{ Enhancement }} The Pyodide JavaScript package is released to npm under [npmjs.com/package/pyodide](https://www.npmjs.com/package/pyodide)
|
||||
{pr}`1762`
|
||||
- {{ API }} {any}`loadPyodide <globalThis.loadPyodide>` no longer automatically
|
||||
stores the API into a global variable called `pyodide`. To get old behavior,
|
||||
|
@ -177,7 +177,7 @@ _August 3rd, 2021_
|
|||
`stdin`, `stdout` and `stderr`
|
||||
{pr}`1728`
|
||||
- {{ Enhancement }} Pyodide now ships with first party typescript types for the entire
|
||||
Javascript API (though no typings are available for `PyProxy` fields).
|
||||
JavaScript API (though no typings are available for `PyProxy` fields).
|
||||
{pr}`1601`
|
||||
|
||||
- {{ Enhancement }} It is now possible to import `Comlink` objects into Pyodide after
|
||||
|
@ -214,7 +214,7 @@ _August 3rd, 2021_
|
|||
{any}`pyodide.loadPackagesFromImports`.
|
||||
{pr}`1538`.
|
||||
- {{ Enhancement }} Added the {any}`PyProxy.callKwargs` method to allow using
|
||||
Python functions with keyword arguments from Javascript.
|
||||
Python functions with keyword arguments from JavaScript.
|
||||
{pr}`1539`
|
||||
- {{ Enhancement }} Added the {any}`PyProxy.copy` method.
|
||||
{pr}`1549` {pr}`1630`
|
||||
|
@ -241,13 +241,13 @@ _August 3rd, 2021_
|
|||
depth as a keyword argument.
|
||||
{pr}`1721`
|
||||
- {{ API }} {any}`toJs <PyProxy.toJs>` and {any}`to_js <pyodide.to_js>` now
|
||||
take an option `pyproxies`, if a Javascript Array is passed for this, then
|
||||
take an option `pyproxies`, if a JavaScript Array is passed for this, then
|
||||
any proxies created during conversion will be placed into this array. This
|
||||
allows easy cleanup later. The `create_pyproxies` option can be used to
|
||||
disable creation of pyproxies during conversion (instead a `ConversionError`
|
||||
is raised). {pr}`1726`
|
||||
- {{ API }} `toJs` and `to_js` now take an option `dict_converter` which will be
|
||||
called on a Javascript iterable of two-element Arrays as the final step of
|
||||
called on a JavaScript iterable of two-element Arrays as the final step of
|
||||
converting dictionaries. For instance, pass `Object.fromEntries` to convert to
|
||||
an object or `Array.from` to convert to an array of pairs.
|
||||
{pr}`1742`
|
||||
|
@ -299,27 +299,27 @@ See the {ref}`0-17-0-release-notes` for more information.
|
|||
|
||||
### Python / JS type conversions
|
||||
|
||||
- {{ Feature }} A `JsProxy` of a Javascript `Promise` or other awaitable object is now a
|
||||
- {{ Feature }} A `JsProxy` of a JavaScript `Promise` or other awaitable object is now a
|
||||
Python awaitable.
|
||||
{pr}`880`
|
||||
- {{ API }} Instead of automatically converting Python lists and dicts into
|
||||
Javascript, they are now wrapped in `PyProxy`. Added a new {any}`PyProxy.toJs`
|
||||
JavaScript, they are now wrapped in `PyProxy`. Added a new {any}`PyProxy.toJs`
|
||||
API to request the conversion behavior that used to be implicit.
|
||||
{pr}`1167`
|
||||
- {{ API }} Added {any}`JsProxy.to_py` API to convert a Javascript object to Python.
|
||||
- {{ API }} Added {any}`JsProxy.to_py` API to convert a JavaScript object to Python.
|
||||
{pr}`1244`
|
||||
- {{ Feature }} Flexible jsimports: it now possible to add custom Python
|
||||
"packages" backed by Javascript code, like the `js` package. The `js` package
|
||||
"packages" backed by JavaScript code, like the `js` package. The `js` package
|
||||
is now implemented using this system.
|
||||
{pr}`1146`
|
||||
- {{ Feature }} A `PyProxy` of a Python coroutine or awaitable is now an
|
||||
awaitable Javascript object. Awaiting a coroutine will schedule it to run on
|
||||
awaitable JavaScript object. Awaiting a coroutine will schedule it to run on
|
||||
the Python event loop using `asyncio.ensure_future`.
|
||||
{pr}`1170`
|
||||
- {{ Enhancement }} Made `PyProxy` of an iterable Python object an iterable Js
|
||||
object: defined the `[Symbol.iterator]` method, can be used like `for(let x of proxy)`. Made a `PyProxy` of a Python iterator an iterator: `proxy.next()` is
|
||||
translated to `next(it)`. Made a `PyProxy` of a Python generator into a
|
||||
Javascript generator: `proxy.next(val)` is translated to `gen.send(val)`.
|
||||
JavaScript generator: `proxy.next(val)` is translated to `gen.send(val)`.
|
||||
{pr}`1180`
|
||||
- {{ API }} Updated `PyProxy` so that if the wrapped Python object supports `__getitem__`
|
||||
access, then the wrapper has `get`, `set`, `has`, and `delete` methods which do
|
||||
|
@ -328,15 +328,15 @@ See the {ref}`0-17-0-release-notes` for more information.
|
|||
- {{ API }} The {any}`pyodide.pyimport` function is deprecated in favor of using
|
||||
`pyodide.globals.get('key')`. {pr}`1367`
|
||||
- {{ API }} Added {any}`PyProxy.getBuffer` API to allow direct access to Python
|
||||
buffers as Javascript TypedArrays.
|
||||
buffers as JavaScript TypedArrays.
|
||||
{pr}`1215`
|
||||
- {{ API }} The innermost level of a buffer converted to Javascript used to be a
|
||||
- {{ API }} The innermost level of a buffer converted to JavaScript used to be a
|
||||
TypedArray if the buffer was contiguous and otherwise an Array. Now the
|
||||
innermost level will be a TypedArray unless the buffer format code is a '?' in
|
||||
which case it will be an Array of booleans, or if the format code is a "s" in
|
||||
which case the innermost level will be converted to a string.
|
||||
{pr}`1376`
|
||||
- {{ Enhancement }} Javascript `BigInt`s are converted into Python `int` and
|
||||
- {{ Enhancement }} JavaScript `BigInt`s are converted into Python `int` and
|
||||
Python `int`s larger than 2^53 are converted into `BigInt`.
|
||||
{pr}`1407`
|
||||
- {{ API }} Added {any}`pyodide.isPyProxy` to test if an object is a `PyProxy`.
|
||||
|
@ -344,11 +344,11 @@ See the {ref}`0-17-0-release-notes` for more information.
|
|||
- {{ Enhancement }} `PyProxy` and `PyBuffer` objects are now garbage collected
|
||||
if the browser supports `FinalizationRegistry`.
|
||||
{pr}`1306`
|
||||
- {{ Enhancement }} Automatic conversion of Javascript functions to CPython
|
||||
- {{ Enhancement }} Automatic conversion of JavaScript functions to CPython
|
||||
calling conventions.
|
||||
{pr}`1051`, {pr}`1080`
|
||||
- {{ Enhancement }} Automatic detection of fatal errors. In this case Pyodide
|
||||
will produce both a Javascript and a Python stack trace with explicit
|
||||
will produce both a JavaScript and a Python stack trace with explicit
|
||||
instruction to open a bug report.
|
||||
pr`{1151}`, pr`{1390}`, pr`{1478}`.
|
||||
- {{ Enhancement }} Systematic memory leak detection in the test suite and a
|
||||
|
@ -362,19 +362,19 @@ See the {ref}`0-17-0-release-notes` for more information.
|
|||
Conversely, `bool(empty_js_set)` and `bool(empty_js_map)` were `True` but now
|
||||
are `False`.
|
||||
{pr}`1061`
|
||||
- {{ Fix }} When calling a Javascript function from Python without keyword
|
||||
- {{ Fix }} When calling a JavaScript function from Python without keyword
|
||||
arguments, Pyodide no longer passes a `PyProxy`-wrapped `NULL` pointer as the
|
||||
last argument. {pr}`1033`
|
||||
- {{ Fix }} JsBoundMethod is now a subclass of JsProxy, which fixes nested
|
||||
attribute access and various other strange bugs.
|
||||
{pr}`1124`
|
||||
- {{ Fix }} Javascript functions imported like `from js import fetch` no longer
|
||||
- {{ Fix }} JavaScript functions imported like `from js import fetch` no longer
|
||||
trigger "invalid invocation" errors (issue {issue}`461`) and
|
||||
`js.fetch("some_url")` also works now (issue {issue}`768`).
|
||||
{pr}`1126`
|
||||
- {{ Fix }} Javascript bound method calls now work correctly with keyword arguments.
|
||||
- {{ Fix }} JavaScript bound method calls now work correctly with keyword arguments.
|
||||
{pr}`1138`
|
||||
- {{ Fix }} Javascript constructor calls now work correctly with keyword
|
||||
- {{ Fix }} JavaScript constructor calls now work correctly with keyword
|
||||
arguments.
|
||||
{pr}`1433`
|
||||
|
||||
|
@ -419,7 +419,7 @@ See the {ref}`0-17-0-release-notes` for more information.
|
|||
|
||||
- {{ Feature }} `micropip` now supports installing wheels from relative URLs.
|
||||
{pr}`872`
|
||||
- {{ API }} `micropip.install` now returns a Python `Future` instead of a Javascript `Promise`.
|
||||
- {{ API }} `micropip.install` now returns a Python `Future` instead of a JavaScript `Promise`.
|
||||
{pr}`1324`
|
||||
- {{ Fix }} {any}`micropip.install` now interacts correctly with
|
||||
{any}`pyodide.loadPackage`.
|
||||
|
@ -516,7 +516,7 @@ by 0.16.1 with identical contents.
|
|||
|
||||
- FIX Only call `Py_INCREF()` once when proxied by PyProxy
|
||||
{pr}`708`
|
||||
- Javascript exceptions can now be raised and caught in Python. They are
|
||||
- JavaScript exceptions can now be raised and caught in Python. They are
|
||||
wrapped in pyodide.JsException.
|
||||
{pr}`891`
|
||||
|
||||
|
@ -551,7 +551,7 @@ by 0.16.1 with identical contents.
|
|||
- Updated default `--ldflags` argument to `pyodide_build` scripts to equal what
|
||||
Pyodide actually uses.
|
||||
{pr}`817`
|
||||
- Replace C lz4 implementation with the (upstream) Javascript implementation.
|
||||
- Replace C lz4 implementation with the (upstream) JavaScript implementation.
|
||||
{pr}`851`
|
||||
- Pyodide deployment URL can now be specified with the `PYODIDE_BASE_URL`
|
||||
environment variable during build. The `pyodide_dev.js` is no longer
|
||||
|
@ -628,10 +628,10 @@ _May 19, 2020_
|
|||
|
||||
_Dec 11, 2019_
|
||||
|
||||
- Convert Javascript numbers containing integers, e.g. `3.0`, to a real Python
|
||||
- Convert JavaScript numbers containing integers, e.g. `3.0`, to a real Python
|
||||
long (e.g. `3`).
|
||||
- Adds `__bool__` method to for `JsProxy` objects.
|
||||
- Adds a Javascript-side auto completion function for Iodide that uses jedi.
|
||||
- Adds a JavaScript-side auto completion function for Iodide that uses jedi.
|
||||
- New packages: nltk, jeudi, statsmodels, regex, cytoolz, xlrd, uncertainties
|
||||
|
||||
## Version 0.14.0
|
||||
|
@ -657,14 +657,14 @@ _May 3, 2019_
|
|||
{ref}`micropip` for more information.
|
||||
|
||||
- Thanks to PEP 562, you can now `import js` from Python and use it to access
|
||||
anything in the global Javascript namespace.
|
||||
anything in the global JavaScript namespace.
|
||||
|
||||
- Passing a Python object to Javascript always creates the same object in
|
||||
Javascript. This makes APIs like `removeEventListener` usable.
|
||||
- Passing a Python object to JavaScript always creates the same object in
|
||||
JavaScript. This makes APIs like `removeEventListener` usable.
|
||||
|
||||
- Calling `dir()` in Python on a Javascript proxy now works.
|
||||
- Calling `dir()` in Python on a JavaScript proxy now works.
|
||||
|
||||
- Passing an `ArrayBuffer` from Javascript to Python now correctly creates a
|
||||
- Passing an `ArrayBuffer` from JavaScript to Python now correctly creates a
|
||||
`memoryview` object.
|
||||
|
||||
- Pyodide now works on Safari.
|
||||
|
|
|
@ -26,5 +26,5 @@
|
|||
## Other projects
|
||||
|
||||
- [wc-code](https://github.com/vanillawc/wc-code) is a library to run
|
||||
Javascript, Python, and Theme in the browser with inline code blocks.
|
||||
JavaScript, Python, and Theme in the browser with inline code blocks.
|
||||
It uses Pyodide to execute Python code.
|
||||
|
|
|
@ -18,7 +18,7 @@ We added full support for asyncio, including a new Python event loop that
|
|||
schedules tasks on the browser event loop, support for top level await in
|
||||
{any}`pyodide.runPythonAsync`, and implementations of `await` for {any}`JsProxy`
|
||||
and {any}`PyProxy`, so that it is possible to await a Python awaitable from
|
||||
Javascript and a Javascript thenable from Python. This allows seamless
|
||||
JavaScript and a JavaScript thenable from Python. This allows seamless
|
||||
interoperability:
|
||||
|
||||
```pyodide
|
||||
|
@ -33,7 +33,7 @@ pyodide.runPython(`
|
|||
`);
|
||||
let test = pyodide.globals.get("test");
|
||||
// test returns a coroutine, we can await the coroutine
|
||||
// from Javascript and it will schedule it on the Python event loop
|
||||
// from JavaScript and it will schedule it on the Python event loop
|
||||
result = await test();
|
||||
console.log(result); // ["asciitree", "parso", "scikit-learn", ...]
|
||||
```
|
||||
|
@ -42,10 +42,10 @@ console.log(result); // ["asciitree", "parso", "scikit-learn", ...]
|
|||
|
||||
### Error Handling
|
||||
|
||||
Errors can now be thrown in Python and caught in Javascript or thrown in
|
||||
Javascript and caught in Python.
|
||||
Errors can now be thrown in Python and caught in JavaScript or thrown in
|
||||
JavaScript and caught in Python.
|
||||
|
||||
Support for this is integrated at the lowest level, so calls between Javascript
|
||||
Support for this is integrated at the lowest level, so calls between JavaScript
|
||||
and C functions behave as expected. The error conversion code is generated by C
|
||||
macros which makes implementing and debugging new logic dramatically simpler.
|
||||
|
||||
|
@ -65,9 +65,9 @@ pyodide.runPython(`
|
|||
|
||||
(Added in PRs {pr}`1051` and {pr}`1080`)
|
||||
|
||||
### Python "builtin" Modules implemented in Javascript
|
||||
### Python "builtin" Modules implemented in JavaScript
|
||||
|
||||
It is now simple to add a Python module implemented in Javascript using
|
||||
It is now simple to add a Python module implemented in JavaScript using
|
||||
{any}`pyodide.registerJsModule`:
|
||||
|
||||
```pyodide
|
||||
|
@ -96,7 +96,7 @@ foreign function interface. In particular, the goal was to make it easier for
|
|||
users to avoid leaking memory.
|
||||
|
||||
For the basic use cases, we have {any}`PyProxy.toJs` and {any}`JsProxy.to_py`
|
||||
which respectively convert Python objects to Javascript objects and Javascript
|
||||
which respectively convert Python objects to JavaScript objects and JavaScript
|
||||
objects to Python objects. We also added also "wrong-way" conversion functions
|
||||
{any}`pyodide.to_js` and {any}`pyodide.toPy` which are particularly helpful for
|
||||
when returning values across languages or to give extra control over the
|
||||
|
@ -123,12 +123,12 @@ deprecated).
|
|||
### Changes to type translations
|
||||
|
||||
In the past we found that one of the major pain points in using Pyodide occurred
|
||||
when an object makes a round trip from Python to Javascript and back to Python
|
||||
when an object makes a round trip from Python to JavaScript and back to Python
|
||||
and comes back different. This violates the expectations of the user and forces
|
||||
inelegant workarounds (see {issue}`780` and {issue}`892` among others).
|
||||
|
||||
The type conversion module has significantly reworked in v0.17 with the goal
|
||||
that round trip conversions of objects between Python and Javascript produces an
|
||||
that round trip conversions of objects between Python and JavaScript produces an
|
||||
identical object. That is, Python -> JS -> Python conversion produces an object
|
||||
that's now equal to the original object, and JS -> Python -> JS conversion
|
||||
verifies the `===` equality operation.
|
||||
|
@ -199,9 +199,9 @@ expect when using the foreign function interface has gone way down.
|
|||
|
||||
Similarly, we consolidated the entrypoints and removed redundant APIs. Now every
|
||||
public entrypoint into C code has been consolidated into the file `pyproxy.js`.
|
||||
The number of places where C calls into Javascript is much more diverse, but
|
||||
The number of places where C calls into JavaScript is much more diverse, but
|
||||
these call sites have all been wrapped in a special macro that automatically
|
||||
converts Javascript functions to use the CPython calling convention. They can
|
||||
converts JavaScript functions to use the CPython calling convention. They can
|
||||
even be passed as function pointers to C functions from the Python standard
|
||||
library!
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Javascript API
|
||||
# JavaScript API
|
||||
|
||||
Backward compatibility of the API is not guaranteed at this point.
|
||||
|
||||
|
@ -22,7 +22,7 @@ Backward compatibility of the API is not guaranteed at this point.
|
|||
|
||||
## PyProxy
|
||||
|
||||
A PyProxy is an object that allows idiomatic use of a Python object from Javascript. See {ref}`type-translations-pyproxy`.
|
||||
A PyProxy is an object that allows idiomatic use of a Python object from JavaScript. See {ref}`type-translations-pyproxy`.
|
||||
|
||||
```{eval-rst}
|
||||
.. js-doc-summary:: PyProxy
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
Backward compatibility of the API is not guaranteed at this point.
|
||||
|
||||
**Javascript Modules**
|
||||
**JavaScript Modules**
|
||||
|
||||
By default there are two Javascript modules. More can be added with
|
||||
By default there are two JavaScript modules. More can be added with
|
||||
{any}`pyodide.registerJsModule`. You can import these modules using the Python
|
||||
`import` statement in the normal way.
|
||||
|
||||
|
@ -12,9 +12,9 @@ By default there are two Javascript modules. More can be added with
|
|||
.. list-table::
|
||||
|
||||
* - ``js``
|
||||
- The global Javascript scope.
|
||||
- The global JavaScript scope.
|
||||
* - :js:mod:`pyodide_js <pyodide>`
|
||||
- The Javascript Pyodide module.
|
||||
- The JavaScript Pyodide module.
|
||||
```
|
||||
|
||||
```{eval-rst}
|
||||
|
|
|
@ -17,14 +17,14 @@ local file system.
|
|||
|
||||
## Why can't I load files from the local file system?
|
||||
|
||||
For security reasons Javascript in the browser is not allowed to load local data
|
||||
For security reasons JavaScript in the browser is not allowed to load local data
|
||||
files. You need to serve them with a web-browser. There is a
|
||||
[File System API](https://wicg.github.io/file-system-access/) supported in Chrome
|
||||
but not in Firefox or Safari.
|
||||
|
||||
## How can I change the behavior of {any}`runPython <pyodide.runPython>` and {any}`runPythonAsync <pyodide.runPythonAsync>`?
|
||||
|
||||
You can directly call Python functions from Javascript. For most purposes it
|
||||
You can directly call Python functions from JavaScript. For most purposes it
|
||||
makes sense to make your own Python function as an entrypoint and call that
|
||||
instead of redefining `runPython`. The definitions of {any}`runPython <pyodide.runPython>` and {any}`runPythonAsync <pyodide.runPythonAsync>` are very
|
||||
simple:
|
||||
|
@ -118,10 +118,10 @@ if "PYODIDE" in os.environ:
|
|||
We used to use the environment variable `PYODIDE_BASE_URL` for this purpose,
|
||||
but this usage is deprecated.
|
||||
|
||||
## How do I create custom Python packages from Javascript?
|
||||
## How do I create custom Python packages from JavaScript?
|
||||
|
||||
Put a collection of functions into a Javascript object and use {any}`pyodide.registerJsModule`:
|
||||
Javascript:
|
||||
Put a collection of functions into a JavaScript object and use {any}`pyodide.registerJsModule`:
|
||||
JavaScript:
|
||||
|
||||
```javascript
|
||||
let my_module = {
|
||||
|
@ -207,7 +207,7 @@ proxy_f.destroy()
|
|||
|
||||
## How can I use fetch with optional arguments from Python?
|
||||
|
||||
The most obvious translation of the Javascript code won't work:
|
||||
The most obvious translation of the JavaScript code won't work:
|
||||
|
||||
```py
|
||||
import json
|
||||
|
|
|
@ -62,12 +62,12 @@ self.addEventListener("message", (msg) => {
|
|||
});
|
||||
```
|
||||
|
||||
## Allowing Javascript code to be interrupted
|
||||
## Allowing JavaScript code to be interrupted
|
||||
|
||||
The interrupt system above allows interruption of Python code and also of C code
|
||||
that opts to allow itself to be interrupted by periodically calling
|
||||
`PyErr_CheckSignals`. There is also a function {any}`pyodide.checkInterrupt` that
|
||||
allows Javascript functions called from Python to check for an interrupt. As a
|
||||
allows JavasSript functions called from Python to check for an interrupt. As a
|
||||
simple example, we can implement an interruptable sleep function using
|
||||
`Atomics.wait`:
|
||||
|
||||
|
|
|
@ -38,9 +38,9 @@ main();
|
|||
|
||||
Python code is run using the {any}`pyodide.runPython` function. It takes as
|
||||
input a string of Python code. If the code ends in an expression, it returns the
|
||||
result of the expression, translated to Javascript objects (see
|
||||
result of the expression, translated to JavaScript objects (see
|
||||
{ref}`type-translations`). For example the following code will return the
|
||||
version string as a Javascript string:
|
||||
version string as a JavaScript string:
|
||||
|
||||
```pyodide
|
||||
pyodide.runPython(`
|
||||
|
@ -136,13 +136,13 @@ Create and save a test `index.html` page with the following contents:
|
|||
</html>
|
||||
```
|
||||
|
||||
## Accessing Python scope from Javascript
|
||||
## Accessing Python scope from JavaScript
|
||||
|
||||
You can also access from Javascript all functions and variables defined in
|
||||
You can also access from JavaScript all functions and variables defined in
|
||||
Python by using the {any}`pyodide.globals` object.
|
||||
|
||||
For example, if you run the code `x = numpy.ones([3,3])` in Python, you can
|
||||
access the variable `x` from Javascript in your browser's developer console
|
||||
access the variable `x` from JavaScript in your browser's developer console
|
||||
as `pyodide.globals.get("x")`. The same goes
|
||||
for functions and imports. See {ref}`type-translations` for more details.
|
||||
|
||||
|
@ -162,8 +162,8 @@ x = pyodide.globals.get('numpy').ones(new Int32Array([3, 4])).toJs();
|
|||
```
|
||||
|
||||
Since you have full access to Python global scope, you can also re-assign new
|
||||
values or even Javascript functions to variables, and create new ones from
|
||||
Javascript:
|
||||
values or even JavaScript functions to variables, and create new ones from
|
||||
JavaScript:
|
||||
|
||||
```pyodide
|
||||
// re-assign a new value to an existing variable
|
||||
|
@ -182,9 +182,9 @@ pyodide.runPython("square(3)");
|
|||
|
||||
Feel free to play around with the code using the browser console and the above example.
|
||||
|
||||
## Accessing Javascript scope from Python
|
||||
## Accessing JavaScript scope from Python
|
||||
|
||||
The Javascript scope can be accessed from Python using the `js` module (see
|
||||
The JavaScript scope can be accessed from Python using the `js` module (see
|
||||
{ref}`type-translations_using-js-obj-from-py`). This module represents the
|
||||
global object `window` that allows us to directly manipulate the DOM and access
|
||||
global variables and functions from Python.
|
||||
|
|
|
@ -2,38 +2,38 @@
|
|||
|
||||
# Type translations
|
||||
|
||||
In order to communicate between Python and Javascript, we "translate" objects
|
||||
In order to communicate between Python and JavaScript, we "translate" objects
|
||||
between the two languages. Depending on the type of the object we either
|
||||
translate the object by implicitly converting it or by proxying it. By
|
||||
"converting" an object we mean producing a new object in the target language
|
||||
which is the equivalent of the object from the source language, for example
|
||||
converting a Python string to the equivalent a Javascript string. By "proxying"
|
||||
converting a Python string to the equivalent a JavaScript string. By "proxying"
|
||||
an object we mean producing a special object in the target language that
|
||||
forwards requests to the source language. When we proxy a Javascript object into
|
||||
forwards requests to the source language. When we proxy a JavaScript object into
|
||||
Python, the result is a {any}`JsProxy` object. When we proxy a Python object
|
||||
into Javascript, the result is a {any}`PyProxy` object. A proxied object can be
|
||||
into JavaScript, the result is a {any}`PyProxy` object. A proxied object can be
|
||||
explicitly converted using the explicit conversion methods {any}`JsProxy.to_py`
|
||||
and {any}`PyProxy.toJs`.
|
||||
|
||||
Python to Javascript translations occur:
|
||||
Python to JavaScript translations occur:
|
||||
|
||||
- when returning the final expression from a {any}`pyodide.runPython` call,
|
||||
- when [importing Python objects into Javascript](type-translations_using-py-obj-from-js)
|
||||
- when passing arguments to a Javascript function called from Python,
|
||||
- when returning the results of a Python function called from Javascript,
|
||||
- when [importing Python objects into JavaScript](type-translations_using-py-obj-from-js)
|
||||
- when passing arguments to a JavaScript function called from Python,
|
||||
- when returning the results of a Python function called from JavaScript,
|
||||
- when accessing an attribute of a {any}`PyProxy`
|
||||
|
||||
Javascript to Python translations occur:
|
||||
JavaScript to Python translations occur:
|
||||
|
||||
- when [importing from the `js` module](type-translations_using-js-obj-from-py)
|
||||
- when passing arguments to a Python function called from Javascript
|
||||
- when returning the result of a Javascript function called from Python
|
||||
- when passing arguments to a Python function called from JavaScript
|
||||
- when returning the result of a JavaScript function called from Python
|
||||
- when accessing an attribute of a {any}`JsProxy`
|
||||
|
||||
```{admonition} Memory Leaks and Python to Javascript translations
|
||||
```{admonition} Memory Leaks and Python to JavaScript translations
|
||||
:class: warning
|
||||
|
||||
Any time a Python to Javascript translation occurs, it may create a
|
||||
Any time a Python to JavaScript translation occurs, it may create a
|
||||
{any}`PyProxy`. To avoid memory leaks, you must store the {any}`PyProxy` and
|
||||
{any}`destroy <PyProxy.destroy>` it when you are done with it. See
|
||||
{ref}`avoiding-leaks` for more info.
|
||||
|
@ -41,9 +41,9 @@ Any time a Python to Javascript translation occurs, it may create a
|
|||
|
||||
## Round trip conversions
|
||||
|
||||
Translating an object from Python to Javascript and then back to Python is
|
||||
Translating an object from Python to JavaScript and then back to Python is
|
||||
guaranteed to give an object that is equal to the original object. Furthermore,
|
||||
if the object is proxied into Javascript, then translation back unwraps the
|
||||
if the object is proxied into JavaScript, then translation back unwraps the
|
||||
proxy, and the result of the round trip conversion `is` the original object (in
|
||||
the sense that they live at the same memory address). There are a few
|
||||
exceptions:
|
||||
|
@ -51,7 +51,7 @@ exceptions:
|
|||
1. `nan` is converted to `nan` after a round trip but `nan != nan`
|
||||
2. proxies created using {any}`pyodide.create_proxy` will be unwrapped.
|
||||
|
||||
Translating an object from Javascript to Python and then back to Javascript
|
||||
Translating an object from JavaScript to Python and then back to JavaScript
|
||||
gives an object that is `===` to the original object. Furthermore, if the object
|
||||
is proxied into Python, then translation back unwraps the proxy, and the result
|
||||
of the round trip conversion is the original object (in the sense that they live
|
||||
|
@ -65,19 +65,19 @@ at the same memory address). There are a few exceptions:
|
|||
## Implicit conversions
|
||||
|
||||
We implicitly convert immutable types but not mutable types. This ensures that
|
||||
mutable Python objects can be modified from Javascript and vice-versa. Python
|
||||
mutable Python objects can be modified from JavaScript and vice-versa. Python
|
||||
has immutable types such as `tuple` and `bytes` that have no equivalent in
|
||||
Javascript. In order to ensure that round trip translations yield an object of
|
||||
JavaScript. In order to ensure that round trip translations yield an object of
|
||||
the same type as the original object, we proxy `tuple` and `bytes` objects.
|
||||
|
||||
(type-translations_py2js-table)=
|
||||
|
||||
### Python to Javascript
|
||||
### Python to JavaScript
|
||||
|
||||
The following immutable types are implicitly converted from Javascript to
|
||||
The following immutable types are implicitly converted from JavaScript to
|
||||
Python:
|
||||
|
||||
| Python | Javascript |
|
||||
| Python | JavaScript |
|
||||
| ------- | ---------------------- |
|
||||
| `int` | `Number` or `BigInt`\* |
|
||||
| `float` | `Number` |
|
||||
|
@ -88,16 +88,16 @@ Python:
|
|||
\* An `int` is converted to a `Number` if the `int` is between -2^{53} and
|
||||
2^{53} inclusive, otherwise it is converted to a `BigInt`. (If the browser does
|
||||
not support `BigInt` then a `Number` will be used instead. In this case,
|
||||
conversion of large integers from Python to Javascript is lossy.)
|
||||
conversion of large integers from Python to JavaScript is lossy.)
|
||||
|
||||
(type-translations_js2py-table)=
|
||||
|
||||
### Javascript to Python
|
||||
### JavaScript to Python
|
||||
|
||||
The following immutable types are implicitly converted from Python to
|
||||
Javascript:
|
||||
JavaScript:
|
||||
|
||||
| Javascript | Python |
|
||||
| JavaScript | Python |
|
||||
| ----------- | --------------------------------- |
|
||||
| `Number` | `int` or `float` as appropriate\* |
|
||||
| `BigInt` | `int` |
|
||||
|
@ -118,12 +118,12 @@ language.
|
|||
|
||||
(type-translations-jsproxy)=
|
||||
|
||||
### Proxying from Javascript into Python
|
||||
### Proxying from JavaScript into Python
|
||||
|
||||
When most Javascript objects are translated into Python a {any}`JsProxy` is
|
||||
When most JavaScript objects are translated into Python a {any}`JsProxy` is
|
||||
returned. The following operations are currently supported on a {any}`JsProxy`:
|
||||
|
||||
| Python | Javascript |
|
||||
| Python | JavaScript |
|
||||
| ---------------------------------- | --------------------------------- |
|
||||
| `str(proxy)` | `x.toString()` |
|
||||
| `proxy.foo` | `x.foo` |
|
||||
|
@ -144,7 +144,7 @@ returned. The following operations are currently supported on a {any}`JsProxy`:
|
|||
| `next(proxy)` | `x.next()` |
|
||||
| `await proxy` | `await x` |
|
||||
|
||||
Note that each of these operations is only supported if the proxied Javascript
|
||||
Note that each of these operations is only supported if the proxied JavaScript
|
||||
object supports the corresponding operation. See {any}`the JsProxy API docs <JsProxy>` for the rest of the methods supported on {any}`JsProxy`. Some other
|
||||
code snippets:
|
||||
|
||||
|
@ -174,11 +174,11 @@ function dir(x) {
|
|||
}
|
||||
```
|
||||
|
||||
As a special case, Javascript `Array`, `HTMLCollection`, and `NodeList` are
|
||||
As a special case, JavaScript `Array`, `HTMLCollection`, and `NodeList` are
|
||||
container types, but instead of using `array.get(7)` to get the 7th element,
|
||||
Javascript uses `array[7]`. For these cases, we translate:
|
||||
JavaScript uses `array[7]`. For these cases, we translate:
|
||||
|
||||
| Python | Javascript |
|
||||
| Python | JavaScript |
|
||||
| ------------------ | ------------------- |
|
||||
| `proxy[idx]` | `array[idx]` |
|
||||
| `proxy[idx] = val` | `array[idx] = val` |
|
||||
|
@ -187,16 +187,16 @@ Javascript uses `array[7]`. For these cases, we translate:
|
|||
|
||||
(type-translations-pyproxy)=
|
||||
|
||||
### Proxying from Python into Javascript
|
||||
### Proxying from Python into JavaScript
|
||||
|
||||
When most Python objects are translated to Javascript a {any}`PyProxy` is
|
||||
When most Python objects are translated to JavaScript a {any}`PyProxy` is
|
||||
produced.
|
||||
|
||||
Fewer operations can be overloaded in Javascript than in Python so some
|
||||
Fewer operations can be overloaded in JavaScript than in Python so some
|
||||
operations are more cumbersome on a {any}`PyProxy` than on a {any}`JsProxy`. The
|
||||
following operations are supported:
|
||||
|
||||
| Javascript | Python |
|
||||
| JavaScript | Python |
|
||||
| ----------------------------------- | ------------------- |
|
||||
| `foo in proxy` | `hasattr(x, 'foo')` |
|
||||
| `proxy.foo` | `x.foo` |
|
||||
|
@ -232,9 +232,9 @@ foo(); // throws Error: Object has already been destroyed
|
|||
|
||||
(type-translations-pyproxy-to-js)=
|
||||
|
||||
### Python to Javascript
|
||||
### Python to JavaScript
|
||||
|
||||
Explicit conversion of a {any}`PyProxy` into a native Javascript object is done
|
||||
Explicit conversion of a {any}`PyProxy` into a native JavaScript object is done
|
||||
with the {any}`PyProxy.toJs` method. You can also perform such a conversion in
|
||||
Python using {any}`to_js <pyodide.to_js>` which behaves in much the same way. By
|
||||
default, the `toJs` method does a recursive "deep" conversion, to do a shallow
|
||||
|
@ -242,7 +242,7 @@ conversion use `proxy.toJs({depth : 1})`. In addition to [the normal type
|
|||
conversion](type-translations_py2js-table), `toJs` method performs the following
|
||||
explicit conversions:
|
||||
|
||||
| Python | Javascript |
|
||||
| Python | JavaScript |
|
||||
| --------------- | ------------ |
|
||||
| `list`, `tuple` | `Array` |
|
||||
| `dict` | `Map` |
|
||||
|
@ -255,11 +255,11 @@ If you need to convert `dict` instead to `Object`, you can pass
|
|||
`Object.fromEntries` as the `dict_converter` argument:
|
||||
`proxy.toJs({dict_converter : Object.fromEntries})`.
|
||||
|
||||
In Javascript, `Map` and `Set` keys are compared using object identity unless
|
||||
In JavaScript, `Map` and `Set` keys are compared using object identity unless
|
||||
the key is an immutable type (meaning a string, a number, a bigint, a boolean,
|
||||
`undefined`, or `null`). On the other hand, in Python, `dict` and `set` keys are
|
||||
compared using deep equality. If a key is encountered in a `dict` or `set` that
|
||||
would have different semantics in Javascript than in Python, then a
|
||||
would have different semantics in JavaScript than in Python, then a
|
||||
`ConversionError` will be thrown.
|
||||
|
||||
See {ref}`buffer_tojs` for the behavior of `toJs` on buffers.
|
||||
|
@ -290,14 +290,14 @@ raised instead.
|
|||
|
||||
(type-translations-jsproxy-to-py)=
|
||||
|
||||
### Javascript to Python
|
||||
### JavaScript to Python
|
||||
|
||||
Explicit conversion of a {any}`JsProxy` into a native Python object is done with
|
||||
the {any}`JsProxy.to_py` method. By default, the `to_py` method does a recursive
|
||||
"deep" conversion, to do a shallow conversion use `proxy.to_py(depth=1)` The
|
||||
`to_py` method performs the following explicit conversions:
|
||||
|
||||
| Javascript | Python |
|
||||
| JavaScript | Python |
|
||||
| ---------- | ------ |
|
||||
| `Array` | `list` |
|
||||
| `Object`\* | `dict` |
|
||||
|
@ -321,23 +321,23 @@ pyodide.runPython(`
|
|||
`);
|
||||
```
|
||||
|
||||
In Javascript, `Map` and `Set` keys are compared using object identity unless
|
||||
In JavaScript, `Map` and `Set` keys are compared using object identity unless
|
||||
the key is an immutable type (meaning a string, a number, a bigint, a boolean,
|
||||
`undefined`, or `null`). On the other hand, in Python, `dict` and `set` keys are
|
||||
compared using deep equality. If a key is encountered in a `Map` or `Set` that
|
||||
would have different semantics in Python than in Javascript, then a
|
||||
`ConversionError` will be thrown. Also, in Javascript, `true !== 1` and `false !== 0`, but in Python, `True == 1` and `False == 0`. This has the result that a
|
||||
Javascript map can use `true` and `1` as distinct keys but a Python `dict`
|
||||
cannot. If the Javascript map contains both `true` and `1` a `ConversionError`
|
||||
would have different semantics in Python than in JavaScript, then a
|
||||
`ConversionError` will be thrown. Also, in JavaScript, `true !== 1` and `false !== 0`, but in Python, `True == 1` and `False == 0`. This has the result that a
|
||||
JavaScript map can use `true` and `1` as distinct keys but a Python `dict`
|
||||
cannot. If the JavaScript map contains both `true` and `1` a `ConversionError`
|
||||
will be thrown.
|
||||
|
||||
## Functions
|
||||
|
||||
### Calling Python objects from Javascript
|
||||
### Calling Python objects from JavaScript
|
||||
|
||||
If a Python object is callable, the proxy will be callable too. The arguments
|
||||
will be translated from Javascript to Python as appropriate, and the return
|
||||
value will be translated from Javascript back to Python. If the return value is
|
||||
will be translated from JavaScript to Python as appropriate, and the return
|
||||
value will be translated from JavaScript back to Python. If the return value is
|
||||
a `PyProxy`, you must explicitly destroy it or else it will be leaked.
|
||||
|
||||
An example:
|
||||
|
@ -355,8 +355,8 @@ let result_js = result_py.toJs();
|
|||
result_py.destroy();
|
||||
```
|
||||
|
||||
If a function is indended to be used from Javascript, you can use {any}`to_js <pyodide.to_js>` on the return value. This prevents the return value from
|
||||
leaking without requiring the Javascript code to explicitly destroy it. This is
|
||||
If a function is indended to be used from JavaScript, you can use {any}`to_js <pyodide.to_js>` on the return value. This prevents the return value from
|
||||
leaking without requiring the JavaScript code to explicitly destroy it. This is
|
||||
particularly important for callbacks.
|
||||
|
||||
```pyodide
|
||||
|
@ -370,7 +370,7 @@ let result = test([1,2,3,4]);
|
|||
// result is the array [1, 4, 9, 16], nothing needs to be destroyed.
|
||||
```
|
||||
|
||||
If you need to use a key word argument, use {any}`callKwargs <PyProxy.callKwargs>`. The last argument should be a Javascript object with the
|
||||
If you need to use a key word argument, use {any}`callKwargs <PyProxy.callKwargs>`. The last argument should be a JavaScript object with the
|
||||
key value arguments.
|
||||
|
||||
```pyodide
|
||||
|
@ -386,27 +386,27 @@ let result = test.callKwargs([1,2,3,4], { offset : 7});
|
|||
|
||||
(call-js-from-py)=
|
||||
|
||||
### Calling Javascript functions from Python
|
||||
### Calling JavaScript functions from Python
|
||||
|
||||
What happens when calling a Javascript function from Python is a bit more
|
||||
complicated than calling a Python function from Javascript. If there are any
|
||||
keyword arguments, they are combined into a Javascript object and used as the
|
||||
What happens when calling a JavaScript function from Python is a bit more
|
||||
complicated than calling a Python function from JavaScript. If there are any
|
||||
keyword arguments, they are combined into a JavaScript object and used as the
|
||||
final argument. Thus, if you call:
|
||||
|
||||
```py
|
||||
f(a=2, b=3)
|
||||
```
|
||||
|
||||
then the Javascript function receives one argument which is a Javascript object
|
||||
then the JavaScript function receives one argument which is a JavaScript object
|
||||
`{a : 2, b : 3}`.
|
||||
|
||||
When a Javascript function is called and it returns anything but a promise, if
|
||||
When a JavaScript function is called and it returns anything but a promise, if
|
||||
the result is a `PyProxy` it is destroyed. Also, any arguments that are
|
||||
PyProxies that were created in the process of argument conversion are also
|
||||
destroyed. If the `PyProxy` was created in Python using
|
||||
{any}`pyodide.create_proxy` it is not destroyed.
|
||||
|
||||
When a Javascript function returns a `Promise` (for example, if the function is
|
||||
When a JavaScript function returns a `Promise` (for example, if the function is
|
||||
an `async` function), it is assumed that the `Promise` is going to do some work
|
||||
that uses the arguments of the function, so it is not safe to destroy them until
|
||||
the `Promise` resolves. In this case, the proxied function returns a Python
|
||||
|
@ -416,7 +416,7 @@ result is converted to Python and the converted value is used to resolve the
|
|||
created in converting the arguments are also destroyed at this point.
|
||||
|
||||
As a result of this, if a `PyProxy` is persisted to be used later, then it must
|
||||
either be copied using {any}`PyProxy.copy` in Javascript or it must be created
|
||||
either be copied using {any}`PyProxy.copy` in JavaScript or it must be created
|
||||
with {any}`pyodide.create_proxy` or `pyodide.create_once_callable`. If it's only
|
||||
going to be called once use `pyodide.create_once_callable`:
|
||||
|
||||
|
@ -445,9 +445,9 @@ proxy.destroy()
|
|||
|
||||
## Buffers
|
||||
|
||||
### Using Javascript Typed Arrays from Python
|
||||
### Using JavaScript Typed Arrays from Python
|
||||
|
||||
Javascript ArrayBuffers and ArrayBuffer views (`Int8Array` and friends) are
|
||||
JavaScript ArrayBuffers and ArrayBuffer views (`Int8Array` and friends) are
|
||||
proxied into Python. Python can't directly access arrays if they are outside of
|
||||
the wasm heap so it's impossible to directly use these proxied buffers as Python
|
||||
buffers. You can convert such a proxy to a Python `memoryview` using the `to_py`
|
||||
|
@ -477,7 +477,7 @@ console.log(jsarray); // [1, 2, 3, 4, 77, 6]
|
|||
```
|
||||
|
||||
The {any}`JsProxy.assign` and {any}`JsProxy.assign_to` methods can be used to
|
||||
assign a Javascript buffer from / to a Python buffer which is appropriately
|
||||
assign a JavaScript buffer from / to a Python buffer which is appropriately
|
||||
sized and contiguous. The assignment methods will only work if the data types
|
||||
match, the total length of the buffers match, and the Python buffer is
|
||||
contiguous.
|
||||
|
@ -487,13 +487,13 @@ future.
|
|||
|
||||
(buffer_tojs)=
|
||||
|
||||
### Using Python Buffer objects from Javascript
|
||||
### Using Python Buffer objects from JavaScript
|
||||
|
||||
Python objects supporting the [Python Buffer
|
||||
protocol](https://docs.python.org/3/c-api/buffer.html) are proxied into
|
||||
Javascript. The data inside the buffer can be accessed via the
|
||||
JavaScript. The data inside the buffer can be accessed via the
|
||||
{any}`PyProxy.toJs` method or the {any}`PyProxy.getBuffer` method. The `toJs`
|
||||
API copies the buffer into Javascript, whereas the `getBuffer` method allows low
|
||||
API copies the buffer into JavaScript, whereas the `getBuffer` method allows low
|
||||
level access to the WASM memory backing the buffer. The `getBuffer` API is more
|
||||
powerful but requires care to use correctly. For simple use cases the `toJs` API
|
||||
should be prefered.
|
||||
|
@ -503,7 +503,7 @@ it to a single `TypedArray`. However, in the case that the format of the buffer
|
|||
is `'s'`, we will convert the buffer to a string and if the format is `'?'` we
|
||||
will convert it to an Array of booleans.
|
||||
|
||||
If the dimension is greater than one, we will convert it to a nested Javascript
|
||||
If the dimension is greater than one, we will convert it to a nested JavaScript
|
||||
array, with the innermost dimension handled in the same way we would handle a 1d
|
||||
array.
|
||||
|
||||
|
@ -515,10 +515,10 @@ x 4 x 1080, the performance of `toJs` will most likely be satisfactory.
|
|||
Typically the innermost dimension won't matter for performance.
|
||||
|
||||
The {any}`PyProxy.getBuffer` method can be used to retrieve a reference to a
|
||||
Javascript typed array that points to the data backing the Python object,
|
||||
JavaScript typed array that points to the data backing the Python object,
|
||||
combined with other metadata about the buffer format. The metadata is suitable
|
||||
for use with a Javascript ndarray library if one is present. For instance, if
|
||||
you load the Javascript [ndarray](https://github.com/scijs/ndarray) package, you
|
||||
for use with a JavaScript ndarray library if one is present. For instance, if
|
||||
you load the JavaScript [ndarray](https://github.com/scijs/ndarray) package, you
|
||||
can do:
|
||||
|
||||
```js
|
||||
|
@ -547,13 +547,13 @@ try {
|
|||
|
||||
## Errors
|
||||
|
||||
All entrypoints and exit points from Python code are wrapped in Javascript `try`
|
||||
blocks. At the boundary between Python and Javascript, errors are caught,
|
||||
All entrypoints and exit points from Python code are wrapped in JavaScript `try`
|
||||
blocks. At the boundary between Python and JavaScript, errors are caught,
|
||||
converted between languages, and rethrown.
|
||||
|
||||
Javascript errors are wrapped in a {any}`JsException <pyodide.JsException>`.
|
||||
JavaScript errors are wrapped in a {any}`JsException <pyodide.JsException>`.
|
||||
Python exceptions are converted to a {any}`PythonError <pyodide.PythonError>`.
|
||||
At present if an exception crosses between Python and Javascript several times,
|
||||
At present if an exception crosses between Python and JavaScript several times,
|
||||
the resulting error message won't be as useful as one might hope.
|
||||
|
||||
In order to reduce memory leaks, the {any}`PythonError <pyodide.PythonError>`
|
||||
|
@ -602,11 +602,11 @@ objects on the custom namespaces.
|
|||
|
||||
(type-translations_using-py-obj-from-js)=
|
||||
|
||||
### Importing Python objects into Javascript
|
||||
### Importing Python objects into JavaScript
|
||||
|
||||
A Python object in the `__main__` global scope can imported into Javascript
|
||||
A Python object in the `__main__` global scope can imported into JavaScript
|
||||
using the {any}`pyodide.globals.get <PyProxy.get>` method. Given the name of the
|
||||
Python object to import, it returns the object translated to Javascript.
|
||||
Python object to import, it returns the object translated to JavaScript.
|
||||
|
||||
```js
|
||||
let sys = pyodide.globals.get("sys");
|
||||
|
@ -633,14 +633,14 @@ let x = my_py_namespace.get("x");
|
|||
|
||||
(type-translations_using-js-obj-from-py)=
|
||||
|
||||
### Importing Javascript objects into Python
|
||||
### Importing JavaScript objects into Python
|
||||
|
||||
Javascript objects in the
|
||||
JavaScript objects in the
|
||||
[`globalThis`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis)
|
||||
global scope can be imported into Python using the `js` module.
|
||||
|
||||
When importing a name from the `js` module, the `js` module looks up Javascript
|
||||
attributes of the `globalThis` scope and translates the Javascript objects into
|
||||
When importing a name from the `js` module, the `js` module looks up JavaScript
|
||||
attributes of the `globalThis` scope and translates the JavaScript objects into
|
||||
Python.
|
||||
|
||||
```py
|
||||
|
@ -650,14 +650,14 @@ from js.document.location import reload as reload_page
|
|||
reload_page()
|
||||
```
|
||||
|
||||
You can also assign to Javascript global variables in this way:
|
||||
You can also assign to JavaScript global variables in this way:
|
||||
|
||||
```pyodide
|
||||
pyodide.runPython("js.x = 2");
|
||||
console.log(window.x); // 2
|
||||
```
|
||||
|
||||
You can create your own custom Javascript modules using
|
||||
You can create your own custom JavaScript modules using
|
||||
{any}`pyodide.registerJsModule` and they will behave like the `js` module except
|
||||
with a custom scope:
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ In this example process we will have three parties involved:
|
|||
Our goal is to run some Python code in another thread, this other thread will
|
||||
not have access to the main thread objects. Therefore we will need an API that takes
|
||||
as input not only the Python `script` we wan to run, but also the `context` on which
|
||||
it relies (some Javascript variables that we would normally get access to if we
|
||||
it relies (some JavaScript variables that we would normally get access to if we
|
||||
were running the Python script in the main thread). Let's first describe what API
|
||||
we would like to have.
|
||||
|
||||
|
@ -85,10 +85,10 @@ How does our web worker run the `script` using a given `context`.
|
|||
|
||||
Let's start with the definition. [A worker][worker api] is:
|
||||
|
||||
> A worker is an object created using a constructor (e.g. [Worker()][worker constructor]) that runs a named Javascript file — this file contains the code that will run in the worker thread; workers run in another global context that is different from the current window. This context is represented by either a DedicatedWorkerGlobalScope object (in the case of dedicated workers - workers that are utilized by a single script), or a SharedWorkerGlobalScope (in the case of shared workers - workers that are shared between multiple scripts).
|
||||
> A worker is an object created using a constructor (e.g. [Worker()][worker constructor]) that runs a named JavaScript file — this file contains the code that will run in the worker thread; workers run in another global context that is different from the current window. This context is represented by either a DedicatedWorkerGlobalScope object (in the case of dedicated workers - workers that are utilized by a single script), or a SharedWorkerGlobalScope (in the case of shared workers - workers that are shared between multiple scripts).
|
||||
|
||||
In our case we will use a single worker to execute Python code without interfering with
|
||||
client side rendering (which is done by the main Javascript thread). The worker does
|
||||
client side rendering (which is done by the main JavaScript thread). The worker does
|
||||
two things:
|
||||
|
||||
1. Listen on new messages from the main thread
|
||||
|
|
|
@ -3,7 +3,7 @@ A matplotlib backend that renders to an HTML5 canvas in the same thread.
|
|||
|
||||
The Agg backend is used for the actual rendering underneath, and renders the
|
||||
buffer to the HTML5 canvas. This happens with only a single copy of the data
|
||||
into the Canvas -- passing the data from Python to Javascript requires no
|
||||
into the Canvas -- passing the data from Python to JavaScript requires no
|
||||
copies.
|
||||
|
||||
See matplotlib.backend_bases for documentation for most of the methods, since
|
||||
|
|
|
@ -4,14 +4,14 @@ initialization-time (or import-time) dependencies.
|
|||
1. CPython
|
||||
2. The py/_pyodide package which is a Python package with pure Python code
|
||||
avaiable in the inner stage of the Pyodide bootstrap process.
|
||||
3. The core/pyodide code, implemented in a mix of C and Javascript, which embeds
|
||||
3. The core/pyodide code, implemented in a mix of C and JavaScript, which embeds
|
||||
the CPython interpreter in an emscripten application. This relies on
|
||||
py/pyodide and js/pyodide at runtime. The final stage of initialization is to
|
||||
import py/pyodide.
|
||||
4. The py/pyodide package which has Python code that is needed for the outer
|
||||
stage of the Pyodide bootstrap process. py/pyodide relies on core/pyodide at
|
||||
import time and relies on js/pyodide at runtime.
|
||||
5. The js/pyodide package which defines the Javascript public API, sets up the
|
||||
5. The js/pyodide package which defines the JavaScript public API, sets up the
|
||||
process of loading the core/pyodide emscripten application + CPython
|
||||
interpreter, and then completes the bootstrap by injecting the js/pyodide
|
||||
API into the Python `sys.modules`.
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# core/pyodide
|
||||
|
||||
The C and Javascript code in this package is responsible for embedding the
|
||||
The C and JavaScript code in this package is responsible for embedding the
|
||||
Python interpreter in our emscripten js/wasm application. The primary purpose of
|
||||
this code is to define the foreign function interface between Python and
|
||||
Javascript. Once this foreign function interface is defined, more complex
|
||||
JavaScript. Once this foreign function interface is defined, more complex
|
||||
behaviors are better defined in Python when possible for easier development and
|
||||
debugging.
|
||||
|
||||
|
@ -16,17 +16,17 @@ The core/pyodide code is responsible for the following main steps:
|
|||
2. Import py/\_pyodide
|
||||
3. Initialize `_pyodide_core` which is a Python C extension that we use to make
|
||||
functionality available to py/pyodide.
|
||||
4. Set up functionality to automatically convert functions from Javascript to
|
||||
4. Set up functionality to automatically convert functions from JavaScript to
|
||||
CPython calling conventions (`error_handling.h`).
|
||||
5. Set up the "hiwire" side table to hold references to Javascript objects --
|
||||
5. Set up the "hiwire" side table to hold references to JavaScript objects --
|
||||
necessary because wasm variables can only hold numbers (`hiwire.c`).
|
||||
6. Set up type conversions of basic types between Python and Javascript
|
||||
6. Set up type conversions of basic types between Python and JavaScript
|
||||
(`js2python.c` and `python2js.c`).
|
||||
7. Set up Proxying of remaining types between Python and Javascript (`jsproxy.c`
|
||||
7. Set up Proxying of remaining types between Python and JavaScript (`jsproxy.c`
|
||||
and `pyproxy.c`). This is the most complicated part of the Pyodide runtime
|
||||
and involves careful conversion between [abstract Javascript object
|
||||
and involves careful conversion between [abstract JavaScript object
|
||||
protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
|
||||
(see also [Javascript Iteration
|
||||
(see also [JavaScript Iteration
|
||||
Protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)
|
||||
)
|
||||
and [Python object protocols](https://docs.python.org/3/c-api/abstract.html).
|
||||
|
|
|
@ -26,9 +26,9 @@ EM_JS_NUM(errcode, console_error_obj, (JsRef obj), {
|
|||
});
|
||||
|
||||
/**
|
||||
* Set Python error indicator from Javascript.
|
||||
* Set Python error indicator from JavaScript.
|
||||
*
|
||||
* In Javascript, we can't access the type without relying on the ABI of
|
||||
* In JavaScript, we can't access the type without relying on the ABI of
|
||||
* PyObject. Py_TYPE is part of the Python restricted API which means that there
|
||||
* are fairly strong guarantees about the ABI stability, but even so writing
|
||||
* HEAP32[err/4 + 1] is a bit opaque.
|
||||
|
@ -94,15 +94,15 @@ store_sys_last_exception(PyObject* type, PyObject* value, PyObject* traceback)
|
|||
* the argument value. Used for reentrant errors.
|
||||
* Returns true if it restored the error indicator, false otherwise.
|
||||
*
|
||||
* If we throw a Javascript PythonError and it bubbles out to the enclosing
|
||||
* Python scope (i.e., doesn't get caught in Javascript) then we want to restore
|
||||
* If we throw a JavaScript PythonError and it bubbles out to the enclosing
|
||||
* Python scope (i.e., doesn't get caught in JavaScript) then we want to restore
|
||||
* the original Python exception. This produces much better stack traces in case
|
||||
* of reentrant calls and prevents issues like a KeyboardInterrupt being wrapped
|
||||
* into a PythonError being wrapped into a JsException and being caught.
|
||||
*
|
||||
* We don't do the same thing for Javascript messages that pass through Python
|
||||
* because the Python exceptions have good Javascript stack traces but
|
||||
* Javascript errors have no Python stack info. Also, Javascript has much weaker
|
||||
* We don't do the same thing for JavaScript messages that pass through Python
|
||||
* because the Python exceptions have good JavaScript stack traces but
|
||||
* JavaScript errors have no Python stack info. Also, JavaScript has much weaker
|
||||
* support for catching errors by type.
|
||||
*/
|
||||
bool
|
||||
|
@ -158,7 +158,7 @@ finally:
|
|||
}
|
||||
|
||||
/**
|
||||
* Wrap the exception in a Javascript PythonError object.
|
||||
* Wrap the exception in a JavaScript PythonError object.
|
||||
*
|
||||
* The return value of this function is always a valid hiwire ID to an error
|
||||
* object. It never returns NULL.
|
||||
|
@ -246,7 +246,7 @@ EM_JS_NUM(errcode, error_handling_init_js, (), {
|
|||
restored_error = _restore_sys_last_exception(e.__error_address);
|
||||
}
|
||||
if (!restored_error) {
|
||||
// Wrap the Javascript error
|
||||
// Wrap the JavaScript error
|
||||
let eidx = Module.hiwire.new_value(e);
|
||||
let err = _JsProxy_create(eidx);
|
||||
_set_error(err);
|
||||
|
|
|
@ -21,12 +21,12 @@ void
|
|||
fail_test();
|
||||
|
||||
/**
|
||||
* Raised when conversion between Javascript and Python fails.
|
||||
* Raised when conversion between JavaScript and Python fails.
|
||||
*/
|
||||
extern PyObject* conversion_error;
|
||||
|
||||
/**
|
||||
* Wrap the current Python exception in a Javascript Error and return the
|
||||
* Wrap the current Python exception in a JavaScript Error and return the
|
||||
* result. Usually we use pythonexc2js instead, but for futures and for some
|
||||
* internal error messages it's useful to have this separate.
|
||||
*/
|
||||
|
@ -39,7 +39,7 @@ wrap_exception();
|
|||
errcode log_python_error(JsRef);
|
||||
|
||||
/**
|
||||
* Convert the active Python exception into a Javascript Error object, print
|
||||
* Convert the active Python exception into a JavaScript Error object, print
|
||||
* an appropriate message to the console and throw the error.
|
||||
*/
|
||||
void _Py_NO_RETURN
|
||||
|
|
|
@ -222,7 +222,7 @@ EM_JS_NUM(int, hiwire_init, (), {
|
|||
* the flag checked to false in that case so we allow assignment to/from
|
||||
* anything.
|
||||
*
|
||||
* This is the API for use from Javascript, there's also an EM_JS
|
||||
* This is the API for use from JavaScript, there's also an EM_JS
|
||||
* hiwire_get_buffer_datatype wrapper for use from C. Used in js2python and
|
||||
* in jsproxy.c for buffers.
|
||||
*/
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
|
||||
/**
|
||||
* hiwire: A super-simple framework for converting values between C and
|
||||
* Javascript.
|
||||
* JavaScript.
|
||||
*
|
||||
* Arbitrary Javascript objects are referenced from C using an opaque int value.
|
||||
* Arbitrary JavaScript objects are referenced from C using an opaque int value.
|
||||
* By convention, these ids are stored in variable names beginning with `id`.
|
||||
*
|
||||
* Javascript objects passed to the C side must be manually reference-counted.
|
||||
* JavaScript objects passed to the C side must be manually reference-counted.
|
||||
* Use `hiwire_incref` if you plan to store the object on the C side. Use
|
||||
* `hiwire_decref` when done. Internally, the objects are stored in a global
|
||||
* object. There may be one or more keys pointing to the same object.
|
||||
|
@ -47,7 +47,7 @@ extern const JsRef Js_null;
|
|||
// For when the return value would be Option<JsRef>
|
||||
extern const JsRef Js_novalue;
|
||||
|
||||
// A mechanism for handling static Javascript strings from C
|
||||
// A mechanism for handling static JavaScript strings from C
|
||||
// This is copied from the Python mechanism for handling static Python strings
|
||||
// from C See the Python definition here:
|
||||
// https://github.com/python/cpython/blob/24da544014f78e6f1440d5ce5c2d14794a020340/Include/cpython/object.h#L37
|
||||
|
@ -101,7 +101,7 @@ errcode
|
|||
hiwire_decref(JsRef idval);
|
||||
|
||||
/**
|
||||
* Create a new Javascript integer with the given value.
|
||||
* Create a new JavaScript integer with the given value.
|
||||
*
|
||||
* Returns: New reference
|
||||
*/
|
||||
|
@ -109,7 +109,7 @@ JsRef
|
|||
hiwire_int(int val);
|
||||
|
||||
/**
|
||||
* Create a new Javascript float with the given value.
|
||||
* Create a new JavaScript float with the given value.
|
||||
*
|
||||
* Returns: New reference
|
||||
*/
|
||||
|
@ -117,7 +117,7 @@ JsRef
|
|||
hiwire_double(double val);
|
||||
|
||||
/**
|
||||
* Create a new Javascript string, given a pointer to a buffer
|
||||
* Create a new JavaScript string, given a pointer to a buffer
|
||||
* containing UCS4 and a length. The string data itself is copied.
|
||||
*
|
||||
* Returns: New reference
|
||||
|
@ -126,7 +126,7 @@ JsRef
|
|||
hiwire_string_ucs4(const char* ptr, int len);
|
||||
|
||||
/**
|
||||
* Create a new Javascript string, given a pointer to a buffer
|
||||
* Create a new JavaScript string, given a pointer to a buffer
|
||||
* containing UCS2 and a length. The string data itself is copied.
|
||||
*
|
||||
* Returns: New reference
|
||||
|
@ -135,7 +135,7 @@ JsRef
|
|||
hiwire_string_ucs2(const char* ptr, int len);
|
||||
|
||||
/**
|
||||
* Create a new Javascript string, given a pointer to a buffer
|
||||
* Create a new JavaScript string, given a pointer to a buffer
|
||||
* containing UCS1 and a length. The string data itself is copied.
|
||||
*
|
||||
* Returns: New reference
|
||||
|
@ -144,7 +144,7 @@ JsRef
|
|||
hiwire_string_ucs1(const char* ptr, int len);
|
||||
|
||||
/**
|
||||
* Create a new Javascript string, given a pointer to a null-terminated buffer
|
||||
* Create a new JavaScript string, given a pointer to a null-terminated buffer
|
||||
* containing UTF8. The string data itself is copied.
|
||||
*
|
||||
* Returns: New reference
|
||||
|
@ -153,7 +153,7 @@ JsRef
|
|||
hiwire_string_utf8(const char* ptr);
|
||||
|
||||
/**
|
||||
* Create a new Javascript string, given a pointer to a null-terminated buffer
|
||||
* Create a new JavaScript string, given a pointer to a null-terminated buffer
|
||||
* containing ascii (well, technically latin-1). The string data itself is
|
||||
* copied.
|
||||
*
|
||||
|
@ -163,7 +163,7 @@ JsRef
|
|||
hiwire_string_ascii(const char* ptr);
|
||||
|
||||
/**
|
||||
* Create a new Javascript boolean value.
|
||||
* Create a new JavaScript boolean value.
|
||||
* Return value is true if boolean != 0, false if boolean == 0.
|
||||
*
|
||||
* Returns: "New" reference
|
||||
|
@ -181,7 +181,7 @@ bool
|
|||
JsArray_Check(JsRef idobj);
|
||||
|
||||
/**
|
||||
* Create a new Javascript Array.
|
||||
* Create a new JavaScript Array.
|
||||
*
|
||||
* Returns: New reference
|
||||
*/
|
||||
|
@ -189,13 +189,13 @@ JsRef
|
|||
JsArray_New();
|
||||
|
||||
/**
|
||||
* Push a value to the end of a Javascript array.
|
||||
* Push a value to the end of a JavaScript array.
|
||||
*/
|
||||
errcode
|
||||
JsArray_Push(JsRef idobj, JsRef idval);
|
||||
|
||||
/**
|
||||
* Create a new Javascript object.
|
||||
* Create a new JavaScript object.
|
||||
*
|
||||
* Returns: New reference
|
||||
*/
|
||||
|
@ -356,7 +356,7 @@ bool
|
|||
hiwire_has_length(JsRef idobj);
|
||||
|
||||
/**
|
||||
* Returns the value of the `size` or `length` member on a Javascript object.
|
||||
* Returns the value of the `size` or `length` member on a JavaScript object.
|
||||
* Prefers the `size` member if present and a number to the `length` field. If
|
||||
* both `size` and `length` are missing or not a number, returns `-1` to
|
||||
* indicate error.
|
||||
|
@ -365,7 +365,7 @@ int
|
|||
hiwire_get_length(JsRef idobj);
|
||||
|
||||
/**
|
||||
* Returns the boolean value of a Javascript object.
|
||||
* Returns the boolean value of a JavaScript object.
|
||||
*/
|
||||
bool
|
||||
hiwire_get_bool(JsRef idobj);
|
||||
|
@ -403,7 +403,7 @@ hiwire_is_promise(JsRef idobj);
|
|||
/**
|
||||
* Returns Promise.resolve(obj)
|
||||
*
|
||||
* Returns: New reference to Javascript promise
|
||||
* Returns: New reference to JavaScript promise
|
||||
*/
|
||||
JsRef
|
||||
hiwire_resolve_promise(JsRef idobj);
|
||||
|
@ -411,7 +411,7 @@ hiwire_resolve_promise(JsRef idobj);
|
|||
/**
|
||||
* Gets the string representation of an object by calling `toString`.
|
||||
*
|
||||
* Returns: New reference to Javascript string
|
||||
* Returns: New reference to JavaScript string
|
||||
*/
|
||||
JsRef
|
||||
hiwire_to_string(JsRef idobj);
|
||||
|
@ -419,7 +419,7 @@ hiwire_to_string(JsRef idobj);
|
|||
/**
|
||||
* Gets the `typeof` string for a value.
|
||||
*
|
||||
* Returns: New reference to Javascript string
|
||||
* Returns: New reference to JavaScript string
|
||||
*/
|
||||
JsRef
|
||||
hiwire_typeof(JsRef idobj);
|
||||
|
@ -427,7 +427,7 @@ hiwire_typeof(JsRef idobj);
|
|||
/**
|
||||
* Gets `value.constructor.name`.
|
||||
*
|
||||
* Returns: New reference to Javascript string
|
||||
* Returns: New reference to JavaScript string
|
||||
*/
|
||||
char*
|
||||
hiwire_constructor_name(JsRef idobj);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// The point is to make a file that works with Javascript analysis tools like
|
||||
// JsDoc and LGTM. They want to parse the file as Javascript. Thus, it's key
|
||||
// that included js files should parse as valid Javascript. `JS_FILE` is a
|
||||
// The point is to make a file that works with JavaScript analysis tools like
|
||||
// JsDoc and LGTM. They want to parse the file as JavaScript. Thus, it's key
|
||||
// that included js files should parse as valid JavaScript. `JS_FILE` is a
|
||||
// specially designed macro to allow us to do this. We need to look like a
|
||||
// function call to Javascript parsers. The easiest way to get it to parse is to
|
||||
// make the macro argument look like a Javascript anonymous function, which we
|
||||
// function call to JavaScript parsers. The easiest way to get it to parse is to
|
||||
// make the macro argument look like a JavaScript anonymous function, which we
|
||||
// do with `()=>{`. However, `()=>{` is an invalid C string so the macro needs
|
||||
// to remove it. We put `()=>{0,0;`, JS_FILE removes everything up to
|
||||
// the comma and replace it with a single open brace.
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "jsproxy.h"
|
||||
#include "pyproxy.h"
|
||||
|
||||
// PyUnicodeDATA is a macro, we need to access it from Javascript
|
||||
// PyUnicodeDATA is a macro, we need to access it from JavaScript
|
||||
void*
|
||||
PyUnicode_Data(PyObject* obj)
|
||||
{
|
||||
|
@ -54,7 +54,7 @@ EM_JS_REF(PyObject*, js2python, (JsRef id), {
|
|||
})
|
||||
|
||||
/**
|
||||
* Convert a Javascript object to Python to a given depth. This is the
|
||||
* Convert a JavaScript object to Python to a given depth. This is the
|
||||
* implementation of `toJs`.
|
||||
*/
|
||||
EM_JS_REF(PyObject*, js2python_convert, (JsRef id, int depth), {
|
||||
|
@ -66,7 +66,7 @@ EM_JS_NUM(errcode, js2python_init, (), {
|
|||
function __js2python_string(value)
|
||||
{
|
||||
// The general idea here is to allocate a Python string and then
|
||||
// have Javascript write directly into its buffer. We first need
|
||||
// have JavaScript write directly into its buffer. We first need
|
||||
// to determine if is needs to be a 1-, 2- or 4-byte string, since
|
||||
// Python handles all 3.
|
||||
let max_code_point = 0;
|
||||
|
@ -353,7 +353,7 @@ EM_JS_NUM(errcode, js2python_init, (), {
|
|||
};
|
||||
|
||||
/**
|
||||
* Convert a Javascript object to Python to a given depth. The `cache`
|
||||
* Convert a JavaScript object to Python to a given depth. The `cache`
|
||||
* argument should be a new empty map (it is needed for recursive calls).
|
||||
*/
|
||||
Module.js2python_convert = function(id, cache, depth)
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
#define JS2PYTHON_H
|
||||
|
||||
/**
|
||||
* Translate Javascript objects to Python objects.
|
||||
* Translate JavaScript objects to Python objects.
|
||||
*/
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "Python.h"
|
||||
#include "hiwire.h"
|
||||
|
||||
/** Convert a Javascript object to a Python object.
|
||||
* \param x The Javascript object.
|
||||
/** Convert a JavaScript object to a Python object.
|
||||
* \param x The JavaScript object.
|
||||
* \return The Python object. New reference. If NULL, a Python exception
|
||||
* occurred during the conversion, and the Python exception API should be
|
||||
* used to obtain the exception.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Macros to access memory from Javascript
|
||||
// Macros to access memory from JavaScript
|
||||
|
||||
#define DEREF_U8(addr, offset) HEAPU8[addr + offset]
|
||||
#define DEREF_I8(addr, offset) HEAP8[addr + offset]
|
||||
|
|
|
@ -74,7 +74,7 @@ static PyTypeObject* PyExc_BaseException_Type;
|
|||
////////////////////////////////////////////////////////////
|
||||
// JsProxy
|
||||
//
|
||||
// This is a Python object that provides idiomatic access to a Javascript
|
||||
// This is a Python object that provides idiomatic access to a JavaScript
|
||||
// object.
|
||||
|
||||
// clang-format off
|
||||
|
@ -199,7 +199,7 @@ JsProxy_SetAttr(PyObject* self, PyObject* attr, PyObject* pyvalue)
|
|||
FAIL_IF_NULL(key);
|
||||
|
||||
if (strncmp(key, "__", 2) == 0) {
|
||||
// Avoid creating reference loops between Python and Javascript with js
|
||||
// Avoid creating reference loops between Python and JavaScript with js
|
||||
// modules. Such reference loops make it hard to avoid leaking memory.
|
||||
if (strcmp(key, "__loader__") == 0 || strcmp(key, "__name__") == 0 ||
|
||||
strcmp(key, "__package__") == 0 || strcmp(key, "__path__") == 0 ||
|
||||
|
@ -713,10 +713,10 @@ PyMethodDef JsProxy_toPy_MethodDef = {
|
|||
|
||||
/**
|
||||
* Overload for bool(proxy), implemented for every JsProxy. Return `False` if
|
||||
* the object is falsey in Javascript, or if it has a `size` field equal to 0,
|
||||
* the object is falsey in JavaScript, or if it has a `size` field equal to 0,
|
||||
* or if it has a `length` field equal to zero and is an array. Otherwise return
|
||||
* `True`. This last convention could be replaced with "has a length equal to
|
||||
* zero and is not a function". In Javascript, `func.length` returns the number
|
||||
* zero and is not a function". In JavaScript, `func.length` returns the number
|
||||
* of arguments `func` expects. We definitely don't want 0-argument functions to
|
||||
* be falsey.
|
||||
*/
|
||||
|
@ -1089,7 +1089,7 @@ finally:
|
|||
|
||||
/**
|
||||
* Prepare arguments from a `METH_FASTCALL | METH_KEYWORDS` Python function to a
|
||||
* Javascript call. We call `python2js` on each argument. Any PyProxy *created*
|
||||
* JavaScript call. We call `python2js` on each argument. Any PyProxy *created*
|
||||
* by `python2js` is stored into the `proxies` list to be destroyed later (if
|
||||
* the argument is a PyProxy created with `create_proxy` it won't be recorded
|
||||
* for destruction).
|
||||
|
@ -1243,7 +1243,7 @@ finally:
|
|||
* jsproxy.new implementation. Controlled by IS_CALLABLE.
|
||||
*
|
||||
* This does Reflect.construct(this, args). In other words, this treats the
|
||||
* JsMethod as a Javascript class, constructs a new Javascript object of that
|
||||
* JsMethod as a JavaScript class, constructs a new JavaScript object of that
|
||||
* class and returns a new JsProxy wrapping it. Similar to `new this(args)`.
|
||||
*/
|
||||
static PyObject*
|
||||
|
@ -1389,7 +1389,7 @@ static PyTypeObject BufferType = {
|
|||
* This is a helper function to do error checking for JsBuffer_AssignToPyBuffer
|
||||
* and JsBuffer_AssignPyBuffer.
|
||||
*
|
||||
* self -- The Javascript buffer involved
|
||||
* self -- The JavaScript buffer involved
|
||||
* view -- The Py_buffer view involved
|
||||
* safe -- If true, check data type compatibility, if false only check size
|
||||
* compatibility.
|
||||
|
@ -1492,7 +1492,7 @@ finally:
|
|||
* jsbuffer.
|
||||
*
|
||||
* All other arguments are calculated from jsbuffer, but it's more convenient to
|
||||
* calculate them in Javascript and pass them as arguments than to acquire them
|
||||
* calculate them in JavaScript and pass them as arguments than to acquire them
|
||||
* from C.
|
||||
*
|
||||
* jsbuffer - An ArrayBuffer view or an ArrayBuffer
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
// clang-format on
|
||||
#include "hiwire.h"
|
||||
|
||||
/** A Python object that a Javascript object inside. Used for any non-standard
|
||||
* data types that are passed from Javascript to Python.
|
||||
/** A Python object that a JavaScript object inside. Used for any non-standard
|
||||
* data types that are passed from JavaScript to Python.
|
||||
*/
|
||||
|
||||
/** Make a new JsProxy.
|
||||
* \param v The Javascript object.
|
||||
* \return The Python object wrapping the Javascript object.
|
||||
* \param v The JavaScript object.
|
||||
* \return The Python object wrapping the JavaScript object.
|
||||
*/
|
||||
PyObject*
|
||||
JsProxy_create(JsRef v);
|
||||
|
@ -27,9 +27,9 @@ JsProxy_create_with_this(JsRef object, JsRef this);
|
|||
bool
|
||||
JsProxy_Check(PyObject* x);
|
||||
|
||||
/** Grab the underlying Javascript object from the JsProxy object.
|
||||
/** Grab the underlying JavaScript object from the JsProxy object.
|
||||
* \param x The JsProxy object. Must confirm that it is a JsProxy object using
|
||||
* JsProxy_Check. \return The Javascript object.
|
||||
* JsProxy_Check. \return The JavaScript object.
|
||||
*/
|
||||
JsRef
|
||||
JsProxy_AsJs(PyObject* x);
|
||||
|
@ -52,9 +52,9 @@ JsBuffer_CloneIntoPython(JsRef jsbuffer,
|
|||
bool
|
||||
JsException_Check(PyObject* x);
|
||||
|
||||
/** Grab the underlying Javascript error from the JsException object.
|
||||
/** Grab the underlying JavaScript error from the JsException object.
|
||||
* \param x The JsProxy object. Must confirm that it is a JsException object
|
||||
* using JsProxy_Check. \return The Javascript object.
|
||||
* using JsProxy_Check. \return The JavaScript object.
|
||||
*/
|
||||
JsRef
|
||||
JsException_AsJs(PyObject* x);
|
||||
|
|
|
@ -106,7 +106,7 @@ get_python_stack_depth()
|
|||
* 1. Initialize init_dict so that runPythonSimple will work.
|
||||
* 2. Initialize the different ffi components and create the _pyodide_core
|
||||
* module
|
||||
* 3. Create a PyProxy wrapper around init_dict so that Javascript can retreive
|
||||
* 3. Create a PyProxy wrapper around init_dict so that JavaScript can retreive
|
||||
* PyProxies from the runPythonSimple namespace.
|
||||
*/
|
||||
int
|
||||
|
@ -167,7 +167,7 @@ main(int argc, char** argv)
|
|||
FATAL_ERROR("Failed to add '_pyodide_core' module to modules dict.");
|
||||
}
|
||||
|
||||
// Enable Javascript access to the globals from runPythonSimple.
|
||||
// Enable JavaScript access to the globals from runPythonSimple.
|
||||
init_dict_proxy = python2js(init_dict);
|
||||
if (init_dict_proxy == NULL) {
|
||||
FATAL_ERROR("Failed to create init_dict proxy.");
|
||||
|
|
|
@ -158,7 +158,7 @@ int numpy_patch_init(){
|
|||
// clang-format on
|
||||
|
||||
/**
|
||||
* It's annoying to set errors from Javascript.
|
||||
* It's annoying to set errors from JavaScript.
|
||||
*/
|
||||
void
|
||||
set_shape_mismatch_err()
|
||||
|
@ -173,7 +173,7 @@ set_shape_mismatch_err()
|
|||
* I rearranged the code a small amount to save effort.
|
||||
* Pretty much all that happened is that we destroyed type information, replaced
|
||||
* declarations with "let", and had to make special macros to do most memory
|
||||
* access which is much more annoying than in Javascript.
|
||||
* access which is much more annoying than in JavaScript.
|
||||
*
|
||||
* See below for the C equivalent.
|
||||
*/
|
||||
|
|
|
@ -15,7 +15,7 @@ _Py_IDENTIFIER(ensure_future);
|
|||
_Py_IDENTIFIER(add_done_callback);
|
||||
|
||||
// Use raw EM_JS for the next five commands. We intend to signal a fatal error
|
||||
// if a Javascript error is thrown.
|
||||
// if a JavaScript error is thrown.
|
||||
|
||||
EM_JS(int, pyproxy_Check, (JsRef x), {
|
||||
if (x == 0) {
|
||||
|
@ -150,13 +150,13 @@ pyproxy_getflags(PyObject* pyobj)
|
|||
//
|
||||
// This section defines wrappers for Python Object protocol API calls that we
|
||||
// are planning to offer on the PyProxy. Much of this could be written in
|
||||
// Javascript instead. Some reasons to do it in C:
|
||||
// JavaScript instead. Some reasons to do it in C:
|
||||
// 1. Some CPython APIs are actually secretly macros which cannot be used from
|
||||
// Javascript.
|
||||
// JavaScript.
|
||||
// 2. The code is a bit more concise in C.
|
||||
// 3. It may be preferable to minimize the number of times we cross between
|
||||
// wasm and javascript for performance reasons
|
||||
// 4. Better separation of functionality: Most of the Javascript code is
|
||||
// 4. Better separation of functionality: Most of the JavaScript code is
|
||||
// boilerpalte. Most of this code here is boilerplate. However, the
|
||||
// boilerplate in these C API wwrappers is a bit different than the
|
||||
// boilerplate in the javascript wrappers, so we've factored it into two
|
||||
|
@ -472,7 +472,7 @@ finally:
|
|||
|
||||
/**
|
||||
* This sets up a call to _PyObject_Vectorcall. It's a helper fucntion for
|
||||
* callPyObjectKwargs. This is the primary entrypoint from Javascript into
|
||||
* callPyObjectKwargs. This is the primary entrypoint from JavaScript into
|
||||
* Python code.
|
||||
*
|
||||
* Vectorcall expects the arguments to be communicated as:
|
||||
|
@ -491,12 +491,12 @@ finally:
|
|||
* Our arguments are:
|
||||
*
|
||||
* callable : The object to call.
|
||||
* args : The list of Javascript arguments, both positional and kwargs.
|
||||
* args : The list of JavaScript arguments, both positional and kwargs.
|
||||
* numposargs : The number of positional arguments.
|
||||
* kwnames : List of names of the keyword arguments
|
||||
* numkwargs : The length of kwargs
|
||||
*
|
||||
* Returns: The return value translated to Javascript.
|
||||
* Returns: The return value translated to JavaScript.
|
||||
*/
|
||||
JsRef
|
||||
_pyproxy_apply(PyObject* callable,
|
||||
|
@ -641,7 +641,7 @@ _pyproxyGen_FetchStopIterationValue()
|
|||
// future with future.add_done_callback but we need to make a little python
|
||||
// closure "FutureDoneCallback" that remembers how to resolve the promise.
|
||||
//
|
||||
// From Javascript we will use the single function _pyproxy_ensure_future, the
|
||||
// From JavaScript we will use the single function _pyproxy_ensure_future, the
|
||||
// rest of this segment is helper functions for _pyproxy_ensure_future. The
|
||||
// FutureDoneCallback object is never exposed to the user.
|
||||
|
||||
|
@ -802,7 +802,7 @@ size_t py_buffer_len_offset = offsetof(Py_buffer, len);
|
|||
size_t py_buffer_shape_offset = offsetof(Py_buffer, shape);
|
||||
|
||||
/**
|
||||
* Convert a C array of Py_ssize_t to Javascript.
|
||||
* Convert a C array of Py_ssize_t to JavaScript.
|
||||
*/
|
||||
EM_JS_REF(JsRef, array_to_js, (Py_ssize_t * array, int len), {
|
||||
return Module.hiwire.new_value(
|
||||
|
@ -992,7 +992,7 @@ create_once_callable_py(PyObject* _mod, PyObject* obj)
|
|||
* handle_exception -- Python callable expecting one argument, called with the
|
||||
* exception if the promise is rejected. Can be NULL.
|
||||
*
|
||||
* done_callback_id -- A JsRef to a Javascript callback to be called when the
|
||||
* done_callback_id -- A JsRef to a JavaScript callback to be called when the
|
||||
* promise is either resolved or rejected. Can be NULL.
|
||||
*
|
||||
* Returns: a JsRef to a pair [onResolved, onRejected].
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
#include "Python.h"
|
||||
|
||||
/**
|
||||
* Makes Python objects usable from Javascript.
|
||||
* Makes Python objects usable from JavaScript.
|
||||
*/
|
||||
|
||||
// This implements the Javascript Proxy handler interface as defined here:
|
||||
// This implements the JavaScript Proxy handler interface as defined here:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
|
||||
|
||||
JsRef
|
||||
|
@ -31,7 +31,7 @@ errcode
|
|||
destroy_proxies(JsRef proxies_id, char* msg);
|
||||
|
||||
/**
|
||||
* Wrap a Python callable in a Javascript function that can be called once.
|
||||
* Wrap a Python callable in a JavaScript function that can be called once.
|
||||
* After being called, the reference count of the python object is automatically
|
||||
* decremented. The Proxy also has a "destroy" API that can decrement the
|
||||
* reference count without calling the function.
|
||||
|
@ -40,7 +40,7 @@ JsRef
|
|||
create_once_callable(PyObject* obj);
|
||||
|
||||
/**
|
||||
* Wrap a pair of Python callables in a Javascript function that can be called
|
||||
* Wrap a pair of Python callables in a JavaScript function that can be called
|
||||
* once between the two of them. After being called, the reference counts of
|
||||
* both python objects are automatically decremented. The wrappers also have a
|
||||
* "destroy" API that can decrement the reference counts without calling the
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* runPythonSimple which is defined in main.c
|
||||
*
|
||||
* Any time we call into wasm, the call should be wrapped in a try catch block.
|
||||
* This way if a Javascript error emerges from the wasm, we can escalate it to a
|
||||
* This way if a JavaScript error emerges from the wasm, we can escalate it to a
|
||||
* fatal error.
|
||||
*
|
||||
* This is file is preprocessed with -imacros "pyproxy.c". As a result of this,
|
||||
|
@ -216,7 +216,7 @@ Module.pyproxy_destroy = function (proxy, destroyed_msg) {
|
|||
}
|
||||
let ptrobj = _getPtr(proxy);
|
||||
Module.finalizationRegistry.unregister(proxy);
|
||||
// Maybe the destructor will call Javascript code that will somehow try
|
||||
// Maybe the destructor will call JavaScript code that will somehow try
|
||||
// to use this proxy. Mark it deleted before decrementing reference count
|
||||
// just in case!
|
||||
proxy.$$.ptr = null;
|
||||
|
@ -231,7 +231,7 @@ Module.pyproxy_destroy = function (proxy, destroyed_msg) {
|
|||
};
|
||||
|
||||
// Now a lot of boilerplate to wrap the abstract Object protocol wrappers
|
||||
// defined in pyproxy.c in Javascript functions.
|
||||
// defined in pyproxy.c in JavaScript functions.
|
||||
|
||||
Module.callPyObjectKwargs = function (ptrobj, ...jsargs) {
|
||||
// We don't do any checking for kwargs, checks are in PyProxy.callKwargs
|
||||
|
@ -345,7 +345,7 @@ class PyProxyClass {
|
|||
return Module.pyproxy_new(ptrobj, this.$$.cache);
|
||||
}
|
||||
/**
|
||||
* Converts the ``PyProxy`` into a Javascript object as best as possible. By
|
||||
* Converts the ``PyProxy`` into a JavaScript object as best as possible. By
|
||||
* default does a deep conversion, if a shallow conversion is desired, you can
|
||||
* use ``proxy.toJs({depth : 1})``. See :ref:`Explicit Conversion of PyProxy
|
||||
* <type-translations-pyproxy-to-js>` for more info.
|
||||
|
@ -366,7 +366,7 @@ class PyProxyClass {
|
|||
* desired output. For instance, ``Object.fromEntries`` would convert the dict
|
||||
* to an object, ``Array.from`` converts it to an array of entries, and ``(it) =>
|
||||
* new Map(it)`` converts it to a ``Map`` (which is the default behavior).
|
||||
* @return {any} The Javascript object resulting from the conversion.
|
||||
* @return {any} The JavaScript object resulting from the conversion.
|
||||
*/
|
||||
toJs({
|
||||
depth = -1,
|
||||
|
@ -873,7 +873,7 @@ let PyProxyHandlers = {
|
|||
},
|
||||
get(jsobj, jskey) {
|
||||
// Preference order:
|
||||
// 1. stuff from Javascript
|
||||
// 1. stuff from JavaScript
|
||||
// 2. the result of Python getattr
|
||||
|
||||
// python_getattr will crash if given a Symbol.
|
||||
|
@ -919,7 +919,7 @@ let PyProxyHandlers = {
|
|||
}
|
||||
python_delattr(jsobj, jskey);
|
||||
// Must return "false" if "jskey" is a nonconfigurable own property.
|
||||
// Otherwise Javascript will throw a TypeError.
|
||||
// Otherwise JavaScript will throw a TypeError.
|
||||
return !descr || descr.configurable;
|
||||
},
|
||||
ownKeys(jsobj) {
|
||||
|
@ -947,7 +947,7 @@ let PyProxyHandlers = {
|
|||
*/
|
||||
|
||||
/**
|
||||
* The Promise / javascript awaitable API.
|
||||
* The Promise / JavaScript awaitable API.
|
||||
* @private
|
||||
*/
|
||||
class PyProxyAwaitableMethods {
|
||||
|
@ -1107,14 +1107,14 @@ let type_to_array_map = new Map([
|
|||
*/
|
||||
class PyProxyBufferMethods {
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Present only if the proxied Python object supports the `Python Buffer
|
||||
* Protocol <https://docs.python.org/3/c-api/buffer.html>`_.
|
||||
*
|
||||
* 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 use the :any:`toJs` api or copy the
|
||||
* buffer to one that doesn't use suboffets (using e.g.,
|
||||
* `numpy.ascontiguousarray
|
||||
|
@ -1260,7 +1260,7 @@ class PyProxyBufferMethods {
|
|||
*/
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* When you are done, release it with the :any:`release <PyBuffer.release>`
|
||||
* method. See
|
||||
|
|
|
@ -265,7 +265,7 @@ finally:
|
|||
|
||||
/**
|
||||
* Convert x if x is an immutable python type for which there exists an
|
||||
* equivalent immutable Javascript type. Otherwise return Js_novalue.
|
||||
* equivalent immutable JavaScript type. Otherwise return Js_novalue.
|
||||
*
|
||||
* Return type would be Option<JsRef>
|
||||
*/
|
||||
|
@ -289,7 +289,7 @@ _python2js_immutable(PyObject* x)
|
|||
}
|
||||
|
||||
/**
|
||||
* If x is a wrapper around a Javascript object, unwrap the Javascript object
|
||||
* If x is a wrapper around a JavaScript object, unwrap the JavaScript object
|
||||
* and return it. Otherwise, return Js_novalue.
|
||||
*
|
||||
* Return type would be Option<JsRef>
|
||||
|
@ -337,7 +337,7 @@ finally:
|
|||
}
|
||||
|
||||
/* During conversion of collection types (lists and dicts) from Python to
|
||||
* Javascript, we need to make sure that those collections don't include
|
||||
* JavaScript, we need to make sure that those collections don't include
|
||||
* themselves, otherwise infinite recursion occurs. We also want to make sure
|
||||
* that if the list contains multiple copies of the same list that they point to
|
||||
* the same place. For after:
|
||||
|
@ -348,9 +348,9 @@ finally:
|
|||
* We want to ensure that b.toJs()[0] is the same list as b.toJs()[1].
|
||||
*
|
||||
* The solution is to maintain a cache mapping from the PyObject* to the
|
||||
* Javascript object id for all collection objects. (One could do this for
|
||||
* JavaScript object id for all collection objects. (One could do this for
|
||||
* scalars as well, but that would imply a larger cache, and identical scalars
|
||||
* are probably interned for deduplication on the Javascript side anyway).
|
||||
* are probably interned for deduplication on the JavaScript side anyway).
|
||||
*
|
||||
* This cache only lives for each invocation of python2js.
|
||||
*/
|
||||
|
@ -407,7 +407,7 @@ finally:
|
|||
|
||||
/**
|
||||
* Do a shallow conversion from python2js. Convert immutable types with
|
||||
* equivalent Javascript immutable types, but all other types are proxied.
|
||||
* equivalent JavaScript immutable types, but all other types are proxied.
|
||||
*
|
||||
*/
|
||||
JsRef
|
||||
|
@ -440,7 +440,7 @@ finally:
|
|||
|
||||
/**
|
||||
* Do a shallow conversion from python2js. Convert immutable types with
|
||||
* equivalent Javascript immutable types.
|
||||
* equivalent JavaScript immutable types.
|
||||
*
|
||||
* Other types are proxied and added to the list proxies (to allow easy memory
|
||||
* management later). If proxies is NULL, python2js will raise an error instead
|
||||
|
@ -453,8 +453,8 @@ python2js_track_proxies(PyObject* x, JsRef proxies)
|
|||
}
|
||||
|
||||
/**
|
||||
* Do a translation from Python to Javascript. Convert immutable types with
|
||||
* equivalent Javascript immutable types, but all other types are proxied.
|
||||
* Do a translation from Python to JavaScript. Convert immutable types with
|
||||
* equivalent JavaScript immutable types, but all other types are proxied.
|
||||
*/
|
||||
JsRef
|
||||
python2js(PyObject* x)
|
||||
|
@ -476,7 +476,7 @@ _JsMap_Set(ConversionContext context, JsRef map, JsRef key, JsRef value)
|
|||
}
|
||||
|
||||
/**
|
||||
* Do a conversion from Python to Javascript using settings from
|
||||
* Do a conversion from Python to JavaScript using settings from
|
||||
* ConversionContext
|
||||
*/
|
||||
JsRef
|
||||
|
@ -514,7 +514,7 @@ python2js_with_context(ConversionContext context, PyObject* x)
|
|||
}
|
||||
|
||||
/**
|
||||
* Do a conversion from Python to Javascript, converting lists, dicts, and sets
|
||||
* Do a conversion from Python to JavaScript, converting lists, dicts, and sets
|
||||
* down to depth "depth".
|
||||
*/
|
||||
JsRef
|
||||
|
@ -565,8 +565,8 @@ _JsArray_PostProcess(ConversionContext context, JsRef array)
|
|||
}
|
||||
|
||||
/**
|
||||
* dict_converter should be a Javascript function that converts an Iterable of
|
||||
* pairs into the desired Javascript object. If dict_converter is NULL, we use
|
||||
* dict_converter should be a JavaScript function that converts an Iterable of
|
||||
* pairs into the desired JavaScript object. If dict_converter is NULL, we use
|
||||
* python2js_with_depth which converts dicts to Map (the default)
|
||||
*/
|
||||
JsRef
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PYTHON2JS_H
|
||||
#define PYTHON2JS_H
|
||||
|
||||
/** Translate Python objects to Javascript.
|
||||
/** Translate Python objects to JavaScript.
|
||||
*/
|
||||
// clang-format off
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
|
@ -10,8 +10,8 @@
|
|||
#include "hiwire.h"
|
||||
|
||||
/**
|
||||
* Do a shallow conversion from python to Javascript. Convert immutable types
|
||||
* with equivalent Javascript immutable types, but all other types are proxied.
|
||||
* Do a shallow conversion from python to JavaScript. Convert immutable types
|
||||
* with equivalent JavaScript immutable types, but all other types are proxied.
|
||||
*/
|
||||
JsRef
|
||||
python2js(PyObject* x);
|
||||
|
@ -27,14 +27,14 @@ JsRef
|
|||
python2js_track_proxies(PyObject* x, JsRef proxies);
|
||||
|
||||
/**
|
||||
* Convert a Python object to a Javascript object, copying standard collections
|
||||
* Convert a Python object to a JavaScript object, copying standard collections
|
||||
* into javascript down to specified depth
|
||||
* \param x The Python object
|
||||
* \param depth The maximum depth to copy
|
||||
* \param proxies If this is Null, will raise an error if we have no Javascript
|
||||
* conversion for a Python object. If not NULL, should be a Javascript
|
||||
* \param proxies If this is Null, will raise an error if we have no JavaScript
|
||||
* conversion for a Python object. If not NULL, should be a JavaScript
|
||||
* list. We will add all PyProxies created to the list.
|
||||
* \return The Javascript object -- might be an Error object in the case of an
|
||||
* \return The JavaScript object -- might be an Error object in the case of an
|
||||
* exception.
|
||||
*/
|
||||
JsRef
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
#include "jsmemops.h"
|
||||
|
||||
// This file handles the conversion of Python buffer objects (which loosely
|
||||
// represent Numpy arrays) to Javascript.
|
||||
// Converts everything to nested Javascript arrays, where the scalars are
|
||||
// standard Javascript numbers (python2js_buffer_recursive)
|
||||
// represent Numpy arrays) to JavaScript.
|
||||
// Converts everything to nested JavaScript arrays, where the scalars are
|
||||
// standard JavaScript numbers (python2js_buffer_recursive)
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* A simple helper function that puts the arguments into a Javascript object
|
||||
* A simple helper function that puts the arguments into a JavaScript object
|
||||
* (for readability) and looks up the conversion function, then calls into
|
||||
* python2js_buffer_recursive.
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PYTHON2JS_BUFFER_H
|
||||
#define PYTHON2JS_BUFFER_H
|
||||
|
||||
/** Utilities to convert Python buffer objects to Javascript.
|
||||
/** Utilities to convert Python buffer objects to JavaScript.
|
||||
*/
|
||||
// clang-format off
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
|
@ -9,10 +9,10 @@
|
|||
// clang-format on
|
||||
#include "hiwire.h"
|
||||
|
||||
/** Convert a Python buffer object to a Javascript object.
|
||||
/** Convert a Python buffer object to a JavaScript object.
|
||||
*
|
||||
* \param The Python object
|
||||
* \return The Javascript object -- might be an Error object in the case of an
|
||||
* \return The JavaScript object -- might be an Error object in the case of an
|
||||
* exception.
|
||||
*/
|
||||
JsRef
|
||||
|
|
|
@ -3,14 +3,14 @@ JS_FILE(python2js_buffer_init, () => {
|
|||
|
||||
/**
|
||||
* Determine type and endianness of data from format. This is a helper
|
||||
* function for converting buffers from Python to Javascript, used in
|
||||
* function for converting buffers from Python to JavaScript, used in
|
||||
* PyProxyBufferMethods and in `toJs` on a buffer.
|
||||
*
|
||||
* To understand this function it will be helpful to look at the tables here:
|
||||
* https://docs.python.org/3/library/struct.html#format-strings
|
||||
*
|
||||
* @arg format {String} A Python format string (caller must convert it to a
|
||||
* Javascript string).
|
||||
* JavaScript string).
|
||||
* @arg errorMessage {String} Extra stuff to append to an error message if
|
||||
* thrown. Should be a complete sentence.
|
||||
* @returns A pair, an appropriate TypedArray constructor and a boolean which
|
||||
|
@ -106,7 +106,7 @@ JS_FILE(python2js_buffer_init, () => {
|
|||
};
|
||||
|
||||
/**
|
||||
* Convert a 1-dimensional contiguous buffer to Javascript.
|
||||
* Convert a 1-dimensional contiguous buffer to JavaScript.
|
||||
*
|
||||
* In this case we can just slice the memory out of the wasm HEAP.
|
||||
* @param {number} ptr A pointer to the start of the buffer in wasm memory
|
||||
|
@ -124,7 +124,7 @@ JS_FILE(python2js_buffer_init, () => {
|
|||
};
|
||||
|
||||
/**
|
||||
* Convert a 1d noncontiguous buffer to Javascript.
|
||||
* Convert a 1d noncontiguous buffer to JavaScript.
|
||||
*
|
||||
* Since the buffer is not contiguous we have to copy it in chunks.
|
||||
* @param {number} ptr The WAM memory pointer to the start of the buffer.
|
||||
|
@ -160,7 +160,7 @@ JS_FILE(python2js_buffer_init, () => {
|
|||
};
|
||||
|
||||
/**
|
||||
* Convert an ndarray to a nested Javascript array, the main function.
|
||||
* Convert an ndarray to a nested JavaScript array, the main function.
|
||||
*
|
||||
* This is called by _python2js_buffer_inner (defined in python2js_buffer.c).
|
||||
* There are two layers of setup that need to be done to get the base case of
|
||||
|
@ -176,7 +176,7 @@ JS_FILE(python2js_buffer_init, () => {
|
|||
* @param {number} bufferData All of the data out of the Py_buffer, plus the
|
||||
* converter function: ndim, format, itemsize, shape (a ptr), strides (a ptr),
|
||||
* suboffsets (a ptr), converter,
|
||||
* @returns A nested Javascript array, the result of the conversion.
|
||||
* @returns A nested JavaScript array, the result of the conversion.
|
||||
* @private
|
||||
*/
|
||||
Module._python2js_buffer_recursive = function (ptr, curdim, bufferData) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Pyodide Javascript package
|
||||
# Pyodide JavaScript package
|
||||
|
||||
<a href="https://www.npmjs.com/package/pyodide"><img src="https://img.shields.io/npm/v/pyodide" alt="npm"></a>
|
||||
|
||||
|
@ -26,15 +26,15 @@ See the [documentation](https://pyodide.org/en/stable/) fore more details.
|
|||
|
||||
## Details
|
||||
|
||||
The Javascript code in this package is responsible for the following tasks:
|
||||
The JavaScript code in this package is responsible for the following tasks:
|
||||
|
||||
1. Defines the public [Javascript API](https://pyodide.org/en/stable/usage/api/js-api.html)
|
||||
1. Defines the public [JavaScript API](https://pyodide.org/en/stable/usage/api/js-api.html)
|
||||
- Package loading code to allow loading of other Python packages.
|
||||
- Can load
|
||||
[micropip](https://pyodide.org/en/stable/usage/api/micropip-api.html) to
|
||||
bootstrap loading of pure Python wheels
|
||||
2. Loads the CPython interpreter and the core/pyodide emscripten application
|
||||
which embeds the interpreter.
|
||||
3. Injects the `js/pyodide` Javascript API into `sys.modules`. This is the
|
||||
3. Injects the `js/pyodide` JavaScript API into `sys.modules`. This is the
|
||||
final runtime dependency for `core/pyodide` & `py/pyodide`, so after this step
|
||||
the interpreter is fully up and running.
|
||||
|
|
|
@ -14,7 +14,7 @@ export { loadPackage, loadedPackages, isPyProxy };
|
|||
* An alias to the Python :py:mod:`pyodide` package.
|
||||
*
|
||||
* You can use this to call functions defined in the Pyodide Python package
|
||||
* from Javascript.
|
||||
* from JavaScript.
|
||||
*
|
||||
* @type {PyProxy}
|
||||
*/
|
||||
|
@ -32,7 +32,7 @@ let pyodide_py = {}; // actually defined in runPythonSimple in loadPyodide (see
|
|||
let globals = {}; // actually defined in runPythonSimple in loadPyodide (see pyodide.js)
|
||||
|
||||
/**
|
||||
* A Javascript error caused by a Python exception.
|
||||
* A JavaScript error caused by a Python exception.
|
||||
*
|
||||
* In order to reduce the risk of large memory leaks, the ``PythonError``
|
||||
* contains no reference to the Python exception that caused it. You can find
|
||||
|
@ -77,7 +77,7 @@ export class PythonError {
|
|||
export let version = ""; // actually defined in runPythonSimple in loadPyodide (see pyodide.js)
|
||||
|
||||
/**
|
||||
* Runs a string of Python code from Javascript.
|
||||
* Runs a string of Python code from JavaScript.
|
||||
*
|
||||
* The last part of the string may be an expression, in which case, its value
|
||||
* is returned.
|
||||
|
@ -86,7 +86,7 @@ export let version = ""; // actually defined in runPythonSimple in loadPyodide (
|
|||
* @param {PyProxy} globals An optional Python dictionary to use as the globals.
|
||||
* Defaults to :any:`pyodide.globals`. Uses the Python API
|
||||
* :any:`pyodide.eval_code` to evaluate the code.
|
||||
* @returns {Py2JsResult} The result of the Python code translated to Javascript. See the
|
||||
* @returns {Py2JsResult} The result of the Python code translated to JavaScript. See the
|
||||
* documentation for :any:`pyodide.eval_code` for more info.
|
||||
*/
|
||||
export function runPython(code, globals = Module.globals) {
|
||||
|
@ -151,18 +151,18 @@ export async function loadPackagesFromImports(
|
|||
}
|
||||
|
||||
/**
|
||||
* Access a Python object in the global namespace from Javascript.
|
||||
* Access a Python object in the global namespace from JavaScript.
|
||||
*
|
||||
* @deprecated This function will be removed in version 0.18.0. Use
|
||||
* :any:`pyodide.globals.get('key') <pyodide.globals>` instead.
|
||||
*
|
||||
* @param {string} name Python variable name
|
||||
* @returns {Py2JsResult} The Python object translated to Javascript.
|
||||
* @returns {Py2JsResult} The Python object translated to JavaScript.
|
||||
*/
|
||||
export function pyimport(name) {
|
||||
console.warn(
|
||||
"Access to the Python global namespace via pyodide.pyimport is deprecated and " +
|
||||
"will be removed in version 0.18.0. Use pyodide.globals.get('key') instead."
|
||||
"will be removed in version 0.18.0. Use pyodide.globals.get('key') instead."
|
||||
);
|
||||
return Module.globals.get(name);
|
||||
}
|
||||
|
@ -185,13 +185,13 @@ export function pyimport(name) {
|
|||
* 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
|
||||
* # If final statement is an expression, its value is returned to JavaScript
|
||||
* len(packages.packages.object_keys())
|
||||
* `);
|
||||
* console.log(result); // 79
|
||||
*
|
||||
* @param {string} code Python code to evaluate
|
||||
* @returns {Py2JsResult} The result of the Python code translated to Javascript.
|
||||
* @returns {Py2JsResult} The result of the Python code translated to JavaScript.
|
||||
* @async
|
||||
*/
|
||||
export async function runPythonAsync(code) {
|
||||
|
@ -205,15 +205,15 @@ export async function runPythonAsync(code) {
|
|||
Module.runPythonAsync = runPythonAsync;
|
||||
|
||||
/**
|
||||
* Registers the Javascript object ``module`` as a Javascript module named
|
||||
* Registers the JavaScript object ``module`` as a JavaScript module named
|
||||
* ``name``. This module can then be imported from Python using the standard
|
||||
* Python import system. If another module by the same name has already been
|
||||
* imported, this won't have much effect unless you also delete the imported
|
||||
* module from ``sys.modules``. This calls the ``pyodide_py`` API
|
||||
* :func:`pyodide.register_js_module`.
|
||||
*
|
||||
* @param {string} name Name of the Javascript module to add
|
||||
* @param {object} module Javascript object backing the module
|
||||
* @param {string} name Name of the JavaScript module to add
|
||||
* @param {object} module JavaScript object backing the module
|
||||
*/
|
||||
export function registerJsModule(name, module) {
|
||||
Module.pyodide_py.register_js_module(name, module);
|
||||
|
@ -228,24 +228,24 @@ export function registerComlink(Comlink) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Unregisters a Javascript module with given name that has been previously
|
||||
* Unregisters a JavaScript module with given name that has been previously
|
||||
* registered with :js:func:`pyodide.registerJsModule` or
|
||||
* :func:`pyodide.register_js_module`. If a Javascript module with that name
|
||||
* :func:`pyodide.register_js_module`. If a JavaScript module with that name
|
||||
* does not already exist, will throw an error. Note that if the module has
|
||||
* already been imported, this won't have much effect unless you also delete
|
||||
* the imported module from ``sys.modules``. This calls the ``pyodide_py`` API
|
||||
* :func:`pyodide.unregister_js_module`.
|
||||
*
|
||||
* @param {string} name Name of the Javascript module to remove
|
||||
* @param {string} name Name of the JavaScript module to remove
|
||||
*/
|
||||
export function unregisterJsModule(name) {
|
||||
Module.pyodide_py.unregister_js_module(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the Javascript object to a Python object as best as possible.
|
||||
* Convert the JavaScript object to a Python object as best as possible.
|
||||
*
|
||||
* This is similar to :any:`JsProxy.to_py` but for use from Javascript. If the
|
||||
* This is similar to :any:`JsProxy.to_py` but for use from JavaScript. If the
|
||||
* object is immutable or a :any:`PyProxy`, it will be returned unchanged. If
|
||||
* the object cannot be converted into Python, it will be returned unchanged.
|
||||
*
|
||||
|
@ -328,7 +328,7 @@ export function setInterruptBuffer(interrupt_buffer) {
|
|||
* Throws a KeyboardInterrupt error if a KeyboardInterrupt has been requested
|
||||
* via the interrupt buffer.
|
||||
*
|
||||
* This can be used to enable keyboard interrupts during execution of Javascript
|
||||
* This can be used to enable keyboard interrupts during execution of JavaScript
|
||||
* code, just as `PyErr_CheckSignals` is used to enable keyboard interrupts
|
||||
* during execution of C code.
|
||||
*/
|
||||
|
|
|
@ -305,7 +305,7 @@ export let loadedPackages = {};
|
|||
* ``<package-name>.js`` and there must be a file called
|
||||
* ``<package-name>.data`` in the same directory. The argument can be a
|
||||
* ``PyProxy`` of a list, in which case the list will be converted to
|
||||
* Javascript and the ``PyProxy`` will be destroyed.
|
||||
* JavaScript and the ``PyProxy`` will be destroyed.
|
||||
* @param {LogFn=} messageCallback A callback, called with progress messages
|
||||
* (optional)
|
||||
* @param {LogFn=} errorCallback A callback, called with error/warning
|
||||
|
|
|
@ -44,7 +44,7 @@ let fatal_error_occurred = false;
|
|||
/**
|
||||
* Signal a fatal error.
|
||||
*
|
||||
* Dumps the Python traceback, shows a Javascript traceback, and prints a clear
|
||||
* Dumps the Python traceback, shows a JavaScript traceback, and prints a clear
|
||||
* message indicating a fatal error. It then dummies out the public API so that
|
||||
* further attempts to use Pyodide will clearly indicate that Pyodide has failed
|
||||
* and can no longer be used. pyodide._module is left accessible and it is
|
||||
|
@ -109,7 +109,7 @@ Module.fatal_error = function (e) {
|
|||
* 1. `runPythonSimple` doesn't return anything (and so won't leak
|
||||
* PyProxies)
|
||||
* 2. `runPythonSimple` doesn't require access to any state on the
|
||||
* Javascript `pyodide` module.
|
||||
* JavaScript `pyodide` module.
|
||||
* 3. `runPython` uses `pyodide.eval_code`, whereas `runPythonSimple` uses
|
||||
* `PyRun_String` which is the C API for `eval` / `exec`.
|
||||
* 4. `runPythonSimple` runs with `globals` a separate dict which is called
|
||||
|
@ -137,8 +137,8 @@ Module.runPythonSimple = function (code) {
|
|||
};
|
||||
|
||||
/**
|
||||
* The Javascript/Wasm call stack is too small to handle the default Python call
|
||||
* stack limit of 1000 frames. Here, we determine the Javascript call stack
|
||||
* The JavaScript/Wasm call stack is too small to handle the default Python call
|
||||
* stack limit of 1000 frames. Here, we determine the JavaScript call stack
|
||||
* depth available, and then divide by 50 (determined heuristically) to set the
|
||||
* maximum Python call stack depth.
|
||||
*
|
||||
|
@ -162,7 +162,7 @@ function fixRecursionLimit() {
|
|||
/**
|
||||
* Load the main Pyodide wasm module and initialize it.
|
||||
*
|
||||
* Only one copy of Pyodide can be loaded in a given Javascript global scope
|
||||
* Only one copy of Pyodide can be loaded in a given JavaScript global scope
|
||||
* because Pyodide uses global variables to load packages. If an attempt is made
|
||||
* to load a second copy of Pyodide, :any:`loadPyodide` will throw an error.
|
||||
* (This can be fixed once `Firefox adopts support for ES6 modules in webworkers
|
||||
|
|
|
@ -12,22 +12,22 @@ __name__ = "pyodide"
|
|||
# From jsproxy.c
|
||||
class JsException(Exception):
|
||||
"""
|
||||
A wrapper around a Javascript Error to allow it to be thrown in Python.
|
||||
A wrapper around a JavaScript Error to allow it to be thrown in Python.
|
||||
See :ref:`type-translations-errors`.
|
||||
"""
|
||||
|
||||
@property
|
||||
def js_error(self) -> "JsProxy":
|
||||
"""The original Javascript error"""
|
||||
"""The original JavaScript error"""
|
||||
return JsProxy()
|
||||
|
||||
|
||||
class ConversionError(Exception):
|
||||
"""An error thrown when conversion between Javascript and Python fails."""
|
||||
"""An error thrown when conversion between JavaScript and Python fails."""
|
||||
|
||||
|
||||
class JsProxy:
|
||||
"""A proxy to make a Javascript object behave like a Python object
|
||||
"""A proxy to make a JavaScript object behave like a Python object
|
||||
|
||||
For more information see the :ref:`type-translations` documentation. In
|
||||
particular, see
|
||||
|
@ -36,16 +36,16 @@ class JsProxy:
|
|||
"""
|
||||
|
||||
def object_entries(self) -> "JsProxy":
|
||||
"The Javascript API ``Object.entries(object)``"
|
||||
"The JavaScript API ``Object.entries(object)``"
|
||||
|
||||
def object_keys(self) -> "JsProxy":
|
||||
"The Javascript API ``Object.keys(object)``"
|
||||
"The JavaScript API ``Object.keys(object)``"
|
||||
|
||||
def object_values(self) -> "JsProxy":
|
||||
"The Javascript API ``Object.values(object)``"
|
||||
"The JavaScript API ``Object.values(object)``"
|
||||
|
||||
def new(self, *args, **kwargs) -> "JsProxy":
|
||||
"""Construct a new instance of the Javascript object"""
|
||||
"""Construct a new instance of the JavaScript object"""
|
||||
|
||||
def to_py(self, *, depth: int = -1) -> Any:
|
||||
"""Convert the :class:`JsProxy` to a native Python object as best as
|
||||
|
@ -61,7 +61,7 @@ class JsProxy:
|
|||
"""The ``Promise.then`` API, wrapped to manage the lifetimes of the
|
||||
handlers.
|
||||
|
||||
Present only 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
|
||||
when the promise resolves.
|
||||
"""
|
||||
|
@ -70,7 +70,7 @@ class JsProxy:
|
|||
"""The ``Promise.catch`` API, wrapped to manage the lifetimes of the
|
||||
handler.
|
||||
|
||||
Present only 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
|
||||
when the promise resolves.
|
||||
"""
|
||||
|
@ -79,7 +79,7 @@ class JsProxy:
|
|||
"""The ``Promise.finally`` API, wrapped to manage the lifetimes of
|
||||
the handler.
|
||||
|
||||
Present only 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
|
||||
when the promise resolves. Note the trailing underscore in the name;
|
||||
this is needed because ``finally`` is a reserved keyword in Python.
|
||||
|
@ -93,18 +93,18 @@ class JsProxy:
|
|||
# Argument should be a buffer.
|
||||
# See https://github.com/python/typing/issues/593
|
||||
def assign(self, rhs: Any):
|
||||
"""Assign from a Python buffer into the Javascript buffer.
|
||||
"""Assign from a Python buffer into the JavaScript buffer.
|
||||
|
||||
Present only if the wrapped Javascript object is an ArrayBuffer or
|
||||
Present only if the wrapped JavaScript object is an ArrayBuffer or
|
||||
an ArrayBuffer view.
|
||||
"""
|
||||
|
||||
# Argument should be a buffer.
|
||||
# See https://github.com/python/typing/issues/593
|
||||
def assign_to(self, to: Any):
|
||||
"""Assign to a Python buffer from the Javascript buffer.
|
||||
"""Assign to a Python buffer from the JavaScript buffer.
|
||||
|
||||
Present only if the wrapped Javascript object is an ArrayBuffer or
|
||||
Present only if the wrapped JavaScript object is an ArrayBuffer or
|
||||
an ArrayBuffer view.
|
||||
"""
|
||||
|
||||
|
@ -113,10 +113,10 @@ class JsProxy:
|
|||
|
||||
|
||||
def create_once_callable(obj: Callable) -> JsProxy:
|
||||
"""Wrap a Python callable in a Javascript function that can be called once.
|
||||
"""Wrap a Python callable in a JavaScript function that can be called once.
|
||||
|
||||
After being called the proxy will decrement the reference count
|
||||
of the Callable. The Javascript function also has a ``destroy`` API that
|
||||
of the Callable. The JavaScript function also has a ``destroy`` API that
|
||||
can be used to release the proxy without calling it.
|
||||
"""
|
||||
return obj # type: ignore
|
||||
|
@ -142,11 +142,11 @@ def to_js(
|
|||
create_pyproxies: bool = True,
|
||||
dict_converter: Callable[[Iterable[JsProxy]], JsProxy] = None,
|
||||
) -> JsProxy:
|
||||
"""Convert the object to Javascript.
|
||||
"""Convert the object to JavaScript.
|
||||
|
||||
This is similar to :any:`PyProxy.toJs`, but for use from Python. If the
|
||||
object would be implicitly translated to Javascript, it will be returned
|
||||
unchanged. If the object cannot be converted into Javascript, this
|
||||
object would be implicitly translated to JavaScript, it will be returned
|
||||
unchanged. If the object cannot be converted into JavaScript, this
|
||||
method will return a :any:`JsProxy` of a :any:`PyProxy`, as if you had
|
||||
used :any:`pyodide.create_proxy`.
|
||||
|
||||
|
@ -162,23 +162,23 @@ def to_js(
|
|||
as infinite. Set this to 1 to do a shallow conversion.
|
||||
|
||||
pyproxies: JsProxy, default = None
|
||||
Should be a Javascript ``Array``. If provided, any ``PyProxies`` generated
|
||||
Should be a JavaScript ``Array``. If provided, any ``PyProxies`` generated
|
||||
will be stored here. You can later use :any:`destroy_proxies` if you want
|
||||
to destroy the proxies from Python (or from Javascript you can just iterate
|
||||
to destroy the proxies from Python (or from JavaScript you can just iterate
|
||||
over the ``Array`` and destroy the proxies).
|
||||
|
||||
create_pyproxies: bool, default=True
|
||||
If you set this to False, :any:`to_js` will raise an error
|
||||
|
||||
dict_converter: Callable[[Iterable[JsProxy]], JsProxy], defauilt = None
|
||||
This converter if provided recieves a (Javascript) iterable of
|
||||
(Javascript) pairs [key, value]. It is expected to return the
|
||||
This converter if provided recieves a (JavaScript) iterable of
|
||||
(JavaScript) pairs [key, value]. It is expected to return the
|
||||
desired result of the dict conversion. Some suggested values for
|
||||
this argument:
|
||||
|
||||
js.Map.new -- similar to the default behavior
|
||||
js.Array.from -- convert to an array of entries
|
||||
js.Object.fromEntries -- convert to a Javascript object
|
||||
js.Object.fromEntries -- convert to a JavaScript object
|
||||
"""
|
||||
return obj
|
||||
|
||||
|
@ -188,7 +188,7 @@ class Promise(JsProxy):
|
|||
|
||||
|
||||
def destroy_proxies(pyproxies: JsProxy):
|
||||
"""Destroy all PyProxies in a Javascript array.
|
||||
"""Destroy all PyProxies in a JavaScript array.
|
||||
|
||||
pyproxies must be a JsProxy of type PyProxy[]. Intended for use with the
|
||||
arrays created from the "pyproxies" argument of :any:`PyProxy.toJs` and
|
||||
|
|
|
@ -34,11 +34,11 @@ class JsFinder(MetaPathFinder):
|
|||
|
||||
def register_js_module(self, name: str, jsproxy):
|
||||
"""
|
||||
Registers ``jsproxy`` as a Javascript module named ``name``. The module
|
||||
Registers ``jsproxy`` as a JavaScript module named ``name``. The module
|
||||
can then be imported from Python using the standard Python import
|
||||
system. If another module by the same name has already been imported,
|
||||
this won't have much effect unless you also delete the imported module
|
||||
from ``sys.modules``. This is called by the javascript API
|
||||
from ``sys.modules``. This is called by the JavaScript API
|
||||
:any:`pyodide.registerJsModule`.
|
||||
|
||||
Parameters
|
||||
|
@ -47,7 +47,7 @@ class JsFinder(MetaPathFinder):
|
|||
Name of js module
|
||||
|
||||
jsproxy : JsProxy
|
||||
Javascript object backing the module
|
||||
JavaScript object backing the module
|
||||
"""
|
||||
if not isinstance(name, str):
|
||||
raise TypeError(
|
||||
|
@ -61,12 +61,12 @@ class JsFinder(MetaPathFinder):
|
|||
|
||||
def unregister_js_module(self, name: str):
|
||||
"""
|
||||
Unregisters a Javascript module with given name that has been previously
|
||||
Unregisters a JavaScript module with given name that has been previously
|
||||
registered with :any:`pyodide.registerJsModule` or
|
||||
:any:`pyodide.register_js_module`. If a Javascript module with that name
|
||||
:any:`pyodide.register_js_module`. If a JavaScript module with that name
|
||||
does not already exist, will raise an error. If the module has already
|
||||
been imported, this won't have much effect unless you also delete the
|
||||
imported module from ``sys.modules``. This is called by the Javascript
|
||||
imported module from ``sys.modules``. This is called by the JavaScript
|
||||
API :any:`pyodide.unregisterJsModule`.
|
||||
|
||||
Parameters
|
||||
|
|
|
@ -174,7 +174,7 @@ class ConsoleFuture(Future):
|
|||
formatted_error : str
|
||||
If the ``Future`` is rejected, this will be filled with a formatted version of
|
||||
the code. This is a convenience that simplifies code and helps to avoid large
|
||||
memory leaks when using from Javascript.
|
||||
memory leaks when using from JavaScript.
|
||||
|
||||
"""
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from _pyodide._importhook import jsfinder
|
|||
def save_state() -> dict:
|
||||
"""Record the current global state.
|
||||
|
||||
This includes which Javascript packages are loaded and the global scope in
|
||||
This includes which JavaScript packages are loaded and the global scope in
|
||||
``__main__.__dict__``. Many loaded modules might have global state, but
|
||||
there is no general way to track it and we don't try to.
|
||||
"""
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
default:
|
||||
throw new Error(`Unexpected type ${ty}`);
|
||||
}
|
||||
// In Javascript, await automatically also awaits any results of
|
||||
// In JavaScript, await automatically also awaits any results of
|
||||
// awaits, so if an async function returns a future, it will await
|
||||
// the inner future too. This is not what we want so we
|
||||
// temporarily put it into a list to protect it.
|
||||
|
|
Loading…
Reference in New Issue