Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2e3e54a
Add sys.abi_info
zklaus Aug 1, 2025
2ddafa4
📜🤖 Added by blurb_it.
blurb-it[bot] Aug 6, 2025
cdc50c3
Simplify pointer_bits handling
zklaus Aug 7, 2025
6fb25a3
Remove explicit C API function
zklaus Aug 7, 2025
4c3d83d
Make abi_info object a simple namespace with no explicit C API
zklaus Aug 7, 2025
820e002
Cleanup scaffolding
zklaus Aug 7, 2025
918521f
Fix make_abi_info to be static
zklaus Aug 7, 2025
7863651
Add test
zklaus Aug 12, 2025
81d75fc
Fix test
zklaus Aug 12, 2025
41027a3
Add link
zklaus Aug 14, 2025
56726ab
Rename attributes
zklaus Aug 14, 2025
94b7f40
Add better attribute specification to docs
zklaus Aug 21, 2025
6887d6c
Base `debug` on Py_REF_DEBUG
zklaus Aug 21, 2025
7ced683
Add byteorder
zklaus Aug 21, 2025
cc5ae8c
Fix test
zklaus Aug 21, 2025
5c18587
Improve error message in test
zklaus Aug 21, 2025
d025d17
Apply suggestions from code review
zklaus Sep 2, 2025
a089371
Revert "Base `debug` on Py_REF_DEBUG"
zklaus Sep 2, 2025
44ce7c7
Add whatsnew entry for improved sys module
zklaus Sep 2, 2025
8f57f17
Update Python/sysmodule.c
zklaus Sep 3, 2025
77f7b9b
Integrate suggestions from Adam Turner
zklaus Sep 3, 2025
312bff1
Add Windows configuration equivalents
zklaus Sep 4, 2025
ed7b6d9
Fix rst lint
zklaus Sep 4, 2025
15f065a
Use Sphinx markup for attributes
encukou Sep 5, 2025
151eb4c
Merge pull request #3 from encukou/add-sys.abi_info
zklaus Sep 8, 2025
9f5ffae
Merge branch 'main' into add-sys.abi_info
AA-Turner Sep 8, 2025
128b150
Don't use ReST in a C comment
encukou Sep 8, 2025
0506533
docs rephrasing
AA-Turner Sep 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions Doc/library/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.


.. 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.
Comment on lines +25 to +26
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.g. would have been better spelled out as for example


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``
Expand Down
7 changes: 7 additions & 0 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,13 @@ ssl
(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
-------

Expand Down
14 changes: 14 additions & 0 deletions Lib/test/test_sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,20 @@ def test_thread_info(self):
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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add ``sys.abi_info`` object to make ABI information more easily accessible.
70 changes: 70 additions & 0 deletions Python/sysmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3268,6 +3268,7 @@ PyDoc_STR(
"\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\
Expand Down Expand Up @@ -3638,6 +3639,73 @@ make_impl_info(PyObject *version_info)
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__,
Expand Down Expand Up @@ -3863,6 +3931,8 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)

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)
Expand Down
Loading