You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Start using our replacement for inspect.iscode
This commit is contained in:
53
uncompyle6/code.py
Normal file
53
uncompyle6/code.py
Normal 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)
|
@@ -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) 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
|
CPython magic- and version- independent disassembly routines
|
||||||
@@ -21,15 +21,16 @@ from __future__ import print_function
|
|||||||
import inspect, os, sys
|
import inspect, os, sys
|
||||||
|
|
||||||
import uncompyle6
|
import uncompyle6
|
||||||
from uncompyle6.scanner import get_scanner
|
from uncompyle6.code import iscode
|
||||||
from uncompyle6.load import check_object_path, load_module
|
from uncompyle6.load import check_object_path, load_module
|
||||||
|
from uncompyle6.scanner import get_scanner
|
||||||
|
|
||||||
def disco(version, co, out=None):
|
def disco(version, co, out=None):
|
||||||
"""
|
"""
|
||||||
diassembles and deparses a given code block 'co'
|
diassembles and deparses a given code block 'co'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
assert hasattr(co, 'co_name')
|
assert iscode(co)
|
||||||
|
|
||||||
# store final output stream for case of error
|
# store final output stream for case of error
|
||||||
real_out = out or sys.stdout
|
real_out = out or sys.stdout
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import datetime, inspect, os, sys
|
import datetime, inspect, os, sys
|
||||||
|
|
||||||
from uncompyle6.disas import check_object_path
|
|
||||||
from uncompyle6 import verify, PYTHON_VERSION
|
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.semantics import pysource
|
||||||
|
|
||||||
from uncompyle6.load import load_module
|
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'
|
disassembles and deparses a given code block 'co'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
assert hasattr(co, 'co_name')
|
assert iscode(co)
|
||||||
|
|
||||||
# store final output stream for case of error
|
# store final output stream for case of error
|
||||||
real_out = out or sys.stdout
|
real_out = out or sys.stdout
|
||||||
|
@@ -20,6 +20,7 @@ from struct import unpack
|
|||||||
|
|
||||||
import uncompyle6.scanners.scanner3 as scan3
|
import uncompyle6.scanners.scanner3 as scan3
|
||||||
from uncompyle6.magics import PYTHON_MAGIC_INT
|
from uncompyle6.magics import PYTHON_MAGIC_INT
|
||||||
|
from uncompyle6.code import Code3
|
||||||
|
|
||||||
internStrings = []
|
internStrings = []
|
||||||
internObjects = []
|
internObjects = []
|
||||||
@@ -132,7 +133,7 @@ def load_code_type(fp, magic_int, bytes_for_s=False, code_objects={}):
|
|||||||
co_filename = str(co_filename)
|
co_filename = str(co_filename)
|
||||||
co_name = str(co_name)
|
co_name = str(co_name)
|
||||||
if 3020 < magic_int <= 20121:
|
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_nlocals, co_stacksize, co_flags, co_code,
|
||||||
co_consts, co_names, co_varnames, co_filename, co_name,
|
co_consts, co_names, co_varnames, co_filename, co_name,
|
||||||
co_firstlineno, co_lnotab, co_freevars, co_cellvars)
|
co_firstlineno, co_lnotab, co_freevars, co_cellvars)
|
||||||
|
@@ -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) 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
|
Python 2.7 bytecode scanner/deparser
|
||||||
|
|
||||||
@@ -17,6 +17,7 @@ import dis, inspect
|
|||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from array import array
|
from array import array
|
||||||
|
|
||||||
|
from uncompyle6.code import iscode
|
||||||
from uncompyle6.opcodes.opcode_27 import * # NOQA
|
from uncompyle6.opcodes.opcode_27 import * # NOQA
|
||||||
import uncompyle6.scanner as scan
|
import uncompyle6.scanner as scan
|
||||||
|
|
||||||
@@ -138,11 +139,7 @@ class Scanner27(scan.Scanner):
|
|||||||
continue
|
continue
|
||||||
if op in hasconst:
|
if op in hasconst:
|
||||||
const = co.co_consts[oparg]
|
const = co.co_consts[oparg]
|
||||||
# We can't use inspect.iscode() because we may be
|
if iscode(const):
|
||||||
# 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'):
|
|
||||||
oparg = const
|
oparg = const
|
||||||
if const.co_name == '<lambda>':
|
if const.co_name == '<lambda>':
|
||||||
assert op_name == 'LOAD_CONST'
|
assert op_name == 'LOAD_CONST'
|
||||||
|
@@ -13,6 +13,7 @@ import dis
|
|||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from array import array
|
from array import array
|
||||||
|
|
||||||
|
from uncompyle6.code import iscode
|
||||||
from uncompyle6.scanner import Token
|
from uncompyle6.scanner import Token
|
||||||
from uncompyle6 import PYTHON_VERSION, PYTHON3
|
from uncompyle6 import PYTHON_VERSION, PYTHON3
|
||||||
|
|
||||||
@@ -24,30 +25,6 @@ globals().update(op3.opmap)
|
|||||||
|
|
||||||
import uncompyle6.scanner as scan
|
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):
|
class Scanner3(scan.Scanner):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -145,11 +122,7 @@ class Scanner3(scan.Scanner):
|
|||||||
if not PYTHON3 and isinstance(const, str):
|
if not PYTHON3 and isinstance(const, str):
|
||||||
if const in code_objects:
|
if const in code_objects:
|
||||||
const = code_objects[const]
|
const = code_objects[const]
|
||||||
# Not sure if'we can inspect.iscode() because we may be
|
if iscode(const):
|
||||||
# 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'):
|
|
||||||
oparg = const
|
oparg = const
|
||||||
if const.co_name == '<lambda>':
|
if const.co_name == '<lambda>':
|
||||||
assert op_name == 'LOAD_CONST'
|
assert op_name == 'LOAD_CONST'
|
||||||
|
@@ -15,6 +15,7 @@ from array import array
|
|||||||
import uncompyle6.scanners.scanner3 as scan3
|
import uncompyle6.scanners.scanner3 as scan3
|
||||||
|
|
||||||
from uncompyle6 import PYTHON_VERSION
|
from uncompyle6 import PYTHON_VERSION
|
||||||
|
from uncompyle6.code import iscode
|
||||||
from uncompyle6.scanner import Token
|
from uncompyle6.scanner import Token
|
||||||
|
|
||||||
# Get all the opcodes into globals
|
# Get all the opcodes into globals
|
||||||
@@ -92,13 +93,9 @@ class Scanner34(scan3.Scanner3):
|
|||||||
pattr = inst.argrepr
|
pattr = inst.argrepr
|
||||||
opname = inst.opname
|
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']:
|
if opname in ['LOAD_CONST']:
|
||||||
const = inst.argval
|
const = inst.argval
|
||||||
if hasattr(const, 'co_name'):
|
if iscode(const):
|
||||||
if const.co_name == '<lambda>':
|
if const.co_name == '<lambda>':
|
||||||
opname = 'LOAD_LAMBDA'
|
opname = 'LOAD_LAMBDA'
|
||||||
elif const.co_name == '<genexpr>':
|
elif const.co_name == '<genexpr>':
|
||||||
|
@@ -29,6 +29,7 @@ from __future__ import print_function
|
|||||||
import inspect, re, sys
|
import inspect, re, sys
|
||||||
|
|
||||||
from uncompyle6 import PYTHON3
|
from uncompyle6 import PYTHON3
|
||||||
|
from uncompyle6.code import iscode
|
||||||
from uncompyle6.semantics import pysource
|
from uncompyle6.semantics import pysource
|
||||||
from uncompyle6.parser import get_python_parser
|
from uncompyle6.parser import get_python_parser
|
||||||
from uncompyle6 import parser
|
from uncompyle6 import parser
|
||||||
@@ -482,7 +483,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
self.prec = 27
|
self.prec = 27
|
||||||
code = node[-5].attr
|
code = node[-5].attr
|
||||||
|
|
||||||
assert hasattr(co, 'co_name')
|
assert iscode(co)
|
||||||
code = Code(code, self.scanner, self.currentclass)
|
code = Code(code, self.scanner, self.currentclass)
|
||||||
# assert isinstance(code, Code)
|
# assert isinstance(code, Code)
|
||||||
|
|
||||||
@@ -525,8 +526,8 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
self.prec = 27
|
self.prec = 27
|
||||||
code = node[code_index].attr
|
code = node[code_index].attr
|
||||||
|
|
||||||
assert hasattr(code, 'co_name')
|
assert iscode(code)
|
||||||
## Or Code3
|
# Or Code3
|
||||||
code = Code(code, self.scanner, self.currentclass)
|
code = Code(code, self.scanner, self.currentclass)
|
||||||
# assert isinstance(code, Code)
|
# assert isinstance(code, Code)
|
||||||
|
|
||||||
@@ -1246,7 +1247,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
def deparse_code(version, co, out=StringIO(), showasm=False, showast=False,
|
def deparse_code(version, co, out=StringIO(), showasm=False, showast=False,
|
||||||
showgrammar=False):
|
showgrammar=False):
|
||||||
|
|
||||||
assert hasattr(co, 'co_name')
|
assert iscode(co)
|
||||||
# store final output stream for case of error
|
# store final output stream for case of error
|
||||||
scanner = get_scanner(version)
|
scanner = get_scanner(version)
|
||||||
|
|
||||||
|
@@ -67,6 +67,7 @@ from __future__ import print_function
|
|||||||
import inspect, sys, re
|
import inspect, sys, re
|
||||||
|
|
||||||
from uncompyle6 import PYTHON3
|
from uncompyle6 import PYTHON3
|
||||||
|
from uncompyle6.code import iscode
|
||||||
from uncompyle6.parser import get_python_parser
|
from uncompyle6.parser import get_python_parser
|
||||||
from uncompyle6.parsers.astnode import AST
|
from uncompyle6.parsers.astnode import AST
|
||||||
from uncompyle6.parsers.spark import GenericASTTraversal, DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
from uncompyle6.parsers.spark import GenericASTTraversal, DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||||
@@ -980,7 +981,7 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
self.prec = 27
|
self.prec = 27
|
||||||
code = node[code_index].attr
|
code = node[code_index].attr
|
||||||
|
|
||||||
assert hasattr(code, 'co_name')
|
assert iscode(code)
|
||||||
code = Code(code, self.scanner, self.currentclass)
|
code = Code(code, self.scanner, self.currentclass)
|
||||||
ast = self.build_ast(code._tokens, code._customize)
|
ast = self.build_ast(code._tokens, code._customize)
|
||||||
self.customize(code._customize)
|
self.customize(code._customize)
|
||||||
@@ -1025,7 +1026,7 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
self.prec = 27
|
self.prec = 27
|
||||||
code = node[code_index].attr
|
code = node[code_index].attr
|
||||||
|
|
||||||
assert hasattr(code, 'co_name')
|
assert iscode(code)
|
||||||
code = Code(code, self.scanner, self.currentclass)
|
code = Code(code, self.scanner, self.currentclass)
|
||||||
# assert isinstance(code, Code)
|
# assert isinstance(code, Code)
|
||||||
|
|
||||||
@@ -1448,7 +1449,7 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
defparams = node[:node[-1].attr]
|
defparams = node[:node[-1].attr]
|
||||||
code = node[code_index].attr
|
code = node[code_index].attr
|
||||||
|
|
||||||
assert hasattr(code, 'co_name')
|
assert iscode(code)
|
||||||
code = Code(code, self.scanner, self.currentclass)
|
code = Code(code, self.scanner, self.currentclass)
|
||||||
# assert isinstance(code, Code)
|
# assert isinstance(code, Code)
|
||||||
|
|
||||||
@@ -1515,7 +1516,7 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
def build_class(self, code):
|
def build_class(self, code):
|
||||||
"""Dump class definition, doc string and class body."""
|
"""Dump class definition, doc string and class body."""
|
||||||
|
|
||||||
assert hasattr(code, 'co_name')
|
assert iscode(code)
|
||||||
self.classes.append(self.currentclass)
|
self.classes.append(self.currentclass)
|
||||||
code = Code(code, self.scanner, self.currentclass)
|
code = Code(code, self.scanner, self.currentclass)
|
||||||
# assert isinstance(code, Code)
|
# 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'
|
disassembles and deparses a given code block 'co'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
assert hasattr(co, 'co_name')
|
assert iscode(co)
|
||||||
# store final output stream for case of error
|
# store final output stream for case of error
|
||||||
scanner = get_scanner(version)
|
scanner = get_scanner(version)
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@ import dis, inspect, operator
|
|||||||
import uncompyle6
|
import uncompyle6
|
||||||
import uncompyle6.scanner as scanner
|
import uncompyle6.scanner as scanner
|
||||||
from uncompyle6 import PYTHON3
|
from uncompyle6 import PYTHON3
|
||||||
|
from uncompyle6.code import iscode
|
||||||
from uncompyle6.magics import PYTHON_MAGIC_INT
|
from uncompyle6.magics import PYTHON_MAGIC_INT
|
||||||
from uncompyle6.load import load_file, load_module
|
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.
|
This is the main part of this module.
|
||||||
"""
|
"""
|
||||||
# print code_obj1, type(code_obj2)
|
# print code_obj1, type(code_obj2)
|
||||||
assert code_obj1, hasattr('co_name')
|
assert iscode(code_obj1)
|
||||||
assert code_obj2, hasattr('co_name')
|
assert iscode(code_obj2)
|
||||||
# print dir(code_obj1)
|
# print dir(code_obj1)
|
||||||
if isinstance(code_obj1, object):
|
if isinstance(code_obj1, object):
|
||||||
# new style classes (Python 2.2)
|
# new style classes (Python 2.2)
|
||||||
|
Reference in New Issue
Block a user