https://github.com/python/cpython/commit/e8e151d4715839f785ff853c77594d7302b40266
commit: e8e151d4715839f785ff853c77594d7302b40266
branch: main
author: Jelle Zijlstra <[email protected]>
committer: JelleZijlstra <[email protected]>
date: 2024-06-20T07:07:24-07:00
summary:
gh-120780: Show attribute name for LOAD_SPECIAL in dis output (#120781)
files:
A Misc/NEWS.d/next/Library/2024-06-19-23-08-25.gh-issue-120780.0Omopb.rst
M Lib/dis.py
M Lib/opcode.py
M Lib/test/test_dis.py
M Modules/_opcode.c
M Modules/clinic/_opcode.c.h
diff --git a/Lib/dis.py b/Lib/dis.py
index f5bb7976b5fa62..bb922b786f5307 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -14,6 +14,7 @@
_common_constants,
_intrinsic_1_descs,
_intrinsic_2_descs,
+ _special_method_names,
_specializations,
_specialized_opmap,
)
@@ -46,6 +47,7 @@
CALL_INTRINSIC_1 = opmap['CALL_INTRINSIC_1']
CALL_INTRINSIC_2 = opmap['CALL_INTRINSIC_2']
LOAD_COMMON_CONSTANT = opmap['LOAD_COMMON_CONSTANT']
+LOAD_SPECIAL = opmap['LOAD_SPECIAL']
LOAD_FAST_LOAD_FAST = opmap['LOAD_FAST_LOAD_FAST']
STORE_FAST_LOAD_FAST = opmap['STORE_FAST_LOAD_FAST']
STORE_FAST_STORE_FAST = opmap['STORE_FAST_STORE_FAST']
@@ -609,6 +611,8 @@ def get_argval_argrepr(self, op, arg, offset):
argrepr = obj.__name__
else:
argrepr = repr(obj)
+ elif deop == LOAD_SPECIAL:
+ argrepr = _special_method_names[arg]
return argval, argrepr
def get_instructions(x, *, first_line=None, show_caches=None, adaptive=False):
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 85c0834c698ba2..2698609cd5636d 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -36,6 +36,7 @@
_intrinsic_1_descs = _opcode.get_intrinsic1_descs()
_intrinsic_2_descs = _opcode.get_intrinsic2_descs()
+_special_method_names = _opcode.get_special_method_names()
_common_constants = [AssertionError, NotImplementedError]
_nb_ops = _opcode.get_nb_ops()
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index ffbeea2ef56095..ab1c48f9b25361 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -481,10 +481,10 @@ def _with(c):
%4d LOAD_FAST 0 (c)
COPY 1
- LOAD_SPECIAL 1
+ LOAD_SPECIAL 1 (__exit__)
SWAP 2
SWAP 3
- LOAD_SPECIAL 0
+ LOAD_SPECIAL 0 (__enter__)
CALL 0
L1: POP_TOP
@@ -543,10 +543,10 @@ async def _asyncwith(c):
%4d LOAD_FAST 0 (c)
COPY 1
- LOAD_SPECIAL 3
+ LOAD_SPECIAL 3 (__aexit__)
SWAP 2
SWAP 3
- LOAD_SPECIAL 2
+ LOAD_SPECIAL 2 (__aenter__)
CALL 0
GET_AWAITABLE 1
LOAD_CONST 0 (None)
@@ -1738,10 +1738,10 @@ def _prepare_test_cases():
Instruction(opname='POP_TOP', opcode=29, arg=None, argval=None, argrepr='',
offset=240, start_offset=240, starts_line=False, line_number=21, label=None,
positions=None, cache_info=None),
Instruction(opname='LOAD_FAST', opcode=83, arg=0, argval='i', argrepr='i',
offset=242, start_offset=242, starts_line=True, line_number=25, label=None,
positions=None, cache_info=None),
Instruction(opname='COPY', opcode=58, arg=1, argval=1, argrepr='',
offset=244, start_offset=244, starts_line=False, line_number=25, label=None,
positions=None, cache_info=None),
- Instruction(opname='LOAD_SPECIAL', opcode=91, arg=1, argval=1, argrepr='',
offset=246, start_offset=246, starts_line=False, line_number=25, label=None,
positions=None, cache_info=None),
+ Instruction(opname='LOAD_SPECIAL', opcode=91, arg=1, argval=1,
argrepr='__exit__', offset=246, start_offset=246, starts_line=False,
line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='SWAP', opcode=114, arg=2, argval=2, argrepr='',
offset=248, start_offset=248, starts_line=False, line_number=25, label=None,
positions=None, cache_info=None),
Instruction(opname='SWAP', opcode=114, arg=3, argval=3, argrepr='',
offset=250, start_offset=250, starts_line=False, line_number=25, label=None,
positions=None, cache_info=None),
- Instruction(opname='LOAD_SPECIAL', opcode=91, arg=0, argval=0, argrepr='',
offset=252, start_offset=252, starts_line=False, line_number=25, label=None,
positions=None, cache_info=None),
+ Instruction(opname='LOAD_SPECIAL', opcode=91, arg=0, argval=0,
argrepr='__enter__', offset=252, start_offset=252, starts_line=False,
line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='CALL', opcode=50, arg=0, argval=0, argrepr='',
offset=254, start_offset=254, starts_line=False, line_number=25, label=None,
positions=None, cache_info=[('counter', 1, b'\x00\x00'), ('func_version', 2,
b'\x00\x00\x00\x00')]),
Instruction(opname='STORE_FAST', opcode=109, arg=1, argval='dodgy',
argrepr='dodgy', offset=262, start_offset=262, starts_line=False,
line_number=25, label=None, positions=None, cache_info=None),
Instruction(opname='LOAD_GLOBAL', opcode=89, arg=3, argval='print',
argrepr='print + NULL', offset=264, start_offset=264, starts_line=True,
line_number=26, label=None, positions=None, cache_info=[('counter', 1,
b'\x00\x00'), ('index', 1, b'\x00\x00'), ('module_keys_version', 1,
b'\x00\x00'), ('builtin_keys_version', 1, b'\x00\x00')]),
diff --git
a/Misc/NEWS.d/next/Library/2024-06-19-23-08-25.gh-issue-120780.0Omopb.rst
b/Misc/NEWS.d/next/Library/2024-06-19-23-08-25.gh-issue-120780.0Omopb.rst
new file mode 100644
index 00000000000000..df3cfbcdbd2e29
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-06-19-23-08-25.gh-issue-120780.0Omopb.rst
@@ -0,0 +1 @@
+Show string value of LOAD_SPECIAL oparg in :mod:`dis` output.
diff --git a/Modules/_opcode.c b/Modules/_opcode.c
index cc72cb170ceaed..d666f634757510 100644
--- a/Modules/_opcode.c
+++ b/Modules/_opcode.c
@@ -5,6 +5,7 @@
#include "Python.h"
#include "compile.h"
#include "opcode.h"
+#include "internal/pycore_ceval.h"
#include "internal/pycore_code.h"
#include "internal/pycore_compile.h"
#include "internal/pycore_intrinsics.h"
@@ -349,6 +350,32 @@ _opcode_get_intrinsic2_descs_impl(PyObject *module)
/*[clinic input]
+_opcode.get_special_method_names
+
+Return a list of special method names.
+[clinic start generated code]*/
+
+static PyObject *
+_opcode_get_special_method_names_impl(PyObject *module)
+/*[clinic end generated code: output=fce72614cd988d17 input=25f2115560bdf163]*/
+{
+ PyObject *list = PyList_New(SPECIAL_MAX + 1);
+ if (list == NULL) {
+ return NULL;
+ }
+ for (int i=0; i <= SPECIAL_MAX; i++) {
+ PyObject *name = _Py_SpecialMethods[i].name;
+ if (name == NULL) {
+ Py_DECREF(list);
+ return NULL;
+ }
+ PyList_SET_ITEM(list, i, name);
+ }
+ return list;
+}
+
+/*[clinic input]
+
_opcode.get_executor
code: object
@@ -392,6 +419,7 @@ opcode_functions[] = {
_OPCODE_GET_INTRINSIC1_DESCS_METHODDEF
_OPCODE_GET_INTRINSIC2_DESCS_METHODDEF
_OPCODE_GET_EXECUTOR_METHODDEF
+ _OPCODE_GET_SPECIAL_METHOD_NAMES_METHODDEF
{NULL, NULL, 0, NULL}
};
diff --git a/Modules/clinic/_opcode.c.h b/Modules/clinic/_opcode.c.h
index fb90fb8e32f918..32ac9521a2b5cf 100644
--- a/Modules/clinic/_opcode.c.h
+++ b/Modules/clinic/_opcode.c.h
@@ -669,6 +669,24 @@ _opcode_get_intrinsic2_descs(PyObject *module, PyObject
*Py_UNUSED(ignored))
return _opcode_get_intrinsic2_descs_impl(module);
}
+PyDoc_STRVAR(_opcode_get_special_method_names__doc__,
+"get_special_method_names($module, /)\n"
+"--\n"
+"\n"
+"Return a list of special method names.");
+
+#define _OPCODE_GET_SPECIAL_METHOD_NAMES_METHODDEF \
+ {"get_special_method_names",
(PyCFunction)_opcode_get_special_method_names, METH_NOARGS,
_opcode_get_special_method_names__doc__},
+
+static PyObject *
+_opcode_get_special_method_names_impl(PyObject *module);
+
+static PyObject *
+_opcode_get_special_method_names(PyObject *module, PyObject
*Py_UNUSED(ignored))
+{
+ return _opcode_get_special_method_names_impl(module);
+}
+
PyDoc_STRVAR(_opcode_get_executor__doc__,
"get_executor($module, /, code, offset)\n"
"--\n"
@@ -728,4 +746,4 @@ _opcode_get_executor(PyObject *module, PyObject *const
*args, Py_ssize_t nargs,
exit:
return return_value;
}
-/*[clinic end generated code: output=2dbb31b041b49c8f input=a9049054013a1b77]*/
+/*[clinic end generated code: output=3b4d4f32eedd636e input=a9049054013a1b77]*/
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]