This makes information about the interpreter ABI more accessible.
Co-authored-by: Petr Viktorin <encukou@gmail.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
always available. Unless explicitly noted otherwise, all variables are read-only.
+.. data:: abi_info
+
+ .. versionadded:: next
+
+ An object containing information about the ABI of the currently running
+ Python interpreter.
+ It should include information that affect the CPython ABI in ways that
+ require a specific build of the interpreter chosen from variants that can
+ co-exist on a single machine.
+ For example, it does not encode the base OS (Linux or Windows), but does
+ include pointer size since some systems support both 32- and 64-bit builds.
+ The available entries are the same on all platforms;
+ e.g. *pointer_size* is available even on 64-bit-only architectures.
+
+ The following attributes are available:
+
+ .. attribute:: abi_info.pointer_bits
+
+ The width of pointers in bits, as an integer,
+ equivalent to ``8 * sizeof(void *)``.
+ Usually, this is ``32`` or ``64``.
+
+ .. attribute:: abi_info.free_threaded
+
+ A Boolean indicating whether the interpreter was built with
+ :term:`free threading` support.
+ This reflects either the presence of the :option:`--disable-gil`
+ :file:`configure` option (on Unix)
+ or setting the ``DisableGil`` property (on Windows).
+
+ .. attribute:: abi_info.debug
+
+ A Boolean indicating whether the interpreter was built in
+ :ref:`debug mode <debug-build>`.
+ This reflects either the presence of the :option:`--with-pydebug`
+ :file:`configure` option (on Unix)
+ or the ``Debug`` configuration (on Windows).
+
+ .. attribute:: abi_info.byteorder
+
+ A string indicating the native byte order,
+ either ``'big'`` or ``'little'``.
+ This is the same as the :data:`byteorder` attribute.
+
+
.. data:: abiflags
On POSIX systems where Python was built with the standard ``configure``
(Contributed by Ron Frederick in :gh:`138252`.)
+sys
+---
+
+* Add :data:`sys.abi_info` namespace to improve access to ABI information.
+ (Contributed by Klaus Zimmermann in :gh:`137476`.)
+
+
tarfile
-------
elif sys.platform == "wasi":
self.assertEqual(info.name, "pthread-stubs")
+ def test_abi_info(self):
+ info = sys.abi_info
+ self.assertEqual(len(info.__dict__), 4)
+ pointer_bits = 64 if sys.maxsize > 2**32 else 32
+ self.assertEqual(info.pointer_bits, pointer_bits)
+ self.assertEqual(info.byteorder, sys.byteorder)
+ for attr, flag in [
+ ("free_threaded", "Py_GIL_DISABLED"),
+ ("debug", "Py_DEBUG"),
+ ]:
+ self.assertEqual(getattr(info, attr, None),
+ bool(sysconfig.get_config_var(flag)),
+ f"for {attr}")
+
@unittest.skipUnless(support.is_emscripten, "only available on Emscripten")
def test_emscripten_info(self):
self.assertEqual(len(sys._emscripten_info), 4)
--- /dev/null
+Add ``sys.abi_info`` object to make ABI information more easily accessible.
"\n\
Static objects:\n\
\n\
+abi_info -- Python ABI information.\n\
builtin_module_names -- tuple of module names built into this interpreter\n\
copyright -- copyright notice pertaining to this interpreter\n\
exec_prefix -- prefix used to find the machine-specific Python library\n\
return NULL;
}
+
+static PyObject *
+make_abi_info(void)
+{
+ // New entries should be added when needed for a supported platform, or (for
+ // enabling an unsupported one) by core dev consensus. Entries should be removed
+ // following PEP 387.
+ int res;
+ PyObject *abi_info, *value, *ns;
+ abi_info = PyDict_New();
+ if (abi_info == NULL) {
+ goto error;
+ }
+
+ value = PyLong_FromLong(sizeof(void *) * 8);
+ if (value == NULL) {
+ goto error;
+ }
+ res = PyDict_SetItemString(abi_info, "pointer_bits", value);
+ Py_DECREF(value);
+ if (res < 0) {
+ goto error;
+ }
+
+#ifdef Py_GIL_DISABLED
+ value = Py_True;
+#else
+ value = Py_False;
+#endif
+ res = PyDict_SetItemString(abi_info, "free_threaded", value);
+ if (res < 0) {
+ goto error;
+ }
+
+#ifdef Py_DEBUG
+ value = Py_True;
+#else
+ value = Py_False;
+#endif
+ res = PyDict_SetItemString(abi_info, "debug", value);
+ if (res < 0) {
+ goto error;
+ }
+
+#if PY_BIG_ENDIAN
+ value = PyUnicode_FromString("big");
+#else
+ value = PyUnicode_FromString("little");
+#endif
+ if (value == NULL) {
+ goto error;
+ }
+ res = PyDict_SetItemString(abi_info, "byteorder", value);
+ Py_DECREF(value);
+ if (res < 0) {
+ goto error;
+ }
+
+ ns = _PyNamespace_New(abi_info);
+ Py_DECREF(abi_info);
+ return ns;
+
+error:
+ Py_DECREF(abi_info);
+ return NULL;
+}
+
#ifdef __EMSCRIPTEN__
PyDoc_STRVAR(emscripten_info__doc__,
SET_SYS("thread_info", PyThread_GetInfo());
+ SET_SYS("abi_info", make_abi_info());
+
/* initialize asyncgen_hooks */
if (_PyStructSequence_InitBuiltin(interp, &AsyncGenHooksType,
&asyncgen_hooks_desc) < 0)