Upgrade Pyodide to version 0.28.3
Updated Pyodide from 0.27.5 to 0.28.3, including new binaries, updated micropip to 0.10.1, and changes to type definitions and package metadata. Added new dev dependencies, updated license, and improved type conversion options in ffi.d.ts.
This commit is contained in:
parent
28c987f9a7
commit
73471b397f
|
|
@ -1,5 +1,8 @@
|
|||
// Generated by dts-bundle-generator v8.1.2
|
||||
|
||||
/**
|
||||
* @docgroup pyodide.ffi
|
||||
*/
|
||||
export type TypedArray = Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array;
|
||||
interface PyProxy {
|
||||
[x: string]: any;
|
||||
|
|
@ -37,7 +40,7 @@ declare class PyProxy {
|
|||
get type(): string;
|
||||
/**
|
||||
* Returns `str(o)` (unless `pyproxyToStringRepr: true` was passed to
|
||||
* :js:func:`~globalThis.loadPyodide` in which case it will return `repr(o)`)
|
||||
* :js:func:`~exports.loadPyodide` in which case it will return `repr(o)`)
|
||||
*/
|
||||
toString(): string;
|
||||
/**
|
||||
|
|
@ -71,7 +74,7 @@ declare class PyProxy {
|
|||
* @param options
|
||||
* @return The JavaScript object resulting from the conversion.
|
||||
*/
|
||||
toJs({ depth, pyproxies, create_pyproxies, dict_converter, default_converter, }?: {
|
||||
toJs({ depth, pyproxies, create_pyproxies, dict_converter, default_converter, eager_converter, }?: {
|
||||
/** How many layers deep to perform the conversion. Defaults to infinite */
|
||||
depth?: number;
|
||||
/**
|
||||
|
|
@ -106,6 +109,15 @@ declare class PyProxy {
|
|||
* documentation of :meth:`~pyodide.ffi.to_js`.
|
||||
*/
|
||||
default_converter?: (obj: PyProxy, convert: (obj: PyProxy) => any, cacheConversion: (obj: PyProxy, result: any) => void) => any;
|
||||
/**
|
||||
* Optional callback to convert objects which gets called after ``str``,
|
||||
* ``int``, ``float``, ``bool``, ``None``, and ``JsProxy`` are converted but
|
||||
* *before* any default conversions are applied to standard data structures.
|
||||
*
|
||||
* Its arguments are the same as `dict_converter`.
|
||||
* See the documentation of :meth:`~pyodide.ffi.to_js`.
|
||||
*/
|
||||
eager_converter?: (obj: PyProxy, convert: (obj: PyProxy) => any, cacheConversion: (obj: PyProxy, result: any) => void) => any;
|
||||
}): any;
|
||||
}
|
||||
/**
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "pyodide",
|
||||
"version": "0.27.5",
|
||||
"version": "0.28.3",
|
||||
"description": "The Pyodide JavaScript package",
|
||||
"keywords": [
|
||||
"python",
|
||||
|
|
@ -14,9 +14,10 @@
|
|||
"bugs": {
|
||||
"url": "https://github.com/pyodide/pyodide/issues"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"license": "MPL-2.0",
|
||||
"devDependencies": {
|
||||
"@types/assert": "^1.5.6",
|
||||
"@types/emscripten": "^1.40.1",
|
||||
"@types/expect": "^24.3.0",
|
||||
"@types/mocha": "^9.1.0",
|
||||
"@types/node": "^20.8.4",
|
||||
|
|
@ -25,7 +26,7 @@
|
|||
"chai-as-promised": "^7.1.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"dts-bundle-generator": "^8.1.1",
|
||||
"esbuild": "^0.17.12",
|
||||
"esbuild": "^0.25.0",
|
||||
"express": "^4.17.3",
|
||||
"mocha": "^9.0.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -1,14 +1,5 @@
|
|||
// Generated by dts-bundle-generator v8.1.2
|
||||
|
||||
/**
|
||||
*
|
||||
* The Pyodide version.
|
||||
*
|
||||
* The version here is a Python version, following :pep:`440`. This is different
|
||||
* from the version in ``package.json`` which follows the node package manager
|
||||
* version convention.
|
||||
*/
|
||||
export declare const version: string;
|
||||
interface CanvasInterface {
|
||||
setCanvas2D(canvas: HTMLCanvasElement): void;
|
||||
getCanvas2D(): HTMLCanvasElement | undefined;
|
||||
|
|
@ -35,6 +26,9 @@ declare function setStderr(options?: {
|
|||
write?: (buffer: Uint8Array) => number;
|
||||
isatty?: boolean;
|
||||
}): void;
|
||||
/**
|
||||
* @docgroup pyodide.ffi
|
||||
*/
|
||||
/** @deprecated Use `import type { TypedArray } from "pyodide/ffi"` instead */
|
||||
export type TypedArray = Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array;
|
||||
type FSNode = {
|
||||
|
|
@ -44,7 +38,9 @@ type FSNode = {
|
|||
mode: number;
|
||||
};
|
||||
type FSStream = {
|
||||
tty?: boolean;
|
||||
tty?: {
|
||||
ops: object;
|
||||
};
|
||||
seekable?: boolean;
|
||||
stream_ops: FSStreamOps;
|
||||
node: FSNode;
|
||||
|
|
@ -57,45 +53,107 @@ type FSStreamOpsGen<T> = {
|
|||
read: (a: T, b: Uint8Array, offset: number, length: number, pos: number) => number;
|
||||
write: (a: T, b: Uint8Array, offset: number, length: number, pos: number) => number;
|
||||
};
|
||||
interface FSType {
|
||||
unlink: (path: string) => void;
|
||||
/** @deprecated Use `import type { PyodideFSType } from "pyodide/ffi"` instead */
|
||||
interface PyodideFSType {
|
||||
mkdirTree: (path: string, mode?: number) => void;
|
||||
chdir: (path: string) => void;
|
||||
symlink: (target: string, src: string) => FSNode;
|
||||
createDevice: ((parent: string, name: string, input?: (() => number | null) | null, output?: ((code: number) => void) | null) => FSNode) & {
|
||||
major: number;
|
||||
};
|
||||
closeStream: (fd: number) => void;
|
||||
open: (path: string, flags: string | number, mode?: number) => FSStream;
|
||||
makedev: (major: number, minor: number) => number;
|
||||
mkdev: (path: string, dev: number) => FSNode;
|
||||
filesystems: any;
|
||||
stat: (path: string, dontFollow?: boolean) => any;
|
||||
readdir: (path: string) => string[];
|
||||
isDir: (mode: number) => boolean;
|
||||
isMountpoint: (mode: FSNode) => boolean;
|
||||
lookupPath: (path: string, options?: {
|
||||
follow_mount?: boolean;
|
||||
}) => {
|
||||
node: FSNode;
|
||||
};
|
||||
isFile: (mode: number) => boolean;
|
||||
open: (path: string, flags: string | number, mode?: number) => FSStream;
|
||||
filesystems: any;
|
||||
isMountpoint: (node: FSNode) => boolean;
|
||||
closeStream: (fd: number) => void;
|
||||
registerDevice<T>(dev: number, ops: FSStreamOpsGen<T>): void;
|
||||
writeFile: (path: string, contents: any, o?: {
|
||||
canOwn?: boolean;
|
||||
}) => void;
|
||||
chmod: (path: string, mode: number) => void;
|
||||
utime: (path: string, atime: number, mtime: number) => void;
|
||||
rmdir: (path: string) => void;
|
||||
mount: (type: any, opts: any, mountpoint: string) => any;
|
||||
write: (stream: FSStream, buffer: any, offset: number, length: number, position?: number) => number;
|
||||
close: (stream: FSStream) => void;
|
||||
ErrnoError: {
|
||||
new (errno: number): Error;
|
||||
};
|
||||
registerDevice<T>(dev: number, ops: FSStreamOpsGen<T>): void;
|
||||
syncfs(dir: boolean, oncomplete: (val: void) => void): void;
|
||||
findObject(a: string, dontResolveLastLink?: boolean): any;
|
||||
readFile(a: string): Uint8Array;
|
||||
}
|
||||
type FSType = Omit<typeof FS, "lookupPath"> & PyodideFSType;
|
||||
/**
|
||||
* The lockfile platform info. The ``abi_version`` field is used to check if the
|
||||
* lockfile is compatible with the interpreter. The remaining fields are
|
||||
* informational.
|
||||
*/
|
||||
interface LockfileInfo {
|
||||
/**
|
||||
* Machine architecture. At present, only can be wasm32. Pyodide has no wasm64
|
||||
* build.
|
||||
*/
|
||||
arch: "wasm32";
|
||||
/**
|
||||
* The ABI version is structured as ``yyyy_patch``. For the lockfile to be
|
||||
* compatible with the current interpreter this field must match exactly with
|
||||
* the ABI version of the interpreter.
|
||||
*/
|
||||
abi_version: string;
|
||||
/**
|
||||
* The Emscripten versions for instance, `emscripten_4_0_9`. Different
|
||||
* Emscripten versions have different ABIs so if this changes ``abi_version``
|
||||
* must also change.
|
||||
*/
|
||||
platform: string;
|
||||
/**
|
||||
* The Pyodide version the lockfile was made with. Informational only, has no
|
||||
* compatibility implications. May be removed in the future.
|
||||
*/
|
||||
version: string;
|
||||
/**
|
||||
* The Python version this lock file was made with. If the minor version
|
||||
* changes (e.g, 3.12 to 3.13) this changes the ABI and the ``abi_version``
|
||||
* must change too. Patch versions do not imply a change to the
|
||||
* ``abi_version``.
|
||||
*/
|
||||
python: string;
|
||||
}
|
||||
/**
|
||||
* A package entry in the lock file.
|
||||
*/
|
||||
interface LockfilePackage {
|
||||
/**
|
||||
* The unnormalized name of the package.
|
||||
*/
|
||||
name: string;
|
||||
version: string;
|
||||
/**
|
||||
* The file name or url of the package wheel. If it's relative, it will be
|
||||
* resolved with respect to ``packageBaseUrl``. If there is no
|
||||
* ``packageBaseUrl``, attempting to install a package with a relative
|
||||
* ``file_name`` will fail.
|
||||
*/
|
||||
file_name: string;
|
||||
package_type: PackageType;
|
||||
/**
|
||||
* The installation directory. Will be ``site`` except for certain system
|
||||
* dynamic libraries that need to go on the global LD_LIBRARY_PATH.
|
||||
*/
|
||||
install_dir: "site" | "dynlib";
|
||||
/**
|
||||
* Integrity. Must be present unless ``checkIntegrity: false`` is passed to
|
||||
* ``loadPyodide``.
|
||||
*/
|
||||
sha256: string;
|
||||
/**
|
||||
* The set of imports provided by this package as best we can tell. Used by
|
||||
* :js:func:`pyodide.loadPackagesFromImports` to work out what packages to
|
||||
* install.
|
||||
*/
|
||||
imports: string[];
|
||||
/**
|
||||
* The set of dependencies of this package.
|
||||
*/
|
||||
depends: string[];
|
||||
}
|
||||
/**
|
||||
* The type of a package lockfile.
|
||||
*/
|
||||
interface Lockfile {
|
||||
info: LockfileInfo;
|
||||
packages: Record<string, LockfilePackage>;
|
||||
}
|
||||
type PackageType = "package" | "cpython_module" | "shared_library" | "static_library";
|
||||
interface PackageData {
|
||||
|
|
@ -139,7 +197,7 @@ declare class PyProxy {
|
|||
get type(): string;
|
||||
/**
|
||||
* Returns `str(o)` (unless `pyproxyToStringRepr: true` was passed to
|
||||
* :js:func:`~globalThis.loadPyodide` in which case it will return `repr(o)`)
|
||||
* :js:func:`~exports.loadPyodide` in which case it will return `repr(o)`)
|
||||
*/
|
||||
toString(): string;
|
||||
/**
|
||||
|
|
@ -173,7 +231,7 @@ declare class PyProxy {
|
|||
* @param options
|
||||
* @return The JavaScript object resulting from the conversion.
|
||||
*/
|
||||
toJs({ depth, pyproxies, create_pyproxies, dict_converter, default_converter, }?: {
|
||||
toJs({ depth, pyproxies, create_pyproxies, dict_converter, default_converter, eager_converter, }?: {
|
||||
/** How many layers deep to perform the conversion. Defaults to infinite */
|
||||
depth?: number;
|
||||
/**
|
||||
|
|
@ -208,6 +266,15 @@ declare class PyProxy {
|
|||
* documentation of :meth:`~pyodide.ffi.to_js`.
|
||||
*/
|
||||
default_converter?: (obj: PyProxy, convert: (obj: PyProxy) => any, cacheConversion: (obj: PyProxy, result: any) => void) => any;
|
||||
/**
|
||||
* Optional callback to convert objects which gets called after ``str``,
|
||||
* ``int``, ``float``, ``bool``, ``None``, and ``JsProxy`` are converted but
|
||||
* *before* any default conversions are applied to standard data structures.
|
||||
*
|
||||
* Its arguments are the same as `dict_converter`.
|
||||
* See the documentation of :meth:`~pyodide.ffi.to_js`.
|
||||
*/
|
||||
eager_converter?: (obj: PyProxy, convert: (obj: PyProxy) => any, cacheConversion: (obj: PyProxy, result: any) => void) => any;
|
||||
}): any;
|
||||
}
|
||||
declare class PyProxyWithLength extends PyProxy {
|
||||
|
|
@ -1065,7 +1132,7 @@ declare class PythonError extends Error {
|
|||
type NativeFS = {
|
||||
syncfs: () => Promise<void>;
|
||||
};
|
||||
declare class PyodideAPI {
|
||||
declare class PyodideAPI_ {
|
||||
/** @hidden */
|
||||
static version: string;
|
||||
/** @hidden */
|
||||
|
|
@ -1073,7 +1140,7 @@ declare class PyodideAPI {
|
|||
messageCallback?: (message: string) => void;
|
||||
errorCallback?: (message: string) => void;
|
||||
checkIntegrity?: boolean;
|
||||
}) => Promise<Array<PackageData>>;
|
||||
}) => Promise<PackageData[]>;
|
||||
/** @hidden */
|
||||
static loadedPackages: LoadedPackages;
|
||||
/** @hidden */
|
||||
|
|
@ -1443,16 +1510,38 @@ declare class PyodideAPI {
|
|||
*/
|
||||
static setDebug(debug: boolean): boolean;
|
||||
/**
|
||||
*
|
||||
* @param param0
|
||||
* @returns
|
||||
* @private
|
||||
*/
|
||||
static makeMemorySnapshot({ serializer, }?: {
|
||||
serializer?: (obj: any) => any;
|
||||
}): Uint8Array;
|
||||
/**
|
||||
* Returns the pyodide lockfile used to load the current Pyodide instance.
|
||||
* The format of the lockfile is defined in the `pyodide/pyodide-lock
|
||||
* <https://github.com/pyodide/pyodide-lock>`_ repository.
|
||||
*/
|
||||
static get lockfile(): Lockfile;
|
||||
/**
|
||||
* Returns the URL or path with respect to which relative paths in the lock
|
||||
* file are resolved, or undefined.
|
||||
*/
|
||||
static get lockfileBaseUrl(): string | undefined;
|
||||
}
|
||||
/** @hidden */
|
||||
export type PyodideInterface = typeof PyodideAPI;
|
||||
/**
|
||||
* The return type of :js:func:`~exports.loadPyodide`. See
|
||||
* :ref:`the pyodide api docs <js-api-pyodide>` for more information.
|
||||
* @hidetype
|
||||
* @docgroup exports
|
||||
*/
|
||||
export type PyodideAPI = typeof PyodideAPI_;
|
||||
/**
|
||||
* The Pyodide version.
|
||||
*
|
||||
* The version here is a Python version, following :pep:`440`. This is different
|
||||
* from the version in ``package.json`` which follows the node package manager
|
||||
* version convention.
|
||||
*/
|
||||
export declare const version: string;
|
||||
/**
|
||||
* See documentation for loadPyodide.
|
||||
* @hidden
|
||||
|
|
@ -1460,7 +1549,7 @@ export type PyodideInterface = typeof PyodideAPI;
|
|||
type ConfigType = {
|
||||
indexURL: string;
|
||||
packageCacheDir: string;
|
||||
lockFileURL: string;
|
||||
lockFileContents: Lockfile | string | Promise<Lockfile | string>;
|
||||
fullStdLib?: boolean;
|
||||
stdLibURL?: string;
|
||||
stdin?: () => string;
|
||||
|
|
@ -1480,6 +1569,8 @@ type ConfigType = {
|
|||
enableRunUntilComplete: boolean;
|
||||
checkAPIVersion: boolean;
|
||||
BUILD_ID: string;
|
||||
packageBaseUrl?: string;
|
||||
cdnUrl: string;
|
||||
};
|
||||
/**
|
||||
* Load the main Pyodide wasm module and initialize it.
|
||||
|
|
@ -1520,6 +1611,26 @@ export declare function loadPyodide(options?: {
|
|||
* Default: ```${indexURL}/pyodide-lock.json```
|
||||
*/
|
||||
lockFileURL?: string;
|
||||
/**
|
||||
* The contents of a lockfile. If a string, it should be valid json and
|
||||
* ``JSON.parse()`` should return a ``Lockfile`` instance. See
|
||||
* :js:interface:`~pyodide.Lockfile` for the schema.
|
||||
*/
|
||||
lockFileContents?: Lockfile | string | Promise<Lockfile | string>;
|
||||
/**
|
||||
* The base url relative to which a relative value of
|
||||
* :js:attr:`~pyodide.LockfilePackage.file_name` is interpreted. If
|
||||
* ``lockfileContents`` is provided, then ``lockFileContents`` must be
|
||||
* provided explicitly in order to install packages with relative paths.
|
||||
*
|
||||
* Otherwise, the default is calculated as follows:
|
||||
*
|
||||
* 1. If `lockFileURL` contains a ``/``, the default is everything before the last
|
||||
* ``/`` in ``lockFileURL``.
|
||||
* 2. If in the browser, the default is ``location.toString()``.
|
||||
* 3. Otherwise, the default is `'.'`.
|
||||
*/
|
||||
packageBaseUrl?: string;
|
||||
/**
|
||||
* Load the full Python standard library. Setting this to false excludes
|
||||
* unvendored modules from the standard library.
|
||||
|
|
@ -1596,12 +1707,13 @@ export declare function loadPyodide(options?: {
|
|||
packages?: string[];
|
||||
/**
|
||||
* Opt into the old behavior where :js:func:`PyProxy.toString() <pyodide.ffi.PyProxy.toString>`
|
||||
* calls :py:func:`repr` and not :py:class:`str() <str>`.
|
||||
* calls :py:func:`repr` and not :py:class:`str() <str>`. Deprecated.
|
||||
* @deprecated
|
||||
*/
|
||||
pyproxyToStringRepr?: boolean;
|
||||
/**
|
||||
* Make loop.run_until_complete() function correctly using stack switching
|
||||
* Make loop.run_until_complete() function correctly using stack switching.
|
||||
* Default: ``true``.
|
||||
*/
|
||||
enableRunUntilComplete?: boolean;
|
||||
/**
|
||||
|
|
@ -1618,13 +1730,23 @@ export declare function loadPyodide(options?: {
|
|||
fsInit?: (FS: FSType, info: {
|
||||
sitePackages: string;
|
||||
}) => Promise<void>;
|
||||
/**
|
||||
* Opt into the old behavior where JavaScript `null` is converted to `None`
|
||||
* instead of `jsnull`. Deprecated.
|
||||
* @deprecated
|
||||
*/
|
||||
convertNullToNone?: boolean;
|
||||
/** @ignore */
|
||||
_makeSnapshot?: boolean;
|
||||
/** @ignore */
|
||||
_loadSnapshot?: Uint8Array | ArrayBuffer | PromiseLike<Uint8Array | ArrayBuffer>;
|
||||
/** @ignore */
|
||||
_snapshotDeserializer?: (obj: any) => any;
|
||||
}): Promise<PyodideInterface>;
|
||||
}): Promise<PyodideAPI>;
|
||||
|
||||
export type {
|
||||
PyodideAPI as PyodideInterface,
|
||||
};
|
||||
|
||||
export type {};
|
||||
export type {PackageData};
|
||||
export type {Lockfile, LockfileInfo, LockfilePackage, PackageData};
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if [[ $1 == "-m" ]] && [[ $2 == "pip" ]]; then
|
||||
# redirect python -m pip to execute in host environment
|
||||
shift 2
|
||||
which $(dirname $0)/pip > /dev/null || { \
|
||||
>&2 echo "Cannot find pyodide pip. Make a pyodide venv first?" && exit 1; \
|
||||
}
|
||||
exec $(dirname $0)/pip $@
|
||||
fi
|
||||
|
||||
which node > /dev/null || { \
|
||||
>&2 echo "No node executable found on the path" && exit 1; \
|
||||
}
|
||||
|
||||
ARGS=$(node -e "$(cat <<"EOF"
|
||||
const major_version = Number(process.version.split(".")[0].slice(1));
|
||||
if(major_version < 18) {
|
||||
console.error("Need node version >= 18. Got node version", process.version);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (major_version >= 20) {
|
||||
process.stdout.write("--experimental-wasm-stack-switching");
|
||||
}
|
||||
EOF
|
||||
)")
|
||||
|
||||
# Macs come with FreeBSD coreutils which doesn't have the -s option
|
||||
# so feature detect and work around it.
|
||||
if which grealpath > /dev/null; then
|
||||
# It has brew installed gnu core utils, use that
|
||||
REALPATH="grealpath -s"
|
||||
elif which realpath > /dev/null && realpath --version > /dev/null 2> /dev/null && realpath --version | grep GNU > /dev/null; then
|
||||
# realpath points to GNU realpath so use it.
|
||||
REALPATH="realpath -s"
|
||||
else
|
||||
# Shim for macs without GNU coreutils
|
||||
abs_path () {
|
||||
echo "$(cd "$(dirname "$1")" || exit; pwd)/$(basename "$1")"
|
||||
}
|
||||
REALPATH=abs_path
|
||||
fi
|
||||
|
||||
|
||||
RESOLVED_DIR=$(dirname $(realpath "$0"))
|
||||
|
||||
# Compute our own path, not following symlinks and pass it in so that
|
||||
# node_entry.mjs can set sys.executable correctly.
|
||||
# Intentionally allow word splitting on $NODEFLAGS.
|
||||
exec node $NODEFLAGS $ARGS $RESOLVED_DIR/python_cli_entry.mjs --this-program="$($REALPATH "$0")" "$@"
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
import { loadPyodide } from "./pyodide.mjs";
|
||||
import { readdirSync } from "fs";
|
||||
|
||||
/**
|
||||
* Determine which native top level directories to mount into the Emscripten
|
||||
* file system.
|
||||
*
|
||||
* This is a bit brittle, if the machine has a top level directory with certain
|
||||
* names it is possible this could break. The most surprising one here is tmp, I
|
||||
* am not sure why but if we link tmp then the process silently fails.
|
||||
*/
|
||||
function dirsToMount() {
|
||||
return readdirSync("/")
|
||||
.filter((dir) => !["dev", "lib", "proc"].includes(dir))
|
||||
.map((dir) => "/" + dir);
|
||||
}
|
||||
|
||||
const thisProgramFlag = "--this-program=";
|
||||
const thisProgramIndex = process.argv.findIndex((x) =>
|
||||
x.startsWith(thisProgramFlag),
|
||||
);
|
||||
const args = process.argv.slice(thisProgramIndex + 1);
|
||||
const _sysExecutable = process.argv[thisProgramIndex].slice(
|
||||
thisProgramFlag.length,
|
||||
);
|
||||
|
||||
function fsInit(FS) {
|
||||
const mounts = dirsToMount();
|
||||
for (const mount of mounts) {
|
||||
FS.mkdirTree(mount);
|
||||
FS.mount(FS.filesystems.NODEFS, { root: mount }, mount);
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
let py;
|
||||
try {
|
||||
py = await loadPyodide({
|
||||
args,
|
||||
_sysExecutable,
|
||||
env: Object.assign(
|
||||
{
|
||||
PYTHONINSPECT: "",
|
||||
},
|
||||
process.env,
|
||||
{ HOME: process.cwd() },
|
||||
),
|
||||
fullStdLib: false,
|
||||
fsInit,
|
||||
});
|
||||
} catch (e) {
|
||||
if (e.constructor.name !== "ExitStatus") {
|
||||
throw e;
|
||||
}
|
||||
// If the user passed `--help`, `--version`, or a set of command line
|
||||
// arguments that is invalid in some way, we will exit here.
|
||||
process.exit(e.status);
|
||||
}
|
||||
py.setStdout();
|
||||
py.setStderr();
|
||||
let sideGlobals = py.runPython("{}");
|
||||
function handleExit(code) {
|
||||
if (code === undefined) {
|
||||
code = 0;
|
||||
}
|
||||
if (py._module._Py_FinalizeEx() < 0) {
|
||||
code = 120;
|
||||
}
|
||||
// It's important to call `process.exit` immediately after
|
||||
// `_Py_FinalizeEx` because otherwise any asynchronous tasks still
|
||||
// scheduled will segfault.
|
||||
process.exit(code);
|
||||
}
|
||||
sideGlobals.set("handleExit", handleExit);
|
||||
|
||||
py.runPython(
|
||||
`
|
||||
from pyodide._package_loader import SITE_PACKAGES, should_load_dynlib
|
||||
from pyodide.ffi import to_js
|
||||
import re
|
||||
dynlibs_to_load = to_js([
|
||||
str(path) for path in SITE_PACKAGES.glob("**/*.so*")
|
||||
if should_load_dynlib(path)
|
||||
])
|
||||
`,
|
||||
{ globals: sideGlobals },
|
||||
);
|
||||
const dynlibs = sideGlobals.get("dynlibs_to_load");
|
||||
for (const dynlib of dynlibs) {
|
||||
try {
|
||||
await py._module.API.loadDynlib(dynlib);
|
||||
} catch (e) {
|
||||
console.error("Failed to load lib ", dynlib);
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
py.runPython(
|
||||
`
|
||||
import asyncio
|
||||
# Keep the event loop alive until all tasks are finished, or SystemExit or
|
||||
# KeyboardInterupt is raised.
|
||||
loop = asyncio.get_event_loop()
|
||||
# Make sure we don't run _no_in_progress_handler before we finish _run_main.
|
||||
loop._in_progress += 1
|
||||
loop._no_in_progress_handler = handleExit
|
||||
loop._system_exit_handler = handleExit
|
||||
loop._keyboard_interrupt_handler = lambda: handleExit(130)
|
||||
|
||||
# Make shutil.get_terminal_size tell the terminal size accurately.
|
||||
import shutil
|
||||
from js.process import stdout
|
||||
import os
|
||||
def get_terminal_size(fallback=(80, 24)):
|
||||
columns = getattr(stdout, "columns", None)
|
||||
rows = getattr(stdout, "rows", None)
|
||||
if columns is None:
|
||||
columns = fallback[0]
|
||||
if rows is None:
|
||||
rows = fallback[1]
|
||||
return os.terminal_size((columns, rows))
|
||||
shutil.get_terminal_size = get_terminal_size
|
||||
`,
|
||||
{ globals: sideGlobals },
|
||||
);
|
||||
|
||||
let errcode;
|
||||
try {
|
||||
if (py._module.jspiSupported) {
|
||||
errcode = await py._module.promisingRunMain();
|
||||
} else {
|
||||
errcode = py._module._run_main();
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.constructor.name === "ExitStatus") {
|
||||
process.exit(e.status);
|
||||
}
|
||||
py._api.fatal_error(e);
|
||||
}
|
||||
if (errcode) {
|
||||
process.exit(errcode);
|
||||
}
|
||||
py.runPython("loop._decrement_in_progress()", { globals: sideGlobals });
|
||||
}
|
||||
main().catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
const defaultPyodideUrl = "https://cdn.jsdelivr.net/pyodide/v0.27.7/full/pyodide.js";
|
||||
const defaultPyodideUrl = "https://cdn.jsdelivr.net/pyodide/v0.28.3/full/pyodide.js";
|
||||
|
||||
let _apps = {};
|
||||
let _documentUrl = document.URL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue