You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 08:49:51 +08:00
Handle 3.5+ BUILD_MAP_UNPACK used in dictionaries
A number of weaknesses have been uncovered though
This commit is contained in:
@@ -641,19 +641,27 @@ class Python3Parser(PythonParser):
|
||||
self.add_unique_rule(rule, 'kvlist_n', 1, customize)
|
||||
rule = "dict ::= BUILD_MAP_n kvlist_n"
|
||||
elif self.version >= 3.5:
|
||||
if opname != 'BUILD_MAP_WITH_CALL':
|
||||
if opname == 'BUILD_MAP_UNPACK':
|
||||
if not opname.startswith('BUILD_MAP_WITH_CALL'):
|
||||
# FIXME: Use the attr
|
||||
# so this doesn't run into exponential parsing time.
|
||||
if opname.startswith('BUILD_MAP_UNPACK'):
|
||||
# FIXME: start here
|
||||
# rule = "%s ::= %s %s" % (kvlist_n, 'expr ' * (token.attr*2), opname)
|
||||
rule = kvlist_n + ' ::= ' + 'expr ' * (token.attr*2)
|
||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
||||
rule = 'dict_entry ::= ' + 'expr ' * (token.attr*2)
|
||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
||||
rule = 'dict ::= ' + 'dict_entry ' * token.attr
|
||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
||||
rule = ('unmap_dict ::= ' +
|
||||
('dict ' * token.attr) +
|
||||
'BUILD_MAP_UNPACK')
|
||||
rule = 'dict ::= %s' % ('dict_entry ' * token.attr)
|
||||
self.addRule(rule, nop_func)
|
||||
|
||||
# FIXME: really we need a combination of dict_entry-like things.
|
||||
# It just so happens the most common case is not to mix
|
||||
# dictionary comphensions with dictionary, elements
|
||||
if self.seen_LOAD_DICTCOMP:
|
||||
rule = 'dict ::= %s%s' % ('dict_comp ' * token.attr, opname)
|
||||
self.addRule(rule, nop_func)
|
||||
|
||||
rule = 'unmap_dict ::= %s%s' % (('dict ' * token.attr), opname)
|
||||
else:
|
||||
rule = "%s ::= %s %s" % (kvlist_n, 'expr ' * (token.attr*2), opname)
|
||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
||||
|
@@ -1720,7 +1720,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
self.write(name, ': ')
|
||||
value = self.traverse(l[i+1], indent=self.indent+(len(name)+2)*' ')
|
||||
self.write(value)
|
||||
sep = ","
|
||||
sep = ", "
|
||||
if line_number != self.line_number:
|
||||
sep += "\n" + self.indent + INDENT_PER_LEVEL[:-1]
|
||||
line_number = self.line_number
|
||||
@@ -1747,7 +1747,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
self.write(name, ': ')
|
||||
value = self.traverse(l[i], indent=self.indent+(len(name)+2)*' ')
|
||||
self.write(value)
|
||||
sep = ","
|
||||
sep = ", "
|
||||
if line_number != self.line_number:
|
||||
sep += "\n" + self.indent + INDENT_PER_LEVEL[:-1]
|
||||
line_number = self.line_number
|
||||
@@ -1767,7 +1767,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
line_number = self.line_number
|
||||
self.write(':')
|
||||
self.write(self.traverse(value[0]))
|
||||
sep = ","
|
||||
sep = ", "
|
||||
if line_number != self.line_number:
|
||||
sep += "\n" + self.indent + INDENT_PER_LEVEL[:-1]
|
||||
line_number = self.line_number
|
||||
@@ -1778,6 +1778,16 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
if sep.startswith(",\n"):
|
||||
self.write(sep[1:])
|
||||
pass
|
||||
elif node[-1].kind.startswith('BUILD_MAP_UNPACK'):
|
||||
assert self.version >= 3.5
|
||||
# FIXME: I think we can intermingle dict_comp's with other
|
||||
# dictionary kinds of things. The most common though is
|
||||
# a sequence of dict_comp's
|
||||
kwargs = node[-1].attr
|
||||
template = ("**%C", (0, kwargs, ", **"))
|
||||
self.template_engine(template, node)
|
||||
sep = ''
|
||||
|
||||
pass
|
||||
else:
|
||||
# Python 2 style kvlist. Find beginning of kvlist.
|
||||
@@ -1833,7 +1843,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
value = self.traverse(kv[0], indent=self.indent+(len(name)+2)*' ')
|
||||
pass
|
||||
self.write(value)
|
||||
sep = ","
|
||||
sep = ", "
|
||||
if line_number != self.line_number:
|
||||
sep += "\n" + self.indent + " "
|
||||
line_number = self.line_number
|
||||
|
Reference in New Issue
Block a user