diff --git a/__pkginfo__.py b/__pkginfo__.py index fb11cac3..db4ecb49 100644 --- a/__pkginfo__.py +++ b/__pkginfo__.py @@ -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' diff --git a/pytest/test_fjt.py b/pytest/test_fjt.py index 4d0ee192..fdf2c4b8 100644 --- a/pytest/test_fjt.py +++ b/pytest/test_fjt.py @@ -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'}, diff --git a/pytest/test_load.py b/pytest/test_load.py deleted file mode 100644 index 63602265..00000000 --- a/pytest/test_load.py +++ /dev/null @@ -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 diff --git a/pytest/test_marsh.py b/pytest/test_marsh.py deleted file mode 100644 index b5a4739a..00000000 --- a/pytest/test_marsh.py +++ /dev/null @@ -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" diff --git a/uncompyle6/__init__.py b/uncompyle6/__init__.py index 4942994d..d3cf9bee 100644 --- a/uncompyle6/__init__.py +++ b/uncompyle6/__init__.py @@ -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: diff --git a/uncompyle6/bin/pydisassemble.py b/uncompyle6/bin/pydisassemble.py index c990f92c..eb01d0b7 100755 --- a/uncompyle6/bin/pydisassemble.py +++ b/uncompyle6/bin/pydisassemble.py @@ -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: diff --git a/uncompyle6/code.py b/uncompyle6/code.py deleted file mode 100644 index c5637ec7..00000000 --- a/uncompyle6/code.py +++ /dev/null @@ -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) diff --git a/uncompyle6/disas.py b/uncompyle6/disas.py index 13245bf2..20a76cc2 100644 --- a/uncompyle6/disas.py +++ b/uncompyle6/disas.py @@ -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) diff --git a/uncompyle6/load.py b/uncompyle6/load.py deleted file mode 100644 index 47cdab43..00000000 --- a/uncompyle6/load.py +++ /dev/null @@ -1,117 +0,0 @@ -# Copyright (c) 2015 by Rocky Bernstein -# Copyright (c) 2000 by hartmut Goebel -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 diff --git a/uncompyle6/magics.py b/uncompyle6/magics.py deleted file mode 100755 index cc1680ab..00000000 --- a/uncompyle6/magics.py +++ /dev/null @@ -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() diff --git a/uncompyle6/main.py b/uncompyle6/main.py index f6c756aa..a03068f6 100644 --- a/uncompyle6/main.py +++ b/uncompyle6/main.py @@ -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={}): diff --git a/uncompyle6/marsh.py b/uncompyle6/marsh.py deleted file mode 100644 index ce0e0fcd..00000000 --- a/uncompyle6/marsh.py +++ /dev/null @@ -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 -# Copyright (c) 2005 by Dan Pascu -# 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 diff --git a/uncompyle6/parser.py b/uncompyle6/parser.py index d559ff43..ddc813bb 100644 --- a/uncompyle6/parser.py +++ b/uncompyle6/parser.py @@ -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): diff --git a/uncompyle6/scanner.py b/uncompyle6/scanner.py index 5af7801a..bac2c387 100755 --- a/uncompyle6/scanner.py +++ b/uncompyle6/scanner.py @@ -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__": diff --git a/uncompyle6/scanners/scanner27.py b/uncompyle6/scanners/scanner27.py index 9f24b574..99973dc5 100755 --- a/uncompyle6/scanners/scanner27.py +++ b/uncompyle6/scanners/scanner27.py @@ -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 diff --git a/uncompyle6/scanners/scanner3.py b/uncompyle6/scanners/scanner3.py index b2f4f7f1..462c4836 100644 --- a/uncompyle6/scanners/scanner3.py +++ b/uncompyle6/scanners/scanner3.py @@ -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 diff --git a/uncompyle6/semantics/fragments.py b/uncompyle6/semantics/fragments.py index 42257db1..3b05bc19 100644 --- a/uncompyle6/semantics/fragments.py +++ b/uncompyle6/semantics/fragments.py @@ -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 diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 9dbb29ba..4aac5dbc 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -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 diff --git a/uncompyle6/verify.py b/uncompyle6/verify.py index 682fa536..fc8754cb 100755 --- a/uncompyle6/verify.py +++ b/uncompyle6/verify.py @@ -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: