Merge branch 'buildstring' of github.com:moagstar/python-uncompyle6 into buildstring

This commit is contained in:
rocky
2016-10-22 07:23:19 -04:00
4 changed files with 39 additions and 21 deletions

View File

@@ -21,9 +21,13 @@ def expressions(draw):
'container',
'self.attribute',
'self.method()',
'sorted(items, key=lambda x: x.name)',
'func(*args, **kwargs)',
'text or default',
# 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)',
#'func(*args, **kwargs)',
#'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):
hypothesis.assume(len(text))
hypothesis.assume("f'{" in text)
expr = text + '\n'
code = compile(expr, '<string>', 'single')
deparsed = deparse_code(PYTHON_VERSION, code, compile_mode='single')
@@ -137,7 +143,7 @@ def test_uncompyle_fstring(fstring):
@pytest.mark.skipif(PYTHON_VERSION < 3.6, reason='need at least python 3.6')
@pytest.mark.parametrize('fstring', [
#"f'{abc}{abc!s}'",
"f'{abc!s}'",
"f'{abc}0'",
])
def test_uncompyle_direct(fstring):
"""useful for debugging"""

View File

@@ -516,9 +516,24 @@ class Python3Parser(PythonParser):
elif opname == 'FORMAT_VALUE':
# Python 3.6+
self.addRule("""
expr ::= fstring_single
fstring_single ::= expr FORMAT_VALUE
""", nop_func)
elif opname == 'BUILD_STRING':
# Python 3.6+
v = token.attr
fstring_expr_or_str_n = "fstring_expr_or_str_%s" % v
rule = """
expr ::= fstring_expr
fstring_expr ::= expr FORMAT_VALUE
""", nop_func)
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
""" % (fstring_expr_or_str_n, fstring_expr_or_str_n, "fstring_expr_or_str " * v)
self.addRule(rule, nop_func)
elif opname in ('CALL_FUNCTION', 'CALL_FUNCTION_VAR',
'CALL_FUNCTION_VAR_KW', 'CALL_FUNCTION_KW'):
@@ -542,14 +557,6 @@ class Python3Parser(PythonParser):
if opname_base == 'BUILD_TUPLE':
rule = ('load_closure ::= %s%s' % (('LOAD_CLOSURE ' * v), opname))
self.add_unique_rule(rule, opname, token.attr, customize)
if opname_base == 'BUILD_LIST' and saw_format_value:
format_or_str_n = "formatted_value_or_str_%s" % v
self.addRule("""
expr ::= joined_str
joined_str ::= LOAD_CONST LOAD_ATTR %s CALL_FUNCTION_1
%s ::= %s%s
""" % (format_or_str_n, format_or_str_n, ("formatted_value_or_str " *v), opname),
nop_func)
elif opname == 'LOOKUP_METHOD':
# A PyPy speciality - DRY with parse2

View File

@@ -16,14 +16,14 @@ class Python36Parser(Python35Parser):
def p_36misc(self, args):
"""
formatted_value ::= LOAD_FAST FORMAT_VALUE
fstring_single ::= expr FORMAT_VALUE
fstring_expr ::= expr FORMAT_VALUE
str ::= LOAD_CONST
joined_str ::= LOAD_CONST LOAD_ATTR format_value_or_strs
BUILD_LIST CALL_FUNCTION
format_value_or_strs ::= format_value_or_strs format_value_or_str
format_value_or_strs ::= format_value_or_str
format_value_or_str ::= format_value
format_value_or_str ::= str
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_str
fstring_expr_or_str ::= fstring_expr
fstring_expr_or_str ::= str
"""
class Python36ParserSingle(Python36Parser, PythonParserSingle):

View File

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