]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-46841: Fix error message hacks in `GET_AWAITABLE` (GH-31664)
authorBrandt Bucher <brandtbucher@microsoft.com>
Fri, 4 Mar 2022 12:41:17 +0000 (04:41 -0800)
committerGitHub <noreply@github.com>
Fri, 4 Mar 2022 12:41:17 +0000 (12:41 +0000)
Doc/library/dis.rst
Include/opcode.h
Lib/importlib/_bootstrap_external.py
Lib/opcode.py
Misc/NEWS.d/next/Core and Builtins/2022-03-03-12-36-15.bpo-46841.apPev2.rst [new file with mode: 0644]
Python/ceval.c
Python/compile.c
Python/opcode_targets.h

index 3dac3911da276746d87d69f397cb2a1d2dedbe1f..65e888dc86a194893b934ae5837df0597b014da2 100644 (file)
@@ -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
 
index 110f8c36171404bc797dd1f558808b1e9caa03e2..1b9eeacdeab01382098cf81836fdc58d83a2f6ab 100644 (file)
@@ -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
index 9d36bc27c44d4c4c482f10d21f4aa67c19dc4903..529ca5a295178e8dd735cae7d926c56ef23af8af 100644 (file)
@@ -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__'
index f6e2dec32e0f57e089064e3e54e6c8ea0c0b449d..3675780839671ced6356beba79d0f2c5107fe93b 100644 (file)
@@ -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 (file)
index 0000000..6a45e6e
--- /dev/null
@@ -0,0 +1,2 @@
+Use an oparg to simplify the construction of helpful error messages in
+:opcode:`GET_AWAITABLE`.
index 915ab9313a95af691fdc81ffea77bb3e8264a33c..67c8b46db2d63c076ee8e6d420dcca4f5127469d 100644 (file)
@@ -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",
index 14595d9b576f5d2e7a9b9b8fb731be8f847e6545..ac9ddbcd79d033e1ddc22b6b4165dbab45cffb7b 100644 (file)
@@ -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;
index 7be7b168a755d8a4cedf94a1bf09fe38967b4aca..2060793b4f1c8aa129ac27b8c61d499b23a0e0a9 100644 (file)
@@ -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,