diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 79491b4bfdfd42..9ffc8f71c5bac6 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -1536,13 +1536,10 @@ Build Changes :file:`!configure`. (Contributed by Christian Heimes in :gh:`89886`.) -* C extensions built with the :ref:`limited C API ` - on :ref:`Python build in debug mode ` no longer support Python - 3.9 and older. In this configuration, :c:func:`Py_INCREF` and - :c:func:`Py_DECREF` are now always implemented as opaque function calls, - but the called functions were added to Python 3.10. Build C extensions - with a release build of Python or with Python 3.12 and older, to keep support - for Python 3.9 and older. +* Python built in debug mode can no longer build C extensions using the + :ref:`limited C API ` version 3.9 and older. Build C + extensions with a release build of Python (recommended), or with Python 3.12 + and older. (Contributed by Victor Stinner in :gh:`102304`.) diff --git a/Include/object.h b/Include/object.h index dc5b087db2f467..880eec93229c9e 100644 --- a/Include/object.h +++ b/Include/object.h @@ -62,6 +62,12 @@ whose size is determined when the object is allocated. # error Py_LIMITED_API is incompatible with Py_TRACE_REFS #endif +// gh-102304: In debug mode, the limited API implements Py_INCREF() by calling +// _Py_IncRef() which was added to Python 3.10. +#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030a0000 +# error "Python built in debug mode is incompatible with limited C API older than 3.10" +#endif + #ifdef Py_TRACE_REFS /* Define pointers to support a doubly-linked list of all live heap objects. */ #define _PyObject_HEAD_EXTRA \ diff --git a/Lib/test/test_xxlimited.py b/Lib/test/test_xxlimited.py index 6dbfb3f439393c..de7f9f224d5c75 100644 --- a/Lib/test/test_xxlimited.py +++ b/Lib/test/test_xxlimited.py @@ -3,7 +3,10 @@ import types xxlimited = import_helper.import_module('xxlimited') -xxlimited_35 = import_helper.import_module('xxlimited_35') +try: + import xxlimited_35 +except ImportError: + xxlimited_35 = None class CommonTests: @@ -70,6 +73,7 @@ def test_buffer(self): self.assertEqual(b2[0], 1) +@unittest.skipIf(xxlimited_35 is None, 'need xxlimited_35 extension') class TestXXLimited35(CommonTests, unittest.TestCase): module = xxlimited_35 diff --git a/Misc/NEWS.d/next/C API/2023-06-06-17-15-55.gh-issue-102304.RPP7AB.rst b/Misc/NEWS.d/next/C API/2023-06-06-17-15-55.gh-issue-102304.RPP7AB.rst new file mode 100644 index 00000000000000..5553aeb48d594f --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-06-06-17-15-55.gh-issue-102304.RPP7AB.rst @@ -0,0 +1,4 @@ +Python built in debug mode can no longer build C extensions using the +:ref:`limited C API ` version 3.9 and older. Build C +extensions with a release build of Python (recommended), or with Python 3.12 +and older. Patch by Victor Stinner. diff --git a/configure b/configure index 7f17fe42120a2c..daf1b3414f588c 100755 --- a/configure +++ b/configure @@ -30373,7 +30373,7 @@ printf %s "checking for stdlib extension module xxlimited_35... " >&6; } if test "$py_cv_module_xxlimited_35" != "n/a" then : - if test "$with_trace_refs" = "no" + if test "$with_trace_refs" = "no" -a "$Py_DEBUG" != "true" then : if test "$ac_cv_func_dlopen" = yes then : diff --git a/configure.ac b/configure.ac index 3d03fa6f611d38..2ee9a9d83e9b19 100644 --- a/configure.ac +++ b/configure.ac @@ -7390,7 +7390,9 @@ dnl Limited API template modules. dnl The limited C API is not compatible with the Py_TRACE_REFS macro. dnl Emscripten does not support shared libraries yet. PY_STDLIB_MOD([xxlimited], [test "$with_trace_refs" = "no"], [test "$ac_cv_func_dlopen" = yes]) -PY_STDLIB_MOD([xxlimited_35], [test "$with_trace_refs" = "no"], [test "$ac_cv_func_dlopen" = yes]) +dnl xxlimited_35 cannot be built with Python built in debug mode +dnl (if the Py_REF_DEBUG macro is defined) +PY_STDLIB_MOD([xxlimited_35], [test "$with_trace_refs" = "no" -a "$Py_DEBUG" != "true"], [test "$ac_cv_func_dlopen" = yes]) # substitute multiline block, must come after last PY_STDLIB_MOD() AC_SUBST([MODULE_BLOCK])