summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrandt Bucher <brandtbucher@microsoft.com>2022-03-04 12:41:17 (GMT)
committerGitHub <noreply@github.com>2022-03-04 12:41:17 (GMT)
commit586b24d3be1aec5d2568b070a249b4d75e608782 (patch)
treee5e92e960433634f839118b51039a3fec3429d3e
parent03c2a36b2bd2d4469160d1607619ee144175d753 (diff)
downloadcpython-586b24d3be1aec5d2568b070a249b4d75e608782.zip
cpython-586b24d3be1aec5d2568b070a249b4d75e608782.tar.gz
cpython-586b24d3be1aec5d2568b070a249b4d75e608782.tar.bz2
bpo-46841: Fix error message hacks in `GET_AWAITABLE` (GH-31664)
-rw-r--r--Doc/library/dis.rst11
-rw-r--r--Include/opcode.h16
-rw-r--r--Lib/importlib/_bootstrap_external.py3
-rw-r--r--Lib/opcode.py3
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-36-15.bpo-46841.apPev2.rst2
-rw-r--r--Python/ceval.c16
-rw-r--r--Python/compile.c12
-rw-r--r--Python/opcode_targets.h6
8 files changed, 37 insertions, 32 deletions
diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index 3dac391..65e888d 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -475,15 +475,24 @@ the original TOS1.
**Coroutine opcodes**
-.. opcode:: GET_AWAITABLE
+.. opcode:: GET_AWAITABLE (where)
Implements ``TOS = get_awaitable(TOS)``, where ``get_awaitable(o)``
returns ``o`` if ``o`` is a coroutine object or a generator object with
the CO_ITERABLE_COROUTINE flag, or resolves
``o.__await__``.
+ If the ``where`` operand is nonzero, it indicates where the instruction
+ occurs:
+
+ * ``1`` After a call to ``__aenter__``
+ * ``2`` After a call to ``__aexit__``
+
.. versionadded:: 3.5
+ .. versionchanged:: 3.11
+ Previously, this instruction did not have an oparg.
+
.. opcode:: GET_AITER
diff --git a/Include/opcode.h b/Include/opcode.h
index 110f8c3..1b9eeac 100644
--- a/Include/opcode.h
+++ b/Include/opcode.h
@@ -33,7 +33,6 @@ extern "C" {
#define GET_YIELD_FROM_ITER 69
#define PRINT_EXPR 70
#define LOAD_BUILD_CLASS 71
-#define GET_AWAITABLE 73
#define LOAD_ASSERTION_ERROR 74
#define RETURN_GENERATOR 75
#define LIST_TO_TUPLE 82
@@ -86,6 +85,7 @@ extern "C" {
#define POP_JUMP_IF_NOT_NONE 128
#define POP_JUMP_IF_NONE 129
#define RAISE_VARARGS 130
+#define GET_AWAITABLE 131
#define MAKE_FUNCTION 132
#define BUILD_SLICE 133
#define JUMP_NO_INTERRUPT 134
@@ -160,13 +160,13 @@ extern "C" {
#define PRECALL_BUILTIN_FAST_WITH_KEYWORDS 66
#define PRECALL_NO_KW_LEN 67
#define PRECALL_NO_KW_ISINSTANCE 72
-#define PRECALL_NO_KW_LIST_APPEND 76
-#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 77
-#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 78
-#define PRECALL_NO_KW_STR_1 79
-#define PRECALL_NO_KW_TUPLE_1 80
-#define PRECALL_NO_KW_TYPE_1 81
-#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 131
+#define PRECALL_NO_KW_LIST_APPEND 73
+#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 76
+#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 77
+#define PRECALL_NO_KW_STR_1 78
+#define PRECALL_NO_KW_TUPLE_1 79
+#define PRECALL_NO_KW_TYPE_1 80
+#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 81
#define PRECALL_BOUND_METHOD 140
#define PRECALL_PYFUNC 141
#define RESUME_QUICK 143
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index 9d36bc2..529ca5a 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -392,6 +392,7 @@ _code_type = type(_write_atomic.__code__)
# Python 3.11a5 3483 (Use inline caching for COMPARE_OP and BINARY_SUBSCR)
# Python 3.11a5 3484 (Use inline caching for LOAD_ATTR, LOAD_METHOD, and
# STORE_ATTR)
+# Python 3.11a5 3485 (Add an oparg to GET_AWAITABLE)
# Python 3.12 will start with magic number 3500
@@ -406,7 +407,7 @@ _code_type = type(_write_atomic.__code__)
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated.
-MAGIC_NUMBER = (3484).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3485).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
_PYCACHE = '__pycache__'
diff --git a/Lib/opcode.py b/Lib/opcode.py
index f6e2dec..3675780 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -92,7 +92,6 @@ def_op('GET_YIELD_FROM_ITER', 69)
def_op('PRINT_EXPR', 70)
def_op('LOAD_BUILD_CLASS', 71)
-def_op('GET_AWAITABLE', 73)
def_op('LOAD_ASSERTION_ERROR', 74)
def_op('RETURN_GENERATOR', 75)
@@ -153,7 +152,7 @@ jabs_op('JUMP_IF_NOT_EG_MATCH', 127)
jabs_op('POP_JUMP_IF_NOT_NONE', 128)
jabs_op('POP_JUMP_IF_NONE', 129)
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
-
+def_op('GET_AWAITABLE', 131)
def_op('MAKE_FUNCTION', 132) # Flags
def_op('BUILD_SLICE', 133) # Number of items
jabs_op('JUMP_NO_INTERRUPT', 134) # Target byte offset from beginning of code
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-36-15.bpo-46841.apPev2.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-36-15.bpo-46841.apPev2.rst
new file mode 100644
index 0000000..6a45e6e
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-36-15.bpo-46841.apPev2.rst
@@ -0,0 +1,2 @@
+Use an oparg to simplify the construction of helpful error messages in
+:opcode:`GET_AWAITABLE`.
diff --git a/Python/ceval.c b/Python/ceval.c
index 915ab93..67c8b46 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -95,7 +95,7 @@ static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg
static int check_except_type_valid(PyThreadState *tstate, PyObject* right);
static int check_except_star_type_valid(PyThreadState *tstate, PyObject* right);
static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs);
-static void format_awaitable_error(PyThreadState *, PyTypeObject *, int, int);
+static void format_awaitable_error(PyThreadState *, PyTypeObject *, int);
static int get_exception_handler(PyCodeObject *, int, int*, int*, int*);
static _PyInterpreterFrame *
_PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
@@ -2505,13 +2505,7 @@ handle_eval_breaker:
PyObject *iter = _PyCoro_GetAwaitableIter(iterable);
if (iter == NULL) {
- int opcode_at_minus_4 = 0;
- if ((next_instr - first_instr) > 4) {
- opcode_at_minus_4 = _Py_OPCODE(next_instr[-4]);
- }
- format_awaitable_error(tstate, Py_TYPE(iterable),
- opcode_at_minus_4,
- _Py_OPCODE(next_instr[-2]));
+ format_awaitable_error(tstate, Py_TYPE(iterable), oparg);
}
Py_DECREF(iterable);
@@ -7638,16 +7632,16 @@ format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg)
}
static void
-format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevprevprevopcode, int prevopcode)
+format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int oparg)
{
if (type->tp_as_async == NULL || type->tp_as_async->am_await == NULL) {
- if (prevopcode == BEFORE_ASYNC_WITH) {
+ if (oparg == 1) {
_PyErr_Format(tstate, PyExc_TypeError,
"'async with' received an object from __aenter__ "
"that does not implement __await__: %.100s",
type->tp_name);
}
- else if (prevopcode == WITH_EXCEPT_START || (prevopcode == CALL && prevprevprevopcode == LOAD_CONST)) {
+ else if (oparg == 2) {
_PyErr_Format(tstate, PyExc_TypeError,
"'async with' received an object from __aexit__ "
"that does not implement __await__: %.100s",
diff --git a/Python/compile.c b/Python/compile.c
index 14595d9..ac9ddbc 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1978,7 +1978,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info,
return 0;
}
if (info->fb_type == ASYNC_WITH) {
- ADDOP(c, GET_AWAITABLE);
+ ADDOP_I(c, GET_AWAITABLE, 2);
ADDOP_LOAD_CONST(c, Py_None);
ADD_YIELD_FROM(c, 1);
}
@@ -5353,7 +5353,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
ADDOP_I(c, CALL, 0);
if (is_async_generator && type != COMP_GENEXP) {
- ADDOP(c, GET_AWAITABLE);
+ ADDOP_I(c, GET_AWAITABLE, 0);
ADDOP_LOAD_CONST(c, Py_None);
ADD_YIELD_FROM(c, 1);
}
@@ -5485,7 +5485,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos)
VISIT(c, expr, item->context_expr);
ADDOP(c, BEFORE_ASYNC_WITH);
- ADDOP(c, GET_AWAITABLE);
+ ADDOP_I(c, GET_AWAITABLE, 1);
ADDOP_LOAD_CONST(c, Py_None);
ADD_YIELD_FROM(c, 1);
@@ -5522,7 +5522,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos)
SET_LOC(c, s);
if(!compiler_call_exit_with_nones(c))
return 0;
- ADDOP(c, GET_AWAITABLE);
+ ADDOP_I(c, GET_AWAITABLE, 2);
ADDOP_LOAD_CONST(c, Py_None);
ADD_YIELD_FROM(c, 1);
@@ -5536,7 +5536,7 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos)
ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
ADDOP(c, PUSH_EXC_INFO);
ADDOP(c, WITH_EXCEPT_START);
- ADDOP(c, GET_AWAITABLE);
+ ADDOP_I(c, GET_AWAITABLE, 2);
ADDOP_LOAD_CONST(c, Py_None);
ADD_YIELD_FROM(c, 1);
compiler_with_except_finish(c, cleanup);
@@ -5710,7 +5710,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
}
VISIT(c, expr, e->v.Await.value);
- ADDOP(c, GET_AWAITABLE);
+ ADDOP_I(c, GET_AWAITABLE, 0);
ADDOP_LOAD_CONST(c, Py_None);
ADD_YIELD_FROM(c, 1);
break;
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index 7be7b16..2060793 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -72,15 +72,15 @@ static void *opcode_targets[256] = {
&&TARGET_PRINT_EXPR,
&&TARGET_LOAD_BUILD_CLASS,
&&TARGET_PRECALL_NO_KW_ISINSTANCE,
- &&TARGET_GET_AWAITABLE,
+ &&TARGET_PRECALL_NO_KW_LIST_APPEND,
&&TARGET_LOAD_ASSERTION_ERROR,
&&TARGET_RETURN_GENERATOR,
- &&TARGET_PRECALL_NO_KW_LIST_APPEND,
&&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_O,
&&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS,
&&TARGET_PRECALL_NO_KW_STR_1,
&&TARGET_PRECALL_NO_KW_TUPLE_1,
&&TARGET_PRECALL_NO_KW_TYPE_1,
+ &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST,
&&TARGET_LIST_TO_TUPLE,
&&TARGET_RETURN_VALUE,
&&TARGET_IMPORT_STAR,
@@ -130,7 +130,7 @@ static void *opcode_targets[256] = {
&&TARGET_POP_JUMP_IF_NOT_NONE,
&&TARGET_POP_JUMP_IF_NONE,
&&TARGET_RAISE_VARARGS,
- &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST,
+ &&TARGET_GET_AWAITABLE,
&&TARGET_MAKE_FUNCTION,
&&TARGET_BUILD_SLICE,
&&TARGET_JUMP_NO_INTERRUPT,