diff options
Diffstat (limited to 'Python/ceval.c')
| -rw-r--r-- | Python/ceval.c | 665 | 
1 files changed, 587 insertions, 78 deletions
| diff --git a/Python/ceval.c b/Python/ceval.c index 7a0cb7f04a..7b405188d3 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -12,8 +12,10 @@  #include "Python.h"  #include "code.h" +#include "dictobject.h"  #include "frameobject.h"  #include "opcode.h" +#include "setobject.h"  #include "structmember.h"  #include <ctype.h> @@ -735,7 +737,7 @@ _Py_CheckRecursiveCall(const char *where)      if (tstate->recursion_depth > recursion_limit) {          --tstate->recursion_depth;          tstate->overflowed = 1; -        PyErr_Format(PyExc_RuntimeError, +        PyErr_Format(PyExc_RecursionError,                       "maximum recursion depth exceeded%s",                       where);          return -1; @@ -1189,7 +1191,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)      f->f_stacktop = NULL;       /* remains NULL unless yield suspends frame */      f->f_executing = 1; -    if (co->co_flags & CO_GENERATOR) { +    if (co->co_flags & (CO_GENERATOR | CO_COROUTINE)) {          if (!throwflag && f->f_exc_type != NULL && f->f_exc_type != Py_None) {              /* We were in an except handler when we left,                 restore the exception state which was put aside @@ -1504,6 +1506,18 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              DISPATCH();          } +        TARGET(BINARY_MATRIX_MULTIPLY) { +            PyObject *right = POP(); +            PyObject *left = TOP(); +            PyObject *res = PyNumber_MatrixMultiply(left, right); +            Py_DECREF(left); +            Py_DECREF(right); +            SET_TOP(res); +            if (res == NULL) +                goto error; +            DISPATCH(); +        } +          TARGET(BINARY_TRUE_DIVIDE) {              PyObject *divisor = POP();              PyObject *dividend = TOP(); @@ -1549,7 +1563,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              if (PyUnicode_CheckExact(left) &&                       PyUnicode_CheckExact(right)) {                  sum = unicode_concatenate(left, right, f, next_instr); -                /* unicode_concatenate consumed the ref to v */ +                /* unicode_concatenate consumed the ref to left */              }              else {                  sum = PyNumber_Add(left, right); @@ -1694,6 +1708,18 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              DISPATCH();          } +        TARGET(INPLACE_MATRIX_MULTIPLY) { +            PyObject *right = POP(); +            PyObject *left = TOP(); +            PyObject *res = PyNumber_InPlaceMatrixMultiply(left, right); +            Py_DECREF(left); +            Py_DECREF(right); +            SET_TOP(res); +            if (res == NULL) +                goto error; +            DISPATCH(); +        } +          TARGET(INPLACE_TRUE_DIVIDE) {              PyObject *divisor = POP();              PyObject *dividend = TOP(); @@ -1736,7 +1762,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              PyObject *sum;              if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) {                  sum = unicode_concatenate(left, right, f, next_instr); -                /* unicode_concatenate consumed the ref to v */ +                /* unicode_concatenate consumed the ref to left */              }              else {                  sum = PyNumber_InPlaceAdd(left, right); @@ -1827,7 +1853,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              PyObject *v = THIRD();              int err;              STACKADJ(-3); -            /* v[w] = u */ +            /* container[sub] = v */              err = PyObject_SetItem(container, sub, v);              Py_DECREF(v);              Py_DECREF(container); @@ -1842,7 +1868,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              PyObject *container = SECOND();              int err;              STACKADJ(-2); -            /* del v[w] */ +            /* del container[sub] */              err = PyObject_DelItem(container, sub);              Py_DECREF(container);              Py_DECREF(sub); @@ -1900,11 +1926,166 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              goto fast_block_end;          } +        TARGET(GET_AITER) { +            unaryfunc getter = NULL; +            PyObject *iter = NULL; +            PyObject *awaitable = NULL; +            PyObject *obj = TOP(); +            PyTypeObject *type = Py_TYPE(obj); + +            if (type->tp_as_async != NULL) { +                getter = type->tp_as_async->am_aiter; +            } + +            if (getter != NULL) { +                iter = (*getter)(obj); +                Py_DECREF(obj); +                if (iter == NULL) { +                    SET_TOP(NULL); +                    goto error; +                } +            } +            else { +                SET_TOP(NULL); +                PyErr_Format( +                    PyExc_TypeError, +                    "'async for' requires an object with " +                    "__aiter__ method, got %.100s", +                    type->tp_name); +                Py_DECREF(obj); +                goto error; +            } + +            if (Py_TYPE(iter)->tp_as_async != NULL && +                    Py_TYPE(iter)->tp_as_async->am_anext != NULL) { + +                /* Starting with CPython 3.5.2 __aiter__ should return +                   asynchronous iterators directly (not awaitables that +                   resolve to asynchronous iterators.) + +                   Therefore, we check if the object that was returned +                   from __aiter__ has an __anext__ method.  If it does, +                   we wrap it in an awaitable that resolves to `iter`. + +                   See http://bugs.python.org/issue27243 for more +                   details. +                */ + +                PyObject *wrapper = _PyAIterWrapper_New(iter); +                Py_DECREF(iter); +                SET_TOP(wrapper); +                DISPATCH(); +            } + +            awaitable = _PyCoro_GetAwaitableIter(iter); +            if (awaitable == NULL) { +                SET_TOP(NULL); +                PyErr_Format( +                    PyExc_TypeError, +                    "'async for' received an invalid object " +                    "from __aiter__: %.100s", +                    Py_TYPE(iter)->tp_name); + +                Py_DECREF(iter); +                goto error; +            } else { +                Py_DECREF(iter); + +                if (PyErr_WarnFormat( +                        PyExc_PendingDeprecationWarning, 1, +                        "'%.100s' implements legacy __aiter__ protocol; " +                        "__aiter__ should return an asynchronous " +                        "iterator, not awaitable", +                        type->tp_name)) +                { +                    /* Warning was converted to an error. */ +                    Py_DECREF(awaitable); +                    SET_TOP(NULL); +                    goto error; +                } +            } + +            SET_TOP(awaitable); +            DISPATCH(); +        } + +        TARGET(GET_ANEXT) { +            unaryfunc getter = NULL; +            PyObject *next_iter = NULL; +            PyObject *awaitable = NULL; +            PyObject *aiter = TOP(); +            PyTypeObject *type = Py_TYPE(aiter); + +            if (type->tp_as_async != NULL) +                getter = type->tp_as_async->am_anext; + +            if (getter != NULL) { +                next_iter = (*getter)(aiter); +                if (next_iter == NULL) { +                    goto error; +                } +            } +            else { +                PyErr_Format( +                    PyExc_TypeError, +                    "'async for' requires an iterator with " +                    "__anext__ method, got %.100s", +                    type->tp_name); +                goto error; +            } + +            awaitable = _PyCoro_GetAwaitableIter(next_iter); +            if (awaitable == NULL) { +                PyErr_Format( +                    PyExc_TypeError, +                    "'async for' received an invalid object " +                    "from __anext__: %.100s", +                    Py_TYPE(next_iter)->tp_name); + +                Py_DECREF(next_iter); +                goto error; +            } else +                Py_DECREF(next_iter); + +            PUSH(awaitable); +            DISPATCH(); +        } + +        TARGET(GET_AWAITABLE) { +            PyObject *iterable = TOP(); +            PyObject *iter = _PyCoro_GetAwaitableIter(iterable); + +            Py_DECREF(iterable); + +            if (iter != NULL && PyCoro_CheckExact(iter)) { +                PyObject *yf = _PyGen_yf((PyGenObject*)iter); +                if (yf != NULL) { +                    /* `iter` is a coroutine object that is being +                       awaited, `yf` is a pointer to the current awaitable +                       being awaited on. */ +                    Py_DECREF(yf); +                    Py_CLEAR(iter); +                    PyErr_SetString( +                        PyExc_RuntimeError, +                        "coroutine is being awaited already"); +                    /* The code below jumps to `error` if `iter` is NULL. */ +                } +            } + +            SET_TOP(iter); /* Even if it's NULL */ + +            if (iter == NULL) { +                goto error; +            } + +            DISPATCH(); +        } +          TARGET(YIELD_FROM) {              PyObject *v = POP();              PyObject *reciever = TOP();              int err; -            if (PyGen_CheckExact(reciever)) { +            if (PyGen_CheckExact(reciever) || PyCoro_CheckExact(reciever)) {                  retval = _PyGen_Send((PyGenObject *)reciever, v);              } else {                  _Py_IDENTIFIER(send); @@ -1926,7 +2107,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)                  SET_TOP(val);                  DISPATCH();              } -            /* x remains on stack, retval is value to be yielded */ +            /* receiver remains on stack, retval is value to be yielded */              f->f_stacktop = stack_pointer;              why = WHY_YIELD;              /* and repeat... */ @@ -2015,7 +2196,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              else {                  PyObject *build_class_str = _PyUnicode_FromId(&PyId___build_class__);                  if (build_class_str == NULL) -                    break; +                    goto error;                  bc = PyObject_GetItem(f->f_builtins, build_class_str);                  if (bc == NULL) {                      if (PyErr_ExceptionMatches(PyExc_KeyError)) @@ -2233,6 +2414,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)                  /* Slow-path if globals or builtins is not a dict */                  v = PyObject_GetItem(f->f_globals, name);                  if (v == NULL) { +                    if (!PyErr_ExceptionMatches(PyExc_KeyError)) +                        goto error; +                    PyErr_Clear(); +                      v = PyObject_GetItem(f->f_builtins, name);                      if (v == NULL) {                          if (PyErr_ExceptionMatches(PyExc_KeyError)) @@ -2355,17 +2540,56 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              DISPATCH();          } +        TARGET_WITH_IMPL(BUILD_TUPLE_UNPACK, _build_list_unpack) +        TARGET(BUILD_LIST_UNPACK) +        _build_list_unpack: { +            int convert_to_tuple = opcode == BUILD_TUPLE_UNPACK; +            int i; +            PyObject *sum = PyList_New(0); +            PyObject *return_value; +            if (sum == NULL) +                goto error; + +            for (i = oparg; i > 0; i--) { +                PyObject *none_val; + +                none_val = _PyList_Extend((PyListObject *)sum, PEEK(i)); +                if (none_val == NULL) { +                    Py_DECREF(sum); +                    goto error; +                } +                Py_DECREF(none_val); +            } + +            if (convert_to_tuple) { +                return_value = PyList_AsTuple(sum); +                Py_DECREF(sum); +                if (return_value == NULL) +                    goto error; +            } +            else { +                return_value = sum; +            } + +            while (oparg--) +                Py_DECREF(POP()); +            PUSH(return_value); +            DISPATCH(); +        } +          TARGET(BUILD_SET) {              PyObject *set = PySet_New(NULL);              int err = 0; +            int i;              if (set == NULL)                  goto error; -            while (--oparg >= 0) { -                PyObject *item = POP(); +            for (i = oparg; i > 0; i--) { +                PyObject *item = PEEK(i);                  if (err == 0)                      err = PySet_Add(set, item);                  Py_DECREF(item);              } +            STACKADJ(-oparg);              if (err != 0) {                  Py_DECREF(set);                  goto error; @@ -2374,26 +2598,140 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              DISPATCH();          } +        TARGET(BUILD_SET_UNPACK) { +            int i; +            PyObject *sum = PySet_New(NULL); +            if (sum == NULL) +                goto error; + +            for (i = oparg; i > 0; i--) { +                if (_PySet_Update(sum, PEEK(i)) < 0) { +                    Py_DECREF(sum); +                    goto error; +                } +            } + +            while (oparg--) +                Py_DECREF(POP()); +            PUSH(sum); +            DISPATCH(); +        } +          TARGET(BUILD_MAP) { +            int i;              PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg);              if (map == NULL)                  goto error; +            for (i = oparg; i > 0; i--) { +                int err; +                PyObject *key = PEEK(2*i); +                PyObject *value = PEEK(2*i - 1); +                err = PyDict_SetItem(map, key, value); +                if (err != 0) { +                    Py_DECREF(map); +                    goto error; +                } +            } + +            while (oparg--) { +                Py_DECREF(POP()); +                Py_DECREF(POP()); +            }              PUSH(map);              DISPATCH();          } -        TARGET(STORE_MAP) { -            PyObject *key = TOP(); -            PyObject *value = SECOND(); -            PyObject *map = THIRD(); -            int err; -            STACKADJ(-2); -            assert(PyDict_CheckExact(map)); -            err = PyDict_SetItem(map, key, value); -            Py_DECREF(value); -            Py_DECREF(key); -            if (err != 0) +        TARGET_WITH_IMPL(BUILD_MAP_UNPACK_WITH_CALL, _build_map_unpack) +        TARGET(BUILD_MAP_UNPACK) +        _build_map_unpack: { +            int with_call = opcode == BUILD_MAP_UNPACK_WITH_CALL; +            int num_maps; +            int i; +            PyObject *sum = PyDict_New(); +            if (sum == NULL)                  goto error; +            if (with_call) { +                num_maps = oparg & 0xff; +            } +            else { +                num_maps = oparg; +            } + +            for (i = num_maps; i > 0; i--) { +                PyObject *arg = PEEK(i); +                if (with_call) { +                    PyObject *intersection = _PyDictView_Intersect(sum, arg); + +                    if (intersection == NULL) { +                        if (PyErr_ExceptionMatches(PyExc_AttributeError) || +                            !PyMapping_Check(arg)) { +                            int function_location = (oparg>>8) & 0xff; +                            PyObject *func = ( +                                    PEEK(function_location + num_maps)); +                            PyErr_Format(PyExc_TypeError, +                                    "%.200s%.200s argument after ** " +                                    "must be a mapping, not %.200s", +                                    PyEval_GetFuncName(func), +                                    PyEval_GetFuncDesc(func), +                                    arg->ob_type->tp_name); +                        } +                        Py_DECREF(sum); +                        goto error; +                    } + +                    if (PySet_GET_SIZE(intersection)) { +                        Py_ssize_t idx = 0; +                        PyObject *key; +                        int function_location = (oparg>>8) & 0xff; +                        PyObject *func = PEEK(function_location + num_maps); +                        Py_hash_t hash; +                        _PySet_NextEntry(intersection, &idx, &key, &hash); +                        if (!PyUnicode_Check(key)) { +                            PyErr_Format(PyExc_TypeError, +                                    "%.200s%.200s keywords must be strings", +                                    PyEval_GetFuncName(func), +                                    PyEval_GetFuncDesc(func)); +                        } else { +                            PyErr_Format(PyExc_TypeError, +                                    "%.200s%.200s got multiple " +                                    "values for keyword argument '%U'", +                                    PyEval_GetFuncName(func), +                                    PyEval_GetFuncDesc(func), +                                    key); +                        } +                        Py_DECREF(intersection); +                        Py_DECREF(sum); +                        goto error; +                    } +                    Py_DECREF(intersection); +                } + +                if (PyDict_Update(sum, arg) < 0) { +                    if (PyErr_ExceptionMatches(PyExc_AttributeError)) { +                        if (with_call) { +                            int function_location = (oparg>>8) & 0xff; +                            PyObject *func = PEEK(function_location + num_maps); +                            PyErr_Format(PyExc_TypeError, +                                    "%.200s%.200s argument after ** " +                                    "must be a mapping, not %.200s", +                                    PyEval_GetFuncName(func), +                                    PyEval_GetFuncDesc(func), +                                    arg->ob_type->tp_name); +                        } +                        else { +                            PyErr_Format(PyExc_TypeError, +                                    "'%.200s' object is not a mapping", +                                    arg->ob_type->tp_name); +                        } +                    } +                    Py_DECREF(sum); +                    goto error; +                } +            } + +            while (num_maps--) +                Py_DECREF(POP()); +            PUSH(sum);              DISPATCH();          } @@ -2405,7 +2743,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              STACKADJ(-2);              map = stack_pointer[-oparg];  /* dict */              assert(PyDict_CheckExact(map)); -            err = PyDict_SetItem(map, key, value);  /* v[w] = u */ +            err = PyDict_SetItem(map, key, value);  /* map[key] = value */              Py_DECREF(value);              Py_DECREF(key);              if (err != 0) @@ -2655,6 +2993,34 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              DISPATCH();          } +        TARGET(GET_YIELD_FROM_ITER) { +            /* before: [obj]; after [getiter(obj)] */ +            PyObject *iterable = TOP(); +            PyObject *iter; +            if (PyCoro_CheckExact(iterable)) { +                /* `iterable` is a coroutine */ +                if (!(co->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) { +                    /* and it is used in a 'yield from' expression of a +                       regular generator. */ +                    Py_DECREF(iterable); +                    SET_TOP(NULL); +                    PyErr_SetString(PyExc_TypeError, +                                    "cannot 'yield from' a coroutine object " +                                    "in a non-coroutine generator"); +                    goto error; +                } +            } +            else if (!PyGen_CheckExact(iterable)) { +                /* `iterable` is not a generator. */ +                iter = PyObject_GetIter(iterable); +                Py_DECREF(iterable); +                SET_TOP(iter); +                if (iter == NULL) +                    goto error; +            } +            DISPATCH(); +        } +          PREDICTED_WITH_ARG(FOR_ITER);          TARGET(FOR_ITER) {              /* before: [iter]; after: [iter, iter()] *or* [] */ @@ -2707,6 +3073,39 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              DISPATCH();          } +        TARGET(BEFORE_ASYNC_WITH) { +            _Py_IDENTIFIER(__aexit__); +            _Py_IDENTIFIER(__aenter__); + +            PyObject *mgr = TOP(); +            PyObject *exit = special_lookup(mgr, &PyId___aexit__), +                     *enter; +            PyObject *res; +            if (exit == NULL) +                goto error; +            SET_TOP(exit); +            enter = special_lookup(mgr, &PyId___aenter__); +            Py_DECREF(mgr); +            if (enter == NULL) +                goto error; +            res = PyObject_CallFunctionObjArgs(enter, NULL); +            Py_DECREF(enter); +            if (res == NULL) +                goto error; +            PUSH(res); +            DISPATCH(); +        } + +        TARGET(SETUP_ASYNC_WITH) { +            PyObject *res = POP(); +            /* Setup the finally block before pushing the result +               of __aenter__ on the stack. */ +            PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg, +                               STACK_LEVEL()); +            PUSH(res); +            DISPATCH(); +        } +          TARGET(SETUP_WITH) {              _Py_IDENTIFIER(__exit__);              _Py_IDENTIFIER(__enter__); @@ -2733,7 +3132,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              DISPATCH();          } -        TARGET(WITH_CLEANUP) { +        TARGET(WITH_CLEANUP_START) {              /* At the top of the stack are 1-6 values indicating                 how/why we entered the finally clause:                 - TOP = None @@ -2761,7 +3160,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              PyObject *exit_func;              PyObject *exc = TOP(), *val = Py_None, *tb = Py_None, *res; -            int err;              if (exc == Py_None) {                  (void)POP();                  exit_func = TOP(); @@ -2811,11 +3209,26 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              if (res == NULL)                  goto error; +            Py_INCREF(exc); /* Duplicating the exception on the stack */ +            PUSH(exc); +            PUSH(res); +            PREDICT(WITH_CLEANUP_FINISH); +            DISPATCH(); +        } + +        PREDICTED(WITH_CLEANUP_FINISH); +        TARGET(WITH_CLEANUP_FINISH) { +            PyObject *res = POP(); +            PyObject *exc = POP(); +            int err; +              if (exc != Py_None)                  err = PyObject_IsTrue(res);              else                  err = 0; +              Py_DECREF(res); +            Py_DECREF(exc);              if (err < 0)                  goto error; @@ -2867,8 +3280,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)                  Py_INCREF(self);                  func = PyMethod_GET_FUNCTION(func);                  Py_INCREF(func); -                Py_DECREF(*pfunc); -                *pfunc = self; +                Py_SETREF(*pfunc, self);                  na++;                  /* n++; */              } else @@ -2923,6 +3335,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)                  PyObject *anns = PyDict_New();                  if (anns == NULL) {                      Py_DECREF(func); +                    Py_DECREF(names);                      goto error;                  }                  name_ix = PyTuple_Size(names); @@ -2938,9 +3351,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)                      if (err != 0) {                          Py_DECREF(anns);                          Py_DECREF(func); +                        Py_DECREF(names);                          goto error;                      }                  } +                Py_DECREF(names);                  if (PyFunction_SetAnnotations(func, anns) != 0) {                      /* Can't happen unless @@ -2950,7 +3365,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)                      goto error;                  }                  Py_DECREF(anns); -                Py_DECREF(names);              }              /* XXX Maybe this should be a separate opcode? */ @@ -3026,6 +3440,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              goto dispatch_opcode;          } +  #if USE_COMPUTED_GOTOS          _unknown_opcode:  #endif @@ -3168,11 +3583,10 @@ fast_block_end:      if (why != WHY_RETURN)          retval = NULL; -    assert((retval != NULL && !PyErr_Occurred()) -            || (retval == NULL && PyErr_Occurred())); +    assert((retval != NULL) ^ (PyErr_Occurred() != NULL));  fast_yield: -    if (co->co_flags & CO_GENERATOR) { +    if (co->co_flags & (CO_GENERATOR | CO_COROUTINE)) {          /* The purpose of this block is to put aside the generator's exception             state and restore that of the calling frame. If the current @@ -3230,7 +3644,7 @@ exit_eval_frame:      f->f_executing = 0;      tstate->frame = f->f_back; -    return retval; +    return _Py_CheckFunctionResult(NULL, retval, "PyEval_EvalFrameEx");  }  static void @@ -3387,10 +3801,11 @@ too_many_positional(PyCodeObject *co, int given, int defcount, PyObject **fastlo     PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust     the test in the if statements in Misc/gdbinit (pystack and pystackv). */ -PyObject * -PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, +static PyObject * +_PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,             PyObject **args, int argcount, PyObject **kws, int kwcount, -           PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure) +           PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure, +           PyObject *name, PyObject *qualname)  {      PyCodeObject* co = (PyCodeObject*)_co;      PyFrameObject *f; @@ -3573,7 +3988,21 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,          freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o;      } -    if (co->co_flags & CO_GENERATOR) { +    if (co->co_flags & (CO_GENERATOR | CO_COROUTINE)) { +        PyObject *gen; +        PyObject *coro_wrapper = tstate->coroutine_wrapper; +        int is_coro = co->co_flags & CO_COROUTINE; + +        if (is_coro && tstate->in_coroutine_wrapper) { +            assert(coro_wrapper != NULL); +            PyErr_Format(PyExc_RuntimeError, +                         "coroutine wrapper %.200R attempted " +                         "to recursively wrap %.200R", +                         coro_wrapper, +                         co); +            goto fail; +        } +          /* Don't need to keep the reference to f_back, it will be set           * when the generator is resumed. */          Py_CLEAR(f->f_back); @@ -3582,7 +4011,23 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,          /* Create a new generator that owns the ready to run frame           * and return that as the value. */ -        return PyGen_New(f); +        if (is_coro) { +            gen = PyCoro_New(f, name, qualname); +        } else { +            gen = PyGen_NewWithQualName(f, name, qualname); +        } +        if (gen == NULL) +            return NULL; + +        if (is_coro && coro_wrapper != NULL) { +            PyObject *wrapped; +            tstate->in_coroutine_wrapper = 1; +            wrapped = PyObject_CallFunction(coro_wrapper, "N", gen); +            tstate->in_coroutine_wrapper = 0; +            return wrapped; +        } + +        return gen;      }      retval = PyEval_EvalFrameEx(f,0); @@ -3601,6 +4046,16 @@ fail: /* Jump here from prelude on failure */      return retval;  } +PyObject * +PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, +           PyObject **args, int argcount, PyObject **kws, int kwcount, +           PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure) +{ +    return _PyEval_EvalCodeWithName(_co, globals, locals, +                                    args, argcount, kws, kwcount, +                                    defs, defcount, kwdefs, closure, +                                    NULL, NULL); +}  static PyObject *  special_lookup(PyObject *o, _Py_Identifier *id) @@ -3683,7 +4138,7 @@ do_raise(PyObject *exc, PyObject *cause)          type = tstate->exc_type;          value = tstate->exc_value;          tb = tstate->exc_traceback; -        if (type == Py_None) { +        if (type == Py_None || type == NULL) {              PyErr_SetString(PyExc_RuntimeError,                              "No active exception to reraise");              return 0; @@ -3791,9 +4246,17 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp)          if (w == NULL) {              /* Iterator done, via error or exhaustion. */              if (!PyErr_Occurred()) { -                PyErr_Format(PyExc_ValueError, -                    "need more than %d value%s to unpack", -                    i, i == 1 ? "" : "s"); +                if (argcntafter == -1) { +                    PyErr_Format(PyExc_ValueError, +                        "not enough values to unpack (expected %d, got %d)", +                        argcnt, i); +                } +                else { +                    PyErr_Format(PyExc_ValueError, +                        "not enough values to unpack " +                        "(expected at least %d, got %d)", +                        argcnt + argcntafter, i); +                }              }              goto Error;          } @@ -3810,8 +4273,9 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp)              return 1;          }          Py_DECREF(w); -        PyErr_Format(PyExc_ValueError, "too many values to unpack " -                     "(expected %d)", argcnt); +        PyErr_Format(PyExc_ValueError, +            "too many values to unpack (expected %d)", +            argcnt);          goto Error;      } @@ -3823,8 +4287,9 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp)      ll = PyList_GET_SIZE(l);      if (ll < argcntafter) { -        PyErr_Format(PyExc_ValueError, "need more than %zd values to unpack", -                     argcnt + ll); +        PyErr_Format(PyExc_ValueError, +            "not enough values to unpack (expected at least %d, got %zd)", +            argcnt + argcntafter, argcnt + ll);          goto Error;      } @@ -4008,6 +4473,22 @@ PyEval_SetTrace(Py_tracefunc func, PyObject *arg)                             || (tstate->c_profilefunc != NULL));  } +void +_PyEval_SetCoroutineWrapper(PyObject *wrapper) +{ +    PyThreadState *tstate = PyThreadState_GET(); + +    Py_XINCREF(wrapper); +    Py_XSETREF(tstate->coroutine_wrapper, wrapper); +} + +PyObject * +_PyEval_GetCoroutineWrapper(void) +{ +    PyThreadState *tstate = PyThreadState_GET(); +    return tstate->coroutine_wrapper; +} +  PyObject *  PyEval_GetBuiltins(void)  { @@ -4086,8 +4567,8 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)  #ifdef Py_DEBUG      /* PyEval_CallObjectWithKeywords() must not be called with an exception -       set, because it may clear it (directly or indirectly) -       and so the caller loses its exception */ +       set. It raises a new exception if parameters are invalid or if +       PyTuple_New() fails, and so the original exception is lost. */      assert(!PyErr_Occurred());  #endif @@ -4114,8 +4595,6 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)      result = PyObject_Call(func, arg, kw);      Py_DECREF(arg); -    assert((result != NULL && !PyErr_Occurred()) -           || (result == NULL && PyErr_Occurred()));      return result;  } @@ -4218,11 +4697,15 @@ call_function(PyObject ***pp_stack, int oparg              PyObject *self = PyCFunction_GET_SELF(func);              if (flags & METH_NOARGS && na == 0) {                  C_TRACE(x, (*meth)(self,NULL)); + +                x = _Py_CheckFunctionResult(func, x, NULL);              }              else if (flags & METH_O && na == 1) {                  PyObject *arg = EXT_POP(*pp_stack);                  C_TRACE(x, (*meth)(self,arg));                  Py_DECREF(arg); + +                x = _Py_CheckFunctionResult(func, x, NULL);              }              else {                  err_args(func, flags, na); @@ -4242,7 +4725,8 @@ call_function(PyObject ***pp_stack, int oparg                  x = NULL;              }          } -    } else { +    } +    else {          if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {              /* optimize access to bound methods */              PyObject *self = PyMethod_GET_SELF(func); @@ -4251,8 +4735,7 @@ call_function(PyObject ***pp_stack, int oparg              Py_INCREF(self);              func = PyMethod_GET_FUNCTION(func);              Py_INCREF(func); -            Py_DECREF(*pfunc); -            *pfunc = self; +            Py_SETREF(*pfunc, self);              na++;              n++;          } else @@ -4264,9 +4747,9 @@ call_function(PyObject ***pp_stack, int oparg              x = do_call(func, pp_stack, na, nk);          READ_TIMESTAMP(*pintr1);          Py_DECREF(func); + +        assert((x != NULL) ^ (PyErr_Occurred() != NULL));      } -    assert((x != NULL && !PyErr_Occurred()) -           || (x == NULL && PyErr_Occurred()));      /* Clear the stack of the function object.  Also removes         the arguments in case they weren't consumed already @@ -4278,8 +4761,7 @@ call_function(PyObject ***pp_stack, int oparg          PCALL(PCALL_POP);      } -    assert((x != NULL && !PyErr_Occurred()) -           || (x == NULL && PyErr_Occurred())); +    assert((x != NULL) ^ (PyErr_Occurred() != NULL));      return x;  } @@ -4299,6 +4781,8 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)      PyObject *globals = PyFunction_GET_GLOBALS(func);      PyObject *argdefs = PyFunction_GET_DEFAULTS(func);      PyObject *kwdefs = PyFunction_GET_KW_DEFAULTS(func); +    PyObject *name = ((PyFunctionObject *)func) -> func_name; +    PyObject *qualname = ((PyFunctionObject *)func) -> func_qualname;      PyObject **d = NULL;      int nd = 0; @@ -4341,10 +4825,11 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)          d = &PyTuple_GET_ITEM(argdefs, 0);          nd = Py_SIZE(argdefs);      } -    return PyEval_EvalCodeEx((PyObject*)co, globals, -                             (PyObject *)NULL, (*pp_stack)-n, na, -                             (*pp_stack)-2*nk, nk, d, nd, kwdefs, -                             PyFunction_GET_CLOSURE(func)); +    return _PyEval_EvalCodeWithName((PyObject*)co, globals, +                                    (PyObject *)NULL, (*pp_stack)-n, na, +                                    (*pp_stack)-2*nk, nk, d, nd, kwdefs, +                                    PyFunction_GET_CLOSURE(func), +                                    name, qualname);  }  static PyObject * @@ -4508,20 +4993,28 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)              kwdict = d;          }      } +    if (nk > 0) { +        kwdict = update_keyword_args(kwdict, nk, pp_stack, func); +        if (kwdict == NULL) +            goto ext_call_fail; +    } +      if (flags & CALL_FLAG_VAR) {          stararg = EXT_POP(*pp_stack);          if (!PyTuple_Check(stararg)) {              PyObject *t = NULL; +            if (Py_TYPE(stararg)->tp_iter == NULL && +                    !PySequence_Check(stararg)) { +                PyErr_Format(PyExc_TypeError, +                             "%.200s%.200s argument after * " +                             "must be an iterable, not %.200s", +                             PyEval_GetFuncName(func), +                             PyEval_GetFuncDesc(func), +                             stararg->ob_type->tp_name); +                goto ext_call_fail; +            }              t = PySequence_Tuple(stararg);              if (t == NULL) { -                if (PyErr_ExceptionMatches(PyExc_TypeError)) { -                    PyErr_Format(PyExc_TypeError, -                                 "%.200s%.200s argument after * " -                                 "must be a sequence, not %.200s", -                                 PyEval_GetFuncName(func), -                                 PyEval_GetFuncDesc(func), -                                 stararg->ob_type->tp_name); -                }                  goto ext_call_fail;              }              Py_DECREF(stararg); @@ -4529,11 +5022,6 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)          }          nstar = PyTuple_GET_SIZE(stararg);      } -    if (nk > 0) { -        kwdict = update_keyword_args(kwdict, nk, pp_stack, func); -        if (kwdict == NULL) -            goto ext_call_fail; -    }      callargs = update_star_args(na, nstar, stararg, pp_stack);      if (callargs == NULL)          goto ext_call_fail; @@ -4563,12 +5051,10 @@ ext_call_fail:      Py_XDECREF(callargs);      Py_XDECREF(kwdict);      Py_XDECREF(stararg); -    assert((result != NULL && !PyErr_Occurred()) -           || (result == NULL && PyErr_Occurred()));      return result;  } -/* Extract a slice index from a PyInt or PyLong or an object with the +/* Extract a slice index from a PyLong or an object with the     nb_index slot defined, and store in *pi.     Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX,     and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1. @@ -4658,12 +5144,35 @@ static PyObject *  import_from(PyObject *v, PyObject *name)  {      PyObject *x; +    _Py_IDENTIFIER(__name__); +    PyObject *fullmodname, *pkgname;      x = PyObject_GetAttr(v, name); -    if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { -        PyErr_Format(PyExc_ImportError, "cannot import name %R", name); +    if (x != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError)) +        return x; +    /* Issue #17636: in case this failed because of a circular relative +       import, try to fallback on reading the module directly from +       sys.modules. */ +    PyErr_Clear(); +    pkgname = _PyObject_GetAttrId(v, &PyId___name__); +    if (pkgname == NULL) { +        goto error; +    } +    fullmodname = PyUnicode_FromFormat("%U.%U", pkgname, name); +    Py_DECREF(pkgname); +    if (fullmodname == NULL) { +        return NULL; +    } +    x = PyDict_GetItem(PyImport_GetModuleDict(), fullmodname); +    Py_DECREF(fullmodname); +    if (x == NULL) { +        goto error;      } +    Py_INCREF(x);      return x; + error: +    PyErr_Format(PyExc_ImportError, "cannot import name %R", name); +    return NULL;  }  static int | 
