mirror of https://github.com/pyodide/pyodide.git
Ensure that package loading runs in sequence
This commit is contained in:
parent
af569129fc
commit
1bd19e3fe4
|
@ -18,6 +18,7 @@ var languagePluginLoader = new Promise((resolve, reject) => {
|
|||
// Package loading
|
||||
var packages = undefined;
|
||||
let loadedPackages = new Array();
|
||||
var loadPackagePromise = new Promise((resolve) => resolve());
|
||||
|
||||
let _uri_to_package_name = (package_uri) => {
|
||||
// Generate a unique package name from URI
|
||||
|
@ -33,7 +34,7 @@ var languagePluginLoader = new Promise((resolve, reject) => {
|
|||
}
|
||||
};
|
||||
|
||||
let loadPackage = (names) => {
|
||||
let _loadPackage = (names) => {
|
||||
// DFS to find all dependencies of the requested packages
|
||||
let packages = window.pyodide.packages.dependencies;
|
||||
let queue = [].concat(names || []);
|
||||
|
@ -121,6 +122,13 @@ var languagePluginLoader = new Promise((resolve, reject) => {
|
|||
return promise;
|
||||
};
|
||||
|
||||
let loadPackage = (names) => {
|
||||
/* We want to make sure that only one loadPackage invocation runs at any
|
||||
* given time, so this creates a "chain" of promises. */
|
||||
loadPackagePromise = loadPackagePromise.then(() => _loadPackage(names));
|
||||
return loadPackagePromise;
|
||||
};
|
||||
|
||||
function fixRecursionLimit(pyodide) {
|
||||
// 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
|
||||
|
|
|
@ -91,12 +91,15 @@ class SeleniumWrapper:
|
|||
return self.driver.execute_script(catch)
|
||||
|
||||
def load_package(self, packages):
|
||||
from selenium.common.exceptions import TimeoutException
|
||||
|
||||
self.run_js(
|
||||
'window.done = false\n' +
|
||||
'pyodide.loadPackage({!r})'.format(packages) +
|
||||
'.then(function() { window.done = true; })')
|
||||
self.wait_until_packages_loaded()
|
||||
|
||||
def wait_until_packages_loaded(self):
|
||||
from selenium.common.exceptions import TimeoutException
|
||||
|
||||
try:
|
||||
self.wait.until(PackageLoaded())
|
||||
except TimeoutException as exc:
|
||||
|
|
|
@ -44,7 +44,29 @@ def test_load_packages_multiple(selenium_standalone, packages):
|
|||
selenium.load_package(packages)
|
||||
selenium.run(f'import {packages[0]}')
|
||||
selenium.run(f'import {packages[1]}')
|
||||
# The long must show that each package is loaded exactly once,
|
||||
# The log must show that each package is loaded exactly once,
|
||||
# including when one package is a dependency of the other
|
||||
# ('pyparsing' and 'matplotlib')
|
||||
assert selenium.logs.count(f'Loading {packages[0]}') == 1
|
||||
assert selenium.logs.count(f'Loading {packages[1]}') == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize('packages', [['pyparsing', 'pytz'],
|
||||
['pyparsing', 'matplotlib']],
|
||||
ids='-'.join)
|
||||
def test_load_packages_sequential(selenium_standalone, packages):
|
||||
selenium = selenium_standalone
|
||||
promises = ','.join(
|
||||
'pyodide.loadPackage("{}")'.format(x) for x in packages
|
||||
)
|
||||
selenium.run_js(
|
||||
'window.done = false\n' +
|
||||
'Promise.all([{}])'.format(promises) +
|
||||
'.then(function() { window.done = true; })')
|
||||
selenium.wait_until_packages_loaded()
|
||||
selenium.run(f'import {packages[0]}')
|
||||
selenium.run(f'import {packages[1]}')
|
||||
# The log must show that each package is loaded exactly once,
|
||||
# including when one package is a dependency of the other
|
||||
# ('pyparsing' and 'matplotlib')
|
||||
assert selenium.logs.count(f'Loading {packages[0]}') == 1
|
||||
|
|
Loading…
Reference in New Issue