]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-100762: Fix optimization in gen_close (#111069)
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>
Wed, 25 Oct 2023 15:22:34 +0000 (16:22 +0100)
committerGitHub <noreply@github.com>
Wed, 25 Oct 2023 15:22:34 +0000 (16:22 +0100)
Lib/test/test_cprofile.py
Lib/test/test_sys_setprofile.py
Objects/genobject.c

index 3056fe84dac5dd37f9bb12c11e670449c3f62704..27e8a7679037773ed15d180a84d8026a0ba37e1f 100644 (file)
@@ -83,8 +83,8 @@ class CProfileTest(ProfileTest):
 
         for func, (cc, nc, _, _, _) in pr.stats.items():
             if func[2] == "<genexpr>":
-                self.assertEqual(cc, 2)
-                self.assertEqual(nc, 2)
+                self.assertEqual(cc, 1)
+                self.assertEqual(nc, 1)
 
 
 class TestCommandLine(unittest.TestCase):
index 9e8936630de920c186804f501e3ff1c20dcc5e30..bb8adc8b555cb4cd670829de3824f5c08fabd8e0 100644 (file)
@@ -265,10 +265,6 @@ class ProfileHookTestCase(TestCaseBase):
         f_ident = ident(f)
         g_ident = ident(g)
         self.check_events(g, [(1, 'call', g_ident),
-                              (2, 'call', f_ident),
-                              (2, 'return', f_ident),
-                              # once more; the generator is being garbage collected
-                              # and it will do a PY_THROW
                               (2, 'call', f_ident),
                               (2, 'return', f_ident),
                               (1, 'return', g_ident),
index 491e631f2242e9a33c531fc74aaa2b24178812fb..6794cc693970c533073620948579c21a9938664f 100644 (file)
@@ -378,7 +378,6 @@ static PyObject *
 gen_close(PyGenObject *gen, PyObject *args)
 {
     PyObject *retval;
-    PyObject *yf = _PyGen_yf(gen);
     int err = 0;
 
     if (gen->gi_frame_state == FRAME_CREATED) {
@@ -388,6 +387,7 @@ gen_close(PyGenObject *gen, PyObject *args)
     if (gen->gi_frame_state >= FRAME_COMPLETED) {
         Py_RETURN_NONE;
     }
+    PyObject *yf = _PyGen_yf(gen);
     if (yf) {
         PyFrameState state = gen->gi_frame_state;
         gen->gi_frame_state = FRAME_EXECUTING;
@@ -400,12 +400,13 @@ gen_close(PyGenObject *gen, PyObject *args)
      * YIELD_VALUE if the debugger has changed the lineno. */
     if (err == 0 && is_yield(frame->prev_instr)) {
         assert(is_resume(frame->prev_instr + 1));
-        int exception_handler_depth = frame->prev_instr[0].op.code;
+        int exception_handler_depth = frame->prev_instr[0].op.arg;
         assert(exception_handler_depth > 0);
         /* We can safely ignore the outermost try block
          * as it automatically generated to handle
          * StopIteration. */
         if (exception_handler_depth == 1) {
+            gen->gi_frame_state = FRAME_COMPLETED;
             Py_RETURN_NONE;
         }
     }