Merge branch 'master' into python-2.4

This commit is contained in:
rocky
2018-02-17 11:28:45 -05:00
8 changed files with 58 additions and 10 deletions

16
NEWS
View File

@@ -1,3 +1,19 @@
uncompyle6 2.16.0 2018-02-17
- API additions:
- add fragments.op_at_code_loc() and
- fragments.deparsed_find()_
- Better 2.7 end_if and COME_FROM determination
- Fix up 3.6+ CALL_FUNCTION_EX
- Misc pydisasm fixes
- Wierd comprehension bug seen via new loctraceback
- Fix Python 3.5+ CALL_FUNCTION_VAR and BUILD_LIST_UNPACK in call; with this
we can can handle 3.5+ f(a, b, *c, *d, *e) now
uncompyle6 2.15.1 2018-02-05
- More bug fixes and revert an improper bug fix in 2.15.0
uncompyle6 2.15.0 2018-02-05 pycon2018.co uncompyle6 2.15.0 2018-02-05 pycon2018.co
- Bug fixes - Bug fixes

Binary file not shown.

View File

@@ -130,6 +130,11 @@ class Python27Parser(Python2Parser):
whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK
else_suitel COME_FROM else_suitel COME_FROM
return_stmts ::= _stmts return_stmt
return_stmts ::= return_stmt
return_stmt ::= return
ifstmt ::= testexpr return_stmts COME_FROM
ifstmt ::= testexpr return_if_stmts COME_FROM ifstmt ::= testexpr return_if_stmts COME_FROM
ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD else_suite COME_FROM ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD else_suite COME_FROM
ifelsestmtc ::= testexpr c_stmts_opt JUMP_ABSOLUTE else_suitec ifelsestmtc ::= testexpr c_stmts_opt JUMP_ABSOLUTE else_suitec

View File

@@ -962,17 +962,32 @@ class Scanner2(Scanner):
'end': end_offset}) 'end': end_offset})
elif code_pre_rtarget == self.opc.RETURN_VALUE: elif code_pre_rtarget == self.opc.RETURN_VALUE:
if self.version == 2.7 or pre_rtarget not in self.ignore_if: if self.version == 2.7 or pre_rtarget not in self.ignore_if:
# 10 is exception-match. If there is an exception match in the # Below, 10 is exception-match. If there is an exception
# compare, then this is an exception clause not an if-then clause # match in the compare, then this is an exception
# clause not an if-then clause
if (self.code[self.prev[offset]] != self.opc.COMPARE_OP or if (self.code[self.prev[offset]] != self.opc.COMPARE_OP or
self.code[self.prev[offset]+1] != 10): self.code[self.prev[offset]+1] != 10):
self.structs.append({'type': 'if-then', self.structs.append({'type': 'if-then',
'start': start, 'start': start,
'end': rtarget}) 'end': rtarget})
self.thens[start] = rtarget self.thens[start] = rtarget
if self.version == 2.7 or code[pre_rtarget+1] != self.opc.JUMP_FORWARD: if (self.version == 2.7 or
code[pre_rtarget+1] != self.opc.JUMP_FORWARD):
# The below is a big hack until we get
# better control flow analysis: disallow
# END_IF if the instruction before the
# END_IF instruction happens to be a jump
# target. In this case, probably what's
# gone on is that we messed up on the
# END_IF location and it should be the
# instruction before.
self.fixed_jumps[offset] = rtarget self.fixed_jumps[offset] = rtarget
self.return_end_ifs.add(pre_rtarget) if (self.version == 2.7 and
self.insts[self.offset2inst_index[pre[pre_rtarget]]].is_jump_target):
self.return_end_ifs.add(pre[pre_rtarget])
pass
else:
self.return_end_ifs.add(pre_rtarget)
pass pass
pass pass
pass pass

View File

@@ -769,7 +769,8 @@ class FragmentsWalker(pysource.SourceWalker, object):
self.set_pos_info(node[-1], gen_start, len(self.f.getvalue())) self.set_pos_info(node[-1], gen_start, len(self.f.getvalue()))
def listcomprehension_walk2(self, node): def listcomprehension_walk2(self, node):
"""List comprehensions the way they are done in Python3. """List comprehensions the way they are done in Python 2 (and
some Python 3?).
They're more other comprehensions, e.g. set comprehensions They're more other comprehensions, e.g. set comprehensions
See if we can combine code. See if we can combine code.
""" """
@@ -779,17 +780,24 @@ class FragmentsWalker(pysource.SourceWalker, object):
code = Code(node[1].attr, self.scanner, self.currentclass) code = Code(node[1].attr, self.scanner, self.currentclass)
ast = self.build_ast(code._tokens, code._customize) ast = self.build_ast(code._tokens, code._customize)
self.customize(code._customize) self.customize(code._customize)
ast = ast[0][0][0][0][0] if node == 'set_comp':
ast = ast[0][0][0]
else:
ast = ast[0][0][0][0][0]
if ast == 'expr':
ast = ast[0]
n = ast[1] n = ast[1]
collection = node[-3] collection = node[-3]
list_if = None list_if = None
assert n == 'list_iter' assert n == 'list_iter'
# find innermost node # Find the list comprehension body. It is the inner-most
# node that is not list_.. .
while n == 'list_iter': while n == 'list_iter':
n = n[0] # recurse one step n = n[0] # recurse one step
if n == 'list_for': if n == 'list_for':
store = n[2] store = n[2]
n = n[3] n = n[3]
elif n in ('list_if', 'list_if_not'): elif n in ('list_if', 'list_if_not'):

View File

@@ -1620,7 +1620,8 @@ class SourceWalker(GenericASTTraversal, object):
self.prec = p self.prec = p
def listcomprehension_walk2(self, node): def listcomprehension_walk2(self, node):
"""List comprehensions the way they are done in Python 2. """List comprehensions the way they are done in Python 2 (and
some Python 3?).
They're more other comprehensions, e.g. set comprehensions They're more other comprehensions, e.g. set comprehensions
See if we can combine code. See if we can combine code.
""" """
@@ -1635,6 +1636,9 @@ class SourceWalker(GenericASTTraversal, object):
else: else:
ast = ast[0][0][0][0][0] ast = ast[0][0][0][0][0]
if ast == 'expr':
ast = ast[0]
n = ast[1] n = ast[1]
collection = node[-3] collection = node[-3]
list_if = None list_if = None

View File

@@ -1,3 +1,3 @@
# This file is suitable for sourcing inside bash as # This file is suitable for sourcing inside bash as
# well as importing into Python # well as importing into Python
VERSION='2.15.1' VERSION='2.16.0'