bpo-38644: Add Py_EnterRecursiveCall() to the limited API (GH-17046)
Provide Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() as
regular functions for the limited API. Previously, there were defined
as macros, but these macros didn't work with the limited API which
cannot access PyThreadState.recursion_depth field.
Remove _Py_CheckRecursionLimit from the stable ABI.
Add Include/cpython/ceval.h header file.
diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst
index c7ba74c..a042c6e 100644
--- a/Doc/c-api/exceptions.rst
+++ b/Doc/c-api/exceptions.rst
@@ -715,15 +715,21 @@
case, a :exc:`RecursionError` is set and a nonzero value is returned.
Otherwise, zero is returned.
- *where* should be a string such as ``" in instance check"`` to be
- concatenated to the :exc:`RecursionError` message caused by the recursion
+ *where* should be a UTF-8 encoded string such as ``" in instance check"`` to
+ be concatenated to the :exc:`RecursionError` message caused by the recursion
depth limit.
-.. c:function:: void Py_LeaveRecursiveCall()
+ .. versionchanged:: 3.9
+ This function is now also available in the limited API.
+
+.. c:function:: void Py_LeaveRecursiveCall(void)
Ends a :c:func:`Py_EnterRecursiveCall`. Must be called once for each
*successful* invocation of :c:func:`Py_EnterRecursiveCall`.
+ .. versionchanged:: 3.9
+ This function is now also available in the limited API.
+
Properly implementing :c:member:`~PyTypeObject.tp_repr` for container types requires
special recursion handling. In addition to protecting the stack,
:c:member:`~PyTypeObject.tp_repr` also needs to track objects to prevent cycles. The
diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst
index 7d7c502..3cac9c5 100644
--- a/Doc/whatsnew/3.9.rst
+++ b/Doc/whatsnew/3.9.rst
@@ -197,6 +197,12 @@
Build and C API Changes
=======================
+* Provide :c:func:`Py_EnterRecursiveCall` and :c:func:`Py_LeaveRecursiveCall`
+ as regular functions for the limited API. Previously, there were defined as
+ macros, but these macros didn't work with the limited API which cannot access
+ ``PyThreadState.recursion_depth`` field. Remove ``_Py_CheckRecursionLimit``
+ from the stable ABI.
+ (Contributed by Victor Stinner in :issue:`38644`.)
* Add a new public :c:func:`PyObject_CallNoArgs` function to the C API, which
calls a callable Python object without any arguments. It is the most efficient
way to call a callable Python object without any argument.