Marshal loading of = >python 3.4 from Python < 3.4

This commit is contained in:
rocky
2015-12-28 14:39:15 -05:00
parent 6f0a252693
commit f77c4b53c4
2 changed files with 109 additions and 102 deletions

View File

@@ -2,7 +2,7 @@ from __future__ import print_function
import datetime, inspect, os, sys
from uncompyle6.disas import check_object_path
from uncompyle6 import verify
from uncompyle6 import verify, PYTHON_VERSION
from uncompyle6.semantics import pysource
from uncompyle6.load import load_module
@@ -17,7 +17,8 @@ def uncompyle(version, co, out=None, showasm=False, showast=False,
# store final output stream for case of error
real_out = out or sys.stdout
print('# Python %s' % version, file=real_out)
print('# Python %s (decompiled from Python %s)' % (version, PYTHON_VERSION),
file=real_out)
if co.co_filename:
print('# Embedded file name: %s' % co.co_filename,
file=real_out)

View File

@@ -22,6 +22,7 @@ import uncompyle6.scanners.scanner3 as scan3
from uncompyle6.magics import PYTHON_MAGIC_INT
internStrings = []
internObjects = []
PYTHON3 = (sys.version_info >= (3, 0))
@@ -56,20 +57,7 @@ def load_code(fp, magic_int, code_objects={}):
fp.seek(seek_pos)
return load_code_internal(fp, magic_int, code_objects=code_objects)
def load_code_internal(fp, magic_int, bytes_for_s=False, code_objects={}):
global internStrings
b1 = ord(fp.read(1))
if b1 & 0x80:
raise TypeError("Can't handle object references yet")
code = load_code_type(fp, magic_int, bytes_for_s, code_objects)
# FIXME: do something with reference?
return code
marshalType = chr(b1)
if marshalType == 'c':
Code = types.CodeType
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)
@@ -113,11 +101,13 @@ def load_code_internal(fp, magic_int, bytes_for_s=False, 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.
@@ -145,17 +135,31 @@ def load_code_internal(fp, magic_int, bytes_for_s=False, code_objects={}):
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
elif marshalType == 'C':
raise KeyError("New-style code not finished yet")
# const type
elif marshalType == '0':
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)
if marshalType == '0':
# Null
return None
elif marshalType == 'N':
@@ -221,7 +225,8 @@ def load_code_internal(fp, magic_int, bytes_for_s=False, code_objects={}):
return internStrings[refnum]
elif marshalType == 'r':
# object reference - new in Python3
raise KeyError("reference code not finished yet")
refnum = unpack('i', fp.read(4))[0]
return internObjects[refnum-1]
elif marshalType == '(':
tuplesize = unpack('i', fp.read(4))[0]
ret = tuple()
@@ -234,8 +239,9 @@ def load_code_internal(fp, magic_int, bytes_for_s=False, code_objects={}):
elif marshalType == '{':
# dictionary
raise KeyError(marshalType)
elif marshalType == '{':
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")
@@ -260,26 +266,26 @@ def load_code_internal(fp, magic_int, bytes_for_s=False, code_objects={}):
s = compat_str(s)
return s
elif marshalType == 'A':
# ascii interned
# 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
# small tuple - since Python3
tuplesize = unpack('B', fp.read(1))[0]
ret = tuple()
while tuplesize > 0:
ret += load_code_internal(fp, magic_int, refs, code_objects=code_objects),
ret += load_code_internal(fp, magic_int, code_objects=code_objects),
tuplesize -= 1
return ret
elif marshalType == 'z':
# short ascii
# short ascii - since Python3
strsize = unpack('B', fp.read(1))[0]
return compat_str(fp.read(strsize))
elif marshalType == 'Z':
# short ascii interned
# short ascii interned - since Python3
# FIXME: check
strsize = unpack('B', fp.read(1))[0]
interned = compat_str(fp.read(strsize))