Add a version variable for Pyodide JavaScript Package (#3074)

This commit is contained in:
Gyeongjae Choi 2022-09-13 13:42:05 +09:00 committed by GitHub
parent 6d5de461a5
commit c3a0ddb0c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 60 additions and 15 deletions

View File

@ -67,6 +67,10 @@ substitutions:
{pr}`3015` included in 0.21.2) and if there is a variable in top level scope
called `__dirname` we use that for the `indexURL`.
- {{ Fix }} `loadPyodide` will now raise error when the version of
JavaScript and Python Pyodide package does not match.
{pr}`3074`
### Build System / Package Loading
- New packages: pycryptodomex {pr}`2966`, pycryptodome {pr}`2965`

View File

@ -2,4 +2,5 @@ const API = Module.API;
const Hiwire = {};
const Tests = {};
API.tests = Tests;
API.version = "0.22.0.dev0";
Module.hiwire = Hiwire;

View File

@ -7,6 +7,7 @@ import { loadPackage, loadedPackages } from "./load-package";
import { isPyProxy, PyBuffer, PyProxy, TypedArray } from "./pyproxy.gen";
import { PythonError } from "./error_handling.gen";
import { loadBinaryFile } from "./compat";
import version from "./version";
export { loadPackage, loadedPackages, isPyProxy };
import "./error_handling.gen.js";
@ -29,16 +30,6 @@ export let pyodide_py: PyProxy; // actually defined in loadPyodide (see pyodide.
*/
export let globals: PyProxy; // actually defined in loadPyodide (see pyodide.js)
/**
*
* The Pyodide version.
*
* It can be either the exact release version (e.g. ``0.1.0``), or
* the latest release version followed by the number of commits since, and
* the git hash of the current commit (e.g. ``0.1.0-1-bd84646``).
*/
export let version: string = ""; // actually defined in loadPyodide (see pyodide.js)
/**
* Just like `runPython` except uses a different globals dict and gets
* `eval_code` from `_pyodide` so that it can work before `pyodide` is imported.

View File

@ -11,6 +11,7 @@ import {
} from "./compat";
import { createModule, setStandardStreams, setHomeDirectory } from "./module";
import version from "./version";
import type { PyodideInterface } from "./api.js";
import type { PyProxy, PyProxyDict } from "./pyproxy.gen";
@ -34,6 +35,8 @@ export type {
export type Py2JsResult = any;
export { version };
/**
* A proxy around globals that falls back to checking for a builtin if has or
* get fails to find a global with the given key. Note that this proxy is
@ -144,11 +147,9 @@ function finalizeBootstrap(API: any, config: ConfigType) {
API.pyodide_code = import_module("pyodide.code");
API.pyodide_ffi = import_module("pyodide.ffi");
API.package_loader = import_module("pyodide._package_loader");
API.version = API.pyodide_py.__version__;
// copy some last constants onto public API.
pyodide.pyodide_py = API.pyodide_py;
pyodide.version = API.version;
pyodide.globals = API.globals;
return pyodide;
}
@ -327,6 +328,15 @@ export async function loadPyodide(
throw Module.exited.toThrow;
}
if (API.version !== version) {
throw new Error(
`\
Pyodide version does not match: '${version}' <==> '${API.version}'. \
If you updated the Pyodide version, make sure you also updated the 'indexURL' parameter passed to loadPyodide.\
`
);
}
// Disable further loading of Emscripten file_packager stuff.
Module.locateFile = (path: string) => {
throw new Error("Didn't expect to load any more file_packager files!");
@ -337,6 +347,7 @@ export async function loadPyodide(
Module._pyodide_init();
const pyodide = finalizeBootstrap(API, config);
// API.runPython works starting here.
if (!pyodide.version.includes("dev")) {
// Currently only used in Node to download packages the first time they are
@ -344,7 +355,7 @@ export async function loadPyodide(
API.setCdnUrl(`https://cdn.jsdelivr.net/pyodide/v${pyodide.version}/full/`);
}
await API.packageIndexReady;
if (API.repodata_info.version !== pyodide.version) {
if (API.repodata_info.version !== version) {
throw new Error("Lock file version doesn't match Pyodide version");
}
API.package_loader.init_loaded_packages();

View File

@ -1,3 +1,3 @@
import { loadPyodide } from "./pyodide";
export { loadPyodide };
import { loadPyodide, version } from "./pyodide";
export { loadPyodide, version };
(globalThis as any).loadPyodide = loadPyodide;

10
src/js/version.ts Normal file
View File

@ -0,0 +1,10 @@
/**
*
* The Pyodide version.
*
* The version here follows PEP440 which is different from the one in package.json,
* as we want to compare this with the version of Pyodide Python package without conversion.
*/
const version: string = "0.22.0.dev0";
export default version;

View File

@ -1126,6 +1126,24 @@ def test_home_directory(selenium_standalone_noload):
)
def test_version_variable(selenium):
js_version = selenium.run_js(
"""
return pyodide.version
"""
)
core_version = selenium.run_js(
"""
return pyodide._api.version
"""
)
from pyodide import __version__ as py_version
assert js_version == py_version == core_version
def test_sys_path0(selenium):
selenium.run_js(
"""

View File

@ -64,6 +64,16 @@ PYTHON_TARGETS = [
build_version_pattern(r"version\s*=\s*{{{python_version}}}"),
prerelease=False,
),
Target(
ROOT / "src/js/version.ts",
build_version_pattern('version: string = "{python_version}"'),
prerelease=True,
),
Target(
ROOT / "src/core/pre.js",
build_version_pattern('API.version = "{python_version}"'),
prerelease=True,
),
]
JS_TARGETS = [