further work on supporting single and multiple fstring decompilation

This commit is contained in:
moagstar
2016-10-20 20:44:27 +02:00
parent 7beaa9f36c
commit cec80e696c
4 changed files with 22 additions and 9 deletions

View File

@@ -21,9 +21,13 @@ def expressions(draw):
'container', 'container',
'self.attribute', 'self.attribute',
'self.method()', 'self.method()',
# These expressions are failing, I think these are control
# flow problems rather than problems with FORMAT_VALUE,
# however I need to confirm this...
#'sorted(items, key=lambda x: x.name)', #'sorted(items, key=lambda x: x.name)',
#'func(*args, **kwargs)', #'func(*args, **kwargs)',
#'text or default', #'text or default',
#'43 if life_the_universe and everything else None'
))) )))
@@ -119,6 +123,8 @@ def test_format_specifiers(format_specifier):
def run_test(text): def run_test(text):
hypothesis.assume(len(text))
hypothesis.assume("f'{" in text)
expr = text + '\n' expr = text + '\n'
code = compile(expr, '<string>', 'single') code = compile(expr, '<string>', 'single')
deparsed = deparse_code(PYTHON_VERSION, code, compile_mode='single') deparsed = deparse_code(PYTHON_VERSION, code, compile_mode='single')

View File

@@ -516,19 +516,21 @@ class Python3Parser(PythonParser):
elif opname == 'FORMAT_VALUE': elif opname == 'FORMAT_VALUE':
# Python 3.6+ # Python 3.6+
self.addRule(""" self.addRule("""
expr ::= fstring_expr expr ::= fstring_single
fstring_expr ::= expr FORMAT_VALUE fstring_single ::= expr FORMAT_VALUE
str ::= LOAD_CONST
fstring_expr_or_str ::= fstring_expr
fstring_expr_or_str ::= str
""", nop_func) """, nop_func)
elif opname == 'BUILD_STRING': elif opname == 'BUILD_STRING':
# Python 3.6+ # Python 3.6+
v = token.attr v = token.attr
fstring_expr_or_str_n = "fstring_expr_or_str_%s" % v fstring_expr_or_str_n = "fstring_expr_or_str_%s" % v
rule = """ rule = """
expr ::= fstring expr ::= fstring_expr
fstring ::= %s BUILD_STRING fstring_expr ::= expr FORMAT_VALUE
str ::= LOAD_CONST
fstring_expr_or_str ::= fstring_expr
fstring_expr_or_str ::= str
expr ::= fstring_multi
fstring_multi ::= %s BUILD_STRING
%s ::= %sBUILD_STRING %s ::= %sBUILD_STRING
""" % (fstring_expr_or_str_n, fstring_expr_or_str_n, "fstring_expr_or_str " * v) """ % (fstring_expr_or_str_n, fstring_expr_or_str_n, "fstring_expr_or_str " * v)
self.addRule(rule, nop_func) self.addRule(rule, nop_func)

View File

@@ -16,9 +16,10 @@ class Python36Parser(Python35Parser):
def p_36misc(self, args): def p_36misc(self, args):
""" """
fstring_single ::= expr FORMAT_VALUE
fstring_expr ::= expr FORMAT_VALUE fstring_expr ::= expr FORMAT_VALUE
str ::= LOAD_CONST str ::= LOAD_CONST
fstring ::= fstring_expr_or_strs BUILD_STRING fstring_multi ::= fstring_expr_or_strs BUILD_STRING
fstring_expr_or_strs ::= fstring_expr_or_strs fstring_expr_or_str fstring_expr_or_strs ::= fstring_expr_or_strs fstring_expr_or_str
fstring_expr_or_strs ::= fstring_expr_or_str fstring_expr_or_strs ::= fstring_expr_or_str
fstring_expr_or_str ::= fstring_expr fstring_expr_or_str ::= fstring_expr

View File

@@ -633,7 +633,8 @@ class SourceWalker(GenericASTTraversal, object):
####################### #######################
TABLE_DIRECT.update({ TABLE_DIRECT.update({
'fstring_expr': ( "{%c%{conversion}}", 0), 'fstring_expr': ( "{%c%{conversion}}", 0),
'fstring': ( "f'%c'", 0), 'fstring_single': ( "f'{%c%{conversion}}'", 0),
'fstring_multi': ( "f'%c'", 0),
}) })
return return
@@ -1893,6 +1894,9 @@ class SourceWalker(GenericASTTraversal, object):
node.conversion = self.FSTRING_CONVERSION_MAP.get(node.data[1].attr, '') node.conversion = self.FSTRING_CONVERSION_MAP.get(node.data[1].attr, '')
self.default(node) self.default(node)
def n_fstring_single(self, node):
return self.n_fstring_expr(node)
def engine(self, entry, startnode): def engine(self, entry, startnode):
"""The format template interpetation engine. See the comment at the """The format template interpetation engine. See the comment at the
beginning of this module for the how we interpret format specifications such as beginning of this module for the how we interpret format specifications such as