]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Restore PEP 523 functionality. (GH-28871)
authorMark Shannon <mark@hotpy.org>
Mon, 11 Oct 2021 10:34:02 +0000 (11:34 +0100)
committerGitHub <noreply@github.com>
Mon, 11 Oct 2021 10:34:02 +0000 (11:34 +0100)
Include/internal/pycore_ceval.h
Python/ceval.c
Python/pystate.c

index 66ddc991a9b11a2dda2fd57b09e1a4715363137b..f2acf10df8c233fa3c5ffeb2ac0ac3265292a326 100644 (file)
@@ -43,6 +43,9 @@ extern PyObject *_PyEval_BuiltinsFromGlobals(
 static inline PyObject*
 _PyEval_EvalFrame(PyThreadState *tstate, struct _interpreter_frame *frame, int throwflag)
 {
+    if (tstate->interp->eval_frame == NULL) {
+        return _PyEval_EvalFrameDefault(tstate, frame, throwflag);
+    }
     return tstate->interp->eval_frame(tstate, frame, throwflag);
 }
 
index df435bf3d76810428b1412ae272b4fd445da0e7d..a63b80395dcfcfd0a998fc5fb46a368384450e3a 100644 (file)
@@ -4612,7 +4612,7 @@ check_eval_breaker:
 
             // Check if the call can be inlined or not
             PyObject *function = PEEK(oparg + 1);
-            if (Py_TYPE(function) == &PyFunction_Type) {
+            if (Py_TYPE(function) == &PyFunction_Type && tstate->interp->eval_frame == NULL) {
                 int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(function))->co_flags;
                 PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : PyFunction_GET_GLOBALS(function);
                 int is_generator = code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR);
@@ -4630,7 +4630,6 @@ check_eval_breaker:
                     }
 
                     STACK_SHRINK(oparg + 1);
-                    assert(tstate->interp->eval_frame != NULL);
                     // The frame has stolen all the arguments from the stack,
                     // so there is no need to clean them up.
                     Py_DECREF(function);
@@ -5687,7 +5686,7 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFrameConstructor *con,
         if (steal_args) {
             // If we failed to initialize locals, make sure the caller still own all the
             // arguments. Notice that we only need to increase the reference count of the
-            // *valid* arguments (i.e. the ones that fit into the frame). 
+            // *valid* arguments (i.e. the ones that fit into the frame).
             PyCodeObject *co = (PyCodeObject*)con->fc_code;
             const size_t total_args = co->co_argcount + co->co_kwonlyargcount;
             for (size_t i = 0; i < Py_MIN(argcount, total_args); i++) {
@@ -5734,7 +5733,6 @@ _PyEval_Vector(PyThreadState *tstate, PyFrameConstructor *con,
     if (frame == NULL) {
         return NULL;
     }
-    assert (tstate->interp->eval_frame != NULL);
     PyObject *retval = _PyEval_EvalFrame(tstate, frame, 0);
     assert(_PyFrame_GetStackPointer(frame) == _PyFrame_Stackbase(frame));
     if (_PyEvalFrameClearAndPop(tstate, frame)) {
index 45272142e41734f579201a2846ee9dfd8e6da7c3..f02de926c6f026c9eff8c7621611ed599b5538d0 100644 (file)
@@ -230,7 +230,7 @@ PyInterpreterState_New(void)
     PyConfig_InitPythonConfig(&interp->config);
     _PyType_InitCache(interp);
 
-    interp->eval_frame = _PyEval_EvalFrameDefault;
+    interp->eval_frame = NULL;
 #ifdef HAVE_DLOPEN
 #if HAVE_DECL_RTLD_NOW
     interp->dlopenflags = RTLD_NOW;
@@ -1973,6 +1973,9 @@ _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry)
 _PyFrameEvalFunction
 _PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)
 {
+    if (interp->eval_frame == NULL) {
+        return _PyEval_EvalFrameDefault;
+    }
     return interp->eval_frame;
 }
 
@@ -1981,7 +1984,12 @@ void
 _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp,
                                      _PyFrameEvalFunction eval_frame)
 {
-    interp->eval_frame = eval_frame;
+    if (eval_frame == _PyEval_EvalFrameDefault) {
+        interp->eval_frame = NULL;
+    }
+    else {
+        interp->eval_frame = eval_frame;
+    }
 }