From 73e3898b72bd6e820f03f28db9c45f1e79c1730a Mon Sep 17 00:00:00 2001 From: Roman Yurchak Date: Wed, 19 Sep 2018 18:12:05 +0200 Subject: [PATCH] Load .data files from the same base URL as .js --- src/pyodide.js | 20 ++++++++++++++++++-- test/conftest.py | 5 +++++ test/test_package_loading.py | 14 ++++++++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/pyodide.js b/src/pyodide.js index a0756e67f..06f4318d7 100644 --- a/src/pyodide.js +++ b/src/pyodide.js @@ -35,8 +35,10 @@ var languagePluginLoader = new Promise((resolve, reject) => { let _loadPackage = (names) => { // DFS to find all dependencies of the requested packages let packages = window.pyodide._module.packages.dependencies; + let loadedPackages = window.pyodide.loadedPackages; let queue = [].concat(names || []); let toLoad = new Array(); + window.pyodide._toLoadPackages = toLoad; while (queue.length) { let package_uri = queue.pop(); @@ -87,7 +89,7 @@ var languagePluginLoader = new Promise((resolve, reject) => { window.pyodide._module.monitorRunDependencies = (n) => { if (n === 0) { for (let package in toLoad) { - loadedPackages[package] = toLoad[package]; + window.pyodide.loadedPackages[package] = toLoad[package]; } delete window.pyodide._module.monitorRunDependencies; const packageList = Array.from(Object.keys(toLoad)).join(', '); @@ -195,7 +197,20 @@ var languagePluginLoader = new Promise((resolve, reject) => { return {}; }; - Module.locateFile = (path) => baseURL + path; + Module.locateFile = (path) => { + if ((window.hasOwnProperty('pyodide')) && + (window.pyodide.hasOwnProperty('_toLoadPackages'))) { + // handle packages loaded from custom URLs + let package = path.replace(/\.data$/, ""); + if (package in window.pyodide._toLoadPackages) { + let package_uri = window.pyodide._toLoadPackages[package]; + if (package_uri != 'default channel') { + return package_uri.replace(/\.js$/, ".data"); + }; + }; + }; + return baseURL + path; + }; var postRunPromise = new Promise((resolve, reject) => { Module.postRun = () => { delete window.Module; @@ -232,6 +247,7 @@ var languagePluginLoader = new Promise((resolve, reject) => { // 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.loadedPackages = new Array(); window.pyodide.loadPackage = loadPackage; }; document.head.appendChild(script); diff --git a/test/conftest.py b/test/conftest.py index 081e39c64..c1c340ed5 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -272,6 +272,11 @@ def run_web_server(q, log_filepath): *self.client_address, format_ % args)) + def end_headers(self): + # Enable Cross-Origin Resource Sharing (CORS) + self.send_header('Access-Control-Allow-Origin', '*') + super().end_headers() + Handler.extensions_map['.wasm'] = 'application/wasm' with socketserver.TCPServer(("", 0), Handler) as httpd: diff --git a/test/test_package_loading.py b/test/test_package_loading.py index d4e6e3edb..69a189dc1 100644 --- a/test/test_package_loading.py +++ b/test/test_package_loading.py @@ -11,8 +11,8 @@ def test_load_from_url(selenium_standalone, web_server_secondary): log_main.open('r') as fh_main: # skip existing log lines - fh_main.read() - fh_secondary.read() + fh_main.seek(0, 2) + fh_secondary.seek(0, 2) selenium_standalone.load_package(f"http://{url}:{port}/pyparsing.js") assert "Invalid package name or URI" not in selenium_standalone.logs @@ -32,6 +32,16 @@ def test_load_from_url(selenium_standalone, web_server_secondary): selenium_standalone.run("import numpy as np") +def test_list_loaded_urls(selenium_standalone): + selenium = selenium_standalone + + selenium.load_package('pyparsing') + assert selenium.run_js( + 'return Object.keys(pyodide.loadedPackages)') == ['pyparsing'] + assert selenium.run_js( + "return pyodide.loadedPackages['pyparsing']") == "default channel" + + def test_uri_mismatch(selenium_standalone): selenium_standalone.load_package('pyparsing') selenium_standalone.load_package('http://some_url/pyparsing.js')