Tidy a little bit

This commit is contained in:
rocky
2015-12-16 01:52:11 -05:00
parent 8c94acfca0
commit 9fecb48744
14 changed files with 74 additions and 36 deletions

View File

@@ -20,9 +20,13 @@ all: check
test check: pytest check-short
#: Run tests
check-short: pytest
check-short: pytest
$(MAKE) -C test $@
#: check that disassembly exactly matches Python lib's dis
check-disasm:
$(MAKE) -C test check-disasm
#: Run tests
pytest:
$(MAKE) -C pytest check

1
pytest/testdata/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/*.got

View File

@@ -16,6 +16,10 @@ check: check-short check-2.7-ok
## This leads me to believe the problem is an
## initialization bug?
#: Check deparsing only, but from a different Python version
check-disasm:
$(PYTHON) dis-compare.py
#: Check deparsing only, but from a different Python version
check-bytecode:
$(PYTHON) test_pythonlib.py --bytecode-2.5

BIN
test/bytecode_2.7/if.pyc Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -55,8 +55,10 @@ tests['2.5'] = tests['2.3']
tests['2.6'] = tests['2.5']
# tests['2.7'] = ['mine'] + tests['2.6']
tests['2.7'] = [
'source_3.4/call_arguments/keyword',
'source_3.4/call_arguments/positional'
'source_3.4/branching/ifelse',
'source_3.4/branching/if'
# 'source_3.4/call_arguments/keyword',
# 'source_3.4/call_arguments/positional'
]
tests['3.4'] = [

View File

@@ -61,7 +61,7 @@ try:
except ImportError:
from io import StringIO
import sys, inspect, types, re
import sys, inspect, re
# FIXME: remove uncompyle dups
@@ -464,7 +464,7 @@ class Traverser(walker.Walker, object):
self.prec = 27
code = node[-5].attr
assert isinstance(code, types.CodeType)
assert inspect.iscode(code)
code = Code(code, self.scanner, self.currentclass)
# assert isinstance(code, Code)
@@ -1115,7 +1115,7 @@ class Traverser(walker.Walker, object):
pass
def deparse(version, co, out=StringIO(), showasm=0, showast=0):
assert isinstance(co, types.CodeType)
assert inspect.iscode(co)
# store final output stream for case of error
__real_out = out or sys.stdout
try:

View File

@@ -1,29 +1,41 @@
# Copyright (c) 1999 John Aycock
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
# Copyright (c) 2015 by Rocky Bernstein
"""
CPython magic- and version- independent disassembly routines
Copyright (c) 1999 John Aycock
Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
Copyright (c) 2015 by Rocky Bernstein
There are two reasons we can't use Python's built-in routines
from dis. First, the bytecode we are extracting may be from a different
version of Python (different magic number) than the version of Python
that is doing the extraction.
This is needed when the bytecode extracted is from
a different version than the currently-running Python.
When the two are the same, you can simply use Python's built-in disassemble
Second, we need structured instruction information for the
(de)-parsing step. Python 3.4 and up provides this, but we still do
want to run on Python 2.7.
"""
from __future__ import print_function
import os, sys, types
import importlib, inspect, os, sys
import uncompyle6
def check_object_path(path):
if path.endswith(".py"):
if uncompyle6.PYTHON3:
path = importlib.util.cache_from_source(path)
return path
if not path.endswith(".pyc") and not path.endswith(".pyo"):
raise ValueError("path must point to a .py or .pyc file")
return path
def disco(version, co, out=None):
"""
diassembles and deparses a given code block 'co'
"""
assert isinstance(co, types.CodeType)
assert inspect.iscode(co)
# store final output stream for case of error
real_out = out or sys.stdout
@@ -59,7 +71,11 @@ def disco(version, co, out=None):
def disassemble_file(filename, outstream=None):
"""
disassemble Python byte-code file (.pyc)
If given a Python source file (".py") file, we'll
try to find the corresponding compiled object.
"""
filename = check_object_path(filename)
version, co = uncompyle6.load_module(filename)
if type(co) == list:
for con in co:
@@ -144,9 +160,13 @@ def _test():
"""Simple test program to disassemble a file."""
argc = len(sys.argv)
if argc != 2:
sys.stderr.write("usage: %s [-|CPython compiled file]\n" % __file__)
sys.exit(2)
fn = sys.argv[1]
if argc == 1 and uncompyle6.PYTHON3:
fn = __file__
else:
sys.stderr.write("usage: %s [-|CPython compiled file]\n" % __file__)
sys.exit(2)
else:
fn = sys.argv[1]
disassemble_file(fn)
if __name__ == "__main__":

View File

@@ -1,11 +1,6 @@
"""
CPython magic- and version- independent marshal routines
Copyright (c) 1999 John Aycock
Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
Copyright (c) 2015 by Rocky Bernstein
This is needed when the bytecode extracted is from
a different version than the currently-running Python.
@@ -13,6 +8,11 @@ When the two are the same, you can simply use Python's built-in marshal.loads()
to produce a code object
"""
# Copyright (c) 1999 John Aycock
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
# Copyright (c) 2015 by Rocky Bernstein
from __future__ import print_function
import imp, sys, types

View File

@@ -20,9 +20,11 @@ __all__ = ['Token', 'Scanner', 'Code']
import sys
# FIXME: DRY
if (sys.version_info > (3, 0)):
intern = sys.intern
L65536 = 65536
def cmp(a, b):
return (a > b) - (a < b)
else:

View File

@@ -13,7 +13,7 @@ Python 3 and other versions of Python. Also, we save token
information for later use in deparsing.
"""
import types
import inspect
from collections import namedtuple
from array import array
@@ -152,7 +152,7 @@ class Scanner25(scan.Scanner):
continue
if op in hasconst:
const = co.co_consts[oparg]
if isinstance(const, types.CodeType):
if inspect.iscode(const):
oparg = const
if const.co_name == '<lambda>':
assert op_name == 'LOAD_CONST'

View File

@@ -13,7 +13,7 @@ other versions of Python. Also, we save token information for later
use in deparsing.
"""
import types
import inspect
from collections import namedtuple
from array import array
@@ -147,7 +147,7 @@ class Scanner26(scan.Scanner):
continue
if op in hasconst:
const = co.co_consts[oparg]
if isinstance(const, types.CodeType):
if inspect.iscode(const):
oparg = const
if const.co_name == '<lambda>':
assert op_name == 'LOAD_CONST'

View File

@@ -13,7 +13,7 @@ for later use in deparsing.
from __future__ import print_function
import dis, types
import dis, inspect
from collections import namedtuple
from array import array
@@ -136,7 +136,7 @@ class Scanner27(scan.Scanner):
continue
if op in hasconst:
const = co.co_consts[oparg]
if isinstance(const, types.CodeType):
if inspect.iscode(const):
oparg = const
if const.co_name == '<lambda>':
assert op_name == 'LOAD_CONST'

View File

@@ -1,18 +1,23 @@
from __future__ import print_function
#
# (C) Copyright 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
#
# byte-code verifier for uncompyle
#
import dis, operator, sys, types
from __future__ import print_function
import dis, inspect, operator, sys, types
import uncompyle6
import uncompyle6.scanner as scanner
# FIXME: DRY
if (sys.version_info >= (3, 0)):
truediv = operator.truediv
def cmp(a, b):
return (a > b) - (a < b)
from functools import reduce
else:
truediv = operator.div
@@ -127,8 +132,8 @@ def cmp_code_objects(version, code_obj1, code_obj2, name=''):
This is the main part of this module.
"""
# print code_obj1, type(code_obj2)
assert isinstance(code_obj1, types.CodeType)
assert isinstance(code_obj2, types.CodeType)
assert inspect.iscode(code_obj1)
assert inspect.iscode(code_obj2)
# print dir(code_obj1)
if isinstance(code_obj1, object):
# new style classes (Python 2.2)