You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Merge branch 'master' into python-2.4
This commit is contained in:
@@ -7,7 +7,7 @@ machine:
|
||||
dependencies:
|
||||
override:
|
||||
- pip install -e .
|
||||
- pip install -r requirements-dev.txt
|
||||
- pip install pytest==3.2.5 hypothesis
|
||||
test:
|
||||
override:
|
||||
- python ./setup.py develop && make check-2.6
|
||||
|
@@ -26,7 +26,9 @@ def test_if_in_for():
|
||||
scan = get_scanner(PYTHON_VERSION)
|
||||
if 2.7 <= PYTHON_VERSION <= 3.0 and not IS_PYPY:
|
||||
n = scan.setup_code(code)
|
||||
bytecode = Bytecode(code, scan.opc)
|
||||
scan.build_lines_data(code, n)
|
||||
scan.insts = list(bytecode)
|
||||
scan.build_prev_op(n)
|
||||
fjt = scan.find_jump_targets(False)
|
||||
|
||||
|
BIN
test/bytecode_2.6_run/02_try_else_loop.pyc
Normal file
BIN
test/bytecode_2.6_run/02_try_else_loop.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.6_run/03_try_else.pyc
Normal file
BIN
test/bytecode_2.6_run/03_try_else.pyc
Normal file
Binary file not shown.
@@ -52,22 +52,14 @@ case $PYVERSION in
|
||||
;;
|
||||
2.6)
|
||||
SKIP_TESTS=(
|
||||
[test_binop.py]=1 # need to fix tryelse
|
||||
[test_cmath.py]=1 # Control flow?
|
||||
[test_codecs.py]=1 # need to fix tryelse
|
||||
[test_coercion.py]=1 # Control flow?
|
||||
[test_cookielib.py]=1 # Control flow?
|
||||
[test_decorators.py]=1 # Syntax Error - look at
|
||||
[test_enumerate.py]=1 # Control flow?
|
||||
[test_file.py]=1 # Control flow?
|
||||
[test_frozen.py]=1 # Control flow?
|
||||
[test_ftplib.py]=1 # Control flow?
|
||||
[test_funcattrs.py]=1 # Control flow?
|
||||
[test_grp.py]=1 # Long test - might work Control flow?
|
||||
[test_imp.py]=1
|
||||
[test_int.py]=1
|
||||
[test_long.py]=1
|
||||
[test_pty.py]=1
|
||||
[test_pwd.py]=1 # Long test - might work? Control flow?
|
||||
[test_queue.py]=1 # Control flow?
|
||||
[test_re.py]=1 # Probably Control flow?
|
||||
|
@@ -473,24 +473,20 @@ class Python2Parser(PythonParser):
|
||||
pass
|
||||
continue
|
||||
elif opname == 'SETUP_EXCEPT':
|
||||
# FIXME: have a way here to detect PyPy. Right now we
|
||||
# only have SETUP_EXCEPT customization for PyPy, but that might not
|
||||
# always be the case.
|
||||
self.add_unique_rules([
|
||||
"stmt ::= try_except_pypy",
|
||||
"try_except_pypy ::= SETUP_EXCEPT suite_stmts_opt except_handler_pypy",
|
||||
"except_handler_pypy ::= COME_FROM except_stmts END_FINALLY COME_FROM"
|
||||
], customize)
|
||||
if 'PyPy' in customize:
|
||||
self.add_unique_rules([
|
||||
"stmt ::= try_except_pypy",
|
||||
"try_except_pypy ::= SETUP_EXCEPT suite_stmts_opt except_handler_pypy",
|
||||
"except_handler_pypy ::= COME_FROM except_stmts END_FINALLY COME_FROM"
|
||||
], customize)
|
||||
custom_ops_seen.add(opname)
|
||||
continue
|
||||
elif opname == 'SETUP_FINALLY':
|
||||
# FIXME: have a way here to detect PyPy. Right now we
|
||||
# only have SETUP_EXCEPT customization for PyPy, but that might not
|
||||
# always be the case.
|
||||
self.addRule("""
|
||||
stmt ::= tryfinallystmt_pypy
|
||||
tryfinallystmt_pypy ::= SETUP_FINALLY suite_stmts_opt COME_FROM_FINALLY
|
||||
suite_stmts_opt END_FINALLY""", nop_func)
|
||||
if 'PyPy' in customize:
|
||||
self.addRule("""
|
||||
stmt ::= tryfinallystmt_pypy
|
||||
tryfinallystmt_pypy ::= SETUP_FINALLY suite_stmts_opt COME_FROM_FINALLY
|
||||
suite_stmts_opt END_FINALLY""", nop_func)
|
||||
|
||||
custom_ops_seen.add(opname)
|
||||
continue
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2016-2017 Rocky Bernstein
|
||||
# Copyright (c) 2016-2018 Rocky Bernstein
|
||||
"""
|
||||
spark grammar differences over Python2.5 for Python 2.4.
|
||||
"""
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2016-2017 Rocky Bernstein
|
||||
# Copyright (c) 2016-2018 Rocky Bernstein
|
||||
"""
|
||||
spark grammar differences over Python2.6 for Python 2.5.
|
||||
"""
|
||||
|
@@ -40,6 +40,8 @@ class Python26Parser(Python2Parser):
|
||||
|
||||
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||
except_handler else_suite come_froms
|
||||
tryelsestmtl ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||
except_handler else_suitel
|
||||
|
||||
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM POP_TOP
|
||||
|
||||
@@ -155,10 +157,12 @@ class Python26Parser(Python2Parser):
|
||||
ifstmt ::= testexpr_then _ifstmts_jump
|
||||
|
||||
# Semantic actions want the else to be at position 3
|
||||
ifelsestmt ::= testexpr c_stmts_opt jf_cf_pop else_suite come_froms
|
||||
ifelsestmt ::= testexpr_then c_stmts_opt jf_cf_pop else_suite come_froms
|
||||
ifelsestmt ::= testexpr_then c_stmts_opt filler else_suitel come_froms POP_TOP
|
||||
|
||||
# We have no jumps to jumps, so no "come_froms" but a single "COME_FROM"
|
||||
ifelsestmt ::= testexpr c_stmts_opt jf_cf_pop else_suite COME_FROM
|
||||
|
||||
# Semantic actions want else_suitel to be at index 3
|
||||
ifelsestmtl ::= testexpr_then c_stmts_opt jb_cf_pop else_suitel
|
||||
ifelsestmtc ::= testexpr_then c_stmts_opt ja_cf_pop else_suitec
|
||||
@@ -307,6 +311,7 @@ class Python26Parser(Python2Parser):
|
||||
super(Python26Parser, self).customize_grammar_rules(tokens, customize)
|
||||
self.check_reduce['and'] = 'AST'
|
||||
self.check_reduce['list_for'] = 'AST'
|
||||
self.check_reduce['try_except'] = 'tokens'
|
||||
|
||||
def reduce_is_invalid(self, rule, ast, tokens, first, last):
|
||||
invalid = super(Python26Parser,
|
||||
@@ -333,6 +338,23 @@ class Python26Parser(Python2Parser):
|
||||
# The JUMP_ABSOLUTE has to be to the last POP_TOP or this is invalid
|
||||
ja_attr = ast[4].attr
|
||||
return tokens[last].offset != ja_attr
|
||||
elif rule[0] == 'try_except':
|
||||
# We need to distingush try_except from try_except_else and we do that
|
||||
# by checking the jump before the END_FINALLY
|
||||
# If we have:
|
||||
# insn
|
||||
# POP_TOP
|
||||
# END_FINALLY
|
||||
# COME_FROM
|
||||
# then insn has to be either a JUMP_FORWARD or a RETURN_VALUE
|
||||
if last == len(tokens):
|
||||
last -= 1
|
||||
if tokens[last] != 'COME_FROM' and tokens[last-1] == 'COME_FROM':
|
||||
last -= 1
|
||||
return (tokens[last] == 'COME_FROM'
|
||||
and tokens[last-1] == 'END_FINALLY'
|
||||
and tokens[last-2] == 'POP_TOP'
|
||||
and tokens[last-3].kind not in frozenset(('JUMP_FORWARD', 'RETURN_VALUE')))
|
||||
return False
|
||||
class Python26ParserSingle(Python2Parser, PythonParserSingle):
|
||||
pass
|
||||
|
@@ -172,8 +172,9 @@ class Scanner(object):
|
||||
instr = [instr]
|
||||
|
||||
result_offset = None
|
||||
current_distance = len(code)
|
||||
current_distance = self.insts[-1].offset - self.insts[0].offset
|
||||
extended_arg = 0
|
||||
# FIXME: use self.insts rather than code[]
|
||||
for offset in self.op_range(start, end):
|
||||
op = code[offset]
|
||||
|
||||
@@ -195,6 +196,12 @@ class Scanner(object):
|
||||
if new_distance <= current_distance:
|
||||
current_distance = new_distance
|
||||
result_offset = offset
|
||||
pass
|
||||
pass
|
||||
pass
|
||||
pass
|
||||
extended_arg = 0
|
||||
pass
|
||||
return result_offset
|
||||
|
||||
def all_instr(self, start, end, instr, target=None, include_beyond_target=False):
|
||||
|
@@ -30,7 +30,7 @@ else:
|
||||
from array import array
|
||||
|
||||
from xdis.code import iscode
|
||||
from xdis.bytecode import op_has_argument, op_size, instruction_size
|
||||
from xdis.bytecode import Bytecode, op_has_argument, op_size, instruction_size
|
||||
from xdis.util import code2num
|
||||
|
||||
from uncompyle6.scanner import Scanner
|
||||
@@ -92,10 +92,9 @@ class Scanner2(Scanner):
|
||||
if not show_asm:
|
||||
show_asm = self.show_asm
|
||||
|
||||
bytecode = Bytecode(co, self.opc)
|
||||
# show_asm = 'after'
|
||||
if show_asm in ('both', 'before'):
|
||||
from xdis.bytecode import Bytecode
|
||||
bytecode = Bytecode(co, self.opc)
|
||||
for instr in bytecode.get_instructions(co):
|
||||
print(instr.disassemble())
|
||||
|
||||
@@ -114,6 +113,7 @@ class Scanner2(Scanner):
|
||||
|
||||
self.build_lines_data(co, codelen)
|
||||
self.build_prev_op(codelen)
|
||||
self.insts = list(bytecode)
|
||||
|
||||
free, names, varnames = self.unmangle_code_names(co, classname)
|
||||
self.names = names
|
||||
|
@@ -19,6 +19,7 @@ from uncompyle6.scanner import L65536
|
||||
|
||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||
from xdis.opcodes import opcode_26
|
||||
from xdis.bytecode import Bytecode
|
||||
JUMP_OPS = opcode_26.JUMP_OPS
|
||||
|
||||
class Scanner26(scan.Scanner2):
|
||||
@@ -90,10 +91,9 @@ class Scanner26(scan.Scanner2):
|
||||
if not show_asm:
|
||||
show_asm = self.show_asm
|
||||
|
||||
bytecode = Bytecode(co, self.opc)
|
||||
# show_asm = 'after'
|
||||
if show_asm in ('both', 'before'):
|
||||
from xdis.bytecode import Bytecode
|
||||
bytecode = Bytecode(co, self.opc)
|
||||
for instr in bytecode.get_instructions(co):
|
||||
print(instr.disassemble())
|
||||
|
||||
@@ -110,6 +110,7 @@ class Scanner26(scan.Scanner2):
|
||||
|
||||
self.build_lines_data(co, codelen)
|
||||
self.build_prev_op(codelen)
|
||||
self.insts = list(bytecode)
|
||||
|
||||
free, names, varnames = self.unmangle_code_names(co, classname)
|
||||
self.names = names
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2016-2017 by Rocky Bernstein
|
||||
# Copyright (c) 2016-2018 by Rocky Bernstein
|
||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
# Copyright (c) 1999 John Aycock
|
||||
|
||||
|
Reference in New Issue
Block a user