You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Merge branch 'master' into python-2.4
This commit is contained in:
BIN
test/bytecode_3.2/01_triple_compare.pyc
Normal file
BIN
test/bytecode_3.2/01_triple_compare.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.2/03_if_try_raise.pyc
Normal file
BIN
test/bytecode_3.2/03_if_try_raise.pyc
Normal file
Binary file not shown.
21
test/simple_source/bug32/03_if_try_raise.py
Normal file
21
test/simple_source/bug32/03_if_try_raise.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# From 3.2 distutils/core
|
||||
# Ensure we handle funky trystmt
|
||||
def setup (ok, dist, **attrs):
|
||||
if ok:
|
||||
try:
|
||||
dist.run_commands()
|
||||
except KeyboardInterrupt:
|
||||
raise SystemExit("interrupted")
|
||||
except IOError as exc:
|
||||
error = exc
|
||||
if dist:
|
||||
raise
|
||||
else:
|
||||
raise SystemExit(error)
|
||||
except (RuntimeError) as msg:
|
||||
if dist:
|
||||
raise
|
||||
else:
|
||||
raise SystemExit("error: " + str(msg))
|
||||
|
||||
return dist
|
@@ -477,7 +477,8 @@ class Python3Parser(PythonParser):
|
||||
return
|
||||
|
||||
def custom_classfunc_rule(self, opname, token, customize,
|
||||
seen_LOAD_BUILD_CLASS):
|
||||
seen_LOAD_BUILD_CLASS,
|
||||
seen_GET_AWAITABLE_YIELD_FROM):
|
||||
"""
|
||||
call_function ::= expr {expr}^n CALL_FUNCTION_n
|
||||
call_function ::= expr {expr}^n CALL_FUNCTION_VAR_n
|
||||
@@ -527,7 +528,7 @@ class Python3Parser(PythonParser):
|
||||
'expr ' * nak + token.kind)
|
||||
|
||||
self.add_unique_rule(rule, token.kind, uniq_param, customize)
|
||||
if self.version >= 3.5:
|
||||
if self.version >= 3.5 and seen_GET_AWAITABLE_YIELD_FROM:
|
||||
rule = ('async_call_function ::= expr ' +
|
||||
('pos_arg ' * args_pos) +
|
||||
('kwarg ' * args_kw) +
|
||||
@@ -619,6 +620,7 @@ class Python3Parser(PythonParser):
|
||||
seen_LOAD_DICTCOMP = False
|
||||
seen_LOAD_LISTCOMP = False
|
||||
seen_LOAD_SETCOMP = False
|
||||
seen_GET_AWAITABLE_YIELD_FROM = False
|
||||
|
||||
# Loop over instructions adding custom grammar rules based on
|
||||
# a specific instruction seen.
|
||||
@@ -633,9 +635,16 @@ class Python3Parser(PythonParser):
|
||||
|
||||
has_get_iter_call_function1 = False
|
||||
n = len(tokens)
|
||||
max_branches = 0
|
||||
for i, token in enumerate(tokens):
|
||||
if token == 'GET_ITER' and i < n-2 and self.call_fn_name(tokens[i+1]) == 'CALL_FUNCTION_1':
|
||||
has_get_iter_call_function1 = True
|
||||
max_branches += 1
|
||||
elif (token == 'GET_AWAITABLE' and i < n-3
|
||||
and tokens[i+1] == 'LOAD_CONST' and tokens[i+2] == 'YIELD_FROM'):
|
||||
max_branches += 1
|
||||
seen_GET_AWAITABLE_YIELD_FROM = True
|
||||
if max_branches > 2:
|
||||
break
|
||||
|
||||
for i, token in enumerate(tokens):
|
||||
@@ -726,7 +735,9 @@ class Python3Parser(PythonParser):
|
||||
elif (opname in ('CALL_FUNCTION', 'CALL_FUNCTION_VAR',
|
||||
'CALL_FUNCTION_VAR_KW', 'CALL_FUNCTION_EX_KW')
|
||||
or opname.startswith('CALL_FUNCTION_KW')):
|
||||
self.custom_classfunc_rule(opname, token, customize, seen_LOAD_BUILD_CLASS)
|
||||
self.custom_classfunc_rule(opname, token, customize,
|
||||
seen_LOAD_BUILD_CLASS,
|
||||
seen_GET_AWAITABLE_YIELD_FROM)
|
||||
elif opname_base == 'CALL_METHOD':
|
||||
# PyPy only - DRY with parse2
|
||||
|
||||
|
@@ -9,6 +9,7 @@ class Python32Parser(Python3Parser):
|
||||
def p_32to35(self, args):
|
||||
"""
|
||||
conditional ::= expr jmp_false expr jump_forward_else expr COME_FROM
|
||||
cmp_list2 ::= expr COMPARE_OP RETURN_VALUE
|
||||
|
||||
# Store locals is only in Python 3.0 to 3.3
|
||||
stmt ::= store_locals
|
||||
@@ -18,9 +19,22 @@ class Python32Parser(Python3Parser):
|
||||
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK COME_FROM_LOOP
|
||||
whileTruestmt ::= SETUP_LOOP return_stmts COME_FROM_LOOP
|
||||
|
||||
# Python 3.5+ has jump optimization to remove the redundant
|
||||
# jump_excepts. But in 3.3 we need them added
|
||||
|
||||
trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||
try_middle
|
||||
jump_excepts come_from_except_clauses
|
||||
|
||||
try_middle ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts
|
||||
END_FINALLY
|
||||
|
||||
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||
try_middle else_suite
|
||||
jump_excepts come_from_except_clauses
|
||||
|
||||
jump_excepts ::= jump_except+
|
||||
|
||||
# Python 3.2+ has more loop optimization that removes
|
||||
# JUMP_FORWARD in some cases, and hence we also don't
|
||||
# see COME_FROM
|
||||
|
@@ -14,8 +14,6 @@ class Python33Parser(Python32Parser):
|
||||
expr ::= yield_from
|
||||
yield_from ::= expr expr YIELD_FROM
|
||||
|
||||
cmp_list2 ::= expr COMPARE_OP RETURN_VALUE
|
||||
|
||||
# We do the grammar hackery below for semantics
|
||||
# actions that want c_stmts_opt at index 1
|
||||
|
||||
@@ -25,20 +23,16 @@ class Python33Parser(Python32Parser):
|
||||
# Python 3.5+ has jump optimization to remove the redundant
|
||||
# jump_excepts. But in 3.3 we need them added
|
||||
|
||||
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||
try_middle else_suite
|
||||
jump_excepts come_from_except_clauses
|
||||
|
||||
trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||
try_middle
|
||||
jump_excepts come_from_except_clauses
|
||||
|
||||
jump_excepts ::= jump_except+
|
||||
"""
|
||||
|
||||
def add_custom_rules(self, tokens, customize):
|
||||
self.remove_rules("""
|
||||
# 3.3+ adds POP_BLOCKS
|
||||
whileTruestmt ::= SETUP_LOOP l_stmts JUMP_ABSOLUTE JUMP_BACK COME_FROM_LOOP
|
||||
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK COME_FROM_LOOP
|
||||
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK NOP COME_FROM_LOOP
|
||||
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK NOP COME_FROM_LOOP
|
||||
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK
|
||||
|
@@ -140,6 +140,10 @@ class Python35Parser(Python34Parser):
|
||||
"""
|
||||
|
||||
def add_custom_rules(self, tokens, customize):
|
||||
self.remove_rules("""
|
||||
# FIXME: should this be in 3.3?
|
||||
whileTruestmt ::= SETUP_LOOP return_stmts COME_FROM_LOOP
|
||||
""")
|
||||
super(Python35Parser, self).add_custom_rules(tokens, customize)
|
||||
for i, token in enumerate(tokens):
|
||||
opname = token.kind
|
||||
|
@@ -97,7 +97,9 @@ class Python36Parser(Python35Parser):
|
||||
""" % (fstring_expr_or_str_n, fstring_expr_or_str_n, "fstring_expr_or_str " * v)
|
||||
self.add_unique_doc_rules(rules_str, customize)
|
||||
|
||||
def custom_classfunc_rule(self, opname, token, customize, seen_LOAD_BUILD_CLASS):
|
||||
def custom_classfunc_rule(self, opname, token, customize,
|
||||
seen_LOAD_BUILD_CLASS,
|
||||
seen_GET_AWAITABLE_YIELD_FROM):
|
||||
if opname.startswith('CALL_FUNCTION_KW'):
|
||||
values = 'expr ' * token.attr
|
||||
rule = 'call_function ::= expr kwargs_only_36 {token.kind}'.format(**locals())
|
||||
@@ -106,7 +108,9 @@ class Python36Parser(Python35Parser):
|
||||
self.add_unique_rule(rule, token.kind, token.attr, customize)
|
||||
else:
|
||||
super(Python36Parser, self).custom_classfunc_rule(opname, token,
|
||||
customize, seen_LOAD_BUILD_CLASS)
|
||||
customize,
|
||||
seen_LOAD_BUILD_CLASS,
|
||||
seen_GET_AWAITABLE_YIELD_FROM)
|
||||
|
||||
|
||||
class Python36ParserSingle(Python36Parser, PythonParserSingle):
|
||||
|
Reference in New Issue
Block a user