You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Tidy a little bit
This commit is contained in:
4
Makefile
4
Makefile
@@ -23,6 +23,10 @@ test check: pytest check-short
|
|||||||
check-short: pytest
|
check-short: pytest
|
||||||
$(MAKE) -C test $@
|
$(MAKE) -C test $@
|
||||||
|
|
||||||
|
#: check that disassembly exactly matches Python lib's dis
|
||||||
|
check-disasm:
|
||||||
|
$(MAKE) -C test check-disasm
|
||||||
|
|
||||||
#: Run tests
|
#: Run tests
|
||||||
pytest:
|
pytest:
|
||||||
$(MAKE) -C pytest check
|
$(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
|
## This leads me to believe the problem is an
|
||||||
## initialization bug?
|
## 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 deparsing only, but from a different Python version
|
||||||
check-bytecode:
|
check-bytecode:
|
||||||
$(PYTHON) test_pythonlib.py --bytecode-2.5
|
$(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.6'] = tests['2.5']
|
||||||
# tests['2.7'] = ['mine'] + tests['2.6']
|
# tests['2.7'] = ['mine'] + tests['2.6']
|
||||||
tests['2.7'] = [
|
tests['2.7'] = [
|
||||||
'source_3.4/call_arguments/keyword',
|
'source_3.4/branching/ifelse',
|
||||||
'source_3.4/call_arguments/positional'
|
'source_3.4/branching/if'
|
||||||
|
# 'source_3.4/call_arguments/keyword',
|
||||||
|
# 'source_3.4/call_arguments/positional'
|
||||||
]
|
]
|
||||||
|
|
||||||
tests['3.4'] = [
|
tests['3.4'] = [
|
||||||
|
@@ -61,7 +61,7 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
import sys, inspect, types, re
|
import sys, inspect, re
|
||||||
|
|
||||||
|
|
||||||
# FIXME: remove uncompyle dups
|
# FIXME: remove uncompyle dups
|
||||||
@@ -464,7 +464,7 @@ class Traverser(walker.Walker, object):
|
|||||||
self.prec = 27
|
self.prec = 27
|
||||||
code = node[-5].attr
|
code = node[-5].attr
|
||||||
|
|
||||||
assert isinstance(code, types.CodeType)
|
assert inspect.iscode(code)
|
||||||
code = Code(code, self.scanner, self.currentclass)
|
code = Code(code, self.scanner, self.currentclass)
|
||||||
# assert isinstance(code, Code)
|
# assert isinstance(code, Code)
|
||||||
|
|
||||||
@@ -1115,7 +1115,7 @@ class Traverser(walker.Walker, object):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def deparse(version, co, out=StringIO(), showasm=0, showast=0):
|
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
|
# store final output stream for case of error
|
||||||
__real_out = out or sys.stdout
|
__real_out = out or sys.stdout
|
||||||
try:
|
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
|
CPython magic- and version- independent disassembly routines
|
||||||
|
|
||||||
Copyright (c) 1999 John Aycock
|
There are two reasons we can't use Python's built-in routines
|
||||||
Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
from dis. First, the bytecode we are extracting may be from a different
|
||||||
Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
|
version of Python (different magic number) than the version of Python
|
||||||
Copyright (c) 2015 by Rocky Bernstein
|
that is doing the extraction.
|
||||||
|
|
||||||
This is needed when the bytecode extracted is from
|
Second, we need structured instruction information for the
|
||||||
a different version than the currently-running Python.
|
(de)-parsing step. Python 3.4 and up provides this, but we still do
|
||||||
|
want to run on Python 2.7.
|
||||||
When the two are the same, you can simply use Python's built-in disassemble
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import os, sys, types
|
import importlib, inspect, os, sys
|
||||||
|
|
||||||
import uncompyle6
|
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):
|
def disco(version, co, out=None):
|
||||||
"""
|
"""
|
||||||
diassembles and deparses a given code block 'co'
|
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
|
# store final output stream for case of error
|
||||||
real_out = out or sys.stdout
|
real_out = out or sys.stdout
|
||||||
@@ -59,7 +71,11 @@ def disco(version, co, out=None):
|
|||||||
def disassemble_file(filename, outstream=None):
|
def disassemble_file(filename, outstream=None):
|
||||||
"""
|
"""
|
||||||
disassemble Python byte-code file (.pyc)
|
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)
|
version, co = uncompyle6.load_module(filename)
|
||||||
if type(co) == list:
|
if type(co) == list:
|
||||||
for con in co:
|
for con in co:
|
||||||
@@ -144,8 +160,12 @@ def _test():
|
|||||||
"""Simple test program to disassemble a file."""
|
"""Simple test program to disassemble a file."""
|
||||||
argc = len(sys.argv)
|
argc = len(sys.argv)
|
||||||
if argc != 2:
|
if argc != 2:
|
||||||
|
if argc == 1 and uncompyle6.PYTHON3:
|
||||||
|
fn = __file__
|
||||||
|
else:
|
||||||
sys.stderr.write("usage: %s [-|CPython compiled file]\n" % __file__)
|
sys.stderr.write("usage: %s [-|CPython compiled file]\n" % __file__)
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
else:
|
||||||
fn = sys.argv[1]
|
fn = sys.argv[1]
|
||||||
disassemble_file(fn)
|
disassemble_file(fn)
|
||||||
|
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
"""
|
"""
|
||||||
CPython magic- and version- independent marshal routines
|
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
|
This is needed when the bytecode extracted is from
|
||||||
a different version than the currently-running Python.
|
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
|
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
|
from __future__ import print_function
|
||||||
|
|
||||||
import imp, sys, types
|
import imp, sys, types
|
||||||
|
@@ -20,9 +20,11 @@ __all__ = ['Token', 'Scanner', 'Code']
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
# FIXME: DRY
|
||||||
if (sys.version_info > (3, 0)):
|
if (sys.version_info > (3, 0)):
|
||||||
intern = sys.intern
|
intern = sys.intern
|
||||||
L65536 = 65536
|
L65536 = 65536
|
||||||
|
|
||||||
def cmp(a, b):
|
def cmp(a, b):
|
||||||
return (a > b) - (a < b)
|
return (a > b) - (a < b)
|
||||||
else:
|
else:
|
||||||
|
@@ -13,7 +13,7 @@ Python 3 and other versions of Python. Also, we save token
|
|||||||
information for later use in deparsing.
|
information for later use in deparsing.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import types
|
import inspect
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from array import array
|
from array import array
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ class Scanner25(scan.Scanner):
|
|||||||
continue
|
continue
|
||||||
if op in hasconst:
|
if op in hasconst:
|
||||||
const = co.co_consts[oparg]
|
const = co.co_consts[oparg]
|
||||||
if isinstance(const, types.CodeType):
|
if inspect.iscode(const):
|
||||||
oparg = const
|
oparg = const
|
||||||
if const.co_name == '<lambda>':
|
if const.co_name == '<lambda>':
|
||||||
assert op_name == 'LOAD_CONST'
|
assert op_name == 'LOAD_CONST'
|
||||||
|
@@ -13,7 +13,7 @@ other versions of Python. Also, we save token information for later
|
|||||||
use in deparsing.
|
use in deparsing.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import types
|
import inspect
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from array import array
|
from array import array
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ class Scanner26(scan.Scanner):
|
|||||||
continue
|
continue
|
||||||
if op in hasconst:
|
if op in hasconst:
|
||||||
const = co.co_consts[oparg]
|
const = co.co_consts[oparg]
|
||||||
if isinstance(const, types.CodeType):
|
if inspect.iscode(const):
|
||||||
oparg = const
|
oparg = const
|
||||||
if const.co_name == '<lambda>':
|
if const.co_name == '<lambda>':
|
||||||
assert op_name == 'LOAD_CONST'
|
assert op_name == 'LOAD_CONST'
|
||||||
|
@@ -13,7 +13,7 @@ for later use in deparsing.
|
|||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import dis, types
|
import dis, inspect
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from array import array
|
from array import array
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ class Scanner27(scan.Scanner):
|
|||||||
continue
|
continue
|
||||||
if op in hasconst:
|
if op in hasconst:
|
||||||
const = co.co_consts[oparg]
|
const = co.co_consts[oparg]
|
||||||
if isinstance(const, types.CodeType):
|
if inspect.iscode(const):
|
||||||
oparg = const
|
oparg = const
|
||||||
if const.co_name == '<lambda>':
|
if const.co_name == '<lambda>':
|
||||||
assert op_name == 'LOAD_CONST'
|
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>
|
# (C) Copyright 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||||
#
|
#
|
||||||
# byte-code verifier for uncompyle
|
# 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
|
||||||
import uncompyle6.scanner as scanner
|
import uncompyle6.scanner as scanner
|
||||||
|
|
||||||
|
# FIXME: DRY
|
||||||
if (sys.version_info >= (3, 0)):
|
if (sys.version_info >= (3, 0)):
|
||||||
truediv = operator.truediv
|
truediv = operator.truediv
|
||||||
|
|
||||||
|
def cmp(a, b):
|
||||||
|
return (a > b) - (a < b)
|
||||||
|
from functools import reduce
|
||||||
else:
|
else:
|
||||||
truediv = operator.div
|
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.
|
This is the main part of this module.
|
||||||
"""
|
"""
|
||||||
# print code_obj1, type(code_obj2)
|
# print code_obj1, type(code_obj2)
|
||||||
assert isinstance(code_obj1, types.CodeType)
|
assert inspect.iscode(code_obj1)
|
||||||
assert isinstance(code_obj2, types.CodeType)
|
assert inspect.iscode(code_obj2)
|
||||||
# print dir(code_obj1)
|
# print dir(code_obj1)
|
||||||
if isinstance(code_obj1, object):
|
if isinstance(code_obj1, object):
|
||||||
# new style classes (Python 2.2)
|
# new style classes (Python 2.2)
|
||||||
|
Reference in New Issue
Block a user