diff --git a/test/bytecode_3.5/05_return_in_else.pyc b/test/bytecode_3.5/05_return_in_else.pyc new file mode 100644 index 00000000..fe34b101 Binary files /dev/null and b/test/bytecode_3.5/05_return_in_else.pyc differ diff --git a/test/simple_source/bug35/05_return_in_else.py b/test/simple_source/bug35/05_return_in_else.py new file mode 100644 index 00000000..0bb3d0c2 --- /dev/null +++ b/test/simple_source/bug35/05_return_in_else.py @@ -0,0 +1,12 @@ +# Bug in 3.5 _pydecimal.py was erroriously thinking the +# return after the "else" was an "end if" + +def parseline(self, line): + if not line: + return 5 + elif line: + if hasattr(self, 'do_shell'): + line = 'shell' + else: + return 3 if line[3] else 4 + return 6 diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index 59b54793..89b639d0 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -768,7 +768,6 @@ class Scanner3(Scanner): if come_from_op == self.opc.SETUP_EXCEPT: return pass - pass pass self.return_end_ifs.add(prev_op[rtarget]) @@ -780,7 +779,22 @@ class Scanner3(Scanner): self.fixed_jumps[offset] = unop_target else: self.fixed_jumps[offset] = self.restrict_to_parent(target, parent) - + elif op == self.opc.JUMP_FORWARD and self.version >= 3.5: + # If we have: + # JUMP_FORWARD x, [non-jump, insns], RETURN_VALUE, x: + # then RETURN_VALUE is probably not RETURN_END_IF + rtarget = self.get_target(offset) + rtarget_prev = self.prev[rtarget] + if (code[rtarget_prev] == self.opc.RETURN_VALUE and + rtarget_prev in self.return_end_ifs): + i = rtarget_prev + while i != offset: + if code[i] in [op3.JUMP_FORWARD, op3.JUMP_ABSOLUTE]: + return + i = self.prev[i] + self.return_end_ifs.remove(rtarget_prev) + pass + return def next_except_jump(self, start): """