Skip to content

Commit

Permalink
Add 3.x try reduction rule
Browse files Browse the repository at this point in the history
  • Loading branch information
rocky committed Jan 25, 2020
1 parent 72b053a commit c90ff51
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 24 deletions.
3 changes: 1 addition & 2 deletions test/stdlib/3.3-exclude.sh
Expand Up @@ -15,7 +15,7 @@ SKIP_TESTS=(
[test_io.py]=1 # test takes too long to run: 34 seconds
[test_lib2to3.py]=1
[test_logging.py]=1 # test takes too long to run: 13 seconds
[test_long.py]=1 # FIX: if boundaries wrong in Rat __init__ was okay in 3.6.2 though
[test_long.py]=1 # test assert failure AttributeError: 'Rat' object has no attribute 'd'
[test_math.py]=1
[test_modulefinder.py]=1
[test_multiprocessing.py]=1
Expand All @@ -34,7 +34,6 @@ SKIP_TESTS=(
[test_socket.py]=1
[test_ssl.py]=1 # too installation specific
[test_strlit.py]=1
[test_strtod.py]=1 # FIX: works on release 3.6.2; must be if stmt nesting/handling
[test_subprocess.py]=1 # test takes too long to run: 28 seconds
[test_symtable.py]=1
[test_sys_setprofile.py]=1 # test assertion errors
Expand Down
1 change: 0 additions & 1 deletion test/stdlib/3.4-exclude.sh
Expand Up @@ -77,7 +77,6 @@ SKIP_TESTS=(
[test_socketserver.py]=1 # long 25 seconds
[test_struct.py]=1 # Doesn't terminate
[test_strlit.py]=1 # test failure
[test_strtod.py]=1 # test assertion error
[test_subprocess.py]=1 # Too long
[test_symtable.py]=1 # Investigate bad output
[test_sys_settrace.py]=1 # test assert failures
Expand Down
27 changes: 6 additions & 21 deletions uncompyle6/parsers/parse3.py
Expand Up @@ -34,6 +34,7 @@
# iflaststmt,
testtrue,
tryelsestmtl3,
tryexcept,
while1stmt
)
from uncompyle6.parsers.treenode import SyntaxTree
Expand Down Expand Up @@ -217,8 +218,7 @@ def p_grammar(self, args):
except_handler ::= JUMP_FORWARD COME_FROM except_stmts
END_FINALLY COME_FROM_EXCEPT
except_stmts ::= except_stmts except_stmt
except_stmts ::= except_stmt
except_stmts ::= except_stmt+
except_stmt ::= except_cond1 except_suite
except_stmt ::= except_cond2 except_suite
Expand Down Expand Up @@ -1509,8 +1509,9 @@ def customize_grammar_rules(self, tokens, customize):
self.check_reduce["testtrue"] = "tokens"
if not PYTHON3:
self.check_reduce["kwarg"] = "noAST"
if self.version < 3.6:
if self.version < 3.6 and not self.is_pypy:
# 3.6+ can remove a JUMP_FORWARD which messes up our testing here
# Pypy we need to go over in better detail
self.check_reduce["try_except"] = "AST"

self.check_reduce["tryelsestmtl3"] = "AST"
Expand Down Expand Up @@ -1618,24 +1619,8 @@ def reduce_is_invalid(self, rule, ast, tokens, first, last):
return False
# 3.8+ Doesn't have SETUP_LOOP
return self.version < 3.8 and tokens[first].attr > tokens[last].offset

elif rule == (
"try_except",
(
"SETUP_EXCEPT",
"suite_stmts_opt",
"POP_BLOCK",
"except_handler",
"opt_come_from_except",
),
):
come_from_except = ast[-1]
if come_from_except[0] == "COME_FROM":
# There should be at last two COME_FROMs, one from an
# exception handler and one from the try. Otherwise
# we have a try/else.
return True
pass
elif lhs == "try_except":
return tryexcept(self, lhs, n, rule, ast, tokens, first, last)
elif rule == (
"ifelsestmt",
(
Expand Down
1 change: 1 addition & 0 deletions uncompyle6/parsers/reducecheck/__init__.py
Expand Up @@ -7,6 +7,7 @@
from uncompyle6.parsers.reducecheck.or_check import *
from uncompyle6.parsers.reducecheck.testtrue import *
from uncompyle6.parsers.reducecheck.tryelsestmt import *
from uncompyle6.parsers.reducecheck.tryexcept import *
from uncompyle6.parsers.reducecheck.tryelsestmtl3 import *
from uncompyle6.parsers.reducecheck.while1elsestmt import *
from uncompyle6.parsers.reducecheck.while1stmt import *
59 changes: 59 additions & 0 deletions uncompyle6/parsers/reducecheck/tryexcept.py
@@ -0,0 +1,59 @@
# Copyright (c) 2020 Rocky Bernstein

def tryexcept(self, lhs, n, rule, ast, tokens, first, last):
come_from_except = ast[-1]
if rule == (
"try_except",
(
"SETUP_EXCEPT",
"suite_stmts_opt",
"POP_BLOCK",
"except_handler",
"opt_come_from_except",
),
):
if come_from_except[0] == "COME_FROM":
# There should be at last two COME_FROMs, one from an
# exception handler and one from the try. Otherwise
# we have a try/else.
return True
pass

elif rule == (
'try_except',
(
'SETUP_EXCEPT',
'suite_stmts_opt',
'POP_BLOCK',
'except_handler',
'\\e_opt_come_from_except'
),
):
# Find END_FINALLY.
for i in range(last, first, -1):
if tokens[i] == "END_FINALLY":
jump_before_finally = tokens[i-1]
if jump_before_finally.kind.startswith("JUMP"):
if jump_before_finally == "JUMP_FORWARD":
# If there is a JUMP_FORWARD before
# the END_FINALLY to some jumps place
# beyond tokens[last].off2int() then
# this is a try/else rather than an
# try (no else).
return tokens[i-1].attr > tokens[last].off2int(prefer_last=True)
elif jump_before_finally == "JUMP_BACK":
# If there is a JUMP_BACK before the
# END_FINALLY then this is a looping
# jump, but then jumps in the except
# handlers have to also be a looping
# jump or this is a try/else rather
# than an try (no else).
except_handler = ast[3]
if (except_handler == "except_handler" and
except_handler[0] == "JUMP_FORWARD"):
return True
return False
pass
pass
pass
return False

0 comments on commit c90ff51

Please sign in to comment.