You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Merge branch 'master' into python-2.4
This commit is contained in:
16
NEWS
16
NEWS
@@ -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
|
||||||
|
BIN
test/bytecode_2.7/03_if_vs_and.pyc
Normal file
BIN
test/bytecode_2.7/03_if_vs_and.pyc
Normal file
Binary file not shown.
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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'):
|
||||||
|
@@ -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
|
||||||
|
@@ -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'
|
||||||
|
Reference in New Issue
Block a user