mirror of
https://github.com/python/cpython.git
synced 2025-10-23 01:43:53 +00:00
gh-133143: Add sys.abi_info (GH-137476)
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>
This commit is contained in:
parent
c006a623e7
commit
1acb718ea2
5 changed files with 137 additions and 0 deletions
|
@ -11,6 +11,51 @@ interpreter and to functions that interact strongly with the interpreter. It is
|
||||||
always available. Unless explicitly noted otherwise, all variables are read-only.
|
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
|
.. data:: abiflags
|
||||||
|
|
||||||
On POSIX systems where Python was built with the standard ``configure``
|
On POSIX systems where Python was built with the standard ``configure``
|
||||||
|
|
|
@ -460,6 +460,13 @@ ssl
|
||||||
(Contributed by Ron Frederick in :gh:`138252`.)
|
(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
|
tarfile
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -739,6 +739,20 @@ def test_thread_info(self):
|
||||||
elif sys.platform == "wasi":
|
elif sys.platform == "wasi":
|
||||||
self.assertEqual(info.name, "pthread-stubs")
|
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")
|
@unittest.skipUnless(support.is_emscripten, "only available on Emscripten")
|
||||||
def test_emscripten_info(self):
|
def test_emscripten_info(self):
|
||||||
self.assertEqual(len(sys._emscripten_info), 4)
|
self.assertEqual(len(sys._emscripten_info), 4)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Add ``sys.abi_info`` object to make ABI information more easily accessible.
|
|
@ -3268,6 +3268,7 @@ PyDoc_STR(
|
||||||
"\n\
|
"\n\
|
||||||
Static objects:\n\
|
Static objects:\n\
|
||||||
\n\
|
\n\
|
||||||
|
abi_info -- Python ABI information.\n\
|
||||||
builtin_module_names -- tuple of module names built into this interpreter\n\
|
builtin_module_names -- tuple of module names built into this interpreter\n\
|
||||||
copyright -- copyright notice pertaining to this interpreter\n\
|
copyright -- copyright notice pertaining to this interpreter\n\
|
||||||
exec_prefix -- prefix used to find the machine-specific Python library\n\
|
exec_prefix -- prefix used to find the machine-specific Python library\n\
|
||||||
|
@ -3638,6 +3639,73 @@ make_impl_info(PyObject *version_info)
|
||||||
return NULL;
|
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__
|
#ifdef __EMSCRIPTEN__
|
||||||
|
|
||||||
PyDoc_STRVAR(emscripten_info__doc__,
|
PyDoc_STRVAR(emscripten_info__doc__,
|
||||||
|
@ -3863,6 +3931,8 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
|
||||||
|
|
||||||
SET_SYS("thread_info", PyThread_GetInfo());
|
SET_SYS("thread_info", PyThread_GetInfo());
|
||||||
|
|
||||||
|
SET_SYS("abi_info", make_abi_info());
|
||||||
|
|
||||||
/* initialize asyncgen_hooks */
|
/* initialize asyncgen_hooks */
|
||||||
if (_PyStructSequence_InitBuiltin(interp, &AsyncGenHooksType,
|
if (_PyStructSequence_InitBuiltin(interp, &AsyncGenHooksType,
|
||||||
&asyncgen_hooks_desc) < 0)
|
&asyncgen_hooks_desc) < 0)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue