Skip to content

Commit dcad6cf

Browse files
committed
Fix if return boundary in 3.6+
Fixes rocky#209
1 parent bfceeac commit dcad6cf

File tree

10 files changed

+43
-21
lines changed

10 files changed

+43
-21
lines changed

__pkginfo__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
]}
5858
ftp_url = None
5959
install_requires = ['spark-parser >= 1.8.7, < 1.9.0',
60-
'xdis >= 3.8.9, < 3.9.0']
60+
'xdis >= 3.8.10, < 3.9.0']
6161

6262
license = 'GPL3'
6363
mailing_list = 'python-debugger@googlegroups.com'
339 Bytes
Binary file not shown.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Bug in 3.6 and above.
2+
#Not detecting 2nd return is outside of
3+
# if/then. Fix was to ensure COME_FROM
4+
def return_return_bug(foo):
5+
if foo =='say_hello':
6+
return "hello"
7+
return "world"
8+
9+
assert return_return_bug('say_hello') == 'hello'
10+
assert return_return_bug('world') == 'world'

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[flake8]
44
exclude = .tox,./build,./trepan/processor/command/tmp
55
filename = *.py
6-
ignore = C901,E113,E121,E122,E123,E124,E125,E126,E127,E128,E129,E201,E202,E203,E221,E222,E225,E226,E241,E242,E251,E261,E271,E272,E302,E401,E501,F401,E701,E702
6+
ignore = C901,E113,E121,E122,E123,E124,E125,E126,E127,E128,E129,E201,E202,E203,E221,E222,E225,E226,E241,E242,E251,E261,E271,E272,E302,E401,E402,E501,F401,E701,E702
77

88
[tox]
99
envlist = py27, py34, pypy

uncompyle6/disas.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2015-2016, 2818 by Rocky Bernstein
1+
# Copyright (c) 2015-2016, 2818-2019 by Rocky Bernstein
22
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
33
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
44
# Copyright (c) 1999 John Aycock
@@ -77,18 +77,18 @@ def disco_loop(disasm, queue, real_out):
7777
pass
7878
pass
7979

80-
def disassemble_fp(fp, outstream=None):
81-
"""
82-
disassemble Python byte-code from an open file
83-
"""
84-
(version, timestamp, magic_int, co, is_pypy,
85-
source_size) = load_from_fp(fp)
86-
if type(co) == list:
87-
for con in co:
88-
disco(version, con, outstream)
89-
else:
90-
disco(version, co, outstream, is_pypy=is_pypy)
91-
co = None
80+
# def disassemble_fp(fp, outstream=None):
81+
# """
82+
# disassemble Python byte-code from an open file
83+
# """
84+
# (version, timestamp, magic_int, co, is_pypy,
85+
# source_size) = load_from_fp(fp)
86+
# if type(co) == list:
87+
# for con in co:
88+
# disco(version, con, outstream)
89+
# else:
90+
# disco(version, co, outstream, is_pypy=is_pypy)
91+
# co = None
9292

