[Python-checkins] cpython (merge 3.6 -> default): Merge 3.6

victor.stinner python-checkins at python.org
Thu Nov 24 16:35:16 EST 2016


https://hg.python.org/cpython/rev/6453ff3328b8
changeset:   105358:6453ff3328b8
parent:      105356:72b8a7423cac
parent:      105357:303cedfb9e7a
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Thu Nov 24 22:33:49 2016 +0100
summary:
  Merge 3.6

files:
  Misc/NEWS           |  4 ++++
  Objects/genobject.c |  9 +++++++++
  Python/ceval.c      |  1 +
  3 files changed, 14 insertions(+), 0 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,10 @@
 Core and Builtins
 -----------------
 
+- Issue #28782: Fix a bug in the implementation ``yield from`` when checking
+  if the next instruction is YIELD_FROM. Regression introduced by WORDCODE
+  (issue #26647).
+
 - Issue #28774: Fix error position of the unicode error in ASCII and Latin1
   encoders when a string returned by the error handler contains multiple
   non-encodable characters (non-ASCII for the ASCII codec, characters out
diff --git a/Objects/genobject.c b/Objects/genobject.c
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -355,6 +355,14 @@
         PyObject *bytecode = f->f_code->co_code;
         unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
 
+        if (f->f_lasti < 0) {
+            /* Return immediately if the frame didn't start yet. YIELD_FROM
+               always come after LOAD_CONST: a code object should not start
+               with YIELD_FROM */
+            assert(code[0] != YIELD_FROM);
+            return NULL;
+        }
+
         if (code[f->f_lasti + sizeof(_Py_CODEUNIT)] != YIELD_FROM)
             return NULL;
         yf = f->f_stacktop[-1];
@@ -463,6 +471,7 @@
             assert(ret == yf);
             Py_DECREF(ret);
             /* Termination repetition of YIELD_FROM */
+            assert(gen->gi_frame->f_lasti >= 0);
             gen->gi_frame->f_lasti += sizeof(_Py_CODEUNIT);
             if (_PyGen_FetchStopIterationValue(&val) == 0) {
                 ret = gen_send_ex(gen, val, 0, 0);
diff --git a/Python/ceval.c b/Python/ceval.c
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -2049,6 +2049,7 @@
             f->f_stacktop = stack_pointer;
             why = WHY_YIELD;
             /* and repeat... */
+            assert(f->f_lasti >= (int)sizeof(_Py_CODEUNIT));
             f->f_lasti -= sizeof(_Py_CODEUNIT);
             goto fast_yield;
         }

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list