diff --git a/test/stdlib/runtests.sh b/test/stdlib/runtests.sh index dcfc9b78..318d97e6 100755 --- a/test/stdlib/runtests.sh +++ b/test/stdlib/runtests.sh @@ -110,11 +110,9 @@ case $PYVERSION in [test_capi.py]=1 [test_curses.py]=1 # Possibly fails on its own but not detected [test_cmd_line.py]=1 # Takes too long, maybe hangs, or looking for interactive input? - [test_compilex.py]=1 # Probably complex literals again. Investigate [test_dis.py]=1 # We change line numbers - duh! [test_doctest.py]=1 # Fails on its own [test_exceptions.py]=1 - [test_format.py]=1 # control flow. uncompyle2 does not have problems here [test_grammar.py]=1 # Too many stmts. Handle large stmts [test_grp.py]=1 # test takes to long, works interactively though [test_io.py]=1 # Test takes too long to run @@ -137,7 +135,6 @@ case $PYVERSION in [test_unicode.py]=1 # Too long to run 11 seconds [test_xpickle.py]=1 # Runs ok but takes 72 seconds [test_zipfile64.py]=1 # Runs ok but takes 204 seconds - [test_zipimport.py]=1 # FIXME: improper try from try/else ? ) if (( batch )) ; then # Fails in crontab environment? diff --git a/uncompyle6/parsers/parse2.py b/uncompyle6/parsers/parse2.py index f6dce338..a5b3677d 100644 --- a/uncompyle6/parsers/parse2.py +++ b/uncompyle6/parsers/parse2.py @@ -161,6 +161,17 @@ class Python2Parser(PythonParser): except_handler ::= jmp_abs COME_FROM except_stmts END_FINALLY + # except_handler_else is intended to be used only in a + # try_else. The disambiguation comes from reduction rule + # checking where we make sure that the JUMP_FORWARD mismatches + # the JUMP_FORWARD before the END_FINALLY + except_handler_else ::= JUMP_FORWARD COME_FROM except_stmts + END_FINALLY come_froms + + except_handler_else ::= jmp_abs COME_FROM except_stmts + END_FINALLY + + except_stmts ::= except_stmt+ except_stmt ::= except_cond1 except_suite @@ -637,6 +648,8 @@ class Python2Parser(PythonParser): self.addRule(rule, nop_func) pass + self.check_reduce["except_handler"] = "tokens" + self.check_reduce["except_handler_else"] = "tokens" self.check_reduce["raise_stmt1"] = "tokens" self.check_reduce["assert_expr_and"] = "AST" self.check_reduce["tryelsestmt"] = "AST" @@ -668,6 +681,29 @@ class Python2Parser(PythonParser): jmp_false = ast[1] jump_target = jmp_false[0].attr return jump_target > tokens[last].off2int() + elif lhs in ("except_handler, except_handler_else"): + + # FIXME: expand this to other 2.x version + if self.version != 2.7: return False + + if tokens[first] in ("JUMP_FORWARD", "JUMP_ABSOLUTE"): + first_jump_target = tokens[first].pattr + last = min(last, len(tokens)-1) + for i in range(last, first, -1): + if tokens[i] == "END_FINALLY": + i -= 1 + second_jump = tokens[i] + if second_jump in ("JUMP_FORWARD", "JUMP_ABSOLUTE"): + second_jump_target = second_jump.pattr + equal_target = second_jump_target == first_jump_target + if equal_target: + return lhs != "except_handler" + else: + return lhs != "except_handler_else" + pass + pass + pass + pass elif rule == ("ifstmt", ("testexpr", "_ifstmts_jump")): for i in range(last-1, last-4, -1): t = tokens[i] diff --git a/uncompyle6/parsers/parse27.py b/uncompyle6/parsers/parse27.py index 9e947f6c..f36f9de7 100644 --- a/uncompyle6/parsers/parse27.py +++ b/uncompyle6/parsers/parse27.py @@ -60,13 +60,13 @@ class Python27Parser(Python2Parser): COME_FROM_FINALLY suite_stmts_opt END_FINALLY tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK - except_handler else_suite COME_FROM + except_handler_else else_suite COME_FROM tryelsestmtl ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK - except_handler else_suitel JUMP_BACK COME_FROM + except_handler_else else_suitel JUMP_BACK COME_FROM tryelsestmtl ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK - except_handler else_suitel + except_handler_else else_suitel except_stmt ::= except_cond2 except_suite @@ -216,6 +216,10 @@ class Python27Parser(Python2Parser): super(Python27Parser, self).customize_grammar_rules(tokens, customize) self.check_reduce["and"] = "AST" self.check_reduce["conditional"] = "AST" + + self.check_reduce["except_handler"] = "tokens" + self.check_reduce["except_handler_else"] = "tokens" + # self.check_reduce["or"] = "AST" self.check_reduce["raise_stmt1"] = "AST" self.check_reduce["iflaststmtl"] = "AST"