You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-02 16:44:46 +08:00
Better handling of BUILD_TUPLE_UNPACK
This commit is contained in:
@@ -679,7 +679,9 @@ class Python3Parser(PythonParser):
|
||||
v = token.attr
|
||||
rule = ('starred ::= %s %s' % ('expr ' * v, opname))
|
||||
self.addRule(rule, nop_func)
|
||||
elif opname_base in ('BUILD_LIST', 'BUILD_SET', 'BUILD_TUPLE'):
|
||||
|
||||
elif opname_base in ('BUILD_LIST', 'BUILD_SET', 'BUILD_TUPLE',
|
||||
'BUILD_TUPLE_UNPACK'):
|
||||
v = token.attr
|
||||
|
||||
is_LOAD_CLOSURE = False
|
||||
|
@@ -144,6 +144,8 @@ class Scanner3(Scanner):
|
||||
varargs_ops.add(self.opc.CALL_METHOD)
|
||||
if self.version >= 3.5:
|
||||
varargs_ops |= set([self.opc.BUILD_SET_UNPACK,
|
||||
# self.opc.BUILD_MAP_UNPACK, # we will handle this later
|
||||
self.opc.BUILD_LIST_UNPACK,
|
||||
self.opc.BUILD_TUPLE_UNPACK])
|
||||
if self.version >= 3.6:
|
||||
varargs_ops.add(self.opc.BUILD_CONST_KEY_MAP)
|
||||
|
@@ -252,6 +252,92 @@ def customize_for_version3(self, version):
|
||||
pass
|
||||
self.n_unmapexpr = unmapexpr
|
||||
|
||||
# FIXME: start here
|
||||
def n_list_unpack(node):
|
||||
"""
|
||||
prettyprint an unpacked list or tuple
|
||||
"""
|
||||
p = self.prec
|
||||
self.prec = 100
|
||||
lastnode = node.pop()
|
||||
lastnodetype = lastnode.kind
|
||||
|
||||
# If this build list is inside a CALL_FUNCTION_VAR,
|
||||
# then the first * has already been printed.
|
||||
# Until I have a better way to check for CALL_FUNCTION_VAR,
|
||||
# will assume that if the text ends in *.
|
||||
last_was_star = self.f.getvalue().endswith('*')
|
||||
|
||||
if lastnodetype.startswith('BUILD_LIST'):
|
||||
self.write('['); endchar = ']'
|
||||
elif lastnodetype.startswith('BUILD_TUPLE'):
|
||||
# Tuples can appear places that can NOT
|
||||
# have parenthesis around them, like array
|
||||
# subscripts. We check for that by seeing
|
||||
# if a tuple item is some sort of slice.
|
||||
no_parens = False
|
||||
for n in node:
|
||||
if n == 'expr' and n[0].kind.startswith('build_slice'):
|
||||
no_parens = True
|
||||
break
|
||||
pass
|
||||
if no_parens:
|
||||
endchar = ''
|
||||
else:
|
||||
self.write('('); endchar = ')'
|
||||
pass
|
||||
|
||||
elif lastnodetype.startswith('BUILD_SET'):
|
||||
self.write('{'); endchar = '}'
|
||||
elif lastnodetype.startswith('BUILD_MAP_UNPACK'):
|
||||
self.write('{*'); endchar = '}'
|
||||
elif lastnodetype.startswith('ROT_TWO'):
|
||||
self.write('('); endchar = ')'
|
||||
else:
|
||||
raise TypeError('Internal Error: n_build_list expects list, tuple, set, or unpack')
|
||||
|
||||
flat_elems = flatten_list(node)
|
||||
|
||||
self.indent_more(INDENT_PER_LEVEL)
|
||||
sep = ''
|
||||
for elem in flat_elems:
|
||||
if elem in ('ROT_THREE', 'EXTENDED_ARG'):
|
||||
continue
|
||||
assert elem == 'expr'
|
||||
elem = elem[0]
|
||||
line_number = self.line_number
|
||||
value = self.traverse(elem)
|
||||
if elem == 'tuple':
|
||||
assert value[0] == '('
|
||||
assert value[-1] == ')'
|
||||
value = value[1:-1]
|
||||
if value[-1] == ',':
|
||||
# singleton tuple
|
||||
value = value[:-1]
|
||||
else:
|
||||
value = '*' + value
|
||||
if line_number != self.line_number:
|
||||
sep += '\n' + self.indent + INDENT_PER_LEVEL[:-1]
|
||||
else:
|
||||
if sep != '': sep += ' '
|
||||
if not last_was_star:
|
||||
pass
|
||||
else:
|
||||
last_was_star = False
|
||||
self.write(sep, value)
|
||||
sep = ','
|
||||
if lastnode.attr == 1 and lastnodetype.startswith('BUILD_TUPLE'):
|
||||
self.write(',')
|
||||
self.write(endchar)
|
||||
self.indent_less(INDENT_PER_LEVEL)
|
||||
|
||||
self.prec = p
|
||||
self.prune()
|
||||
return
|
||||
|
||||
self.n_tuple_unpack = n_list_unpack
|
||||
|
||||
|
||||
if version >= 3.6:
|
||||
########################
|
||||
# Python 3.6+ Additions
|
||||
|
@@ -135,7 +135,7 @@ from spark_parser import GenericASTTraversal, DEFAULT_DEBUG as PARSER_DEFAULT_DE
|
||||
from uncompyle6.scanner import Code, get_scanner
|
||||
import uncompyle6.parser as python_parser
|
||||
from uncompyle6.semantics.make_function import (
|
||||
make_function2, make_function3, make_function3_annotate,
|
||||
make_function2, make_function3
|
||||
)
|
||||
from uncompyle6.semantics.parser_error import ParserError
|
||||
from uncompyle6.semantics.check_ast import checker
|
||||
@@ -147,7 +147,7 @@ from uncompyle6.scanners.tok import Token
|
||||
from uncompyle6.semantics.consts import (
|
||||
LINE_LENGTH, RETURN_LOCALS, NONE, RETURN_NONE, PASS,
|
||||
ASSIGN_DOC_STRING, NAME_MODULE, TAB,
|
||||
INDENT_PER_LEVEL, TABLE_R, TABLE_DIRECT, MAP_DIRECT,
|
||||
INDENT_PER_LEVEL, TABLE_R, MAP_DIRECT,
|
||||
MAP, PRECEDENCE, ASSIGN_TUPLE_PARAM, escape, minint)
|
||||
|
||||
|
||||
@@ -1676,6 +1676,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
else:
|
||||
self.write('('); endchar = ')'
|
||||
pass
|
||||
|
||||
elif lastnodetype.startswith('BUILD_SET'):
|
||||
self.write('{'); endchar = '}'
|
||||
elif lastnodetype.startswith('BUILD_MAP_UNPACK'):
|
||||
@@ -1693,6 +1694,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
if elem in ('ROT_THREE', 'EXTENDED_ARG'):
|
||||
continue
|
||||
assert elem == 'expr'
|
||||
elem = elem[0]
|
||||
line_number = self.line_number
|
||||
value = self.traverse(elem)
|
||||
if line_number != self.line_number:
|
||||
@@ -1717,6 +1719,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
self.prune()
|
||||
return
|
||||
|
||||
# FIXME: add n_tuple_unpack to list?
|
||||
n_set = n_tuple = n_build_set = n_list
|
||||
|
||||
def n_unpack(self, node):
|
||||
|
Reference in New Issue
Block a user