You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-02 16:44:46 +08:00
Tidy a little bit
This commit is contained in:
6
Makefile
6
Makefile
@@ -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
1
pytest/testdata/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/*.got
|
@@ -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
BIN
test/bytecode_2.7/if.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.7/ifelse.pyc
Normal file
BIN
test/bytecode_2.7/ifelse.pyc
Normal file
Binary file not shown.
@@ -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'] = [
|
||||
|
@@ -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:
|
||||
|
@@ -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__":
|
||||
|
@@ -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
|
||||
|
@@ -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:
|
||||
|
@@ -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'
|
||||
|
@@ -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'
|
||||
|
@@ -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'
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user