Use xdis for code, magics, and marshal

This commit is contained in:
rocky
2016-05-27 18:21:32 -04:00
parent eebe8249a8
commit 4398b5b2e0
19 changed files with 16 additions and 648 deletions

View File

@@ -36,7 +36,8 @@ entry_points={
'pydisassemble=uncompyle6.bin.pydisassemble:main',
]}
ftp_url = None
install_requires = ['spark-parser >= 1.2.1']
install_requires = ['spark-parser >= 1.2.1',
'xdis >= 1.0.1']
license = 'MIT'
mailing_list = 'python-debugger@googlegroups.com'
modname = 'uncompyle6'

View File

@@ -18,7 +18,6 @@ def test_if_in_for():
scan.build_prev_op(n)
fjt = scan.find_jump_targets()
assert {15: [3], 69: [66], 63: [18]} == fjt
print(scan.structs)
assert scan.structs == \
[{'start': 0, 'end': 72, 'type': 'root'},
{'start': 18, 'end': 66, 'type': 'if-then'},

View File

@@ -1,13 +0,0 @@
import os, sys
from uncompyle6.load import load_file, check_object_path, load_module
def test_load():
"""Basic test of load_file, check_object_path and load_module"""
co = load_file(__file__)
obj_path = check_object_path(__file__)
if os.path.exists(obj_path):
version, timestamp, magic_int, co2 = load_module(obj_path)
assert sys.version[0:3] == str(version)
assert co == co2
else:
assert True, "Skipped because we can't find %s" % obj_path

View File

@@ -1,28 +0,0 @@
#!/usr/bin/env python
import os.path
from uncompyle6.load import load_module
def get_srcdir():
filename = os.path.normcase(os.path.dirname(os.path.abspath(__file__)))
return os.path.realpath(filename)
srcdir = get_srcdir()
def test_load_module():
"""Tests uncompile6.load.load_module"""
# We deliberately pick a bytecode that we aren't likely to be running against
mod_file = os.path.join(get_srcdir(), '..', 'test', 'bytecode_2.5',
'02_complex.pyc')
version, timestamp, magic_int, co = load_module(mod_file)
assert version == 2.5, "Should have picked up Python version properly"
assert co.co_consts == (5j, None), "Code should have a complex constant"
mod_file = os.path.join(get_srcdir(), '..', 'test', 'bytecode_3.3',
'06_frozenset.pyc')
version, timestamp, magic_int, co = load_module(mod_file)
print(co.co_consts)
expect = (0, None, 'attlist', 'linktype', 'link', 'element', 'Yep',
frozenset({'linktype', 'attlist', 'element', 'link'}))
assert co.co_consts == expect, "Should handle frozenset"

View File

@@ -45,10 +45,8 @@ sys.setrecursionlimit(5000)
import uncompyle6.semantics.pysource
import uncompyle6.semantics.fragments
import uncompyle6.load
# Export some functions
from uncompyle6.load import load_module, load_file
from uncompyle6.main import uncompyle_file
# Conventience functions so you can say:

View File

@@ -6,7 +6,6 @@
from __future__ import print_function
import sys, os, getopt
from uncompyle6 import check_python_version
from uncompyle6.disas import disassemble_file
from uncompyle6.version import VERSION
@@ -35,8 +34,6 @@ def main():
Usage_short = """usage: %s FILE...
Type -h for for full help.""" % program
check_python_version(program)
use_uncompyle6_format = False
if len(sys.argv) == 1:

View File

@@ -1,53 +0,0 @@
import inspect
class Code3:
"""Class for a Python3 code object used when a Python interpreter less than 3 is
working on Python3 bytecode
"""
def __init__(self, co_argcount, co_kwonlyargcount,co_nlocals, co_stacksize, co_flags, co_code,
co_consts, co_names, co_varnames, co_filename, co_name,
co_firstlineno, co_lnotab, co_freevars, co_cellvars):
self.co_argcount = co_argcount
self.co_kwonlyargcount = co_kwonlyargcount
self.co_nlocals = co_nlocals
self.co_stacksize = co_stacksize
self.co_flags = co_flags
self.co_code = co_code
self.co_consts = co_consts
self.co_names = co_names
self.co_varnames = co_varnames
self.co_filename = co_filename
self.co_name = co_name
self.co_firstlineno = co_firstlineno
self.co_lnotab = co_lnotab
self.co_freevars = co_freevars
self.co_cellvars = co_cellvars
class Code2:
"""Class for a Python2 code object used when a Python interpreter less than 3 is
working on Python3 bytecode
"""
def __init__(self, co_argcount, co_kwonlyargcount,co_nlocals, co_stacksize, co_flags, co_code,
co_consts, co_names, co_varnames, co_filename, co_name,
co_firstlineno, co_lnotab, co_freevars, co_cellvars):
self.co_argcount = co_argcount
self.co_kwonlyargcount = co_kwonlyargcount
self.co_nlocals = co_nlocals
self.co_stacksize = co_stacksize
self.co_flags = co_flags
self.co_code = co_code
self.co_consts = co_consts
self.co_names = co_names
self.co_varnames = co_varnames
self.co_filename = co_filename
self.co_name = co_name
self.co_firstlineno = co_firstlineno
self.co_lnotab = co_lnotab
self.co_freevars = co_freevars
self.co_cellvars = co_cellvars
def iscode(obj):
"""A replacement for inspect.iscode() which we can't used because we may be
using a different version of Python than the version of Python used
in creating the byte-compiled objects. Here, he code types may mismatch.
"""
return inspect.iscode(obj) or isinstance(obj, Code3)

View File

@@ -22,8 +22,8 @@ import os, sys
from collections import deque
import uncompyle6
from uncompyle6.code import iscode
from uncompyle6.load import check_object_path, load_module
from xdis.code import iscode
from xdis.load import check_object_path, load_module
from uncompyle6.scanner import get_scanner
def disco(version, co, out=None, use_uncompyle6_format=False):
@@ -57,7 +57,7 @@ def disco_loop(disasm, queue, real_out, use_uncompyle6_format):
print('\n# %s line %d of %s' %
(co.co_name, co.co_firstlineno, co.co_filename),
file=real_out)
tokens, customize = disasm(co, use_uncompyle6_format)
tokens, customize = disasm(co)
for t in tokens:
if iscode(t.pattr):
queue.append(t.pattr)

View File

@@ -1,117 +0,0 @@
# Copyright (c) 2015 by Rocky Bernstein
# Copyright (c) 2000 by hartmut Goebel <h.goebel@crazy-compilers.com>
from __future__ import print_function
import imp, marshal, os, py_compile, sys, tempfile
from struct import unpack
import uncompyle6.marsh
from uncompyle6 import PYTHON3
from uncompyle6 import magics
def check_object_path(path):
if path.endswith(".py"):
try:
import importlib
return importlib.util.cache_from_source(path,
optimization='')
except:
try:
import imp
imp.cache_from_source(path, debug_override=False)
except:
pass
pass
basename = os.path.basename(path)[0:-3]
spath = path if PYTHON3 else path.decode('utf-8')
path = tempfile.mkstemp(prefix=basename + '-',
suffix='.pyc', text=False)[1]
py_compile.compile(spath, cfile=path, doraise=True)
if not path.endswith(".pyc") and not path.endswith(".pyo"):
raise ValueError("path %s must point to a .py or .pyc file\n" %
path)
return path
def load_file(filename):
"""
load a Python source file and compile it to byte-code
_load_file(filename: string): code_object
filename: name of file containing Python source code
(normally a .py)
code_object: code_object compiled from this source code
This function does NOT write any file!
"""
with open(filename, 'rb') as fp:
source = fp.read().decode('utf-8') + '\n'
try:
co = compile(source, filename, 'exec', dont_inherit=True)
except SyntaxError:
print('>>Syntax error in %s\n' % filename, file= sys.stderr)
raise
pass
return co
def load_module(filename, code_objects={}):
"""
load a module without importing it.
load_module(filename: string): version, magic_int, code_object
filename: name of file containing Python byte-code object
(normally a .pyc)
code_object: code_object from this file
version: Python major/minor value e.g. 2.7. or 3.4
magic_int: more specific than version. The actual byte code version of the
code object
"""
with open(filename, 'rb') as fp:
magic = fp.read(4)
try:
version = float(magics.versions[magic])
except KeyError:
if len(magic) >= 2:
raise ImportError("Unknown magic number %s in %s" %
(ord(magic[0])+256*ord(magic[1]), filename))
else:
raise ImportError("Bad magic number: '%s'" % magic)
if not (2.5 <= version <= 2.7) and not (3.2 <= version <= 3.5):
raise ImportError("This is a Python %s file! Only "
"Python 2.5 to 2.7 and 3.2 to 3.5 files are supported."
% version)
# print version
ts = fp.read(4)
timestamp = unpack("I", ts)[0]
magic_int = magics.magic2int(magic)
my_magic_int = magics.magic2int(imp.get_magic())
# Note: a higher magic number doesn't necessarily mean a later
# release. At Python 3.0 the magic number decreased
# significantly. Hence the range below. Also note inclusion of
# the size info, occurred within a Python major/minor
# release. Hence the test on the magic value rather than
# PYTHON_VERSION, although PYTHON_VERSION would probably work.
if 3200 <= magic_int < 20121:
fp.read(4) # size mod 2**32
if my_magic_int == magic_int:
bytecode = fp.read()
co = marshal.loads(bytecode)
else:
co = uncompyle6.marsh.load_code(fp, magic_int, code_objects)
pass
return version, timestamp, magic_int, co
if __name__ == '__main__':
co = load_file(__file__)
obj_path = check_object_path(__file__)
version, timestamp, magic_int, co2 = load_module(obj_path)
print("version", version, "magic int", magic_int)
import datetime
print(datetime.datetime.fromtimestamp(timestamp))
if version < 3.5:
assert co == co2

View File

@@ -1,110 +0,0 @@
from __future__ import print_function
import imp, struct, sys
def __build_magic(magic):
if (sys.version_info >= (3, 0)):
return struct.pack('Hcc', magic, bytes('\r', 'utf-8'), bytes('\n', 'utf-8'))
else:
return struct.pack('Hcc', magic, '\r', '\n')
def magic2int(magic):
return struct.unpack('Hcc', magic)[0]
PYTHON_MAGIC_INT = magic2int(imp.get_magic())
by_magic = {}
by_version = {}
def __by_version(magics):
for m, v in list(magics.items()):
by_magic[m] = v
by_version[v] = m
return by_version
versions = {
# taken from from Python/import.c
# or importlib/_bootstrap.py
# magic, version
__build_magic(20121): '1.5', # 1.5, 1.5.1, 1.5.2
__build_magic(50428): '1.6', # 1.6
__build_magic(50823): '2.0', # 2.0, 2.0.1
__build_magic(60202): '2.1', # 2.1, 2.1.1, 2.1.2
__build_magic(60717): '2.2', # 2.2
__build_magic(62011): '2.3', # 2.3a0
__build_magic(62021): '2.3', # 2.3a0
__build_magic(62041): '2.4', # 2.4a0
__build_magic(62051): '2.4', # 2.4a3
__build_magic(62061): '2.4', # 2.4b1
__build_magic(62071): '2.5', # 2.5a0
__build_magic(62081): '2.5', # 2.5a0 (ast-branch)
__build_magic(62091): '2.5', # 2.5a0 (with)
__build_magic(62092): '2.5', # 2.5a0 (changed WITH_CLEANUP opcode)
__build_magic(62101): '2.5', # 2.5b3 (fix wrong code: for x, in ...)
__build_magic(62111): '2.5', # 2.5b3 (fix wrong code: x += yield)
__build_magic(62121): '2.5', # 2.5c1 (fix wrong lnotab with for loops and
# storing constants that should have been removed
__build_magic(62131): '2.5', # 2.5c2 (fix wrong code: for x, in ... in listcomp/genexp)
__build_magic(62151): '2.6', # 2.6a0 (peephole optimizations & STORE_MAP)
__build_magic(62161): '2.6', # 2.6a1 (WITH_CLEANUP optimization)
__build_magic(62171): '2.7', # 2.7a0 (optimize list comprehensions/change LIST_APPEND)
__build_magic(62181): '2.7', # 2.7a0 (optimize conditional branches:
# introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE)
__build_magic(62191): '2.7', # 2.7a0 (introduce SETUP_WITH)
__build_magic(62201): '2.7', # 2.7a0 (introduce BUILD_SET)
__build_magic(62211): '2.7', # 2.7a0 (introduce MAP_ADD and SET_ADD)
__build_magic(62218): '2.7', # 2.7 pypy?
__build_magic(3000): '3.0', # 3.000
__build_magic(3010): '3.0', # 3.000 (removed UNARY_CONVERT)
__build_magic(3020): '3.0', # 3.000 (added BUILD_SET)
__build_magic(3030): '3.0', # 3.000 (added keyword-only parameters)
__build_magic(3040): '3.0', # 3.000 (added signature annotations)
__build_magic(3050): '3.0', # 3.000 (print becomes a function)
__build_magic(3060): '3.0', # 3.000 (PEP 3115 metaclass syntax)
__build_magic(3061): '3.0', # 3.000 (string literals become unicode)
__build_magic(3071): '3.0', # 3.000 (PEP 3109 raise changes)
__build_magic(3081): '3.0', # 3.000 (PEP 3137 make __file__ and __name__ unicode)
__build_magic(3091): '3.0', # 3.000 (kill str8 interning)
__build_magic(3101): '3.0', # 3.000 (merge from 2.6a0, see 62151)
__build_magic(3103): '3.0', # 3.000 (__file__ points to source file)
__build_magic(3111): '3.0', # 3.0a4 (WITH_CLEANUP optimization).
__build_magic(3131): '3.0', # 3.0a5 (lexical exception stacking, including POP_EXCEPT)
__build_magic(3141): '3.1', # 3.1a0 (optimize list, set and dict comprehensions)
__build_magic(3151): '3.1', # 3.1a0 (optimize conditional branches)
__build_magic(3160): '3.2', # 3.2a0 (add SETUP_WITH)
__build_magic(3170): '3.2', # 3.2a1 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR)
__build_magic(3180): '3.2', # 3.2a2 (add DELETE_DEREF)
__build_magic(3190): '3.3', # 3.3a0 3190 __class__ super closure changed
__build_magic(3100): '3.3', # 3.3a0 3200 (__qualname__ added)
__build_magic(3210): '3.3', # 3210 (added size modulo 2**32 to the pyc header)
__build_magic(3220): '3.3', # 3.3a1 3220 (changed PEP 380 implementation)
__build_magic(3230): '3.3', # 3.3a4 3230 (revert changes to implicit __class__ closure)
__build_magic(3250): '3.4', # 3.4a1 3250 (evaluate positional default arg
# keyword-only defaults)
__build_magic(3260): '3.4', # 3.4a1 3260 (add LOAD_CLASSDEREF;
# allow locals of class to override free vars)
__build_magic(3270): '3.4', # 3.4a1 3270 (various tweaks to the __class__ closure)
__build_magic(3280): '3.4', # 3.4a1 3280 (remove implicit class argument)
__build_magic(3290): '3.4', # 3.4a4 3290 (changes to __qualname__ computation)
__build_magic(3300): '3.4', # 3.4a4 3300 (more changes to __qualname__ computation)
__build_magic(3310): '3.4', # 3.4rc2 3310 (alter __qualname__ computation)
__build_magic(3350): '3.5', # 3.5.0
}
magics = __by_version(versions)
def __show(text, magic):
print(text, struct.unpack('BBBB', magic), struct.unpack('HBB', magic))
def test():
magic_20 = magics['2.0']
current = imp.get_magic()
magic_current = by_magic[ current ]
print(type(magic_20), len(magic_20), repr(magic_20))
print()
print('This Python interpreter has version', magic_current)
print('Magic code: ', PYTHON_MAGIC_INT)
print(type(magic_20), len(magic_20), repr(magic_20))
if __name__ == '__main__':
test()

View File

@@ -2,12 +2,12 @@ from __future__ import print_function
import datetime, os, sys
from uncompyle6 import verify, PYTHON_VERSION
from uncompyle6.code import iscode
from xdis.code import iscode
from uncompyle6.disas import check_object_path
from uncompyle6.semantics import pysource
from uncompyle6.parser import ParserError
from uncompyle6.load import load_module
from xdis.load import load_module
def uncompyle(version, co, out=None, showasm=False, showast=False,
timestamp=None, showgrammar=False, code_objects={}):

View File

@@ -1,306 +0,0 @@
"""
CPython magic- and version- independent marshal routines
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 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 sys, types
from struct import unpack
from uncompyle6.magics import PYTHON_MAGIC_INT
from uncompyle6.code import Code3
internStrings = []
internObjects = []
PYTHON3 = (sys.version_info >= (3, 0))
if PYTHON3:
def long(n): return n
def compat_str(s):
return s.decode('utf-8', errors='ignore') if PYTHON3 else str(s)
def load_code(fp, magic_int, code_objects={}):
"""
marshal.load() written in Python. When the Python bytecode magic loaded is the
same magic for the running Python interpreter, we can simply use the
Python-supplied mashal.load().
However we need to use this when versions are different since the internal
code structures are different. Sigh.
"""
global internStrings, internObjects
internStrings = []
internObjects = []
seek_pos = fp.tell()
# Do a sanity check. Is this a code type?
b = ord(fp.read(1))
if (b & 0x80):
b = b & 0x7f
c = chr(b)
if c != 'c':
raise TypeError("File %s doesn't smell like Python bytecode" % fp.name)
fp.seek(seek_pos)
return load_code_internal(fp, magic_int, code_objects=code_objects)
def load_code_type(fp, magic_int, bytes_for_s=False, code_objects={}):
# Python [1.3 .. 2.3)
# FIXME: find out what magics were for 1.3
v13_to_23 = magic_int in (20121, 50428, 50823, 60202, 60717)
# Python [1.5 .. 2.3)
v15_to_23 = magic_int in (20121, 50428, 50823, 60202, 60717)
if v13_to_23:
co_argcount = unpack('h', fp.read(2))[0]
else:
co_argcount = unpack('i', fp.read(4))[0]
if 3020 < magic_int < 20121:
kwonlyargcount = unpack('i', fp.read(4))[0]
else:
kwonlyargcount = 0
if v13_to_23:
co_nlocals = unpack('h', fp.read(2))[0]
else:
co_nlocals = unpack('i', fp.read(4))[0]
if v15_to_23:
co_stacksize = unpack('h', fp.read(2))[0]
else:
co_stacksize = unpack('i', fp.read(4))[0]
if v13_to_23:
co_flags = unpack('h', fp.read(2))[0]
else:
co_flags = unpack('i', fp.read(4))[0]
co_code = load_code_internal(fp, magic_int, bytes_for_s=True,
code_objects=code_objects)
co_consts = load_code_internal(fp, magic_int, code_objects=code_objects)
co_names = load_code_internal(fp, magic_int, code_objects=code_objects)
co_varnames = load_code_internal(fp, magic_int, code_objects=code_objects)
co_freevars = load_code_internal(fp, magic_int, code_objects=code_objects)
co_cellvars = load_code_internal(fp, magic_int, code_objects=code_objects)
co_filename = load_code_internal(fp, magic_int, code_objects=code_objects)
co_name = load_code_internal(fp, magic_int)
co_firstlineno = unpack('i', fp.read(4))[0]
co_lnotab = load_code_internal(fp, magic_int, code_objects=code_objects)
# The Python3 code object is different than Python2's which
# we are reading if we get here.
# Also various parameters which were strings are now
# bytes (which is probably more logical).
if PYTHON3:
Code = types.CodeType
if PYTHON_MAGIC_INT > 3020:
# In later Python3 magic_ints, there is a
# kwonlyargcount parameter which we set to 0.
code = Code(co_argcount, kwonlyargcount, co_nlocals, co_stacksize, co_flags,
co_code, co_consts, co_names, co_varnames, co_filename, co_name,
co_firstlineno, bytes(co_lnotab, encoding='utf-8'),
co_freevars, co_cellvars)
else:
code = Code(co_argcount, kwonlyargcount, co_nlocals, co_stacksize, co_flags,
co_code, co_consts, co_names, co_varnames, co_filename, co_name,
co_firstlineno, bytes(co_lnotab, encoding='utf-8'),
co_freevars, co_cellvars)
else:
if (3000 <= magic_int < 20121):
# Python 3 encodes some fields as Unicode while Python2
# requires the corresponding field to have string values
co_consts = tuple([str(s) if isinstance(s, unicode) else s for s in co_consts])
co_names = tuple([str(s) if isinstance(s, unicode) else s for s in co_names])
co_varnames = tuple([str(s) if isinstance(s, unicode) else s for s in co_varnames])
co_filename = str(co_filename)
co_name = str(co_name)
if 3020 < magic_int <= 20121:
code = Code3(co_argcount, kwonlyargcount,
co_nlocals, co_stacksize, co_flags, co_code,
co_consts, co_names, co_varnames, co_filename, co_name,
co_firstlineno, co_lnotab, co_freevars, co_cellvars)
else:
Code = types.CodeType
code = Code(co_argcount, co_nlocals, co_stacksize, co_flags, co_code,
co_consts, co_names, co_varnames, co_filename, co_name,
co_firstlineno, co_lnotab, co_freevars, co_cellvars)
pass
pass
code_objects[str(code)] = code
return code
def load_code_internal(fp, magic_int, bytes_for_s=False,
code_objects={}, marshalType=None):
global internStrings, internObjects
if marshalType is None:
b1 = ord(fp.read(1))
if b1 & 0x80:
b1 = b1 &0x7f
code = load_code_internal(fp, magic_int, bytes_for_s=False,
code_objects=code_objects,
marshalType=chr(b1))
internObjects.append(code)
return code
marshalType = chr(b1)
# print(marshalType) # debug
if marshalType == '0':
# Null
return None
elif marshalType == 'N':
return None
elif marshalType == 'F':
return False
elif marshalType == 'T':
return True
elif marshalType == 'S':
return StopIteration
elif marshalType == '.':
return Ellipsis
elif marshalType == 'i':
# int
return int(unpack('i', fp.read(4))[0])
elif marshalType == 'I':
# int64
return unpack('q', fp.read(8))[0]
elif marshalType == 'f':
# float
n = fp.read(1)
return float(unpack('d', fp.read(n))[0])
elif marshalType == 'g':
# binary float
return float(unpack('d', fp.read(8))[0])
elif marshalType == 'x':
# complex
raise KeyError(marshalType)
elif marshalType == 'y':
# binary complex
real = unpack('d', fp.read(8))[0]
imag = unpack('d', fp.read(8))[0]
return complex(real, imag)
elif marshalType == 'l':
# long
n = unpack('i', fp.read(4))[0]
if n == 0:
return long(0)
size = abs(n)
d = long(0)
for j in range(0, size):
md = int(unpack('h', fp.read(2))[0])
d += md << j*15
if n < 0:
return long(d*-1)
return d
elif marshalType == 's':
# string
# Note: could mean bytes in Python3 processing Python2 bytecode
strsize = unpack('i', fp.read(4))[0]
s = fp.read(strsize)
if not bytes_for_s:
s = compat_str(s)
return s
elif marshalType == 't':
# interned
strsize = unpack('i', fp.read(4))[0]
interned = compat_str(fp.read(strsize))
internStrings.append(interned)
return interned
elif marshalType == 'R':
# string reference
refnum = unpack('i', fp.read(4))[0]
return internStrings[refnum]
elif marshalType == 'r':
# object reference - new in Python3
refnum = unpack('i', fp.read(4))[0]
return internObjects[refnum-1]
elif marshalType == '(':
tuplesize = unpack('i', fp.read(4))[0]
ret = tuple()
while tuplesize > 0:
ret += load_code_internal(fp, magic_int, code_objects=code_objects),
tuplesize -= 1
return ret
elif marshalType == '[':
raise KeyError(marshalType)
elif marshalType == '{':
# dictionary
raise KeyError(marshalType)
elif marshalType == 'c':
return load_code_type(fp, magic_int, bytes_for_s=False,
code_objects=code_objects)
elif marshalType == 'C':
# code type used in Python 1.0 - 1.2
raise KeyError("C code is Python 1.0 - 1.2; can't handle yet")
elif marshalType == 'u':
strsize = unpack('i', fp.read(4))[0]
unicodestring = fp.read(strsize)
return unicodestring.decode('utf-8')
elif marshalType == '?':
# unknown
raise KeyError(marshalType)
elif marshalType in ['<', '>']:
# set and frozenset
setsize = unpack('i', fp.read(4))[0]
ret = tuple()
while setsize > 0:
ret += load_code_internal(fp, magic_int, code_objects=code_objects),
setsize -= 1
if marshalType == '>':
return frozenset(ret)
else:
return set(ret)
elif marshalType == 'a':
# ascii
# FIXME check
strsize = unpack('i', fp.read(4))[0]
s = fp.read(strsize)
s = compat_str(s)
return s
elif marshalType == 'A':
# ascii interned - since Python3
# FIXME: check
strsize = unpack('i', fp.read(4))[0]
interned = compat_str(fp.read(strsize))
internStrings.append(interned)
return interned
elif marshalType == ')':
# small tuple - since Python3
tuplesize = unpack('B', fp.read(1))[0]
ret = tuple()
while tuplesize > 0:
ret += load_code_internal(fp, magic_int, code_objects=code_objects),
tuplesize -= 1
return ret
elif marshalType == 'z':
# short ascii - since Python3
strsize = unpack('B', fp.read(1))[0]
return compat_str(fp.read(strsize))
elif marshalType == 'Z':
# short ascii interned - since Python3
# FIXME: check
strsize = unpack('B', fp.read(1))[0]
interned = compat_str(fp.read(strsize))
internStrings.append(interned)
return interned
else:
sys.stderr.write("Unknown type %i (hex %x) %c\n" %
(ord(marshalType), ord(marshalType), ord(marshalType)))
return

View File

@@ -10,7 +10,7 @@ from __future__ import print_function
import sys
from uncompyle6.code import iscode
from xdis.code import iscode
from spark_parser import GenericASTBuilder, DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
class ParserError(Exception):

View File

@@ -316,7 +316,7 @@ def get_scanner(version):
import uncompyle6.scanners.scanner35 as scan
scanner = scan.Scanner35()
else:
raise RuntimeError("Unsupported Python version %d" % version)
raise RuntimeError("Unsupported Python version %s" % version)
return scanner
if __name__ == "__main__":

View File

@@ -17,7 +17,7 @@ import dis, inspect
from collections import namedtuple
from array import array
from uncompyle6.code import iscode
from xdis.code import iscode
from uncompyle6.opcodes.opcode_27 import * # NOQA
import uncompyle6.scanner as scan

View File

@@ -29,7 +29,7 @@ import uncompyle6.scanners.dis3 as dis3
from collections import namedtuple
from array import array
from uncompyle6.code import iscode
from xdis.code import iscode
from uncompyle6.scanner import Token
from uncompyle6 import PYTHON3

View File

@@ -29,7 +29,7 @@ from __future__ import print_function
import re, sys
from uncompyle6 import PYTHON3
from uncompyle6.code import iscode
from xdis.code import iscode
from uncompyle6.semantics import pysource
from uncompyle6.parser import get_python_parser
from uncompyle6 import parser

View File

@@ -70,7 +70,7 @@ from __future__ import print_function
import sys, re
from uncompyle6 import PYTHON3
from uncompyle6.code import iscode
from xdis.code import iscode
from uncompyle6.parser import get_python_parser
from uncompyle6.parsers.astnode import AST
from spark_parser import GenericASTTraversal, DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG

View File

@@ -13,9 +13,9 @@ import dis, operator
import uncompyle6
import uncompyle6.scanner as scanner
from uncompyle6 import PYTHON3
from uncompyle6.code import iscode
from uncompyle6.magics import PYTHON_MAGIC_INT
from uncompyle6.load import load_file, load_module
from xdis.code import iscode
from xdis.magics import PYTHON_MAGIC_INT
from xdis.load import load_file, load_module
# FIXME: DRY
if PYTHON3: