bpo-31857: Make the behavior of USE_STACKCHECK deterministic by pdox · Pull Request #4098 · python/cpython

Hm, this is a bit confusing. There are three different values:

ceval.recursion_limit - Used by Py_GetRecursionLimit
ceval.check_recursion_limit - Not used at all
_Py_CheckRecursionLimit - Used by the ceval macros

Then there's this comment:

/* XXX _Py_CheckRecursionLimit should be changed to
   _PyRuntime.ceval.check_recursion_limit.  However, due to the macros
   in which it's used, _Py_CheckRecursionLimit is stuck in the stable
   ABI.  It should be removed therefrom when possible.
*/
PyAPI_DATA(int) _Py_CheckRecursionLimit;

I think the idea was for check_recursion_limit to be the replacement for _Py_CheckRecursionLimit, as a mutable counter field for USE_STACKCHECK, with recursion_limit being constant. So technically, this change makes both _Py_CheckRecursionLimit and check_recursion_limit obsolete. But if we really want to maintain it as part of the "ABI", then we need to keep it around. I doubt the existing code is actually ABI stable though, since the existing macro was:

(++(x) > (_Py_CheckRecursionLimit += PyThreadState_GET()->overflowed - 1))

Which assumes the offset of "overflowed" in the PyThreadState structure is part of the ABI, which it is explicitly not. ( http://legacy.python.org/dev/peps/pep-0384/#structures )

But if we want to keep it compatible, I could add the assignment:

_Py_CheckRecursionLimit = _PyRuntime.ceval.recursion_limit;

in _Py_CheckRecursiveCall. This would preserve the old behavior when the old macro is in use.