From df45d6bc37dd6cb2cd3aefb0a089ba76e7429329 Mon Sep 17 00:00:00 2001 From: Bas Schoenmaeckers Date: Fri, 8 May 2026 14:37:24 +0200 Subject: [PATCH 1/6] Convert `PyBytes_Check` macro to a function --- Doc/data/stable_abi.dat | 1 + Include/boolobject.h | 7 ++++++- Lib/test/test_stable_abi_ctypes.py | 29 +++++++++++++---------------- Misc/stable_abi.toml | 3 +++ Objects/boolobject.c | 8 ++++++++ PC/python3dll.c | 1 + 6 files changed, 32 insertions(+), 17 deletions(-) diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index 2d4278c9d97c85..5936ce128bdf60 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -46,6 +46,7 @@ macro,PyBUF_STRIDES,3.11,, macro,PyBUF_WRITABLE,3.11,, macro,PyBUF_WRITE,3.11,, data,PyBaseObject_Type,3.2,, +func,PyBool_Check,3.16,, func,PyBool_FromLong,3.2,, data,PyBool_Type,3.2,, func,PyBuffer_FillContiguousStrides,3.11,, diff --git a/Include/boolobject.h b/Include/boolobject.h index b56e2baecaa36c..ab8f1ac4015b02 100644 --- a/Include/boolobject.h +++ b/Include/boolobject.h @@ -9,7 +9,12 @@ extern "C" { // PyBool_Type is declared by object.h -#define PyBool_Check(x) Py_IS_TYPE((x), &PyBool_Type) +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03100000 +PyAPI_FUNC(int) PyBool_Check(PyObject *x); +#endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x03100000 +# define PyBool_Check(x) Py_IS_TYPE((x), &PyBool_Type) +#endif /* Py_False and Py_True are the only two bools in existence. */ diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index ac5c4296c663d0..c80398502cd54e 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -55,6 +55,7 @@ def test_windows_feature_macros(self): "PyArg_VaParseTupleAndKeywords", "PyArg_ValidateKeywordArguments", "PyBaseObject_Type", + "PyBool_Check", "PyBool_FromLong", "PyBool_Type", "PyBuffer_FillContiguousStrides", @@ -1032,19 +1033,15 @@ def test_windows_feature_macros(self): 'PyOS_CheckStack', ) -EXPECTED_FEATURE_MACROS = set([ - 'HAVE_FORK', - 'MS_WINDOWS', - 'PY_HAVE_THREAD_NATIVE_ID', - 'Py_REF_DEBUG', - 'Py_TRACE_REFS', - 'USE_STACKCHECK', -]) -WINDOWS_FEATURE_MACROS = { - 'HAVE_FORK': False, - 'MS_WINDOWS': True, - 'PY_HAVE_THREAD_NATIVE_ID': True, - 'Py_REF_DEBUG': 'maybe', - 'Py_TRACE_REFS': 'maybe', - 'USE_STACKCHECK': 'maybe', -} +EXPECTED_FEATURE_MACROS = set(['HAVE_FORK', + 'MS_WINDOWS', + 'PY_HAVE_THREAD_NATIVE_ID', + 'Py_REF_DEBUG', + 'Py_TRACE_REFS', + 'USE_STACKCHECK']) +WINDOWS_FEATURE_MACROS = {'HAVE_FORK': False, + 'MS_WINDOWS': True, + 'PY_HAVE_THREAD_NATIVE_ID': True, + 'Py_REF_DEBUG': 'maybe', + 'Py_TRACE_REFS': 'maybe', + 'USE_STACKCHECK': 'maybe'} diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index 8fd7aba09241e6..7f61fffae4bc3b 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -2831,3 +2831,6 @@ [function.PyObject_CallFinalizerFromDealloc] added = '3.15' + +[function.PyBool_Check] + added = '3.16' diff --git a/Objects/boolobject.c b/Objects/boolobject.c index b694691ae4d0d1..d8e923ad763452 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -23,6 +23,14 @@ PyObject *PyBool_FromLong(long ok) return ok ? Py_True : Py_False; } +#undef PyBool_Check + +int +PyBool_Check(PyObject *x) +{ + return Py_IS_TYPE(x, &PyBool_Type); +} + /* We define bool_new to always return either Py_True or Py_False */ static PyObject * diff --git a/PC/python3dll.c b/PC/python3dll.c index e0be9d65a93cda..f01f445e46f357 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -105,6 +105,7 @@ EXPORT_FUNC(PyArg_UnpackTuple) EXPORT_FUNC(PyArg_ValidateKeywordArguments) EXPORT_FUNC(PyArg_VaParse) EXPORT_FUNC(PyArg_VaParseTupleAndKeywords) +EXPORT_FUNC(PyBool_Check) EXPORT_FUNC(PyBool_FromLong) EXPORT_FUNC(PyBuffer_FillContiguousStrides) EXPORT_FUNC(PyBuffer_FillInfo) From fa5f80fb7cf2ff4d7bcd306138d59be1c0dd8785 Mon Sep 17 00:00:00 2001 From: Bas Schoenmaeckers <7943856+bschoenmaeckers@users.noreply.github.com> Date: Fri, 8 May 2026 18:07:48 +0200 Subject: [PATCH 2/6] Use version helper Co-authored-by: Petr Viktorin --- Include/boolobject.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/boolobject.h b/Include/boolobject.h index ab8f1ac4015b02..336e65b79483bb 100644 --- a/Include/boolobject.h +++ b/Include/boolobject.h @@ -9,7 +9,7 @@ extern "C" { // PyBool_Type is declared by object.h -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03100000 +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= _Py_PACK_VERSION(3, 16) PyAPI_FUNC(int) PyBool_Check(PyObject *x); #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x03100000 From 66afac0df7245f52802593ecb05baa4a7e87920a Mon Sep 17 00:00:00 2001 From: Bas Schoenmaeckers Date: Fri, 8 May 2026 18:13:34 +0200 Subject: [PATCH 3/6] Move `PyBool_Check` to the end of the file --- Objects/boolobject.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Objects/boolobject.c b/Objects/boolobject.c index d8e923ad763452..7b090ff6b47df8 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -23,14 +23,6 @@ PyObject *PyBool_FromLong(long ok) return ok ? Py_True : Py_False; } -#undef PyBool_Check - -int -PyBool_Check(PyObject *x) -{ - return Py_IS_TYPE(x, &PyBool_Type); -} - /* We define bool_new to always return either Py_True or Py_False */ static PyObject * @@ -233,3 +225,8 @@ struct _longobject _Py_TrueStruct = { { 1 } } }; + +// Implementations for the Stable ABI + +#undef PyBool_Check +int PyBool_Check(PyObject *x) { return Py_IS_TYPE(x, &PyBool_Type); } From f2a576f930207371fe9e1ae738884276cbd38b0b Mon Sep 17 00:00:00 2001 From: Bas Schoenmaeckers Date: Fri, 8 May 2026 18:18:50 +0200 Subject: [PATCH 4/6] Fix casting incompatibility Co-authored-by: Petr Viktorin --- Include/boolobject.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Include/boolobject.h b/Include/boolobject.h index 336e65b79483bb..0e7db5d47bf49c 100644 --- a/Include/boolobject.h +++ b/Include/boolobject.h @@ -12,8 +12,10 @@ extern "C" { #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= _Py_PACK_VERSION(3, 16) PyAPI_FUNC(int) PyBool_Check(PyObject *x); #endif -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x03100000 +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < _Py_PACK_VERSION(3, 16) # define PyBool_Check(x) Py_IS_TYPE((x), &PyBool_Type) +#else +# define PyBool_Check(x) PyBool_Check(_PyObject_CAST(x)) #endif /* Py_False and Py_True are the only two bools in existence. */ From 7e21b8b5b7a80c6f8e74b2b8984ce34d3b92067f Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 16:36:38 +0000 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/C_API/2026-05-08-16-36-36.gh-issue-000000.2F1XTY.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/C_API/2026-05-08-16-36-36.gh-issue-000000.2F1XTY.rst diff --git a/Misc/NEWS.d/next/C_API/2026-05-08-16-36-36.gh-issue-000000.2F1XTY.rst b/Misc/NEWS.d/next/C_API/2026-05-08-16-36-36.gh-issue-000000.2F1XTY.rst new file mode 100644 index 00000000000000..1ac7f65adefeaf --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-05-08-16-36-36.gh-issue-000000.2F1XTY.rst @@ -0,0 +1,2 @@ +In the Limited C API 3.16 and newer, :c:func:`PyBool_Check` is now available +as a function instead of a macro. From 2cda8fd537e9927fe45e9950d9251644c5140ba6 Mon Sep 17 00:00:00 2001 From: Bas Schoenmaeckers Date: Fri, 8 May 2026 19:09:06 +0200 Subject: [PATCH 6/6] Rerun `make regen-limited-abi` --- Lib/test/test_stable_abi_ctypes.py | 28 +++++++++++-------- ...-05-08-16-36-36.gh-issue-000000.2F1XTY.rst | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index c80398502cd54e..f560f5cd472a79 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -1033,15 +1033,19 @@ def test_windows_feature_macros(self): 'PyOS_CheckStack', ) -EXPECTED_FEATURE_MACROS = set(['HAVE_FORK', - 'MS_WINDOWS', - 'PY_HAVE_THREAD_NATIVE_ID', - 'Py_REF_DEBUG', - 'Py_TRACE_REFS', - 'USE_STACKCHECK']) -WINDOWS_FEATURE_MACROS = {'HAVE_FORK': False, - 'MS_WINDOWS': True, - 'PY_HAVE_THREAD_NATIVE_ID': True, - 'Py_REF_DEBUG': 'maybe', - 'Py_TRACE_REFS': 'maybe', - 'USE_STACKCHECK': 'maybe'} +EXPECTED_FEATURE_MACROS = set([ + 'HAVE_FORK', + 'MS_WINDOWS', + 'PY_HAVE_THREAD_NATIVE_ID', + 'Py_REF_DEBUG', + 'Py_TRACE_REFS', + 'USE_STACKCHECK', +]) +WINDOWS_FEATURE_MACROS = { + 'HAVE_FORK': False, + 'MS_WINDOWS': True, + 'PY_HAVE_THREAD_NATIVE_ID': True, + 'Py_REF_DEBUG': 'maybe', + 'Py_TRACE_REFS': 'maybe', + 'USE_STACKCHECK': 'maybe', +} diff --git a/Misc/NEWS.d/next/C_API/2026-05-08-16-36-36.gh-issue-000000.2F1XTY.rst b/Misc/NEWS.d/next/C_API/2026-05-08-16-36-36.gh-issue-000000.2F1XTY.rst index 1ac7f65adefeaf..070ac30961d7bd 100644 --- a/Misc/NEWS.d/next/C_API/2026-05-08-16-36-36.gh-issue-000000.2F1XTY.rst +++ b/Misc/NEWS.d/next/C_API/2026-05-08-16-36-36.gh-issue-000000.2F1XTY.rst @@ -1,2 +1,2 @@ -In the Limited C API 3.16 and newer, :c:func:`PyBool_Check` is now available +In the Limited C API 3.16 and newer, :c:func:`PyBool_Check` is now available as a function instead of a macro.