diff --git a/Lib/dis.py b/Lib/dis.py index f64bae66fb8..543fdc7ed06 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -190,6 +190,9 @@ def disassemble(co, lasti=-1): if free is None: free = co.co_cellvars + co.co_freevars print('(' + free[oparg] + ')', end=' ') + elif op in hasnargs: + print('(%d positional, %d keyword pair)' + % (code[i-2], code[i-1]), end=' ') print() def _disassemble_bytes(code, lasti=-1, varnames=None, names=None, @@ -229,6 +232,9 @@ def _disassemble_bytes(code, lasti=-1, varnames=None, names=None, print('(%d)' % oparg, end=' ') elif op in hascompare: print('(' + cmp_op[oparg] + ')', end=' ') + elif op in hasnargs: + print('(%d positional, %d keyword pair)' + % (code[i-2], code[i-1]), end=' ') print() def _disassemble_str(source): diff --git a/Lib/opcode.py b/Lib/opcode.py index 6fe20c72207..a639fe322b7 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -6,7 +6,7 @@ operate on bytecodes (e.g. peephole optimizers). __all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs", "haslocal", "hascompare", "hasfree", "opname", "opmap", - "HAVE_ARGUMENT", "EXTENDED_ARG"] + "HAVE_ARGUMENT", "EXTENDED_ARG", "hasnargs"] cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', 'is not', 'exception match', 'BAD') @@ -18,6 +18,7 @@ hasjabs = [] haslocal = [] hascompare = [] hasfree = [] +hasnargs = [] opmap = {} opname = [''] * 256 @@ -152,6 +153,7 @@ haslocal.append(126) def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3) def_op('CALL_FUNCTION', 131) # #args + (#kwargs << 8) +hasnargs.append(131) def_op('MAKE_FUNCTION', 132) # Number of args with default values def_op('BUILD_SLICE', 133) # Number of items def_op('MAKE_CLOSURE', 134) @@ -165,8 +167,11 @@ def_op('DELETE_DEREF', 138) hasfree.append(138) def_op('CALL_FUNCTION_VAR', 140) # #args + (#kwargs << 8) +hasnargs.append(140) def_op('CALL_FUNCTION_KW', 141) # #args + (#kwargs << 8) +hasnargs.append(141) def_op('CALL_FUNCTION_VAR_KW', 142) # #args + (#kwargs << 8) +hasnargs.append(142) jrel_op('SETUP_WITH', 143) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 1506fe9f6e0..1bcd693f63a 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -38,7 +38,7 @@ def _f(a): dis_f = """\ %-4d 0 LOAD_GLOBAL 0 (print) 3 LOAD_FAST 0 (a) - 6 CALL_FUNCTION 1 + 6 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 9 POP_TOP %-4d 10 LOAD_CONST 1 (1) @@ -50,7 +50,7 @@ dis_f = """\ dis_f_co_code = """\ 0 LOAD_GLOBAL 0 (0) 3 LOAD_FAST 0 (0) - 6 CALL_FUNCTION 1 + 6 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 9 POP_TOP 10 LOAD_CONST 1 (1) 13 RETURN_VALUE @@ -68,7 +68,7 @@ dis_bug708901 = """\ 6 LOAD_CONST 1 (1) %-4d 9 LOAD_CONST 2 (10) - 12 CALL_FUNCTION 2 + 12 CALL_FUNCTION 2 (2 positional, 0 keyword pair) 15 GET_ITER >> 16 FOR_ITER 6 (to 25) 19 STORE_FAST 0 (res) diff --git a/Misc/NEWS b/Misc/NEWS index adbb81081c8..70feaf0cf6f 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -21,6 +21,8 @@ Core and Builtins Library ------- +- Issue #11823: disassembly now shows argument counts on calls with keyword args. + - Issue #14711: os.stat_float_times() has been deprecated. - LZMAFile now accepts the modes "rb"/"wb"/"ab" as synonyms of "r"/"w"/"a".