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 3.4 assertion handling. Improve verify
3.4 has jump optimization like 3.5. verify.py: show mismatch on verification mismatch
This commit is contained in:
BIN
test/bytecode_3.4/04_raise.pyc
Normal file
BIN
test/bytecode_3.4/04_raise.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
test/bytecode_3.5/04_raise.pyc
Normal file
BIN
test/bytecode_3.5/04_raise.pyc
Normal file
Binary file not shown.
@@ -148,6 +148,7 @@ def main(in_base, out_base, files, codes, outfile=None,
|
||||
else:
|
||||
print('\n# %s\n\t%s', infile, msg)
|
||||
except verify.VerifyCmpError as e:
|
||||
print(e)
|
||||
verify_failed_files += 1
|
||||
os.rename(outfile, outfile + '_unverified')
|
||||
if not outfile:
|
||||
|
@@ -247,7 +247,7 @@ class Python3Parser(PythonParser):
|
||||
|
||||
'''
|
||||
|
||||
def p_misc(self, args):
|
||||
def p_misc3(self, args):
|
||||
"""
|
||||
try_middle ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY NOP COME_FROM
|
||||
"""
|
||||
@@ -288,7 +288,6 @@ class Python3Parser(PythonParser):
|
||||
def p_expr3(self, args):
|
||||
'''
|
||||
expr ::= LOAD_CLASSNAME
|
||||
expr ::= LOAD_ASSERT
|
||||
|
||||
# Python 3.4+
|
||||
expr ::= LOAD_CLASSDEREF
|
||||
@@ -615,7 +614,7 @@ class Python35onParser(Python3Parser):
|
||||
expr ::= yield_from
|
||||
yield_from ::= expr GET_YIELD_FROM_ITER LOAD_CONST YIELD_FROM
|
||||
|
||||
# Python 3.5 has more loop optimization that removes
|
||||
# Python 3.4+ has more loop optimization that removes
|
||||
# JUMP_FORWARD in some cases, and hence we also don't
|
||||
# see COME_FROM
|
||||
_ifstmts_jump ::= c_stmts_opt
|
||||
|
@@ -37,6 +37,10 @@ class Python34Parser(Python3Parser):
|
||||
# Is this 3.4 only?
|
||||
yield_from ::= expr GET_ITER LOAD_CONST YIELD_FROM
|
||||
|
||||
# Python 3.4+ has more loop optimization that removes
|
||||
# JUMP_FORWARD in some cases, and hence we also don't
|
||||
# see COME_FROM
|
||||
_ifstmts_jump ::= c_stmts_opt
|
||||
"""
|
||||
class Python34ParserSingle(Python34Parser, PythonParserSingle):
|
||||
pass
|
||||
|
@@ -89,8 +89,14 @@ class Scanner2(scan.Scanner):
|
||||
varnames = co.co_varnames
|
||||
self.names = names
|
||||
|
||||
# Scan for assertions. Later we will
|
||||
# turn 'LOAD_GLOBAL' to 'LOAD_ASSERT'.
|
||||
# 'LOAD_ASSERT' is used in assert statements.
|
||||
self.load_asserts = set()
|
||||
for i in self.op_range(0, n):
|
||||
# We need to detect the difference between
|
||||
# "raise AssertionError" and
|
||||
# "assert"
|
||||
if self.code[i] == self.opc.PJIT and self.code[i+3] == self.opc.LOAD_GLOBAL:
|
||||
if names[self.get_argument(i+3)] == 'AssertionError':
|
||||
self.load_asserts.add(i+3)
|
||||
|
@@ -125,8 +125,14 @@ class Scanner26(scan.Scanner2):
|
||||
|
||||
codelen = len(self.code)
|
||||
|
||||
# Scan for assertions. Later we will
|
||||
# turn 'LOAD_GLOBAL' to 'LOAD_ASSERT'.
|
||||
# 'LOAD_ASSERT' is used in assert statements.
|
||||
self.load_asserts = set()
|
||||
for i in self.op_range(0, n):
|
||||
# We need to detect the difference between
|
||||
# "raise AssertionError" and
|
||||
# "assert"
|
||||
if (self.code[i] == self.opc.JUMP_IF_TRUE and
|
||||
i + 4 < codelen and
|
||||
self.code[i+3] == self.opc.POP_TOP and
|
||||
|
@@ -134,16 +134,19 @@ class Scanner3(scan.Scanner):
|
||||
bytecode = Bytecode(co, self.opc)
|
||||
|
||||
# Scan for assertions. Later we will
|
||||
# turn 'LOAD_GLOBAL' to 'LOAD_ASSERT' for those
|
||||
# assertions
|
||||
# turn 'LOAD_GLOBAL' to 'LOAD_ASSERT'.
|
||||
# 'LOAD_ASSERT' is used in assert statements.
|
||||
self.load_asserts = set()
|
||||
bs = list(bytecode)
|
||||
n = len(bs)
|
||||
for i in range(n):
|
||||
inst = bs[i]
|
||||
|
||||
if inst.opname == 'POP_JUMP_IF_TRUE' and i+1 < n:
|
||||
next_inst = bs[i+1]
|
||||
# We need to detect the difference between
|
||||
# "raise AssertionError" and
|
||||
# "assert"
|
||||
if inst.opname == 'POP_JUMP_IF_TRUE' and i+3 < n:
|
||||
next_inst = bs[i+3]
|
||||
if (next_inst.opname == 'LOAD_GLOBAL' and
|
||||
next_inst.argval == 'AssertionError'):
|
||||
self.load_asserts.add(next_inst.offset)
|
||||
|
@@ -180,7 +180,13 @@ def cmp_code_objects(version, code_obj1, code_obj2, name=''):
|
||||
if member in __IGNORE_CODE_MEMBERS__:
|
||||
pass
|
||||
elif member == 'co_code':
|
||||
if version == 2.5:
|
||||
if version == 2.3:
|
||||
import uncompyle6.scanners.scanner23 as scan
|
||||
scanner = scan.Scanner26()
|
||||
elif version == 2.4:
|
||||
import uncompyle6.scanners.scanner24 as scan
|
||||
scanner = scan.Scanner25()
|
||||
elif version == 2.5:
|
||||
import uncompyle6.scanners.scanner25 as scan
|
||||
scanner = scan.Scanner25()
|
||||
elif version == 2.6:
|
||||
@@ -206,8 +212,8 @@ def cmp_code_objects(version, code_obj1, code_obj2, name=''):
|
||||
JUMP_OPs = list(scan.JUMP_OPs) + ['JUMP_BACK']
|
||||
|
||||
# use changed Token class
|
||||
# We (re)set this here to save exception handling,
|
||||
# which would get confusing.
|
||||
# We (re)set this here to save exception handling,
|
||||
# which would get confusing.
|
||||
scanner.setTokenClass(Token)
|
||||
try:
|
||||
# disassemble both code-objects
|
||||
|
Reference in New Issue
Block a user