Skip to content

Commit da7f603

Browse files
committed
Use _Py_Version to compute Python version for library setup
This requires this upstream fix which came out in Emscripten 3.1.73: emscripten-core/emscripten#23020 Applied upstream in the cpython repo here: https://github.com/python/cpython/pull/127113/files#diff-31f61a127a59386957acba86e9acedf0a96bc6ebe1ac159a48e39b1a291111b5R73-R75 This fixes an error that occurs when building with assertions -- we called `_py_version_major` before the runtime was set up so it triggered an assertion failure.
1 parent 4c9b38b commit da7f603

File tree

8 files changed

+22
-50
lines changed

8 files changed

+22
-50
lines changed

Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ src/core/libpyodide.a: \
9797
src/core/jslib_asm.o \
9898
src/core/python2js.o \
9999
src/core/pyodide_pre.o \
100-
src/core/pyversion.o \
101100
src/core/stack_switching/pystate.o \
102101
src/core/stack_switching/suspenders.o
103102
emar rcs src/core/libpyodide.a $(filter %.o,$^)

Makefile.envs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ EXPORTS=_main \
234234
,__PyTraceback_Add \
235235
,_PyUnicode_Data \
236236
,_PyUnicode_New \
237+
,_Py_Version \
237238

238239

239240
ifeq ($(DISABLE_DYLINK), 1)

src/core/_pyodide_core.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,11 @@ static struct PyModuleDef core_module_def = {
4646

4747
void
4848
pyodide_export(void);
49-
int
50-
py_version_major(void);
5149
void
5250
set_new_cframe(void* frame);
53-
// Force _pyodide_core.o, _pyodide_pre.gen.o, and pystate.o to be included by
51+
// Force _pyodide_pre.gen.o, and pystate.o to be included by
5452
// using a symbol from each of them.
5553
void* pyodide_export_ = pyodide_export;
56-
void* py_version_major_ = py_version_major;
5754
void* set_new_cframe_ = set_new_cframe;
5855

5956
// clang-format off

src/core/pyversion.c

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/core/pyversion.h

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/js/emscripten-settings.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { ConfigType } from "./pyodide";
44
import { initializeNativeFS } from "./nativefs";
55
import { loadBinaryFile, getBinaryResponse } from "./compat";
6-
import { API, PreRunFunc } from "./types";
6+
import { API, PreRunFunc, type Module } from "./types";
77

88
/**
99
* @private
@@ -110,6 +110,15 @@ function mountLocalDirectories(mounts: string[]): PreRunFunc {
110110
};
111111
}
112112

113+
function computeVersionTuple(Module: Module): [number, number, number] {
114+
const versionHex = Module.HEAPU32[Module._Py_Version / 4].toString(16);
115+
const res = versionHex
116+
.padStart(8, "0")
117+
.match(/.{1,2}/g)!
118+
.map((x) => parseInt(x, 16));
119+
return res as any;
120+
}
121+
113122
/**
114123
* Install the Python standard library to the virtual file system.
115124
*
@@ -125,12 +134,9 @@ function mountLocalDirectories(mounts: string[]): PreRunFunc {
125134
*/
126135
function installStdlib(stdlibURL: string): PreRunFunc {
127136
const stdlibPromise: Promise<Uint8Array> = loadBinaryFile(stdlibURL);
128-
return (Module) => {
129-
/* @ts-ignore */
130-
const pymajor = Module._py_version_major();
131-
/* @ts-ignore */
132-
const pyminor = Module._py_version_minor();
133-
137+
return (Module: Module) => {
138+
Module.API.pyVersionTuple = computeVersionTuple(Module);
139+
const [pymajor, pyminor] = Module.API.pyVersionTuple;
134140
Module.FS.mkdirTree("/lib");
135141
Module.FS.mkdirTree(`/lib/python${pymajor}.${pyminor}/site-packages`);
136142

src/js/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ export interface Module {
340340
_Py_EMSCRIPTEN_SIGNAL_HANDLING: number;
341341
Py_EmscriptenSignalBuffer: TypedArray;
342342
HEAP8: Uint8Array;
343+
HEAPU32: Uint32Array;
343344
__hiwire_get(a: number): any;
344345
__hiwire_set(a: number, b: any): void;
345346
__hiwire_immortal_add(a: any): void;
@@ -350,6 +351,7 @@ export interface Module {
350351
handle_js_error(e: any): void;
351352
exitCode: number | undefined;
352353
ExitStatus: { new (exitCode: number): Error };
354+
_Py_Version: number;
353355
}
354356

355357
type LockfileInfo = {
@@ -510,7 +512,7 @@ export interface API {
510512
syncUpSnapshotLoad3(conf: SnapshotConfig): void;
511513
abortSignalAny: (signals: AbortSignal[]) => AbortSignal;
512514
version: string;
513-
515+
pyVersionTuple: [number, number, number];
514516
LiteralMap: any;
515517
}
516518

src/tests/test_pyodide.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,9 +1770,10 @@ def test_python_version(selenium):
17701770
selenium.run_js(
17711771
"""
17721772
sys = pyodide.pyimport("sys");
1773-
assert(() => sys.version_info.major === pyodide._module._py_version_major());
1774-
assert(() => sys.version_info.minor === pyodide._module._py_version_minor());
1775-
assert(() => sys.version_info.micro === pyodide._module._py_version_micro());
1773+
const [major, minor, micro] = pyodide._api.pyVersionTuple;
1774+
assert(() => sys.version_info.major === major);
1775+
assert(() => sys.version_info.minor === minor);
1776+
assert(() => sys.version_info.micro === micro);
17761777
sys.destroy();
17771778
"""
17781779
)

0 commit comments

Comments
 (0)