You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Python 2.5 mistaken try/else
This commit is contained in:
1
pytest/.gitignore
vendored
1
pytest/.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
|
/.hypothesis
|
||||||
/__pycache__
|
/__pycache__
|
||||||
|
BIN
test/bytecode_2.5/02_try_else.pyc
Normal file
BIN
test/bytecode_2.5/02_try_else.pyc
Normal file
Binary file not shown.
12
test/simple_source/bug25/02_try_else.py
Normal file
12
test/simple_source/bug25/02_try_else.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Python 2.5 bug
|
||||||
|
# Was turning into tryelse when there in fact is no else.
|
||||||
|
def options(self, section):
|
||||||
|
"""Return a list of option names for the given section name."""
|
||||||
|
try:
|
||||||
|
opts = self._sections[section].copy()
|
||||||
|
except KeyError:
|
||||||
|
raise NoSectionError(section)
|
||||||
|
opts.update(self._defaults)
|
||||||
|
if '__name__' in opts:
|
||||||
|
del opts['__name__']
|
||||||
|
return opts.keys()
|
@@ -13,7 +13,7 @@ class Python25Parser(Python26Parser):
|
|||||||
self.customized = {}
|
self.customized = {}
|
||||||
|
|
||||||
def p_misc25(self, args):
|
def p_misc25(self, args):
|
||||||
'''
|
"""
|
||||||
# If "return_if_stmt" is in a loop, a JUMP_BACK can be emitted. In 2.6 the
|
# If "return_if_stmt" is in a loop, a JUMP_BACK can be emitted. In 2.6 the
|
||||||
# JUMP_BACK doesn't appear
|
# JUMP_BACK doesn't appear
|
||||||
|
|
||||||
@@ -33,7 +33,31 @@ class Python25Parser(Python26Parser):
|
|||||||
|
|
||||||
with_cleanup ::= LOAD_FAST DELETE_FAST WITH_CLEANUP END_FINALLY
|
with_cleanup ::= LOAD_FAST DELETE_FAST WITH_CLEANUP END_FINALLY
|
||||||
with_cleanup ::= LOAD_NAME DELETE_NAME WITH_CLEANUP END_FINALLY
|
with_cleanup ::= LOAD_NAME DELETE_NAME WITH_CLEANUP END_FINALLY
|
||||||
'''
|
"""
|
||||||
|
|
||||||
|
def add_custom_rules(self, tokens, customize):
|
||||||
|
super(Python25Parser, self).add_custom_rules(tokens, customize)
|
||||||
|
if self.version == 2.5:
|
||||||
|
self.check_reduce['tryelsestmt'] = 'tokens'
|
||||||
|
|
||||||
|
|
||||||
|
def reduce_is_invalid(self, rule, ast, tokens, first, last):
|
||||||
|
super(Python25Parser, self).reduce_is_invalid(rule, ast, tokens, first, last)
|
||||||
|
|
||||||
|
lhs = rule[0]
|
||||||
|
if lhs in ('tryelsestmt', ):
|
||||||
|
# The end of the else part of try/else come_from has to come
|
||||||
|
# from an END_FINALLY statement
|
||||||
|
if tokens[last-1].type.startswith('COME_FROM'):
|
||||||
|
end_finally_offset = int(tokens[last-1].pattr)
|
||||||
|
current = first
|
||||||
|
while current < last:
|
||||||
|
offset = tokens[current].offset
|
||||||
|
if offset == end_finally_offset:
|
||||||
|
return tokens[current].type != 'END_FINALLY'
|
||||||
|
current += 1
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class Python25ParserSingle(Python26Parser, PythonParserSingle):
|
class Python25ParserSingle(Python26Parser, PythonParserSingle):
|
||||||
pass
|
pass
|
||||||
|
@@ -42,7 +42,7 @@ class Python26Parser(Python2Parser):
|
|||||||
try_middle come_froms
|
try_middle come_froms
|
||||||
|
|
||||||
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||||
try_middle else_suite come_froms
|
try_middle else_suite COME_FROM
|
||||||
|
|
||||||
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM POP_TOP
|
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM POP_TOP
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user