Issue #29306: Fix usage of Py_EnterRecursiveCall()

* *PyCFunction_*Call*() functions now call Py_EnterRecursiveCall().
* PyObject_Call() now calls directly _PyFunction_FastCallDict() and
  PyCFunction_Call() to avoid calling Py_EnterRecursiveCall() twice per
  function call
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index 6618d78..0782777 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -90,11 +90,6 @@
 _PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, PyObject **args,
                              Py_ssize_t nargs, PyObject *kwargs)
 {
-    PyCFunction meth;
-    PyObject *result;
-    int flags;
-    PyObject *argstuple;
-
     /* _PyMethodDef_RawFastCallDict() must not be called with an exception set,
        because it can clear it (directly or indirectly) and so the
        caller loses its exception */
@@ -105,18 +100,23 @@
     assert(nargs == 0 || args != NULL);
     assert(kwargs == NULL || PyDict_Check(kwargs));
 
-    meth = method->ml_meth;
-    flags = method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
+    PyCFunction meth = method->ml_meth;
+    int flags = method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
+    PyObject *result = NULL;
+
+    if (Py_EnterRecursiveCall(" while calling a Python object")) {
+        return NULL;
+    }
 
     switch (flags)
     {
     case METH_NOARGS:
-         if (nargs != 0) {
+        if (nargs != 0) {
             PyErr_Format(PyExc_TypeError,
                 "%.200s() takes no arguments (%zd given)",
                 method->ml_name, nargs);
-            return NULL;
-         }
+            goto exit;
+        }
 
         if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
             goto no_keyword_error;
@@ -130,7 +130,7 @@
             PyErr_Format(PyExc_TypeError,
                 "%.200s() takes exactly one argument (%zd given)",
                 method->ml_name, nargs);
-            return NULL;
+            goto exit;
         }
 
         if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
@@ -148,10 +148,11 @@
         /* fall through next case */
 
     case METH_VARARGS | METH_KEYWORDS:
+    {
         /* Slow-path: create a temporary tuple for positional arguments */
-        argstuple = _PyStack_AsTuple(args, nargs);
+        PyObject *argstuple = _PyStack_AsTuple(args, nargs);
         if (argstuple == NULL) {
-            return NULL;
+            goto exit;
         }
 
         if (flags & METH_KEYWORDS) {
@@ -162,6 +163,7 @@
         }
         Py_DECREF(argstuple);
         break;
+    }
 
     case METH_FASTCALL:
     {
@@ -170,7 +172,7 @@
         _PyCFunctionFast fastmeth = (_PyCFunctionFast)meth;
 
         if (_PyStack_UnpackDict(args, nargs, kwargs, &stack, &kwnames) < 0) {
-            return NULL;
+            goto exit;
         }
 
         result = (*fastmeth) (self, stack, nargs, kwnames);
@@ -185,17 +187,19 @@
         PyErr_SetString(PyExc_SystemError,
                         "Bad call flags in _PyMethodDef_RawFastCallDict. "
                         "METH_OLDARGS is no longer supported!");
-        return NULL;
+        goto exit;
     }
 
-    return result;
+    goto exit;
 
 no_keyword_error:
     PyErr_Format(PyExc_TypeError,
                  "%.200s() takes no keyword arguments",
                  method->ml_name, nargs);
 
-    return NULL;
+exit:
+    Py_LeaveRecursiveCall();
+    return result;
 }
 
 PyObject *
@@ -232,7 +236,11 @@
     PyCFunction meth = method->ml_meth;
     int flags = method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
     Py_ssize_t nkwargs = kwnames == NULL ? 0 : PyTuple_Size(kwnames);
-    PyObject *result;
+    PyObject *result = NULL;
+
+    if (Py_EnterRecursiveCall(" while calling a Python object")) {
+        return NULL;
+    }
 
     switch (flags)
     {
@@ -241,7 +249,7 @@
             PyErr_Format(PyExc_TypeError,
                 "%.200s() takes no arguments (%zd given)",
                 method->ml_name, nargs);
-            return NULL;
+            goto exit;
         }
 
         if (nkwargs) {
@@ -256,7 +264,7 @@
             PyErr_Format(PyExc_TypeError,
                 "%.200s() takes exactly one argument (%zd given)",
                 method->ml_name, nargs);
-            return NULL;
+            goto exit;
         }
 
         if (nkwargs) {
@@ -284,7 +292,7 @@
 
         argtuple = _PyStack_AsTuple(args, nargs);
         if (argtuple == NULL) {
-            return NULL;
+            goto exit;
         }
 
         if (flags & METH_KEYWORDS) {
@@ -294,7 +302,7 @@
                 kwdict = _PyStack_AsDict(args + nargs, kwnames);
                 if (kwdict == NULL) {
                     Py_DECREF(argtuple);
-                    return NULL;
+                    goto exit;
                 }
             }
             else {
@@ -315,16 +323,19 @@
         PyErr_SetString(PyExc_SystemError,
                         "Bad call flags in _PyCFunction_FastCallKeywords. "
                         "METH_OLDARGS is no longer supported!");
-        return NULL;
+        goto exit;
     }
 
-    return result;
+    goto exit;
 
 no_keyword_error:
     PyErr_Format(PyExc_TypeError,
                  "%.200s() takes no keyword arguments",
                  method->ml_name);
-    return NULL;
+
+exit:
+    Py_LeaveRecursiveCall();
+    return result;
 }
 
 PyObject *