]> granicus.if.org Git - python/commitdiff
Issue #28317: The disassembler now decodes FORMAT_VALUE argument.
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 8 Oct 2016 09:34:25 +0000 (12:34 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Sat, 8 Oct 2016 09:34:25 +0000 (12:34 +0300)
Lib/dis.py
Lib/test/test_dis.py
Misc/NEWS

index 3a706be3c8914dbfc27a1d4fc0bb43465156d447..0794b7f743b01de50c1575aceff7cab17918395b 100644 (file)
@@ -16,6 +16,8 @@ del _opcodes_all
 _have_code = (types.MethodType, types.FunctionType, types.CodeType,
               classmethod, staticmethod, type)
 
+FORMAT_VALUE = opmap['FORMAT_VALUE']
+
 def _try_compile(source, name):
     """Attempts to compile the given source, first as an expression and
        then as a statement if the first approach fails.
@@ -314,6 +316,13 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
                 argrepr = argval
             elif op in hasfree:
                 argval, argrepr = _get_name_info(arg, cells)
+            elif op == FORMAT_VALUE:
+                argval = ((None, str, repr, ascii)[arg & 0x3], bool(arg & 0x4))
+                argrepr = ('', 'str', 'repr', 'ascii')[arg & 0x3]
+                if argval[1]:
+                    if argrepr:
+                        argrepr += ', '
+                    argrepr += 'with format'
         yield Instruction(opname[op], op,
                           arg, argval, argrepr,
                           offset, starts_line, is_jump_target)
index f3193368e98b5cecaa277bb15172d1efc570ff61..b9b5ac2667ee0a0e56cb70c0a9e78f7bf4fd47fe 100644 (file)
@@ -301,6 +301,27 @@ dis_traceback = """\
        TRACEBACK_CODE.co_firstlineno + 4,
        TRACEBACK_CODE.co_firstlineno + 5)
 
+def _fstring(a, b, c, d):
+    return f'{a} {b:4} {c!r} {d!r:4}'
+
+dis_fstring = """\
+%3d           0 LOAD_FAST                0 (a)
+              2 FORMAT_VALUE             0
+              4 LOAD_CONST               1 (' ')
+              6 LOAD_FAST                1 (b)
+              8 LOAD_CONST               2 ('4')
+             10 FORMAT_VALUE             4 (with format)
+             12 LOAD_CONST               1 (' ')
+             14 LOAD_FAST                2 (c)
+             16 FORMAT_VALUE             2 (repr)
+             18 LOAD_CONST               1 (' ')
+             20 LOAD_FAST                3 (d)
+             22 LOAD_CONST               2 ('4')
+             24 FORMAT_VALUE             6 (repr, with format)
+             26 BUILD_STRING             7
+             28 RETURN_VALUE
+""" % (_fstring.__code__.co_firstlineno + 1,)
+
 def _g(x):
     yield x
 
@@ -404,6 +425,9 @@ class DisTests(unittest.TestCase):
         gen_disas = self.get_disassembly(_g(1))  # Disassemble generator itself
         self.assertEqual(gen_disas, gen_func_disas)
 
+    def test_disassemble_fstring(self):
+        self.do_disassembly_test(_fstring, dis_fstring)
+
     def test_dis_none(self):
         try:
             del sys.last_traceback
index 237bf6fd0103558025834d3ed1b07d1009194dd7..f433959a938d762948f41d41ac27c1878aa45f0b 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -62,6 +62,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #28317: The disassembler now decodes FORMAT_VALUE argument.
+
 - Issue #26293: Fixed writing ZIP files that starts not from the start of the
   file.  Offsets in ZIP file now are relative to the start of the archive in
   conforming to the specification.