diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2018-04-02 22:41:38 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-02 22:41:38 (GMT) |
commit | a68f2f0578bbf812fa2264d0e0bb388340d6e230 (patch) | |
tree | 28e7b09fab40a1a44088ca682bef53dc0ee02171 /Python/ceval.c | |
parent | 55966f3a0d5f1bf823bd22ce1abbde267b06552f (diff) | |
download | cpython-a68f2f0578bbf812fa2264d0e0bb388340d6e230.zip cpython-a68f2f0578bbf812fa2264d0e0bb388340d6e230.tar.gz cpython-a68f2f0578bbf812fa2264d0e0bb388340d6e230.tar.bz2 |
bpo-29922: Improve error messages in 'async with' (GH-6352)
when __aenter__() or __aexit__() return non-awaitable object.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index d18a284..da83e41 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -69,6 +69,7 @@ static PyObject * unicode_concatenate(PyObject *, PyObject *, static PyObject * special_lookup(PyObject *, _Py_Identifier *); static int check_args_iterable(PyObject *func, PyObject *vararg); static void format_kwargs_mapping_error(PyObject *func, PyObject *kwargs); +static void format_awaitable_error(PyTypeObject *, int); #define NAME_ERROR_MSG \ "name '%.200s' is not defined" @@ -1736,6 +1737,11 @@ main_loop: PyObject *iterable = TOP(); PyObject *iter = _PyCoro_GetAwaitableIter(iterable); + if (iter == NULL) { + format_awaitable_error(Py_TYPE(iterable), + _Py_OPCODE(next_instr[-2])); + } + Py_DECREF(iterable); if (iter != NULL && PyCoro_CheckExact(iter)) { @@ -4985,6 +4991,25 @@ format_exc_unbound(PyCodeObject *co, int oparg) } } +static void +format_awaitable_error(PyTypeObject *type, int prevopcode) +{ + if (type->tp_as_async == NULL || type->tp_as_async->am_await == NULL) { + if (prevopcode == BEFORE_ASYNC_WITH) { + PyErr_Format(PyExc_TypeError, + "'async with' received an object from __aenter__ " + "that does not implement __await__: %.100s", + type->tp_name); + } + else if (prevopcode == WITH_CLEANUP_START) { + PyErr_Format(PyExc_TypeError, + "'async with' received an object from __aexit__ " + "that does not implement __await__: %.100s", + type->tp_name); + } + } +} + static PyObject * unicode_concatenate(PyObject *v, PyObject *w, PyFrameObject *f, const _Py_CODEUNIT *next_instr) |