Fix package name / import name dichotomy. Add testing.

This commit is contained in:
Michael Droettboom 2018-10-10 14:17:29 -04:00
parent 3498159efb
commit 4124f18d1a
3 changed files with 121 additions and 11 deletions

View File

@ -77,20 +77,31 @@ EM_JS(int, runpython_init_js, (), {
var jsimports = Module.hiwire_get_value(idimports);
Module.hiwire_decref(idimports);
var internal = function() { return Module._runPythonInternal(pycode); };
var internal = function(resolve, reject) {
try {
resolve(Module._runPythonInternal(pycode));
} catch (e) {
reject(e);
}
};
if (jsimports.length) {
var packages = window.pyodide._module.packages.dependencies;
var packageFilter = function(name)
{
return Object.prototype.hasOwnProperty(packages, name);
};
jsimports = jsimports.filter(packageFilter);
return Module.loadPackage(jsimports, messageCallback).then(internal);
} else {
var resolve = function(resolve) { return resolve(); };
return new Promise(resolve).then(internal);
var packageNames = window.pyodide._module.packages.import_name_to_package_name;
var packages = {};
for (var i = 0; i < jsimports.length; ++i) {
var name = jsimports[i];
if (packageNames[name] !== undefined) {
packages[packageNames[name]] = undefined;
}
}
if (Object.keys(packages).length) {
var runInternal = function() {
return new Promise(internal);
};
return Module.loadPackage(Object.keys(packages), messageCallback).then(runInternal);
}
}
return new Promise(internal);
};
});

View File

@ -105,6 +105,35 @@ class SeleniumWrapper:
return self.run_js(
'return pyodide.runPython({!r})'.format(code))
def run_async(self, code):
from selenium.common.exceptions import TimeoutException
if isinstance(code, str) and code.startswith('\n'):
# we have a multiline string, fix indentation
code = textwrap.dedent(code)
self.run_js(
"""
window.done = false;
pyodide.runPythonAsync({!r})
.then(function(output) {{ window.output = output; window.error = false; }},
function(output) {{ window.output = output; window.error = true; }})
.finally(() => window.done = true);
""".format(code)
)
try:
self.wait.until(PackageLoaded())
except TimeoutException as exc:
_display_driver_logs(self.browser, self.driver)
print(self.logs)
raise TimeoutException('runPythonAsync timed out')
return self.run_js(
"""
if (window.error) {
throw window.output;
}
return window.output;
"""
)
def run_js(self, code):
if isinstance(code, str) and code.startswith('\n'):
# we have a multiline string, fix indentation

View File

@ -442,3 +442,73 @@ def test_recursive_dict(selenium_standalone):
"""
)
selenium_standalone.run_js("x = pyodide.pyimport('x')")
def test_runpythonasync(selenium_standalone):
output = selenium_standalone.run_async(
"""
import numpy as np
np.zeros(5)
"""
)
assert list(output) == [0, 0, 0, 0, 0]
def test_runpythonasync_different_package_name(selenium_standalone):
output = selenium_standalone.run_async(
"""
import dateutil
dateutil.__version__
"""
)
assert isinstance(output, str)
def test_runpythonasync_no_imports(selenium_standalone):
output = selenium_standalone.run_async(
"""
42
"""
)
assert output == 42
def test_runpythonasync_missing_import(selenium_standalone):
try:
selenium_standalone.run_async(
"""
import foo
"""
)
except selenium_standalone.JavascriptException as e:
assert "ModuleNotFoundError" in str(e)
else:
assert False
def test_runpythonasync_exception(selenium_standalone):
try:
selenium_standalone.run_async(
"""
42 / 0
"""
)
except selenium_standalone.JavascriptException as e:
assert "ZeroDivisionError" in str(e)
else:
assert False
def test_runpythonasync_exception_after_import(selenium_standalone):
try:
selenium_standalone.run_async(
"""
import numpy as np
x = np.empty(5)
42 / 0
"""
)
except selenium_standalone.JavascriptException as e:
assert "ZeroDivisionError" in str(e)
else:
assert False