You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Python 2.6 compatability via ericfrederich's patch. DRY version-checking code
This commit is contained in:
6
Makefile
6
Makefile
@@ -23,10 +23,14 @@ test check: pytest check-long
|
||||
check-long: pytest
|
||||
$(MAKE) -C test check-2.7
|
||||
|
||||
#: Run tests
|
||||
#: Run quick tests
|
||||
check-short: pytest
|
||||
$(MAKE) -C test check-short-2.7
|
||||
|
||||
#: Run quick tests
|
||||
check-3.4: pytest
|
||||
$(MAKE) -C test check-3.4
|
||||
|
||||
|
||||
#: check that disassembly exactly matches Python lib's dis
|
||||
check-disasm:
|
||||
|
@@ -3,14 +3,19 @@
|
||||
#
|
||||
# Copyright (c) 2015 by Rocky Bernstein <rb@dustyfeet.com>
|
||||
#
|
||||
"""
|
||||
Usage: pydisassemble [OPTIONS]... FILE
|
||||
from __future__ import print_function
|
||||
import sys, os, getopt
|
||||
|
||||
program = os.path.basename(__file__)
|
||||
|
||||
__doc__ = """
|
||||
Usage: %s [OPTIONS]... FILE
|
||||
|
||||
Examples:
|
||||
pydisassemble foo.pyc
|
||||
pydisassemble foo.py
|
||||
pydisassemble -o foo.pydis foo.pyc
|
||||
pydisassemble -o /tmp foo.pyc
|
||||
%s foo.pyc
|
||||
%s foo.py
|
||||
%s -o foo.pydis foo.pyc
|
||||
%s -o /tmp foo.pyc
|
||||
|
||||
Options:
|
||||
-o <path> output decompiled files to this path:
|
||||
@@ -19,21 +24,16 @@ Options:
|
||||
<path>
|
||||
--help show this message
|
||||
|
||||
"""
|
||||
""" % ((program,) * 5)
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
Usage_short = \
|
||||
"pydissassemble [--help] [--verify] [--showasm] [--showast] [-o <path>] FILE|DIR..."
|
||||
|
||||
import sys, os, getopt
|
||||
import os.path
|
||||
"%s [--help] [--verify] [--showasm] [--showast] [-o <path>] FILE|DIR..." % program
|
||||
|
||||
from uncompyle6 import check_python_version
|
||||
from uncompyle6.disas import disassemble_files
|
||||
|
||||
if sys.version[:3] != '2.7' and sys.version[:3] != '3.4':
|
||||
print('Error: pydisassemble requires Python 2.7 or 3.4.', file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
check_python_version(program)
|
||||
|
||||
outfile = '-'
|
||||
out_base = None
|
||||
|
@@ -41,18 +41,17 @@ Extensions of generated files:
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import sys, os, getopt
|
||||
|
||||
program = os.path.basename(__file__)
|
||||
|
||||
Usage_short = \
|
||||
"uncompyle6 [--help] [--verify] [--showasm] [--showast] [-o <path>] FILE|DIR..."
|
||||
"%s [--help] [--verify] [--showasm] [--showast] [-o <path>] FILE|DIR..." % program
|
||||
|
||||
import sys, os, getopt
|
||||
import os.path
|
||||
from uncompyle6 import main, status_msg, verify
|
||||
from uncompyle6 import main, status_msg, verify, check_python_version
|
||||
import time
|
||||
|
||||
if sys.version[:3] != '2.7' and sys.version[:3] != '3.4':
|
||||
print('Error: uncompyle6 requires Python 2.7 or 3.4.', file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
check_python_version(program)
|
||||
|
||||
showasm = showast = do_verify = recurse_dirs = False
|
||||
numproc = 0
|
||||
|
@@ -53,7 +53,6 @@ tests['2.2'] = ['divide_future', 'divide_no_future', 'iterators',
|
||||
|
||||
tests['2.3'] = tests['2.2']
|
||||
tests['2.5'] = tests['2.3']
|
||||
tests['2.6'] = tests['2.5']
|
||||
# tests['2.7'] = ['mine'] + tests['2.6']
|
||||
tests['2.7'] = [
|
||||
'simple-source/branching/ifelse',
|
||||
@@ -61,6 +60,7 @@ tests['2.7'] = [
|
||||
# 'simple-source/call_arguments/keyword',
|
||||
# 'simple-source/call_arguments/positional'
|
||||
]
|
||||
tests['2.6'] = tests['2.7']
|
||||
|
||||
def file_matches(files, root, basenames, patterns):
|
||||
files.extend(
|
||||
|
@@ -6,7 +6,7 @@
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
import dis, os.path, sys
|
||||
import dis, os.path
|
||||
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
@@ -16,17 +16,16 @@ except ImportError:
|
||||
program = os.path.basename(__file__)
|
||||
|
||||
__doc__ = """
|
||||
Usage: {0} [OPTIONS]... FILE
|
||||
Usage: %s [OPTIONS]... FILE
|
||||
|
||||
""".format(program)
|
||||
""" % program
|
||||
|
||||
usage_short = "Usage: {0} [OPTIONS]... FILE".format(program)
|
||||
usage_short = "Usage: %s [OPTIONS]... FILE" % program
|
||||
|
||||
import uncompyle6
|
||||
from uncompyle6 import PYTHON_VERSION_STR, check_python_version
|
||||
from uncompyle6.disas import disco
|
||||
|
||||
version = sys.version[:3]
|
||||
|
||||
def inst_fmt(inst):
|
||||
if inst.starts_line:
|
||||
return '\n%4d %6s\t%-17s %r' % (inst.starts_line, inst.offset, inst.opname,
|
||||
@@ -39,9 +38,9 @@ def inst_fmt(inst):
|
||||
|
||||
def compare_ok(version, co):
|
||||
out = StringIO()
|
||||
if version == 2.7:
|
||||
if version in (2.6, 2.7):
|
||||
dis.disco(co)
|
||||
return
|
||||
return True
|
||||
|
||||
bytecode = dis.Bytecode(co)
|
||||
disco(version, co, out)
|
||||
@@ -61,10 +60,7 @@ def compare_ok(version, co):
|
||||
i += 1
|
||||
return True
|
||||
|
||||
if version != '2.7' and version != '3.4':
|
||||
print('Error: {0} requires Python 2.7 or 3.4.'.format(program),
|
||||
file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
check_python_version(program)
|
||||
|
||||
# if len(sys.argv) != 2:
|
||||
# print(usage_short, file=sys.stderr)
|
||||
@@ -85,7 +81,7 @@ files=[
|
||||
]
|
||||
|
||||
for base in files:
|
||||
filename = "bytecode_%s/%s.pyc" % (version, base)
|
||||
filename = "bytecode_%s/%s.pyc" % (PYTHON_VERSION_STR, base)
|
||||
version, co = uncompyle6.load_module(filename)
|
||||
ok = True
|
||||
if type(co) == list:
|
||||
|
@@ -33,7 +33,7 @@ from __future__ import print_function
|
||||
|
||||
import os, marshal, sys, types
|
||||
|
||||
PYTHON_VERSION = sys.version_info.major + (sys.version_info.minor / 10.0)
|
||||
# set before importing scanner
|
||||
PYTHON3 = (sys.version_info >= (3, 0))
|
||||
|
||||
import uncompyle6
|
||||
@@ -43,6 +43,21 @@ import uncompyle6.marsh
|
||||
from uncompyle6 import walker, verify, magics
|
||||
|
||||
sys.setrecursionlimit(5000)
|
||||
|
||||
# We do this crazy way to support Python 2.6 which
|
||||
# doesn't support version_major, and has a bug in
|
||||
# floating point so we can't divide 26 by 10 and get
|
||||
# 2.6
|
||||
PYTHON_VERSION = sys.version_info[0]+ (sys.version_info[1] / 10.0)
|
||||
PYTHON_VERSION_STR = "%s.%s" % (sys.version_info[0], sys.version_info[1])
|
||||
|
||||
def check_python_version(program):
|
||||
if not (sys.version_info[0:2] in ((2,6), (2,7), (3,4))):
|
||||
print('Error: %s requires %s Python 2.6, 2.7 or 3.4' % program,
|
||||
file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
return
|
||||
|
||||
__all__ = ['uncompyle_file', 'main']
|
||||
|
||||
def _load_file(filename):
|
||||
|
@@ -18,13 +18,15 @@ want to run on Python 2.7.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import importlib, inspect, os, sys
|
||||
import inspect, os, sys
|
||||
|
||||
import uncompyle6
|
||||
from uncompyle6.scanner import get_scanner
|
||||
|
||||
def check_object_path(path):
|
||||
if path.endswith(".py"):
|
||||
if uncompyle6.PYTHON3:
|
||||
import importlib
|
||||
path = importlib.util.cache_from_source(path)
|
||||
return path
|
||||
if not path.endswith(".pyc") and not path.endswith(".pyo"):
|
||||
|
@@ -47,7 +47,7 @@ def updateGlobal():
|
||||
globals().update({'PJIT': opmap['JUMP_IF_TRUE']})
|
||||
globals().update({'JA': opmap['JUMP_ABSOLUTE']})
|
||||
globals().update({'JF': opmap['JUMP_FORWARD']})
|
||||
globals().update({k.replace('+', '_'): v for (k, v) in opmap.items()})
|
||||
globals().update(dict([(k.replace('+','_'),v) for (k,v) in opmap.items()]))
|
||||
globals().update({'JUMP_OPs': map(lambda op: opname[op], hasjrel + hasjabs)})
|
||||
|
||||
# Instruction opcodes for compiled code
|
||||
|
@@ -47,7 +47,7 @@ def updateGlobal():
|
||||
globals().update({'PJIT': opmap['JUMP_IF_TRUE']})
|
||||
globals().update({'JA': opmap['JUMP_ABSOLUTE']})
|
||||
globals().update({'JF': opmap['JUMP_FORWARD']})
|
||||
globals().update({k.replace('+', '_'): v for (k, v) in opmap.items()})
|
||||
globals().update(dict([(k.replace('+','_'),v) for (k,v) in opmap.items()]))
|
||||
globals().update({'JUMP_OPs': map(lambda op: opname[op], hasjrel + hasjabs)})
|
||||
|
||||
# Instruction opcodes for compiled code
|
||||
|
@@ -43,7 +43,7 @@ def updateGlobal():
|
||||
globals().update({'PJIT': opmap['POP_JUMP_IF_TRUE']})
|
||||
globals().update({'JA': opmap['JUMP_ABSOLUTE']})
|
||||
globals().update({'JF': opmap['JUMP_FORWARD']})
|
||||
globals().update({k.replace('+', '_'): v for (k, v) in opmap.items()})
|
||||
globals().update(dict([(k.replace('+','_'),v) for (k,v) in opmap.items()]))
|
||||
globals().update({'JUMP_OPs': map(lambda op: opname[op], hasjrel + hasjabs)})
|
||||
|
||||
# Instruction opcodes for compiled code
|
||||
|
8
uncompyle6/scanners/scanner25.py
Normal file → Executable file
8
uncompyle6/scanners/scanner25.py
Normal file → Executable file
@@ -520,7 +520,7 @@ class Scanner25(scan.Scanner):
|
||||
start = 0
|
||||
end = len(code)
|
||||
|
||||
stmt_opcodes = {
|
||||
stmt_opcodes = set([
|
||||
SETUP_LOOP, BREAK_LOOP, CONTINUE_LOOP,
|
||||
SETUP_FINALLY, END_FINALLY, SETUP_EXCEPT,
|
||||
POP_BLOCK, STORE_FAST, DELETE_FAST, STORE_DEREF,
|
||||
@@ -529,15 +529,15 @@ class Scanner25(scan.Scanner):
|
||||
RETURN_VALUE, RAISE_VARARGS, POP_TOP,
|
||||
PRINT_EXPR, PRINT_ITEM, PRINT_NEWLINE, PRINT_ITEM_TO, PRINT_NEWLINE_TO,
|
||||
JUMP_ABSOLUTE, EXEC_STMT
|
||||
}
|
||||
])
|
||||
|
||||
stmt_opcode_seqs = [(PJIF, JF), (PJIF, JA), (PJIT, JF), (PJIT, JA)]
|
||||
|
||||
designator_ops = {
|
||||
designator_ops = set([
|
||||
STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR,
|
||||
STORE_SLICE_0, STORE_SLICE_1, STORE_SLICE_2, STORE_SLICE_3,
|
||||
STORE_SUBSCR, UNPACK_SEQUENCE, JA
|
||||
}
|
||||
])
|
||||
|
||||
prelim = self.all_instr(start, end, stmt_opcodes)
|
||||
|
||||
|
8
uncompyle6/scanners/scanner26.py
Normal file → Executable file
8
uncompyle6/scanners/scanner26.py
Normal file → Executable file
@@ -511,7 +511,7 @@ class Scanner26(scan.Scanner):
|
||||
start = 0
|
||||
end = len(code)
|
||||
|
||||
stmt_opcodes = {
|
||||
stmt_opcodes = set([
|
||||
SETUP_LOOP, BREAK_LOOP, CONTINUE_LOOP,
|
||||
SETUP_FINALLY, END_FINALLY, SETUP_EXCEPT,
|
||||
POP_BLOCK, STORE_FAST, DELETE_FAST, STORE_DEREF,
|
||||
@@ -520,15 +520,15 @@ class Scanner26(scan.Scanner):
|
||||
RETURN_VALUE, RAISE_VARARGS, POP_TOP,
|
||||
PRINT_EXPR, PRINT_ITEM, PRINT_NEWLINE, PRINT_ITEM_TO, PRINT_NEWLINE_TO,
|
||||
JUMP_ABSOLUTE, EXEC_STMT,
|
||||
}
|
||||
])
|
||||
|
||||
stmt_opcode_seqs = [(PJIF, JF), (PJIF, JA), (PJIT, JF), (PJIT, JA)]
|
||||
|
||||
designator_ops = {
|
||||
designator_ops = set([
|
||||
STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR,
|
||||
STORE_SLICE_0, STORE_SLICE_1, STORE_SLICE_2, STORE_SLICE_3,
|
||||
STORE_SUBSCR, UNPACK_SEQUENCE, JA
|
||||
}
|
||||
])
|
||||
|
||||
prelim = self.all_instr(start, end, stmt_opcodes)
|
||||
|
||||
|
8
uncompyle6/scanners/scanner27.py
Normal file → Executable file
8
uncompyle6/scanners/scanner27.py
Normal file → Executable file
@@ -223,7 +223,7 @@ class Scanner27(scan.Scanner):
|
||||
start = 0
|
||||
end = len(code)
|
||||
|
||||
stmt_opcodes = {
|
||||
stmt_opcodes = set([
|
||||
SETUP_LOOP, BREAK_LOOP, CONTINUE_LOOP,
|
||||
SETUP_FINALLY, END_FINALLY, SETUP_EXCEPT, SETUP_WITH,
|
||||
POP_BLOCK, STORE_FAST, DELETE_FAST, STORE_DEREF,
|
||||
@@ -234,15 +234,15 @@ class Scanner27(scan.Scanner):
|
||||
STORE_SLICE_0, STORE_SLICE_1, STORE_SLICE_2, STORE_SLICE_3,
|
||||
DELETE_SLICE_0, DELETE_SLICE_1, DELETE_SLICE_2, DELETE_SLICE_3,
|
||||
JUMP_ABSOLUTE, EXEC_STMT,
|
||||
}
|
||||
])
|
||||
|
||||
stmt_opcode_seqs = [(PJIF, JF), (PJIF, JA), (PJIT, JF), (PJIT, JA)]
|
||||
|
||||
designator_ops = {
|
||||
designator_ops = set([
|
||||
STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR,
|
||||
STORE_SLICE_0, STORE_SLICE_1, STORE_SLICE_2, STORE_SLICE_3,
|
||||
STORE_SUBSCR, UNPACK_SEQUENCE, JA
|
||||
}
|
||||
])
|
||||
|
||||
prelim = self.all_instr(start, end, stmt_opcodes)
|
||||
|
||||
|
@@ -332,8 +332,8 @@ class Token(scanner.Token):
|
||||
return 0
|
||||
if JUMP_OPs and t in JUMP_OPs:
|
||||
# ignore offset
|
||||
return cmp(t, o.type)
|
||||
return cmp(t, o.type) or cmp(self.pattr, o.pattr)
|
||||
return t == o.type
|
||||
return (t == o.type) or self.pattr == o.pattr
|
||||
|
||||
def __repr__(self):
|
||||
return '%s %s (%s)' % (str(self.type), str(self.attr),
|
||||
|
Reference in New Issue
Block a user