Start using our replacement for inspect.iscode

This commit is contained in:
rocky
2015-12-30 18:43:22 -05:00
parent 5bbe2c4a45
commit 2e91de8355
10 changed files with 90 additions and 64 deletions

53
uncompyle6/code.py Normal file
View File

@@ -0,0 +1,53 @@
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

@@ -1,7 +1,7 @@
# 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
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
# Copyright (c) 1999 John Aycock
"""
CPython magic- and version- independent disassembly routines
@@ -21,15 +21,16 @@ from __future__ import print_function
import inspect, os, sys
import uncompyle6
from uncompyle6.scanner import get_scanner
from uncompyle6.code import iscode
from uncompyle6.load import check_object_path, load_module
from uncompyle6.scanner import get_scanner
def disco(version, co, out=None):
"""
diassembles and deparses a given code block 'co'
"""
assert hasattr(co, 'co_name')
assert iscode(co)
# store final output stream for case of error
real_out = out or sys.stdout

View File

@@ -1,8 +1,9 @@
from __future__ import print_function
import datetime, inspect, os, sys
from uncompyle6.disas import check_object_path
from uncompyle6 import verify, PYTHON_VERSION
from uncompyle6.code import iscode
from uncompyle6.disas import check_object_path
from uncompyle6.semantics import pysource
from uncompyle6.load import load_module
@@ -13,7 +14,7 @@ def uncompyle(version, co, out=None, showasm=False, showast=False,
disassembles and deparses a given code block 'co'
"""
assert hasattr(co, 'co_name')
assert iscode(co)
# store final output stream for case of error
real_out = out or sys.stdout

View File

@@ -20,6 +20,7 @@ from struct import unpack
import uncompyle6.scanners.scanner3 as scan3
from uncompyle6.magics import PYTHON_MAGIC_INT
from uncompyle6.code import Code3
internStrings = []
internObjects = []
@@ -132,7 +133,7 @@ def load_code_type(fp, magic_int, bytes_for_s=False, code_objects={}):
co_filename = str(co_filename)
co_name = str(co_name)
if 3020 < magic_int <= 20121:
code = scan3.Code3(co_argcount, kwonlyargcount,
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)

View File

@@ -1,7 +1,7 @@
# 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
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
# Copyright (c) 1999 John Aycock
"""
Python 2.7 bytecode scanner/deparser
@@ -17,6 +17,7 @@ import dis, inspect
from collections import namedtuple
from array import array
from uncompyle6.code import iscode
from uncompyle6.opcodes.opcode_27 import * # NOQA
import uncompyle6.scanner as scan
@@ -138,11 +139,7 @@ class Scanner27(scan.Scanner):
continue
if op in hasconst:
const = co.co_consts[oparg]
# We can't use inspect.iscode() because we may be
# using a different version of Python than the
# one that this was byte-compiled on. So the code
# types may mismatch.
if hasattr(const, 'co_name'):
if iscode(const):
oparg = const
if const.co_name == '<lambda>':
assert op_name == 'LOAD_CONST'

View File

@@ -13,6 +13,7 @@ import dis
from collections import namedtuple
from array import array
from uncompyle6.code import iscode
from uncompyle6.scanner import Token
from uncompyle6 import PYTHON_VERSION, PYTHON3
@@ -24,30 +25,6 @@ globals().update(op3.opmap)
import uncompyle6.scanner as scan
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 Scanner3(scan.Scanner):
def __init__(self):
@@ -145,11 +122,7 @@ class Scanner3(scan.Scanner):
if not PYTHON3 and isinstance(const, str):
if const in code_objects:
const = code_objects[const]
# Not sure if'we can inspect.iscode() because we may be
# using a different version of Python than the
# one that this was byte-compiled on. Is probably okay,
# but we'll use hasattr instead here.
if hasattr(const, 'co_name'):
if iscode(const):
oparg = const
if const.co_name == '<lambda>':
assert op_name == 'LOAD_CONST'

View File

@@ -15,6 +15,7 @@ from array import array
import uncompyle6.scanners.scanner3 as scan3
from uncompyle6 import PYTHON_VERSION
from uncompyle6.code import iscode
from uncompyle6.scanner import Token
# Get all the opcodes into globals
@@ -92,13 +93,9 @@ class Scanner34(scan3.Scanner3):
pattr = inst.argrepr
opname = inst.opname
# For constants, the pattr is the same as attr. Using pattr adds
# an extra level of quotes which messes other things up, like getting
# keyword attribute names in a call. I suspect there will be things
# other than LOAD_CONST, but we'll start out with just this for now.
if opname in ['LOAD_CONST']:
const = inst.argval
if hasattr(const, 'co_name'):
if iscode(const):
if const.co_name == '<lambda>':
opname = 'LOAD_LAMBDA'
elif const.co_name == '<genexpr>':

View File

@@ -29,6 +29,7 @@ from __future__ import print_function
import inspect, re, sys
from uncompyle6 import PYTHON3
from uncompyle6.code import iscode
from uncompyle6.semantics import pysource
from uncompyle6.parser import get_python_parser
from uncompyle6 import parser
@@ -482,7 +483,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
self.prec = 27
code = node[-5].attr
assert hasattr(co, 'co_name')
assert iscode(co)
code = Code(code, self.scanner, self.currentclass)
# assert isinstance(code, Code)
@@ -525,8 +526,8 @@ class FragmentsWalker(pysource.SourceWalker, object):
self.prec = 27
code = node[code_index].attr
assert hasattr(code, 'co_name')
## Or Code3
assert iscode(code)
# Or Code3
code = Code(code, self.scanner, self.currentclass)
# assert isinstance(code, Code)
@@ -1246,7 +1247,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
def deparse_code(version, co, out=StringIO(), showasm=False, showast=False,
showgrammar=False):
assert hasattr(co, 'co_name')
assert iscode(co)
# store final output stream for case of error
scanner = get_scanner(version)

View File

@@ -67,6 +67,7 @@ from __future__ import print_function
import inspect, sys, re
from uncompyle6 import PYTHON3
from uncompyle6.code import iscode
from uncompyle6.parser import get_python_parser
from uncompyle6.parsers.astnode import AST
from uncompyle6.parsers.spark import GenericASTTraversal, DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
@@ -980,7 +981,7 @@ class SourceWalker(GenericASTTraversal, object):
self.prec = 27
code = node[code_index].attr
assert hasattr(code, 'co_name')
assert iscode(code)
code = Code(code, self.scanner, self.currentclass)
ast = self.build_ast(code._tokens, code._customize)
self.customize(code._customize)
@@ -1025,7 +1026,7 @@ class SourceWalker(GenericASTTraversal, object):
self.prec = 27
code = node[code_index].attr
assert hasattr(code, 'co_name')
assert iscode(code)
code = Code(code, self.scanner, self.currentclass)
# assert isinstance(code, Code)
@@ -1448,7 +1449,7 @@ class SourceWalker(GenericASTTraversal, object):
defparams = node[:node[-1].attr]
code = node[code_index].attr
assert hasattr(code, 'co_name')
assert iscode(code)
code = Code(code, self.scanner, self.currentclass)
# assert isinstance(code, Code)
@@ -1515,7 +1516,7 @@ class SourceWalker(GenericASTTraversal, object):
def build_class(self, code):
"""Dump class definition, doc string and class body."""
assert hasattr(code, 'co_name')
assert iscode(code)
self.classes.append(self.currentclass)
code = Code(code, self.scanner, self.currentclass)
# assert isinstance(code, Code)
@@ -1626,7 +1627,7 @@ def deparse_code(version, co, out=sys.stdout, showasm=False, showast=False,
disassembles and deparses a given code block 'co'
"""
assert hasattr(co, 'co_name')
assert iscode(co)
# store final output stream for case of error
scanner = get_scanner(version)

View File

@@ -13,6 +13,7 @@ import dis, inspect, 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
@@ -138,8 +139,8 @@ def cmp_code_objects(version, code_obj1, code_obj2, name=''):
This is the main part of this module.
"""
# print code_obj1, type(code_obj2)
assert code_obj1, hasattr('co_name')
assert code_obj2, hasattr('co_name')
assert iscode(code_obj1)
assert iscode(code_obj2)
# print dir(code_obj1)
if isinstance(code_obj1, object):
# new style classes (Python 2.2)