import py |
|
class Code(object): |
""" wrapper around Python code objects """ |
def __init__(self, rawcode): |
rawcode = getattr(rawcode, 'im_func', rawcode) |
rawcode = getattr(rawcode, 'func_code', rawcode) |
self.raw = rawcode |
self.filename = rawcode.co_filename |
try: |
self.firstlineno = rawcode.co_firstlineno - 1 |
except AttributeError: |
raise TypeError("not a code object: %r" %(rawcode,)) |
self.name = rawcode.co_name |
|
def __eq__(self, other): |
return self.raw == other.raw |
|
def __ne__(self, other): |
return not self == other |
|
def new(self, rec=False, **kwargs): |
""" return new code object with modified attributes. |
if rec-cursive is true then dive into code |
objects contained in co_consts. |
""" |
names = [x for x in dir(self.raw) if x[:3] == 'co_'] |
for name in kwargs: |
if name not in names: |
raise TypeError("unknown code attribute: %r" %(name, )) |
if rec: |
newconstlist = [] |
co = self.raw |
cotype = type(co) |
for c in co.co_consts: |
if isinstance(c, cotype): |
c = self.__class__(c).new(rec=True, **kwargs) |
newconstlist.append(c) |
return self.new(rec=False, co_consts=tuple(newconstlist), **kwargs) |
for name in names: |
if name not in kwargs: |
kwargs[name] = getattr(self.raw, name) |
return py.std.new.code( |
kwargs['co_argcount'], |
kwargs['co_nlocals'], |
kwargs['co_stacksize'], |
kwargs['co_flags'], |
kwargs['co_code'], |
kwargs['co_consts'], |
kwargs['co_names'], |
kwargs['co_varnames'], |
kwargs['co_filename'], |
kwargs['co_name'], |
kwargs['co_firstlineno'], |
kwargs['co_lnotab'], |
kwargs['co_freevars'], |
kwargs['co_cellvars'], |
) |
|
def path(self): |
""" return a py.path.local object wrapping the source of the code """ |
try: |
return self.raw.co_filename.__path__ |
except AttributeError: |
return py.path.local(self.raw.co_filename) |
path = property(path, None, None, "path of this code object") |
|
def fullsource(self): |
""" return a py.code.Source object for the full source file of the code |
""" |
fn = self.raw.co_filename |
try: |
return fn.__source__ |
except AttributeError: |
return py.code.Source(self.path.read(mode="rU")) |
fullsource = property(fullsource, None, None, |
"full source containing this code object") |
|
def source(self): |
""" return a py.code.Source object for the code object's source only |
""" |
|
import inspect |
return py.code.Source(inspect.getsource(self.raw)) |
|
def getargs(self): |
""" return a tuple with the argument names for the code object |
""" |
|
raw = self.raw |
return raw.co_varnames[:raw.co_argcount] |
|
|