]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-100762: Fix optimization in gen_close (GH-111069) (#115818)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 22 Feb 2024 14:05:59 +0000 (15:05 +0100)
committerGitHub <noreply@github.com>
Thu, 22 Feb 2024 14:05:59 +0000 (14:05 +0000)
gh-100762: Fix optimization in gen_close  (GH-111069)
(cherry picked from commit 0db2517687efcf5ec0174a32398ec1564b3204f1)

Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
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 3b9e4a6036742025f590ba03eaee9ba04d872026..bc58409c181360bccfcdd84c543220276d5ad8a5 100644 (file)
@@ -374,7 +374,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) {
@@ -384,6 +383,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;
@@ -396,12 +396,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;
         }
     }