Get ready for release 3.5.0

This commit is contained in:
rocky 2019-10-12 19:53:17 -04:00
parent 5cb46c2ed3
commit 0b3d6b8add
22 changed files with 329 additions and 7 deletions

1
.gitignore vendored
View File

@ -6,6 +6,7 @@
/.eggs
/.hypothesis
/.idea
/.mypy_cache
/.pytest_cache
/.python-version
/.tox

View File

@ -1,3 +1,12 @@
4.1.0 2019-10-12 Stony Brook Ride
=================================
- Fix fragment bugs
* missing RETURN_LAST introduced when adding transformation layer
* more parent entries on tokens
- Preliminary support for decompiling Python 1.0, 1.1. 1.2 and 1.6
* Newer xdis version needed
3.4.1 2019-10-02
================

View File

@ -58,7 +58,7 @@ entry_points = {
]}
ftp_url = None
install_requires = ["spark-parser >= 1.8.9, < 1.9.0",
"xdis >= 4.0.4, < 4.1.0"]
"xdis >= 4.1.0, < 4.2.0"]
license = "GPL3"
mailing_list = "python-debugger@googlegroups.com"

View File

@ -1,5 +1,6 @@
PHONY=check clean dist distclean test test-unit test-functional rmChangeLog clean_pyc nosetests \
check-bytecode-1 check-bytecode-1.3 check-bytecode-1.4 check-bytecode-1.5 \
check-bytecode-1.0 check-bytecode-1.1 check-bytecode-1.2 check-bytecode-1.3 \
check-bytecode-1 check-bytecode-1.4 check-bytecode-1.5 check-bytecode-1.6 \
check-bytecode-2 check-bytecode-3 check-bytecode-3-short \
check-bytecode-2.2 check-byteocde-2.3 check-bytecode-2.4 \
check-short check-2.6 check-2.7 check-3.0 check-3.1 check-3.2 check-3.3 \
@ -85,7 +86,7 @@ check-disasm:
$(PYTHON) dis-compare.py
#: Check deparsing bytecode 1.x only
check-bytecode-1: check-bytecode-1.4 check-bytecode-1.5
check-bytecode-1: check-bytecode-1.0 check-bytecode-1.1 check-bytecode-1.2 check-bytecode-1.3 check-bytecode-1.4 check-bytecode-1.5 check-byecode-1.4
#: Check deparsing bytecode 2.x only
check-bytecode-2:
@ -109,6 +110,7 @@ check-bytecode-3-short:
#: Check deparsing bytecode on all Python 2 and Python 3 versions
check-bytecode: check-bytecode-3
$(PYTHON) test_pythonlib.py \
--bytecode-1.0 --bytecode-1.1 --bytecode-1.2 \
--bytecode-1.3 --bytecode-1.4 --bytecode-1.5 \
--bytecode-2.2 --bytecode-2.3 --bytecode-2.4 \
--bytecode-2.1 --bytecode-2.2 --bytecode-2.3 --bytecode-2.4 \
@ -122,6 +124,18 @@ check-bytecode-short: check-bytecode-3-short
--bytecode-2.6 --bytecode-2.7 --bytecode-pypy2.7
#: Check deparsing bytecode 1.0 only
check-bytecode-1.0:
$(PYTHON) test_pythonlib.py --bytecode-1.0
#: Check deparsing bytecode 1.1 only
check-bytecode-1.1:
$(PYTHON) test_pythonlib.py --bytecode-1.1
#: Check deparsing bytecode 1.2 only
check-bytecode-1.2:
$(PYTHON) test_pythonlib.py --bytecode-1.2
#: Check deparsing bytecode 1.3 only
check-bytecode-1.3:
$(PYTHON) test_pythonlib.py --bytecode-1.3

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -77,9 +77,13 @@ for vers in (2.7, 3.4, 3.5, 3.6):
pass
for vers in (
1.0,
1.1,
1.2,
1.3,
1.4,
1.5,
1.6,
2.1,
2.2,
2.3,

View File

@ -628,12 +628,30 @@ def get_python_parser(
if version < 3.0:
if version < 2.2:
if version == 1.0:
import uncompyle6.parsers.parse10 as parse10
if compile_mode == 'exec':
p = parse10.Python10Parser(debug_parser)
else:
p = parse10.Python01ParserSingle(debug_parser)
elif version == 1.1:
import uncompyle6.parsers.parse11 as parse11
if compile_mode == 'exec':
p = parse11.Python11Parser(debug_parser)
else:
p = parse11.Python11ParserSingle(debug_parser)
if version == 1.2:
import uncompyle6.parsers.parse12 as parse12
if compile_mode == 'exec':
p = parse12.Python12Parser(debug_parser)
else:
p = parse12.Python12ParserSingle(debug_parser)
if version == 1.3:
import uncompyle6.parsers.parse13 as parse13
if compile_mode == 'exec':
p = parse13.Python14Parser(debug_parser)
p = parse13.Python13Parser(debug_parser)
else:
p = parse13.Python14ParserSingle(debug_parser)
p = parse13.Python13ParserSingle(debug_parser)
elif version == 1.4:
import uncompyle6.parsers.parse14 as parse14
if compile_mode == 'exec':
@ -646,6 +664,12 @@ def get_python_parser(
p = parse15.Python15Parser(debug_parser)
else:
p = parse15.Python15ParserSingle(debug_parser)
elif version == 1.6:
import uncompyle6.parsers.parse16 as parse16
if compile_mode == 'exec':
p = parse16.Python16Parser(debug_parser)
else:
p = parse16.Python16ParserSingle(debug_parser)
elif version == 2.1:
import uncompyle6.parsers.parse21 as parse21
if compile_mode == 'exec':

View File

@ -0,0 +1,25 @@
# Copyright (c) 2019 Rocky Bernstein
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse11 import Python11Parser
class Python10Parser(Python11Parser):
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
super(Python11Parser, self).__init__(debug_parser)
self.customized = {}
class Python10ParserSingle(Python10Parser, PythonParserSingle):
pass
if __name__ == "__main__":
# Check grammar
p = Python10Parser()
p.check_grammar()
p.dump_grammar()
# local variables:
# tab-width: 4

View File

@ -0,0 +1,25 @@
# Copyright (c) 2019 Rocky Bernstein
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse12 import Python12Parser
class Python11Parser(Python12Parser):
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
super(Python12Parser, self).__init__(debug_parser)
self.customized = {}
class Python11ParserSingle(Python11Parser, PythonParserSingle):
pass
if __name__ == "__main__":
# Check grammar
p = Python12Parser()
p.check_grammar()
p.dump_grammar()
# local variables:
# tab-width: 4

View File

@ -0,0 +1,25 @@
# Copyright (c) 2019 Rocky Bernstein
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse13 import Python13Parser
class Python12Parser(Python13Parser):
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
super(Python12Parser, self).__init__(debug_parser)
self.customized = {}
class Python12ParserSingle(Python12Parser, PythonParserSingle):
pass
if __name__ == "__main__":
# Check grammar
p = Python12Parser()
p.check_grammar()
p.dump_grammar()
# local variables:
# tab-width: 4

View File

@ -0,0 +1,46 @@
# Copyright (c) 2019 Rocky Bernstein
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from uncompyle6.parser import PythonParserSingle, nop_func
from uncompyle6.parsers.parse21 import Python21Parser
class Python16Parser(Python21Parser):
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
super(Python16Parser, self).__init__(debug_parser)
self.customized = {}
def p_import16(self, args):
"""
import ::= filler IMPORT_NAME STORE_FAST
import ::= filler IMPORT_NAME STORE_NAME
import_from ::= filler IMPORT_NAME importlist
import_from ::= filler filler IMPORT_NAME importlist POP_TOP
importlist ::= importlist IMPORT_FROM
importlist ::= IMPORT_FROM
"""
def customize_grammar_rules(self, tokens, customize):
super(Python16Parser, self).customize_grammar_rules(tokens, customize)
for i, token in enumerate(tokens):
opname = token.kind
opname_base = opname[:opname.rfind('_')]
if opname_base == 'UNPACK_LIST':
self.addRule("store ::= unpack_list", nop_func)
class Python16ParserSingle(Python16Parser, PythonParserSingle):
pass
if __name__ == '__main__':
# Check grammar
p = Python15Parser()
p.check_grammar()
p.dump_grammar()
# local variables:
# tab-width: 4

View File

@ -37,7 +37,7 @@ from xdis.util import code2num
# The byte code versions we support.
# Note: these all have to be floats
PYTHON_VERSIONS = frozenset((1.3, 1.4, 1.5,
PYTHON_VERSIONS = frozenset((1.0, 1.1, 1.3, 1.4, 1.5, 1.6,
2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7,
3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8))

View File

@ -0,0 +1,35 @@
# Copyright (c) 2019 by Rocky Bernstein
"""
Python 1.0 bytecode decompiler massaging.
This massages tokenized 1.0 bytecode to make it more amenable for
grammar parsing.
"""
import uncompyle6.scanners.scanner11 as scan
# bytecode verification, verify(), uses JUMP_OPs from here
from xdis.opcodes import opcode_10
JUMP_OPS = opcode_10.JUMP_OPS
# We base this off of 1.1 instead of the other way around
# because we cleaned things up this way.
# The history is that 2.7 support is the cleanest,
# then from that we got 2.6 and so on.
class Scanner10(scan.Scanner11):
def __init__(self, show_asm=False):
scan.Scanner11.__init__(self, show_asm)
self.opc = opcode_10
self.opname = opcode_10.opname
self.version = 1.0
return
# def ingest(self, co, classname=None, code_objects={}, show_asm=None):
# tokens, customize = self.parent_ingest(co, classname, code_objects, show_asm)
# tokens = [t for t in tokens if t.kind != 'SET_LINENO']
# # for t in tokens:
# # print(t)
#
# return tokens, customize

View File

@ -0,0 +1,35 @@
# Copyright (c) 2019 by Rocky Bernstein
"""
Python 1.1 bytecode decompiler massaging.
This massages tokenized 1.1 bytecode to make it more amenable for
grammar parsing.
"""
import uncompyle6.scanners.scanner13 as scan
# bytecode verification, verify(), uses JUMP_OPs from here
from xdis.opcodes import opcode_11
JUMP_OPS = opcode_11.JUMP_OPS
# We base this off of 1.2 instead of the other way around
# because we cleaned things up this way.
# The history is that 2.7 support is the cleanest,
# then from that we got 2.6 and so on.
class Scanner11(scan.Scanner13): # no scanner 1.2
def __init__(self, show_asm=False):
scan.Scanner13.__init__(self, show_asm)
self.opc = opcode_11
self.opname = opcode_11.opname
self.version = 1.1
return
# def ingest(self, co, classname=None, code_objects={}, show_asm=None):
# tokens, customize = self.parent_ingest(co, classname, code_objects, show_asm)
# tokens = [t for t in tokens if t.kind != 'SET_LINENO']
# # for t in tokens:
# # print(t)
#
# return tokens, customize

View File

@ -0,0 +1,36 @@
# Copyright (c) 2019 by Rocky Bernstein
"""
Python 1.2 bytecode decompiler massaging.
This massages tokenized 1.2 bytecode to make it more amenable for
grammar parsing.
"""
import uncompyle6.scanners.scanner13 as scan
# bytecode verification, verify(), uses JUMP_OPs from here
from xdis.opcodes import opcode_11
JUMP_OPS = opcode_11.JUMP_OPS
# We base this off of 1.3 instead of the other way around
# because we cleaned things up this way.
# The history is that 2.7 support is the cleanest,
# then from that we got 2.6 and so on.
class Scanner12(scan.Scanner13):
def __init__(self, show_asm=False):
scan.Scanner14.__init__(self, show_asm)
self.opc = opcode_11
self.opname = opcode_11.opname
self.version = 1.2 # Note: is the same as 1.1 bytecode
return
# def ingest(self, co, classname=None, code_objects={}, show_asm=None):
# tokens, customize = self.parent_ingest(co, classname, code_objects, show_asm)
# tokens = [t for t in tokens if t.kind != 'SET_LINENO']
# # for t in tokens:
# # print(t)
#
# return tokens, customize

View File

@ -7,10 +7,12 @@ grammar parsing.
"""
import uncompyle6.scanners.scanner14 as scan
# from uncompyle6.scanners.scanner26 import ingest as ingest26
# bytecode verification, verify(), uses JUMP_OPs from here
from xdis.opcodes import opcode_13
JUMP_OPS = opcode_13.JUMP_OPS
# We base this off of 1.4 instead of the other way around

View File

@ -0,0 +1,41 @@
# Copyright (c) 2019 by Rocky Bernstein
"""
Python 1.6 bytecode decompiler massaging.
This massages tokenized 1.6 bytecode to make it more amenable for
grammar parsing.
"""
import uncompyle6.scanners.scanner21 as scan
# from uncompyle6.scanners.scanner26 import ingest as ingest26
# bytecode verification, verify(), uses JUMP_OPs from here
from xdis.opcodes import opcode_16
JUMP_OPS = opcode_16.JUMP_OPS
# We base this off of 2.2 instead of the other way around
# because we cleaned things up this way.
# The history is that 2.7 support is the cleanest,
# then from that we got 2.6 and so on.
class Scanner16(scan.Scanner21):
def __init__(self, show_asm=False):
scan.Scanner21.__init__(self, show_asm)
self.opc = opcode_16
self.opname = opcode_16.opname
self.version = 1.6
self.genexpr_name = '<generator expression>'
return
def ingest(self, co, classname=None, code_objects={}, show_asm=None):
"""
Pick out tokens from an uncompyle6 code object, and transform them,
returning a list of uncompyle6 Token's.
The transformations are made to assist the deparsing grammar.
"""
tokens, customize = scan.Scanner21.ingest(self, co, classname, code_objects, show_asm)
for t in tokens:
if t.op == self.opc.UNPACK_LIST:
t.kind = 'UNPACK_LIST_%d' % t.attr
pass
return tokens, customize

View File

@ -12,4 +12,4 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This file is suitable for sourcing inside bash as
# well as importing into Python
VERSION="3.4.1" # noqa
VERSION="3.5.0" # noqa