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:
rocky
2016-05-23 22:41:46 -04:00
parent 544cb334e8
commit 79f4893cd9
5 changed files with 32 additions and 5 deletions

Binary file not shown.

Binary file not shown.

View 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

View 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

View File

@@ -550,7 +550,7 @@ class SourceWalker(GenericASTTraversal, object):
def indentLess(self, indent=TAB):
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)
if indent is None: indent = self.indent
p = self.pending_newlines
@@ -1059,7 +1059,10 @@ class SourceWalker(GenericASTTraversal, object):
self.customize(code._customize)
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'
# find innermost node
@@ -1814,7 +1817,8 @@ class SourceWalker(GenericASTTraversal, object):
self.println(self.text)
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)
@@ -1835,8 +1839,12 @@ class SourceWalker(GenericASTTraversal, object):
if self.hide_internal:
if len(tokens) >= 2 and not noneInNames:
if tokens[-1].type == 'RETURN_VALUE':
# Should we also check for returning None?
if tokens[-2].type == 'LOAD_CONST':
del tokens[-2:]
if True or isTopLevel:
del tokens[-2:]
else:
tokens.append(Token('RETURN_LAST'))
else:
tokens.append(Token('RETURN_LAST'))
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,
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'