summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2018-04-02 22:41:38 (GMT)
committerGitHub <noreply@github.com>2018-04-02 22:41:38 (GMT)
commita68f2f0578bbf812fa2264d0e0bb388340d6e230 (patch)
tree28e7b09fab40a1a44088ca682bef53dc0ee02171 /Python/ceval.c
parent55966f3a0d5f1bf823bd22ce1abbde267b06552f (diff)
downloadcpython-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.c25
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)