Commit bd846468 authored by Michael Droettboom's avatar Michael Droettboom Committed by GitHub

Merge pull request #176 from mdboom/reorganize-public-api

Reorg pyodide ns to separate emscripten details from public API
parents 16b15968 83fa468d
...@@ -139,7 +139,7 @@ build/test.data: $(CPYTHONLIB) ...@@ -139,7 +139,7 @@ build/test.data: $(CPYTHONLIB)
) )
( \ ( \
cd build; \ cd build; \
python $(FILEPACKAGER) test.data --preload ../$(CPYTHONLIB)/test@/lib/python3.7/test --js-output=test.js --export-name=pyodide --exclude \*.wasm.pre --exclude __pycache__ \ python $(FILEPACKAGER) test.data --preload ../$(CPYTHONLIB)/test@/lib/python3.7/test --js-output=test.js --export-name=pyodide._module --exclude \*.wasm.pre --exclude __pycache__ \
) )
uglifyjs build/test.js -o build/test.js uglifyjs build/test.js -o build/test.js
......
...@@ -2,12 +2,6 @@ ...@@ -2,12 +2,6 @@
* The main bootstrap script for loading pyodide. * The main bootstrap script for loading pyodide.
*/ */
// Regexp for validating package name and URI
var package_name_regexp = '[a-z0-9_][a-z0-9_\-]*'
var package_uri_regexp =
new RegExp('^https?://.*?(' + package_name_regexp + ').js$', 'i');
var package_name_regexp = new RegExp('^' + package_name_regexp + '$', 'i');
var languagePluginLoader = new Promise((resolve, reject) => { var languagePluginLoader = new Promise((resolve, reject) => {
// This is filled in by the Makefile to be either a local file or the // This is filled in by the Makefile to be either a local file or the
// deployed location. TODO: This should be done in a less hacky // deployed location. TODO: This should be done in a less hacky
...@@ -16,9 +10,13 @@ var languagePluginLoader = new Promise((resolve, reject) => { ...@@ -16,9 +10,13 @@ var languagePluginLoader = new Promise((resolve, reject) => {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Package loading // Package loading
var packages = undefined;
let loadedPackages = new Array(); let loadedPackages = new Array();
var loadPackagePromise = new Promise((resolve) => resolve()); var loadPackagePromise = new Promise((resolve) => resolve());
// Regexp for validating package name and URI
var package_name_regexp = '[a-z0-9_][a-z0-9_\-]*'
var package_uri_regexp =
new RegExp('^https?://.*?(' + package_name_regexp + ').js$', 'i');
var package_name_regexp = new RegExp('^' + package_name_regexp + '$', 'i');
let _uri_to_package_name = (package_uri) => { let _uri_to_package_name = (package_uri) => {
// Generate a unique package name from URI // Generate a unique package name from URI
...@@ -36,7 +34,7 @@ var languagePluginLoader = new Promise((resolve, reject) => { ...@@ -36,7 +34,7 @@ var languagePluginLoader = new Promise((resolve, reject) => {
let _loadPackage = (names) => { let _loadPackage = (names) => {
// DFS to find all dependencies of the requested packages // DFS to find all dependencies of the requested packages
let packages = window.pyodide.packages.dependencies; let packages = window.pyodide._module.packages.dependencies;
let queue = [].concat(names || []); let queue = [].concat(names || []);
let toLoad = new Array(); let toLoad = new Array();
while (queue.length) { while (queue.length) {
...@@ -86,12 +84,12 @@ var languagePluginLoader = new Promise((resolve, reject) => { ...@@ -86,12 +84,12 @@ var languagePluginLoader = new Promise((resolve, reject) => {
resolve('No new packages to load'); resolve('No new packages to load');
} }
pyodide.monitorRunDependencies = (n) => { window.pyodide._module.monitorRunDependencies = (n) => {
if (n === 0) { if (n === 0) {
for (let package in toLoad) { for (let package in toLoad) {
loadedPackages[package] = toLoad[package]; loadedPackages[package] = toLoad[package];
} }
delete pyodide.monitorRunDependencies; delete window.pyodide._module.monitorRunDependencies;
const packageList = Array.from(Object.keys(toLoad)).join(', '); const packageList = Array.from(Object.keys(toLoad)).join(', ');
resolve(`Loaded ${packageList}`); resolve(`Loaded ${packageList}`);
} }
...@@ -130,6 +128,8 @@ var languagePluginLoader = new Promise((resolve, reject) => { ...@@ -130,6 +128,8 @@ var languagePluginLoader = new Promise((resolve, reject) => {
return loadPackagePromise; return loadPackagePromise;
}; };
////////////////////////////////////////////////////////////
// Fix Python recursion limit
function fixRecursionLimit(pyodide) { function fixRecursionLimit(pyodide) {
// The Javascript/Wasm call stack may be too small to handle the default // The Javascript/Wasm call stack may be too small to handle the default
// Python call stack limit of 1000 frames. This is generally the case on // Python call stack limit of 1000 frames. This is generally the case on
...@@ -156,6 +156,24 @@ var languagePluginLoader = new Promise((resolve, reject) => { ...@@ -156,6 +156,24 @@ var languagePluginLoader = new Promise((resolve, reject) => {
`import sys; sys.setrecursionlimit(int(${recursionLimit}))`); `import sys; sys.setrecursionlimit(int(${recursionLimit}))`);
}; };
////////////////////////////////////////////////////////////
// Rearrange namespace for public API
let PUBLIC_API = [
'loadPackage',
'pyimport',
'repr',
'runPython',
'version',
];
function makePublicAPI(module, public_api) {
var namespace = {_module : module};
for (let name of public_api) {
namespace[name] = module[name];
}
return namespace;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Loading Pyodide // Loading Pyodide
let wasmURL = `${baseURL}pyodide.asm.wasm`; let wasmURL = `${baseURL}pyodide.asm.wasm`;
...@@ -184,8 +202,9 @@ var languagePluginLoader = new Promise((resolve, reject) => { ...@@ -184,8 +202,9 @@ var languagePluginLoader = new Promise((resolve, reject) => {
fetch(`${baseURL}packages.json`) fetch(`${baseURL}packages.json`)
.then((response) => response.json()) .then((response) => response.json())
.then((json) => { .then((json) => {
window.pyodide.packages = json; fixRecursionLimit(window.pyodide);
fixRecursionLimit(pyodide); window.pyodide = makePublicAPI(window.pyodide, PUBLIC_API);
window.pyodide._module.packages = json;
resolve(); resolve();
}); });
}; };
...@@ -209,6 +228,9 @@ var languagePluginLoader = new Promise((resolve, reject) => { ...@@ -209,6 +228,9 @@ var languagePluginLoader = new Promise((resolve, reject) => {
let script = document.createElement('script'); let script = document.createElement('script');
script.src = `${baseURL}pyodide.asm.js`; script.src = `${baseURL}pyodide.asm.js`;
script.onload = () => { script.onload = () => {
// The emscripten module needs to be at this location for the core
// filesystem to install itself. Once that's complete, it will be replaced
// by the call to `makePublicAPI` with a more limited public API.
window.pyodide = pyodide(Module); window.pyodide = pyodide(Module);
window.pyodide.loadPackage = loadPackage; window.pyodide.loadPackage = loadPackage;
}; };
...@@ -231,7 +253,8 @@ var languagePluginLoader = new Promise((resolve, reject) => { ...@@ -231,7 +253,8 @@ var languagePluginLoader = new Promise((resolve, reject) => {
// Add a custom output handler for Python objects // Add a custom output handler for Python objects
window.iodide.addOutputHandler({ window.iodide.addOutputHandler({
shouldHandle : (val) => { shouldHandle : (val) => {
return (typeof val === 'function' && pyodide.PyProxy.isPyProxy(val)); return (typeof val === 'function' &&
pyodide._module.PyProxy.isPyProxy(val));
}, },
render : (val) => { render : (val) => {
......
...@@ -143,10 +143,10 @@ def test_typed_arrays(selenium, wasm_heap, jstype, pytype): ...@@ -143,10 +143,10 @@ def test_typed_arrays(selenium, wasm_heap, jstype, pytype):
else: else:
selenium.run_js( selenium.run_js(
f""" f"""
var buffer = pyodide._malloc( var buffer = pyodide._module._malloc(
4 * {jstype}.BYTES_PER_ELEMENT); 4 * {jstype}.BYTES_PER_ELEMENT);
window.array = new {jstype}( window.array = new {jstype}(
pyodide.HEAPU8.buffer, buffer, 4); pyodide._module.HEAPU8.buffer, buffer, 4);
window.array[0] = 1; window.array[0] = 1;
window.array[1] = 2; window.array[1] = 2;
window.array[2] = 3; window.array[2] = 3;
......
...@@ -129,7 +129,7 @@ def package_files(buildpath, srcpath, pkg, args): ...@@ -129,7 +129,7 @@ def package_files(buildpath, srcpath, pkg, args):
'--preload', '--preload',
'{}@/'.format(install_prefix), '{}@/'.format(install_prefix),
'--js-output={}'.format(name + '.js'), '--js-output={}'.format(name + '.js'),
'--export-name=pyodide', '--export-name=pyodide._module',
'--exclude', '*.wasm.pre', '--exclude', '*.wasm.pre',
'--exclude', '__pycache__', '--exclude', '__pycache__',
'--use-preload-plugins'], '--use-preload-plugins'],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment