You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Slightly better assert detection
This commit is contained in:
@@ -1,8 +1,21 @@
|
|||||||
# Copyright (c) 2015-2017 Rocky Bernstein
|
# Copyright (c) 2015-2017 Rocky Bernstein
|
||||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||||
|
#
|
||||||
# Copyright (c) 1999 John Aycock
|
# Copyright (c) 1999 John Aycock
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
A spark grammar for Python 2.x.
|
Base grammar for Python 2.x.
|
||||||
|
|
||||||
However instead of terminal symbols being the usual ASCII text,
|
However instead of terminal symbols being the usual ASCII text,
|
||||||
e.g. 5, myvariable, "for", etc. they are CPython Bytecode tokens,
|
e.g. 5, myvariable, "for", etc. they are CPython Bytecode tokens,
|
||||||
@@ -175,6 +188,7 @@ class Python2Parser(PythonParser):
|
|||||||
def p_expr2(self, args):
|
def p_expr2(self, args):
|
||||||
"""
|
"""
|
||||||
expr ::= LOAD_LOCALS
|
expr ::= LOAD_LOCALS
|
||||||
|
expr ::= LOAD_ASSERT
|
||||||
expr ::= slice0
|
expr ::= slice0
|
||||||
expr ::= slice1
|
expr ::= slice1
|
||||||
expr ::= slice2
|
expr ::= slice2
|
||||||
@@ -505,6 +519,7 @@ class Python2Parser(PythonParser):
|
|||||||
|
|
||||||
self.check_reduce['aug_assign1'] = 'AST'
|
self.check_reduce['aug_assign1'] = 'AST'
|
||||||
self.check_reduce['aug_assign2'] = 'AST'
|
self.check_reduce['aug_assign2'] = 'AST'
|
||||||
|
self.check_reduce['or'] = 'AST'
|
||||||
# self.check_reduce['_stmts'] = 'AST'
|
# self.check_reduce['_stmts'] = 'AST'
|
||||||
|
|
||||||
# Dead code testing...
|
# Dead code testing...
|
||||||
@@ -522,6 +537,9 @@ class Python2Parser(PythonParser):
|
|||||||
|
|
||||||
if lhs in ('aug_assign1', 'aug_assign2') and ast[0] and ast[0][0] == 'and':
|
if lhs in ('aug_assign1', 'aug_assign2') and ast[0] and ast[0][0] == 'and':
|
||||||
return True
|
return True
|
||||||
|
if rule == ('or', ('expr', 'jmp_true', 'expr', '\\e_come_from_opt')):
|
||||||
|
expr2 = ast[2]
|
||||||
|
return expr2 == 'expr' and expr2[0] == 'LOAD_ASSERT'
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class Python2ParserSingle(Python2Parser, PythonParserSingle):
|
class Python2ParserSingle(Python2Parser, PythonParserSingle):
|
||||||
|
@@ -37,6 +37,7 @@ from __future__ import print_function
|
|||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from array import array
|
from array import array
|
||||||
|
from copy import copy
|
||||||
|
|
||||||
from xdis.code import iscode
|
from xdis.code import iscode
|
||||||
from xdis.bytecode import (
|
from xdis.bytecode import (
|
||||||
@@ -54,6 +55,7 @@ class Scanner2(Scanner):
|
|||||||
# This is the 2.5+ default
|
# This is the 2.5+ default
|
||||||
# For <2.5 it is <generator expression>
|
# For <2.5 it is <generator expression>
|
||||||
self.genexpr_name = '<genexpr>'
|
self.genexpr_name = '<genexpr>'
|
||||||
|
self.load_asserts = set([])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unmangle_name(name, classname):
|
def unmangle_name(name, classname):
|
||||||
@@ -139,6 +141,9 @@ class Scanner2(Scanner):
|
|||||||
# 'LOAD_ASSERT' is used in assert statements.
|
# 'LOAD_ASSERT' is used in assert statements.
|
||||||
self.load_asserts = set()
|
self.load_asserts = set()
|
||||||
for i in self.op_range(0, codelen):
|
for i in self.op_range(0, codelen):
|
||||||
|
|
||||||
|
self.offset2inst_index[inst.offset] = i
|
||||||
|
|
||||||
# We need to detect the difference between:
|
# We need to detect the difference between:
|
||||||
# raise AssertionError
|
# raise AssertionError
|
||||||
# and
|
# and
|
||||||
@@ -159,7 +164,9 @@ class Scanner2(Scanner):
|
|||||||
|
|
||||||
# Get jump targets
|
# Get jump targets
|
||||||
# Format: {target offset: [jump offsets]}
|
# Format: {target offset: [jump offsets]}
|
||||||
|
load_asserts_save = copy(self.load_asserts)
|
||||||
jump_targets = self.find_jump_targets(show_asm)
|
jump_targets = self.find_jump_targets(show_asm)
|
||||||
|
self.load_asserts = load_asserts_save
|
||||||
# print("XXX2", jump_targets)
|
# print("XXX2", jump_targets)
|
||||||
|
|
||||||
last_stmt = self.next_stmt[0]
|
last_stmt = self.next_stmt[0]
|
||||||
|
Reference in New Issue
Block a user