Skip to content

Commit 28ca8c9

Browse files
committed
GH-158628: Implement sys._wasi_info
1 parent 2423814 commit 28ca8c9

4 files changed

Lines changed: 85 additions & 0 deletions

File tree

‎Doc/library/sys.rst‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,29 @@ always available. Unless explicitly noted otherwise, all variables are read-only
418418
.. versionadded:: 3.11
419419

420420

421+
.. data:: _wasi_info
422+
423+
An object containing information about the build on the WebAssembly WASI
424+
platform. The object is provisional and may change in the future.
425+
426+
.. attribute:: _wasi_info.wasi_version
427+
428+
The WASI target version as a string: ``'p1'``, ``'p2'``, or ``'p3'``.
429+
430+
.. attribute:: _wasi_info.wasi_sdk_version
431+
432+
The full WASI SDK version as a string, such as ``'34.0'``.
433+
434+
.. attribute:: _wasi_info.cooperative_threads
435+
436+
``True`` if wasi-libc was compiled with cooperative multithreading
437+
support, ``False`` otherwise.
438+
439+
.. availability:: WASI.
440+
441+
.. versionadded:: next
442+
443+
421444
.. data:: pycache_prefix
422445

423446
If this is set (not ``None``), Python will write bytecode-cache ``.pyc``

‎Lib/test/test_sys.py‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,16 @@ def test_emscripten_info(self):
824824
self.assertIsInstance(sys._emscripten_info.pthreads, bool)
825825
self.assertIsInstance(sys._emscripten_info.shared_memory, bool)
826826

827+
@unittest.skipUnless(support.is_wasi, "only available on WASI")
828+
def test_wasi_info(self):
829+
info = sys._wasi_info
830+
self.assertIn(info.wasi_version, {'p1', 'p2', 'p3'})
831+
self.assertIn('.', info.wasi_sdk_version)
832+
sdk_major, _, sdk_minor = info.wasi_sdk_version.partition('.')
833+
self.assertGreaterEqual(int(sdk_major), 1)
834+
self.assertGreaterEqual(int(sdk_minor), 0)
835+
self.assertIsInstance(info.cooperative_threads, bool)
836+
827837
def test_43581(self):
828838
# Can't use sys.stdout, as this is a StringIO object when
829839
# the test runs under regrtest.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Implement :data:`sys._wasi_info` for exposing WASI-specific system details.

‎Python/sysmodule.c‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ extern const char *PyWin_DLLVersionString;
6464
# include <emscripten.h>
6565
#endif
6666

67+
#ifdef __wasi__
68+
# include <wasi/version.h>
69+
#endif
70+
6771
#ifdef HAVE_FCNTL_H
6872
# include <fcntl.h>
6973
#endif
@@ -3837,6 +3841,49 @@ make_abi_info(void)
38373841
}
38383842

38393843

3844+
#ifdef __wasi__
3845+
3846+
static PyObject *
3847+
make_wasi_info(void)
3848+
{
3849+
#if defined(__wasip1__)
3850+
const char *wasi_version = "p1";
3851+
#elif defined(__wasip2__)
3852+
const char *wasi_version = "p2";
3853+
#elif defined(__wasip3__)
3854+
const char *wasi_version = "p3";
3855+
#else
3856+
# error "Unknown WASI target version"
3857+
#endif
3858+
3859+
// The SDK version is only defined for SDK builds of wasi-libc.
3860+
#ifdef __wasi_sdk_version__
3861+
const char *wasi_sdk_version = __wasi_sdk_version__;
3862+
#else
3863+
# error "Unknown WASI SDK version"
3864+
#endif
3865+
3866+
#ifdef __wasi_cooperative_threads__
3867+
PyObject *cooperative_threads = Py_True;
3868+
#else
3869+
PyObject *cooperative_threads = Py_False;
3870+
#endif
3871+
3872+
PyObject *wasi_info = Py_BuildValue(
3873+
"{s:s,s:s,s:O}",
3874+
"wasi_version", wasi_version,
3875+
"wasi_sdk_version", wasi_sdk_version,
3876+
"cooperative_threads", cooperative_threads);
3877+
if (wasi_info == NULL) {
3878+
return NULL;
3879+
}
3880+
PyObject *ns = _PyNamespace_New(wasi_info);
3881+
Py_DECREF(wasi_info);
3882+
return ns;
3883+
}
3884+
3885+
#endif // __wasi__
3886+
38403887
#ifdef __EMSCRIPTEN__
38413888

38423889
PyDoc_STRVAR(emscripten_info__doc__,
@@ -4084,6 +4131,10 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
40844131

40854132
SET_SYS("abi_info", make_abi_info());
40864133

4134+
#ifdef __wasi__
4135+
SET_SYS("_wasi_info", make_wasi_info());
4136+
#endif
4137+
40874138
/* initialize asyncgen_hooks */
40884139
if (_PyStructSequence_InitBuiltin(interp, &AsyncGenHooksType,
40894140
&asyncgen_hooks_desc) < 0)

0 commit comments

Comments
 (0)