Skip to content

Commit 084aff8

Browse files
authored
GH-158628: Implement sys._wasi_info (GH-159039)
Starting off with WASI version, WASI SDK version, and whether cooperative multithreading is available. All values are required as WASI SDK is the officially supported compiler according to PEP 11.
1 parent 8138bf1 commit 084aff8

7 files changed

Lines changed: 99 additions & 12 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``

‎Include/internal/mimalloc/mimalloc/internal.h‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,14 @@ terms of the MIT license. A copy of the license can be found in the file
2323
#define mi_trace_message(...)
2424
#endif
2525

26-
#if defined(__EMSCRIPTEN__) && !defined(__wasi__)
27-
#define __wasi__
28-
#endif
29-
3026
#if defined(__cplusplus)
3127
#define mi_decl_externc extern "C"
3228
#else
3329
#define mi_decl_externc
3430
#endif
3531

3632
// pthreads
37-
#if !defined(_WIN32) && !defined(__wasi__)
33+
#if !defined(_WIN32) && !defined(__wasm__)
3834
#define MI_USE_PTHREADS
3935
#include <pthread.h>
4036
#endif

‎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.

‎Platforms/WASI/README.md‎

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -279,10 +279,16 @@ posix.uname_result(
279279

280280
### C code
281281

282-
WASI SDK defines several built-in macros. You can dump a full list of built-ins
283-
with ``/path/to/wasi-sdk/bin/clang -dM -E - < /dev/null``.
282+
The following built-in macros identify WebAssembly targets and environments.
283+
For WASI SDK, you can dump a full list of built-ins with
284+
`/path/to/wasi-sdk/bin/clang -dM -E - < /dev/null`.
284285

285-
* WebAssembly ``__wasm__`` (also ``__wasm``)
286-
* wasm32 ``__wasm32__`` (also ``__wasm32``)
287-
* wasm64 ``__wasm64__``
288-
* WASI ``__wasi__``
286+
#### Shared with Emscripten
287+
288+
- WebAssembly target: `__wasm__` (also `__wasm`)
289+
- wasm32 target: `__wasm32__` (also `__wasm32`)
290+
- wasm64 target: `__wasm64__`
291+
292+
#### Unique to WASI
293+
294+
- WASI environment: `__wasi__`

‎Python/marshal.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ module marshal
4444
*/
4545
#if defined(MS_WINDOWS)
4646
# define MAX_MARSHAL_STACK_DEPTH 1000
47-
#elif defined(__wasi__)
47+
#elif defined(__wasm__)
4848
# define MAX_MARSHAL_STACK_DEPTH 1500
4949
// TARGET_OS_IPHONE covers any non-macOS Apple platform.
5050
// It won't be defined on older macOS SDKs

‎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)