You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
final RETURN removal bug
We want to remove a final return from a module, but otherwise not. Note we'll no lonager be able to verify functools.pyc as there is now a return after a raise statement. That will have to be delt with separately. May address Issue #17.
This commit is contained in:
BIN
test/bytecode_2.7/06_return_bug.pyc
Normal file
BIN
test/bytecode_2.7/06_return_bug.pyc
Normal file
Binary file not shown.
Binary file not shown.
11
test/simple_source/def/06_ifTrue_optimize_bug.py
Normal file
11
test/simple_source/def/06_ifTrue_optimize_bug.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Bug in uncompyle6 and pycdc for (some) Python 3 bytecodes.
|
||||||
|
# Problem is JUMP_IF_FALSE is optimized away leaving
|
||||||
|
# the unreachible LOAD_CONST below
|
||||||
|
|
||||||
|
# Disassembly of lambda is:
|
||||||
|
# 0 LOAD_CONST 2: 2
|
||||||
|
# 3 RETURN_VALUE
|
||||||
|
# 4 LOAD_CONST 3: 3
|
||||||
|
# 7 RETURN_VALUE
|
||||||
|
|
||||||
|
lambda: 2 if True else 3
|
7
test/simple_source/def/06_return_bug.py
Normal file
7
test/simple_source/def/06_return_bug.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# But is that we were removing the return 3 at the end of the function
|
||||||
|
# and a the end of *any* function. We do want to remove "return None"
|
||||||
|
# at the end of a main program, but that's something different.
|
||||||
|
def fn(self):
|
||||||
|
if self.id == 'hat':
|
||||||
|
return 4
|
||||||
|
return 3
|
@@ -550,7 +550,7 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
def indentLess(self, indent=TAB):
|
def indentLess(self, indent=TAB):
|
||||||
self.indent = self.indent[:-len(indent)]
|
self.indent = self.indent[:-len(indent)]
|
||||||
|
|
||||||
def traverse(self, node, indent=None, isLambda=0):
|
def traverse(self, node, indent=None, isLambda=False):
|
||||||
self.param_stack.append(self.params)
|
self.param_stack.append(self.params)
|
||||||
if indent is None: indent = self.indent
|
if indent is None: indent = self.indent
|
||||||
p = self.pending_newlines
|
p = self.pending_newlines
|
||||||
@@ -1059,7 +1059,10 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
self.customize(code._customize)
|
self.customize(code._customize)
|
||||||
ast = ast[0][0][0][0][0]
|
ast = ast[0][0][0][0][0]
|
||||||
|
|
||||||
n = ast[iter_index]
|
try:
|
||||||
|
n = ast[iter_index]
|
||||||
|
except:
|
||||||
|
from trepan.api import debug; debug()
|
||||||
assert n == 'list_iter'
|
assert n == 'list_iter'
|
||||||
|
|
||||||
# find innermost node
|
# find innermost node
|
||||||
@@ -1814,7 +1817,8 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
self.println(self.text)
|
self.println(self.text)
|
||||||
self.return_none = rn
|
self.return_none = rn
|
||||||
|
|
||||||
def build_ast(self, tokens, customize, isLambda=0, noneInNames=False):
|
def build_ast(self, tokens, customize, isLambda=False,
|
||||||
|
noneInNames=False, isTopLevel=False):
|
||||||
|
|
||||||
# assert isinstance(tokens[0], Token)
|
# assert isinstance(tokens[0], Token)
|
||||||
|
|
||||||
@@ -1835,8 +1839,12 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
if self.hide_internal:
|
if self.hide_internal:
|
||||||
if len(tokens) >= 2 and not noneInNames:
|
if len(tokens) >= 2 and not noneInNames:
|
||||||
if tokens[-1].type == 'RETURN_VALUE':
|
if tokens[-1].type == 'RETURN_VALUE':
|
||||||
|
# Should we also check for returning None?
|
||||||
if tokens[-2].type == 'LOAD_CONST':
|
if tokens[-2].type == 'LOAD_CONST':
|
||||||
del tokens[-2:]
|
if True or isTopLevel:
|
||||||
|
del tokens[-2:]
|
||||||
|
else:
|
||||||
|
tokens.append(Token('RETURN_LAST'))
|
||||||
else:
|
else:
|
||||||
tokens.append(Token('RETURN_LAST'))
|
tokens.append(Token('RETURN_LAST'))
|
||||||
if len(tokens) == 0:
|
if len(tokens) == 0:
|
||||||
@@ -1877,7 +1885,8 @@ def deparse_code(version, co, out=sys.stdout, showasm=False, showast=False,
|
|||||||
deparsed = SourceWalker(version, out, scanner, showast=showast,
|
deparsed = SourceWalker(version, out, scanner, showast=showast,
|
||||||
debug_parser=debug_parser, compile_mode=compile_mode)
|
debug_parser=debug_parser, compile_mode=compile_mode)
|
||||||
|
|
||||||
deparsed.ast = deparsed.build_ast(tokens, customize)
|
isTopLevel = co.co_name == '<module>'
|
||||||
|
deparsed.ast = deparsed.build_ast(tokens, customize, isTopLevel=isTopLevel)
|
||||||
|
|
||||||
assert deparsed.ast == 'stmts', 'Should have parsed grammar start'
|
assert deparsed.ast == 'stmts', 'Should have parsed grammar start'
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user