def dis(x=None): """ Disassemble classes, methods, functions, or code. With no argument, disassemble the last traceback. """ if x is None: dismodule.distb() return if type(x) is types.InstanceType: x = x.__class__ if hasattr(x, 'im_func'): x = x.im_func if isinstance(x, types.FunctionType): x = sys.get_func_code(x) if hasattr(x, '__dict__'): items = x.__dict__.items() items.sort() for name, x1 in items: if type(x1) in (types.MethodType, types.FunctionType, types.CodeType, types.ClassType): print "Disassembly of %s:" % name try: dis(x1) except TypeError, msg: print "Sorry:", msg print
def findsource(object): """Return the entire source file and starting line number for an object. The argument may be a module, class, method, function, traceback, frame, or code object. The source code is returned as a list of all the lines in the file and the line number indexes a line in that list. An IOError is raised if the source code cannot be retrieved.""" file = inspect.getsourcefile(object) or inspect.getfile(object) module = inspect.getmodule(object, file) if module: lines = linecache.getlines(file, module.__dict__) else: lines = linecache.getlines(file) if not lines: raise IOError('could not get source code') if inspect.ismodule(object): return lines, 0 if inspect.isclass(object): name = object.__name__ pat = re.compile(r'^(\s*)class\s*' + name + r'\b') # make some effort to find the best matching class definition: # use the one with the least indentation, which is the one # that's most probably not inside a function definition. candidates = [] for i in range(len(lines)): match = pat.match(lines[i]) if match: # if it's at toplevel, it's already the best one if lines[i][0] == 'c': return lines, i # else add whitespace to candidate list candidates.append((match.group(1), i)) if candidates: # this will sort by whitespace, and by line number, # less whitespace first candidates.sort() return lines, candidates[0][1] else: raise IOError('could not find class definition') if inspect.ismethod(object): object = object.__func__ if inspect.isfunction(object): object = sys.get_func_code(object) if inspect.istraceback(object): object = object.tb_frame if inspect.isframe(object): object = object.f_code if inspect.iscode(object): if not hasattr(object, 'co_firstlineno'): raise IOError('could not find function definition') lnum = object.co_firstlineno - 1 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)') while lnum > 0: if pat.match(lines[lnum]): break lnum = lnum - 1 return lines, lnum raise IOError('could not find code object')
def findsource(object): """Return the entire source file and starting line number for an object. The argument may be a module, class, method, function, traceback, frame, or code object. The source code is returned as a list of all the lines in the file and the line number indexes a line in that list. An IOError is raised if the source code cannot be retrieved.""" file = inspect.getsourcefile(object) or inspect.getfile(object) module = inspect.getmodule(object, file) if module: lines = linecache.getlines(file, module.__dict__) else: lines = linecache.getlines(file) if not lines: raise IOError('could not get source code') if inspect.ismodule(object): return lines, 0 if inspect.isclass(object): name = object.__name__ pat = re.compile(r'^(\s*)class\s*' + name + r'\b') # make some effort to find the best matching class definition: # use the one with the least indentation, which is the one # that's most probably not inside a function definition. candidates = [] for i in range(len(lines)): match = pat.match(lines[i]) if match: # if it's at toplevel, it's already the best one if lines[i][0] == 'c': return lines, i # else add whitespace to candidate list candidates.append((match.group(1), i)) if candidates: # this will sort by whitespace, and by line number, # less whitespace first candidates.sort() return lines, candidates[0][1] else: raise IOError('could not find class definition') if inspect.ismethod(object): object = object.im_func if isinstance(object, FunctionType): object = sys.get_func_code(object) if inspect.istraceback(object): object = object.tb_frame if inspect.isframe(object): object = object.f_code if inspect.iscode(object): if not hasattr(object, 'co_firstlineno'): raise IOError('could not find function definition') lnum = object.co_firstlineno - 1 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)') while lnum > 0: if pat.match(lines[lnum]): break lnum = lnum - 1 return lines, lnum raise IOError('could not find code object')
def dis(x=None): """Disassemble classes, methods, functions, or code. With no argument, disassemble the last traceback. """ if x is None: dismodule.distb() return if hasattr(x, '__func__'): x = x.__func__ if hasattr(x, '__code__'): x = getattr(x, '__code__') if isinstance(x, FunctionType): x = sys.get_func_code(x) if hasattr(x, '__dict__'): items = sorted(x.__dict__.items()) for name, x1 in items: if isinstance(x1, (types.MethodType, types.FunctionType, types.CodeType, type)): print("Disassembly of %s:" % name) try: dis(x1) except TypeError as msg: print("Sorry:", msg) print() elif hasattr(x, 'co_code'): dismodule.disassemble(x) elif isinstance(x, (bytes, bytearray)): dismodule.disassemble_string(x) else: raise TypeError("don't know how to disassemble %s objects" % type(x).__name__)
def dis(x=None): """ Disassemble classes, methods, functions, or code. With no argument, disassemble the last traceback. """ if x is None: dismodule.distb() return if type(x) is types.InstanceType: x = x.__class__ if hasattr(x, "im_func"): x = x.im_func if isinstance(x, types.FunctionType): x = sys.get_func_code(x) if hasattr(x, "__dict__"): items = x.__dict__.items() items.sort() for name, x1 in items: if type(x1) in (types.MethodType, types.FunctionType, types.CodeType, types.ClassType): print "Disassembly of %s:" % name try: dis(x1) except TypeError, msg: print "Sorry:", msg print
def dis(x=None): """Disassemble classes, methods, functions, or code. With no argument, disassemble the last traceback. """ if x is None: dismodule.distb() return if hasattr(x, '__func__'): x = x.__func__ if hasattr(x, '__code__'): x = getattr(x, '__code__') if isinstance(x, FunctionType): x = sys.get_func_code(x) if hasattr(x, '__dict__'): items = sorted(x.__dict__.items()) for name, x1 in items: if isinstance( x1, (types.MethodType, types.FunctionType, types.CodeType, type)): print("Disassembly of %s:" % name) try: dis(x1) except TypeError as msg: print("Sorry:", msg) print() elif hasattr(x, 'co_code'): dismodule.disassemble(x) elif isinstance(x, (bytes, bytearray)): dismodule.disassemble_string(x) else: raise TypeError("don't know how to disassemble %s objects" % type(x).__name__)
def isgeneratorfunction(object): """Return true if the object is a user-defined generator function. Generator function objects provides same attributes as functions. See isfunction.__doc__ for attributes listing.""" if (isinstance(object, FunctionType) or inspect.ismethod(object)) and \ sys.get_func_code(object).co_flags & CO_GENERATOR: return True
def getargspec(func): """Get the names and default values of a function's arguments. A tuple of four things is returned: (args, varargs, varkw, defaults). 'args' is a list of the argument names (it may contain nested lists). 'varargs' and 'varkw' are the names of the * and ** arguments or None. 'defaults' is an n-tuple of the default values of the last n arguments. """ if inspect.ismethod(func): func = func.im_func if not inspect.isfunction(func): raise TypeError('arg is not a Python function') args, varargs, varkw = inspect.getargs(sys.get_func_code(func)) return inspect.ArgSpec(args, varargs, varkw, func.func_defaults)
def getargspec(func): """Get the names and default values of a function's arguments. A tuple of four things is returned: (args, varargs, varkw, defaults). 'args' is a list of the argument names (it may contain nested lists). 'varargs' and 'varkw' are the names of the * and ** arguments or None. 'defaults' is an n-tuple of the default values of the last n arguments. """ if inspect.ismethod(func): func = func.im_func if not inspect.isfunction(func): raise TypeError("arg is not a Python function") args, varargs, varkw = inspect.getargs(sys.get_func_code(func)) return args, varargs, varkw, func.func_defaults
def getfullargspec(func): """Get the names and default values of a function's arguments. A tuple of seven things is returned: (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults annotations). 'args' is a list of the argument names (it may contain nested lists). 'varargs' and 'varkw' are the names of the * and ** arguments or None. 'defaults' is an n-tuple of the default values of the last n arguments. 'kwonlyargs' is a list of keyword-only argument names. 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults. 'annotations' is a dictionary mapping argument names to annotations. The first four items in the tuple correspond to getargspec(). """ if inspect.ismethod(func): func = func.__func__ if not inspect.isfunction(func): raise TypeError('arg is not a Python function') args, varargs, kwonlyargs, varkw = inspect._getfullargs(sys.get_func_code(func)) return inspect.FullArgSpec(args, varargs, varkw, func.__defaults__, kwonlyargs, func.__kwdefaults__, func.__annotations__)
def getfile(object): """Work out which source or compiled file an object was defined in.""" if inspect.ismodule(object): if hasattr(object, '__file__'): return object.__file__ raise TypeError('arg is a built-in module') if inspect.isclass(object): object = sys.modules.get(object.__module__) if hasattr(object, '__file__'): return object.__file__ raise TypeError('arg is a built-in class') if inspect.ismethod(object): object = object.__func__ if inspect.isfunction(object): object = sys.get_func_code(object) if inspect.istraceback(object): object = object.tb_frame if inspect.isframe(object): object = object.f_code if inspect.iscode(object): return object.co_filename raise TypeError('arg is not a module, class, method, ' 'function, traceback, frame, or code object')
def __decorator(function): if type(function) is not FunctionType: raise TypeError("Argument to the guard decorator is not a function.") func_args = getargs(sys.get_func_code(function))[0] len_args = len(func_args) - 1 def __func(*args, **kwargs): for i, param in enumerate(args): req = spec.get(func_args[i], _marker) if req is not _marker and type(param) is not req: raise TypeError( "%s has to be %r" % (func_args[i], req) ) for name, param in kwargs.iteritems(): if name in spec and type(param) is not spec[name]: raise TypeError("%s has to be %r" % (name, spec[name])) return function(*args, **kwargs) __func.__name__ = function.__name__ __func.__doc__ = function.__doc__ return __func
def getfullargspec(func): """Get the names and default values of a function's arguments. A tuple of seven things is returned: (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults annotations). 'args' is a list of the argument names (it may contain nested lists). 'varargs' and 'varkw' are the names of the * and ** arguments or None. 'defaults' is an n-tuple of the default values of the last n arguments. 'kwonlyargs' is a list of keyword-only argument names. 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults. 'annotations' is a dictionary mapping argument names to annotations. The first four items in the tuple correspond to getargspec(). """ if inspect.ismethod(func): func = func.__func__ if not inspect.isfunction(func): raise TypeError('arg is not a Python function') args, varargs, kwonlyargs, varkw = inspect._getfullargs( sys.get_func_code(func)) return inspect.FullArgSpec(args, varargs, varkw, func.__defaults__, kwonlyargs, func.__kwdefaults__, func.__annotations__)
def _make_constants( function, builtins=None, builtin_only=False, stoplist=(), verbose=False ): """Return the given ``function`` with its constants folded.""" if settings.debug == 2: print "# OPTIMISING : %s.%s" % (function.__module__, function.__name__) co = sys.get_func_code(function) newcode = map(ord, co.co_code) newconsts = list(co.co_consts) names = co.co_names codelen = len(newcode) if builtins: env = vars(builtins).copy() else: env = vars(__builtin__).copy() if builtin_only: stoplist = dict.fromkeys(stoplist) stoplist.update(sys.get_func_globals(function)) else: env.update(sys.get_func_globals(function)) # first pass converts global lookups into constants i = 0 while i < codelen: opcode = newcode[i] if opcode in (EXTENDED_ARG, STORE_GLOBAL): # for simplicity, only optimise common cases return function if opcode == LOAD_GLOBAL: oparg = newcode[i+1] + (newcode[i+2] << 8) name = co.co_names[oparg] if name in env and name not in stoplist: value = env[name] for pos, v in enumerate(newconsts): if v is value: break else: pos = len(newconsts) newconsts.append(value) newcode[i] = LOAD_CONST newcode[i+1] = pos & 0xFF newcode[i+2] = pos >> 8 if verbose or settings.debug: print name, '-->', value i += 1 if opcode >= HAVE_ARGUMENT: i += 2 # second pass folds tuples of constants and constant attribute lookups i = 0 while i < codelen: newtuple = [] while newcode[i] == LOAD_CONST: oparg = newcode[i+1] + (newcode[i+2] << 8) newtuple.append(newconsts[oparg]) i += 3 opcode = newcode[i] if not newtuple: i += 1 if opcode >= HAVE_ARGUMENT: i += 2 continue if opcode == LOAD_ATTR: obj = newtuple[-1] oparg = newcode[i+1] + (newcode[i+2] << 8) name = names[oparg] try: value = getattr(obj, name) except AttributeError: continue deletions = 1 elif opcode == BUILD_TUPLE: oparg = newcode[i+1] + (newcode[i+2] << 8) if oparg != len(newtuple): continue deletions = len(newtuple) value = tuple(newtuple) else: continue reljump = deletions * 3 newcode[i-reljump] = JUMP_FORWARD newcode[i-reljump+1] = (reljump-3) & 0xFF newcode[i-reljump+2] = (reljump-3) >> 8 n = len(newconsts) newconsts.append(value) newcode[i] = LOAD_CONST newcode[i+1] = n & 0xFF newcode[i+2] = n >> 8 i += 3 if verbose or settings.debug: print "new folded constant:", value codestr = ''.join(map(chr, newcode)) codeobj = CodeType( co.co_argcount, co.co_nlocals, co.co_stacksize, co.co_flags, codestr, tuple(newconsts), co.co_names, co.co_varnames, co.co_filename, co.co_name, co.co_firstlineno, co.co_lnotab, co.co_freevars, co.co_cellvars ) return FunctionType( codeobj, sys.get_func_globals(function), function.func_name, function.func_defaults, sys.get_func_closure(function) )