9393
def disassemble_file(filename, outstream=None):
9494
"""
@@ -120,5 +120,6 @@ def _test():
120120
fn = sys.argv[1]
121121
disassemble_file(fn)
122122

123+
123124
if __name__ == "__main__":
124125
_test()

uncompyle6/parser.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ def __str__(self):
3737
return "Parse error at or near `%r' instruction at offset %s\n" % \
3838
(self.token, self.offset)
3939

40-
nop_func = lambda self, args: None
40+
41+
def nop_func(self, args):
42+
return None
4143

4244
class PythonParser(GenericASTBuilder):
4345

@@ -792,6 +794,7 @@ def python_parser(version, co, out=sys.stdout, showasm=False,
792794
p = get_python_parser(version, parser_debug)
793795
return parse(p, tokens, customize)
794796

797+
795798
if __name__ == '__main__':
796799
def parse_test(co):
797800
from uncompyle6 import PYTHON_VERSION, IS_PYPY

uncompyle6/parsers/parse3.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ def p_jump3(self, args):
309309
# FIXME: Common with 2.7
310310
ret_and ::= expr JUMP_IF_FALSE_OR_POP ret_expr_or_cond COME_FROM
311311
ret_or ::= expr JUMP_IF_TRUE_OR_POP ret_expr_or_cond COME_FROM
312-
ret_cond ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF ret_expr_or_cond
312+
ret_cond ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF COME_FROM ret_expr_or_cond
313313
314314
or ::= expr JUMP_IF_TRUE_OR_POP expr COME_FROM
315315
and ::= expr JUMP_IF_FALSE_OR_POP expr COME_FROM
@@ -583,7 +583,6 @@ def customize_grammar_rules(self, tokens, customize):
583583
stmt ::= assign2_pypy
584584
assign3_pypy ::= expr expr expr store store store
585585
assign2_pypy ::= expr expr store store
586-
return_if_lambda ::= RETURN_END_IF_LAMBDA
587586
stmt ::= conditional_lambda
588587
stmt ::= conditional_not_lambda
589588
conditional_lambda ::= expr jmp_false expr return_if_lambda

uncompyle6/parsers/parse36.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ def p_36misc(self, args):
4646
# RETURN_VALUE is meant. Specifcally this can happen in
4747
# ifelsestmt -> ...else_suite _. suite_stmts... (last) stmt
4848
return ::= ret_expr RETURN_END_IF
49+
return ::= ret_expr RETURN_VALUE COME_FROM
50+
return_stmt_lambda ::= ret_expr RETURN_VALUE_LAMBDA COME_FROM
51+
return_if_lambda ::= RETURN_END_IF_LAMBDA COME_FROM
52+
4953
5054
# A COME_FROM is dropped off because of JUMP-to-JUMP optimization
5155
and ::= expr jmp_false expr

uncompyle6/scanner.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,9 +351,9 @@ def inst_matches(self, start, end, instr, target=None, include_beyond_target=Fal
351351

352352
return result
353353

354-
355354
# FIXME: this is broken on 3.6+. Replace remaining (2.x-based) calls
356355
# with inst_matches
356+
357357
def all_instr(self, start, end, instr, target=None, include_beyond_target=False):
358358
"""
359359
Find all `instr` in the block from start to end.
@@ -423,8 +423,8 @@ def remove_extended_args(self, instructions):
423423
last_was_extarg = False
424424
n = len(instructions)
425425
for i, inst in enumerate(instructions):
426-
if (inst.opname == 'EXTENDED_ARG' and
427-
i+1 < n and instructions[i+1].opname != 'MAKE_FUNCTION'):
426+
if (inst.opname == 'EXTENDED_ARG'
427+
and i+1 < n and instructions[i+1].opname != 'MAKE_FUNCTION'):
428428
last_was_extarg = True
429429
starts_line = inst.starts_line
430430
is_jump_target = inst.is_jump_target
@@ -527,6 +527,7 @@ def get_scanner(version, is_pypy=False, show_asm=None):
527527
raise RuntimeError("Unsupported Python version %s" % version)
528528
return scanner
529529

530+
530531
if __name__ == "__main__":
531532
import inspect, uncompyle6
532533
co = inspect.currentframe().f_code

uncompyle6/scanners/scanner3.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,10 @@ def detect_control_flow(self, offset, targets, inst_index):
920920
return
921921
pass
922922
pass
923+
924+
if self.version >= 3.4:
925+
self.fixed_jumps[offset] = rtarget
926+
923927
if code[pre_rtarget] == self.opc.RETURN_VALUE:
924928
# If we are at some sort of POP_JUMP_IF and the instruction before was
925929
# COMPARE_OP exception-match, then pre_rtarget is not an end_if

0 commit comments

Comments
 (0)