MAINT Separate some things out of Module (#2144)

This commit is contained in:
Hood Chatham 2022-01-30 11:08:44 -08:00 committed by GitHub
parent 42cd4a49b7
commit 391c43e662
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 151 additions and 135 deletions

View File

@ -152,9 +152,13 @@ lint: node_modules/.installed
packages/micropip/src/
# Format checks
find src -type f -regex '.*\.\(c\|h\)' \
| xargs clang-format-6.0 -output-replacements-xml \
| (! grep '<replacement ')
for file in src/core/*.c src/core/*.h ; do \
clang-format-6.0 -output-replacements-xml $$file | grep '<replacement ' > /dev/null ; \
if [ $$? -eq 0 ] ; then \
echo clang-format errors for $$file ; \
exit 1 ; \
fi ; \
done
npx prettier --check .
black --check .

View File

@ -87,7 +87,8 @@ export MAIN_MODULE_LDFLAGS= $(LDFLAGS_BASE) \
--exclude-file "*__pycache__*" \
--exclude-file "*/test/*" \
--exclude-file "*/tests/*" \
--exclude-file "*/distutils/*"
--exclude-file "*/distutils/*" \
--pre-js src/core/pre.js
export SIDE_MODULE_CXXFLAGS = $(CXXFLAGS_BASE)

View File

@ -152,7 +152,7 @@ class SeleniumWrapper:
let pyodide = await loadPyodide({ indexURL : './', fullStdLib: false, jsglobals : self });
self.pyodide = pyodide;
globalThis.pyodide = pyodide;
pyodide._module.inTestHoist = true; // improve some error messages for tests
pyodide._api.inTestHoist = true; // improve some error messages for tests
"""
)
@ -170,11 +170,11 @@ class SeleniumWrapper:
pyodide.pyodide_py.register_js_module;
pyodide.pyodide_py.unregister_js_module;
pyodide.pyodide_py.find_imports;
pyodide._module.importlib.invalidate_caches;
pyodide._module.package_loader.unpack_buffer;
pyodide._module.package_loader.get_dynlibs;
pyodide._module._util_module = pyodide.pyimport("pyodide._util");
pyodide._module._util_module.unpack_buffer_archive;
pyodide._api.importlib.invalidate_caches;
pyodide._api.package_loader.unpack_buffer;
pyodide._api.package_loader.get_dynlibs;
pyodide._api._util_module = pyodide.pyimport("pyodide._util");
pyodide._api._util_module.unpack_buffer_archive;
pyodide.runPython("");
"""
)
@ -274,19 +274,19 @@ class SeleniumWrapper:
@property
def force_test_fail(self) -> bool:
return self.run_js("return !!pyodide._module.fail_test;")
return self.run_js("return !!pyodide._api.fail_test;")
def clear_force_test_fail(self):
self.run_js("pyodide._module.fail_test = false;")
self.run_js("pyodide._api.fail_test = false;")
def save_state(self):
self.run_js("self.__savedState = pyodide._module.saveState();")
self.run_js("self.__savedState = pyodide._api.saveState();")
def restore_state(self):
self.run_js(
"""
if(self.__savedState){
pyodide._module.restoreState(self.__savedState)
pyodide._api.restoreState(self.__savedState)
}
"""
)

View File

@ -35,7 +35,7 @@ else:
WHEEL_BASE = Path(tempfile.mkdtemp())
if IN_BROWSER:
BUILTIN_PACKAGES = pyodide_js._module.packages.to_py()
BUILTIN_PACKAGES = pyodide_js._api.packages.to_py()
else:
BUILTIN_PACKAGES = {}

View File

@ -83,7 +83,7 @@ def run_in_pyodide(
eval_code.callKwargs(
{{
source : atob({encoded}.join("")),
globals : pyodide._module.globals,
globals : pyodide._api.globals,
filename : {filename!r}
}}
);

View File

@ -46,8 +46,7 @@ set_error(PyObject* err)
* err - The error object
*/
EM_JS_REF(JsRef, new_error, (const char* msg, PyObject* err), {
return Module.hiwire.new_value(
new Module.PythonError(UTF8ToString(msg), err));
return Module.hiwire.new_value(new API.PythonError(UTF8ToString(msg), err));
});
/**
@ -130,7 +129,7 @@ finally:
return success;
}
EM_JS(void, fail_test, (), { Module.fail_test = true; })
EM_JS(void, fail_test, (), { API.fail_test = true; })
/**
* Calls traceback.format_exception(type, value, traceback) and joins the
@ -217,7 +216,7 @@ EM_JS(void, log_python_error, (JsRef jserror), {
let msg = Module.hiwire.get_value(jserror).message;
console.warn("Python exception:\n" + msg + "\n");
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
}
});

View File

@ -1,5 +1,5 @@
import ErrorStackParser from "error-stack-parser";
import { Module } from "./module.js";
import { Module, API } from "./module.js";
function isPyodideFrame(frame: ErrorStackParser.StackFrame): boolean {
const fileName = frame.fileName || "";
@ -16,7 +16,7 @@ function isPyodideFrame(frame: ErrorStackParser.StackFrame): boolean {
if (funcName.startsWith("Object.")) {
funcName = funcName.slice("Object.".length);
}
if (funcName in Module.public_api && funcName !== "PythonError") {
if (funcName in API.public_api && funcName !== "PythonError") {
frame.functionName = funcName;
return false;
}
@ -42,7 +42,7 @@ Module.handle_js_error = function (e: any) {
return;
}
let restored_error = false;
if (e instanceof Module.PythonError) {
if (e instanceof API.PythonError) {
// Try to restore the original Python exception.
restored_error = Module._restore_sys_last_exception(e.__error_address);
}
@ -114,7 +114,7 @@ export class PythonError extends Error {
this.__error_address = error_address;
}
}
Module.PythonError = PythonError;
API.PythonError = PythonError;
// A special marker. If we call a CPython API from an EM_JS function and the
// CPython API sets an error, we might want to return an error status back to
// C keeping the current Python error flag. This signals to the EM_JS wrappers
@ -122,7 +122,7 @@ Module.PythonError = PythonError;
// appropriate error value (either NULL or -1).
class _PropagatePythonError extends Error {
constructor() {
Module.fail_test = true;
API.fail_test = true;
super(
"If you are seeing this message, an internal Pyodide error has " +
"occurred. Please report it to the Pyodide maintainers."

View File

@ -106,7 +106,7 @@ EM_JS_NUM(int, hiwire_init, (), {
Module.hiwire.get_value = function(idval)
{
if (!idval) {
Module.fail_test = true;
API.fail_test = true;
// clang-format off
// This might have happened because the error indicator is set. Let's
// check.
@ -627,7 +627,7 @@ EM_JS(bool, hiwire_get_bool, (JsRef idobj), {
});
EM_JS(bool, hiwire_is_pyproxy, (JsRef idobj), {
return Module.isPyProxy(Module.hiwire.get_value(idobj));
return API.isPyProxy(Module.hiwire.get_value(idobj));
});
EM_JS(bool, hiwire_is_function, (JsRef idobj), {
@ -638,7 +638,7 @@ EM_JS(bool, hiwire_is_function, (JsRef idobj), {
EM_JS(bool, hiwire_is_comlink_proxy, (JsRef idobj), {
let value = Module.hiwire.get_value(idobj);
return !!(Module.Comlink && value[Module.Comlink.createEndpoint]);
return !!(API.Comlink && value[API.Comlink.createEndpoint]);
});
EM_JS(bool, hiwire_is_error, (JsRef idobj), {

View File

@ -113,7 +113,7 @@ JS_FILE(js2python_init, () => {
return __js2python_true();
} else if (value === false) {
return __js2python_false();
} else if (Module.isPyProxy(value)) {
} else if (API.isPyProxy(value)) {
return __js2python_pyproxy(Module.PyProxy_getPtr(value));
}
return undefined;

View File

@ -1176,7 +1176,7 @@ EM_JS_REF(JsRef, get_async_js_call_done_callback, (JsRef proxies_id), {
for (let px of proxies) {
Module.pyproxy_destroy(px, msg);
}
if (Module.isPyProxy(result)) {
if (API.isPyProxy(result)) {
Module.pyproxy_destroy(result, msg);
}
});

View File

@ -13,8 +13,8 @@ pyodide_callback(void)
if (callback_clock == 0) {
callback_clock = 50;
int interrupt_buffer = EM_ASM_INT({
let result = Module.interrupt_buffer[0];
Module.interrupt_buffer[0] = 0;
let result = API.interrupt_buffer[0];
API.interrupt_buffer[0] = 0;
return result;
});
if (interrupt_buffer == 2) {

View File

@ -158,7 +158,7 @@ pyodide_init(void)
if (_pyodide_proxy == NULL) {
FATAL_ERROR("Failed to create _pyodide proxy.");
}
EM_ASM({ Module._pyodide = Module.hiwire.pop_value($0); }, _pyodide_proxy);
EM_ASM({ API._pyodide = Module.hiwire.pop_value($0); }, _pyodide_proxy);
Py_CLEAR(_pyodide);
Py_CLEAR(core_module);

1
src/core/pre.js Normal file
View File

@ -0,0 +1 @@
let API = Module.API;

View File

@ -22,7 +22,7 @@ EM_JS(int, pyproxy_Check, (JsRef x), {
return false;
}
let val = Module.hiwire.get_value(x);
return Module.isPyProxy(val);
return API.isPyProxy(val);
});
EM_JS(void, destroy_proxies, (JsRef proxies_id, char* msg_ptr), {

View File

@ -14,7 +14,7 @@
* See Makefile recipe for src/js/pyproxy.gen.ts
*/
import { Module } from "./module.js";
import { Module, API } from "./module.js";
// pyodide-skip
@ -50,7 +50,7 @@ declare function DEREF_U32(ptr: number, offset: number): number;
export function isPyProxy(jsobj: any): jsobj is PyProxy {
return !!jsobj && jsobj.$$ !== undefined && jsobj.$$.type === "PyProxy";
}
Module.isPyProxy = isPyProxy;
API.isPyProxy = isPyProxy;
if (globalThis.FinalizationRegistry) {
Module.finalizationRegistry = new FinalizationRegistry(([ptr, cache]) => {
@ -61,7 +61,7 @@ if (globalThis.FinalizationRegistry) {
} catch (e) {
// I'm not really sure what happens if an error occurs inside of a
// finalizer...
Module.fatal_error(e);
API.fatal_error(e);
}
});
// For some unclear reason this code screws up selenium FirefoxDriver. Works
@ -73,7 +73,7 @@ if (globalThis.FinalizationRegistry) {
// Module._PyBuffer_Release(ptr);
// Module._PyMem_Free(ptr);
// } catch (e) {
// Module.fatal_error(e);
// API.fatal_error(e);
// }
// });
} else {
@ -267,7 +267,7 @@ Module.pyproxy_destroy = function (proxy: PyProxy, destroyed_msg: string) {
Module._Py_DecRef(ptrobj);
trace_pyproxy_dealloc(proxy);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
}
};
@ -296,7 +296,7 @@ Module.callPyObjectKwargs = function (ptrobj: number, ...jsargs: any) {
num_kwargs
);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
} finally {
Module.hiwire.decref(idargs);
Module.hiwire.decref(idkwnames);
@ -357,7 +357,7 @@ export class PyProxyClass {
try {
jsref_repr = Module.__pyproxy_repr(ptrobj);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
}
if (jsref_repr === 0) {
Module._pythonexc2js();
@ -448,7 +448,7 @@ export class PyProxyClass {
dict_converter_id
);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
} finally {
Module.hiwire.decref(proxies_id);
Module.hiwire.decref(dict_converter_id);
@ -540,7 +540,7 @@ export class PyProxyLengthMethods {
try {
length = Module._PyObject_Size(ptrobj);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
}
if (length === -1) {
Module._pythonexc2js();
@ -569,7 +569,7 @@ export class PyProxyGetItemMethods {
try {
idresult = Module.__pyproxy_getitem(ptrobj, idkey);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
} finally {
Module.hiwire.decref(idkey);
}
@ -604,7 +604,7 @@ export class PyProxySetItemMethods {
try {
errcode = Module.__pyproxy_setitem(ptrobj, idkey, idval);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
} finally {
Module.hiwire.decref(idkey);
Module.hiwire.decref(idval);
@ -627,7 +627,7 @@ export class PyProxySetItemMethods {
try {
errcode = Module.__pyproxy_delitem(ptrobj, idkey);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
} finally {
Module.hiwire.decref(idkey);
}
@ -657,7 +657,7 @@ export class PyProxyContainsMethods {
try {
result = Module.__pyproxy_contains(ptrobj, idkey);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
} finally {
Module.hiwire.decref(idkey);
}
@ -691,7 +691,7 @@ function* iter_helper(iterptr: number, token: {}): Generator<Py2JsResult> {
yield Module.hiwire.pop_value(item);
}
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
} finally {
Module.finalizationRegistry.unregister(token);
Module._Py_DecRef(iterptr);
@ -725,7 +725,7 @@ export class PyProxyIterableMethods {
try {
iterptr = Module._PyObject_GetIter(ptrobj);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
}
if (iterptr === 0) {
Module._pythonexc2js();
@ -777,7 +777,7 @@ export class PyProxyIteratorMethods {
idresult = Module.__pyproxyGen_FetchStopIterationValue();
}
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
} finally {
Module.hiwire.decref(idarg);
}
@ -800,7 +800,7 @@ function python_hasattr(jsobj: PyProxyClass, jskey: any) {
try {
result = Module.__pyproxy_hasattr(ptrobj, idkey);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
} finally {
Module.hiwire.decref(idkey);
}
@ -821,7 +821,7 @@ function python_getattr(jsobj: PyProxyClass, jskey: any) {
try {
idresult = Module.__pyproxy_getattr(ptrobj, idkey, cacheId);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
} finally {
Module.hiwire.decref(idkey);
}
@ -841,7 +841,7 @@ function python_setattr(jsobj: PyProxyClass, jskey: any, jsval: any) {
try {
errcode = Module.__pyproxy_setattr(ptrobj, idkey, idval);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
} finally {
Module.hiwire.decref(idkey);
Module.hiwire.decref(idval);
@ -858,7 +858,7 @@ function python_delattr(jsobj: PyProxyClass, jskey: any) {
try {
errcode = Module.__pyproxy_delattr(ptrobj, idkey);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
} finally {
Module.hiwire.decref(idkey);
}
@ -947,7 +947,7 @@ let PyProxyHandlers = {
try {
idresult = Module.__pyproxy_ownKeys(ptrobj);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
}
if (idresult === 0) {
Module._pythonexc2js();
@ -996,7 +996,7 @@ export class PyProxyAwaitableMethods {
reject_handle_id
);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
} finally {
Module.hiwire.decref(reject_handle_id);
Module.hiwire.decref(resolve_handle_id);
@ -1183,7 +1183,7 @@ export class PyProxyBufferMethods {
try {
errcode = Module.__pyproxy_get_buffer(buffer_struct_ptr, this_ptr);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
}
if (errcode === -1) {
Module._pythonexc2js();
@ -1277,7 +1277,7 @@ export class PyProxyBufferMethods {
Module._PyBuffer_Release(view_ptr);
Module._PyMem_Free(view_ptr);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
}
}
}
@ -1465,7 +1465,7 @@ export class PyBuffer {
Module._PyBuffer_Release(this._view_ptr);
Module._PyMem_Free(this._view_ptr);
} catch (e) {
Module.fatal_error(e);
API.fatal_error(e);
}
this._released = true;
this.data = null;

View File

@ -1,4 +1,4 @@
import { Module } from "./module.js";
import { Module, API } from "./module.js";
import { loadPackage, loadedPackages } from "./load-package";
import {
isPyProxy,
@ -52,11 +52,11 @@ export let version: string = ""; // actually defined in loadPyodide (see pyodide
*/
export function runPython(
code: string,
globals: PyProxy = Module.globals
globals: PyProxy = API.globals
): Py2JsResult {
return Module.pyodide_py.eval_code(code, globals);
return API.pyodide_py.eval_code(code, globals);
}
Module.runPython = runPython;
API.runPython = runPython;
/**
* Inspect a Python code chunk and use :js:func:`pyodide.loadPackage` to install
@ -84,7 +84,7 @@ export async function loadPackagesFromImports(
messageCallback?: (msg: string) => void,
errorCallback?: (err: string) => void
) {
let pyimports = Module.pyodide_py.find_imports(code);
let pyimports = API.pyodide_py.find_imports(code);
let imports;
try {
imports = pyimports.toJs();
@ -95,7 +95,7 @@ export async function loadPackagesFromImports(
return;
}
let packageNames = Module._import_name_to_package_name;
let packageNames = API._import_name_to_package_name;
let packages: Set<string> = new Set();
for (let name of imports) {
if (packageNames.has(name)) {
@ -140,11 +140,11 @@ export async function loadPackagesFromImports(
*/
export async function runPythonAsync(
code: string,
globals: PyProxy = Module.globals
globals: PyProxy = API.globals
): Promise<Py2JsResult> {
return await Module.pyodide_py.eval_code_async(code, globals);
return await API.pyodide_py.eval_code_async(code, globals);
}
Module.runPythonAsync = runPythonAsync;
API.runPythonAsync = runPythonAsync;
/**
* Registers the JavaScript object ``module`` as a JavaScript module named
@ -158,7 +158,7 @@ Module.runPythonAsync = runPythonAsync;
* @param module JavaScript object backing the module
*/
export function registerJsModule(name: string, module: object) {
Module.pyodide_py.register_js_module(name, module);
API.pyodide_py.register_js_module(name, module);
}
/**
@ -166,7 +166,7 @@ export function registerJsModule(name: string, module: object) {
* Necessary to enable importing Comlink proxies into Python.
*/
export function registerComlink(Comlink: any) {
Module._Comlink = Comlink;
API._Comlink = Comlink;
}
/**
@ -181,7 +181,7 @@ export function registerComlink(Comlink: any) {
* @param name Name of the JavaScript module to remove
*/
export function unregisterJsModule(name: string) {
Module.pyodide_py.unregister_js_module(name);
API.pyodide_py.unregister_js_module(name);
}
/**
@ -213,7 +213,7 @@ export function toPy(
case "undefined":
return obj;
}
if (!obj || Module.isPyProxy(obj)) {
if (!obj || API.isPyProxy(obj)) {
return obj;
}
let obj_id = 0;
@ -272,7 +272,7 @@ export function toPy(
* @returns A PyProxy for the imported module
*/
export function pyimport(mod_name: string): PyProxy {
return Module.importlib.import_module(mod_name);
return API.importlib.import_module(mod_name);
}
/**
@ -290,10 +290,10 @@ export function unpackArchive(
format: string,
extract_dir?: string
) {
if (!Module._util_module) {
Module._util_module = pyimport("pyodide._util");
if (!API._util_module) {
API._util_module = pyimport("pyodide._util");
}
Module._util_module.unpack_buffer_archive.callKwargs(buffer, {
API._util_module.unpack_buffer_archive.callKwargs(buffer, {
format,
extract_dir,
});
@ -302,13 +302,12 @@ export function unpackArchive(
/**
* @private
*/
Module.saveState = () => Module.pyodide_py._state.save_state();
API.saveState = () => API.pyodide_py._state.save_state();
/**
* @private
*/
Module.restoreState = (state: any) =>
Module.pyodide_py._state.restore_state(state);
API.restoreState = (state: any) => API.pyodide_py._state.restore_state(state);
/**
* Sets the interrupt buffer to be `interrupt_buffer`. This is only useful when
@ -318,7 +317,7 @@ Module.restoreState = (state: any) =>
* constant for SIGINT).
*/
export function setInterruptBuffer(interrupt_buffer: TypedArray) {
Module.interrupt_buffer = interrupt_buffer;
API.interrupt_buffer = interrupt_buffer;
Module._set_pyodide_callback(!!interrupt_buffer);
}
@ -331,10 +330,10 @@ export function setInterruptBuffer(interrupt_buffer: TypedArray) {
* during execution of C code.
*/
export function checkInterrupt() {
if (Module.interrupt_buffer[0] === 2) {
Module.interrupt_buffer[0] = 0;
if (API.interrupt_buffer[0] === 2) {
API.interrupt_buffer[0] = 0;
Module._PyErr_SetInterrupt();
Module.runPython("");
API.runPython("");
}
}
@ -405,8 +404,9 @@ export function makePublicAPI(): PyodideInterface {
PythonError,
PyBuffer,
_module: Module,
_api: API,
};
Module.public_api = namespace;
API.public_api = namespace;
return namespace;
}

View File

@ -1,4 +1,4 @@
import { Module } from "./module.js";
import { Module, API } from "./module.js";
import { IN_NODE, nodeFsPromisesMod, _loadBinaryFile } from "./compat.js";
import { PyProxy, isPyProxy } from "./pyproxy.gen";
@ -28,13 +28,13 @@ export async function initializePackageIndex(indexURL: string) {
"Loaded packages.json does not contain the expected key 'packages'."
);
}
Module.packages = package_json.packages;
API.packages = package_json.packages;
// compute the inverted index for imports to package names
Module._import_name_to_package_name = new Map();
for (let name of Object.keys(Module.packages)) {
for (let import_name of Module.packages[name].imports) {
Module._import_name_to_package_name.set(import_name, name);
API._import_name_to_package_name = new Map();
for (let name of Object.keys(API.packages)) {
for (let import_name of API.packages[name].imports) {
API._import_name_to_package_name.set(import_name, name);
}
}
}
@ -71,7 +71,7 @@ function addPackageToLoad(
if (toLoad.has(name)) {
return;
}
const pkg_info = Module.packages[name];
const pkg_info = API.packages[name];
if (!pkg_info) {
throw new Error(`No known package with name '${name}'`);
}
@ -144,10 +144,10 @@ async function downloadPackage(
): Promise<Uint8Array> {
let file_name;
if (channel === DEFAULT_CHANNEL) {
if (!(name in Module.packages)) {
if (!(name in API.packages)) {
throw new Error(`Internal error: no entry for package named ${name}`);
}
file_name = Module.packages[name].file_name;
file_name = API.packages[name].file_name;
} else {
file_name = channel;
}
@ -161,14 +161,19 @@ async function downloadPackage(
* @private
*/
async function installPackage(name: string, buffer: Uint8Array) {
const pkg = Module.packages[name] || {
file_name: ".whl",
install_dir: "site",
shared_library: false,
};
let pkg = API.packages[name];
if (!pkg) {
pkg = {
file_name: ".whl",
install_dir: "site",
shared_library: false,
depends: [],
imports: [] as string[],
};
}
const file_name = pkg.file_name;
// This Python helper function unpacks the buffer and lists out any so files therein.
const dynlibs = Module.package_loader.unpack_buffer(
const dynlibs = API.package_loader.unpack_buffer(
file_name,
buffer,
pkg.install_dir
@ -371,7 +376,7 @@ export async function loadPackage(
// We have to invalidate Python's import caches, or it won't
// see the new files.
Module.importlib.invalidate_caches();
API.importlib.invalidate_caches();
} finally {
releaseLock();
}

View File

@ -10,6 +10,9 @@ Module.noWasmDecoding = false; // we preload wasm using the built in plugin now
Module.preloadedWasm = {};
Module.preRun = [];
export let API: any = {};
Module.API = API;
/**
*
* @param stdin

View File

@ -1,7 +1,7 @@
/**
* The main bootstrap code for loading pyodide.
*/
import { Module, setStandardStreams, setHomeDirectory } from "./module.js";
import { Module, setStandardStreams, setHomeDirectory, API } from "./module.js";
import { loadScript, _loadBinaryFile, initNodeModules } from "./compat.js";
import { initializePackageIndex, loadPackage } from "./load-package.js";
import { makePublicAPI, PyodideInterface } from "./api.js";
@ -31,7 +31,7 @@ export {
*
* @private
*/
Module.dump_traceback = function () {
API.dump_traceback = function () {
const fd_stdout = 1;
Module.__Py_DumpTraceback(fd_stdout, Module._PyGILState_GetThisThreadState());
};
@ -49,7 +49,7 @@ let fatal_error_occurred = false;
* @argument e {Error} The cause of the fatal error.
* @private
*/
Module.fatal_error = function (e: any) {
API.fatal_error = function (e: any) {
if (e.pyodide_fatal_error) {
return;
}
@ -65,7 +65,7 @@ Module.fatal_error = function (e: any) {
"Pyodide has suffered a fatal error. Please report this to the Pyodide maintainers."
);
console.error("The cause of the fatal error was:");
if (Module.inTestHoist) {
if (API.inTestHoist) {
// Test hoist won't print the error object in a useful way so convert it to
// string.
console.error(e.toString());
@ -74,12 +74,12 @@ Module.fatal_error = function (e: any) {
console.error(e);
}
try {
Module.dump_traceback();
for (let key of Object.keys(Module.public_api)) {
API.dump_traceback();
for (let key of Object.keys(API.public_api)) {
if (key.startsWith("_") || key === "version") {
continue;
}
Object.defineProperty(Module.public_api, key, {
Object.defineProperty(API.public_api, key, {
enumerable: true,
configurable: true,
get: () => {
@ -89,8 +89,8 @@ Module.fatal_error = function (e: any) {
},
});
}
if (Module.on_fatal) {
Module.on_fatal(e);
if (API.on_fatal) {
API.on_fatal(e);
}
} catch (err2) {
console.error("Another error occurred while handling the fatal error:");
@ -105,8 +105,8 @@ let runPythonInternal_dict: PyProxy; // Initialized in finalizeBootstrap
* `eval_code` from `_pyodide` so that it can work before `pyodide` is imported.
* @private
*/
Module.runPythonInternal = function (code: string): Py2JsResult {
return Module._pyodide._base.eval_code(code, runPythonInternal_dict);
API.runPythonInternal = function (code: string): Py2JsResult {
return API._pyodide._base.eval_code(code, runPythonInternal_dict);
};
/**
@ -178,20 +178,24 @@ function finalizeBootstrap(config: ConfigType) {
// First make internal dict so that we can use runPythonInternal.
// runPythonInternal uses a separate namespace, so we don't pollute the main
// environment with variables from our setup.
runPythonInternal_dict = Module._pyodide._base.eval_code("{}");
Module.importlib = Module.runPythonInternal("import importlib; importlib");
let import_module = Module.importlib.import_module;
runPythonInternal_dict = API._pyodide._base.eval_code("{}") as PyProxy;
API.importlib = API.runPythonInternal("import importlib; importlib");
let import_module = API.importlib.import_module;
Module.sys = import_module("sys");
Module.sys.path.insert(0, config.homedir);
API.sys = import_module("sys");
API.sys.path.insert(0, config.homedir);
// Set up globals
let globals = Module.runPythonInternal("import __main__; __main__.__dict__");
let builtins = Module.runPythonInternal("import builtins; builtins.__dict__");
Module.globals = wrapPythonGlobals(globals, builtins);
let globals = API.runPythonInternal(
"import __main__; __main__.__dict__"
) as PyProxyDict;
let builtins = API.runPythonInternal(
"import builtins; builtins.__dict__"
) as PyProxyDict;
API.globals = wrapPythonGlobals(globals, builtins);
// Set up key Javascript modules.
let importhook = Module._pyodide._importhook;
let importhook = API._pyodide._importhook;
importhook.register_js_finder();
importhook.register_js_module("js", config.jsglobals);
@ -202,14 +206,14 @@ function finalizeBootstrap(config: ConfigType) {
// already set up before importing pyodide_py to simplify development of
// pyodide_py code (Otherwise it's very hard to keep track of which things
// aren't set up yet.)
Module.pyodide_py = import_module("pyodide");
Module.package_loader = import_module("pyodide._package_loader");
Module.version = Module.pyodide_py.__version__;
API.pyodide_py = import_module("pyodide");
API.package_loader = import_module("pyodide._package_loader");
API.version = API.pyodide_py.__version__;
// copy some last constants onto public API.
pyodide.pyodide_py = Module.pyodide_py;
pyodide.version = Module.version;
pyodide.globals = Module.globals;
pyodide.pyodide_py = API.pyodide_py;
pyodide.version = API.version;
pyodide.globals = API.globals;
return pyodide;
}
@ -292,7 +296,6 @@ export async function loadPyodide(config: {
if (!config.indexURL.endsWith("/")) {
config.indexURL += "/";
}
Module.indexURL = config.indexURL;
await initNodeModules();
let packageIndexReady = initializePackageIndex(config.indexURL);
let pyodide_py_tar_promise = _loadBinaryFile(

View File

@ -150,7 +150,7 @@
term.error(s.trimEnd());
};
term.ready = Promise.resolve();
pyodide._module.on_fatal = async (e) => {
pyodide._api.on_fatal = async (e) => {
term.error(
"Pyodide has suffered a fatal error. Please report this to the Pyodide maintainers."
);

View File

@ -248,7 +248,7 @@ def test_test_unvendoring(selenium_standalone):
assert selenium.run_js(
"""
return pyodide._module.packages['regex'].unvendored_tests;
return pyodide._api.packages['regex'].unvendored_tests;
"""
)

View File

@ -670,11 +670,11 @@ def test_restore_state(selenium):
pyodide.registerJsModule("a", {somefield : 82});
pyodide.registerJsModule("b", { otherfield : 3 });
pyodide.runPython("x = 7; from a import somefield");
let state = pyodide._module.saveState();
let state = pyodide._api.saveState();
pyodide.registerJsModule("c", { thirdfield : 9 });
pyodide.runPython("y = 77; from b import otherfield; import c;");
pyodide._module.restoreState(state);
pyodide._api.restoreState(state);
state.destroy();
"""
)
@ -756,7 +756,7 @@ def test_fatal_error(selenium_standalone):
"""
assertThrows(() => pyodide.runPython, "Error", "Pyodide already fatally failed and can no longer be used.")
assertThrows(() => pyodide.globals, "Error", "Pyodide already fatally failed and can no longer be used.")
assert(() => pyodide._module.runPython("1+1") === 2);
assert(() => pyodide._api.runPython("1+1") === 2);
"""
)

View File

@ -777,8 +777,8 @@ def test_fatal_error(selenium_standalone):
selenium_standalone.run_js(
"""
let fatal_error = false;
let old_fatal_error = pyodide._module.fatal_error;
pyodide._module.fatal_error = (e) => {
let old_fatal_error = pyodide._api.fatal_error;
pyodide._api.fatal_error = (e) => {
fatal_error = true;
throw e;
}
@ -838,7 +838,7 @@ def test_fatal_error(selenium_standalone):
b._view_ptr = 1e10;
expect_fatal(() => b.release());
} finally {
pyodide._module.fatal_error = old_fatal_error;
pyodide._api.fatal_error = old_fatal_error;
}
"""
)