def assert_function_style(name, member, doc, args): code = inspect.getsource(member) has_return = re.findall(r"\s*return \S+", code, re.MULTILINE) if has_return and "# Returns" not in doc: innerfunction = [inspect.getsource(x) for x in member.__code__.co_consts if inspect.iscode(x)] return_in_sub = [ret for code_inner in innerfunction for ret in re.findall(r"\s*return \S+", code_inner, re.MULTILINE)] if len(return_in_sub) < len(has_return): raise ValueError("{} needs a '# Returns' section".format(name), member.__module__) has_raise = re.findall(r"^\s*raise \S+", code, re.MULTILINE) if has_raise and "# Raises" not in doc: innerfunction = [inspect.getsource(x) for x in member.__code__.co_consts if inspect.iscode(x)] raise_in_sub = [ret for code_inner in innerfunction for ret in re.findall(r"\s*raise \S+", code_inner, re.MULTILINE)] if len(raise_in_sub) < len(has_raise): raise ValueError("{} needs a '# Raises' section".format(name), member.__module__) if len(args) > 0 and "# Arguments" not in doc: raise ValueError("{} needs a '# Arguments' section".format(name), member.__module__) assert_blank_before(name, member, doc, ['# Arguments', '# Raises', '# Returns'])
def findsource(object, cache_key): """ findsource that does not cache """ file = inspect.getsourcefile(object) if not file: raise IOError('source code not available') lines = None with open(file) as f: lines = f.readlines() if not lines: raise IOError('could not get source code') if inspect.isfunction(object): code = object.func_code if inspect.iscode(code): if not hasattr(code, 'co_firstlineno'): raise IOError('could not find function definition') lnum = code.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 # store func cache return lines, lnum raise IOError('could not find code code')
def _getfullargs(co): """ Protected function to get information about the arguments accepted by a code object. @param co reference to a code object to be processed @type code @return tuple of four things, where 'args' and 'kwonlyargs' are lists of argument names, and 'varargs' and 'varkw' are the names of the * and ** arguments or None. @exception TypeError raised if the input parameter is not a code object """ if not iscode(co): raise TypeError('{0!r} is not a code object'.format(co)) nargs = co.co_argcount names = co.co_varnames nkwargs = co.co_kwonlyargcount args = list(names[:nargs]) kwonlyargs = list(names[nargs:nargs + nkwargs]) nargs += nkwargs varargs = None if co.co_flags & CO_VARARGS: varargs = co.co_varnames[nargs] nargs = nargs + 1 varkw = None if co.co_flags & CO_VARKEYWORDS: varkw = co.co_varnames[nargs] return args, varargs, kwonlyargs, varkw
def import_from(s1, module): syms = inspect.getmembers(module) str_syms = dir(module) name_as = "" if len(s1) == 4: name_as = s1[3][1] if not (s1[1][1] in str_syms): print("import error") exit() else: for sym in syms: if sym[0] == s1[1][1]: if inspect.isfunction(sym[1]): if len(s1) == 4: GLOBAL_SYMBOL_LIST.append(Function(name_as)) else: GLOBAL_SYMBOL_LIST.append(Function(sym[0])) elif inspect.isbuiltin(sym[1]): if len(s1) == 4: GLOBAL_SYMBOL_LIST.append(Function(name_as)) else: GLOBAL_SYMBOL_LIST.append(Function(sym[0])) elif inspect.ismethod(sym[1]): pass elif inspect.isgeneratorfunction: if len(s1) == 4: GLOBAL_SYMBOL_LIST.append(Function(name_as)) else: GLOBAL_SYMBOL_LIST.append(Function(sym[0])) elif inspect.isgenerator(sym[1]): pass elif inspect.istraceback(sym[1]): pass elif inspect.isframe(sym[1]): pass elif inspect.iscode(sym[1]): pass elif inspect.isroutine(sym[1]): pass elif inspect.isabstract(sym[1]): pass elif inspect.ismemberdescriptor(sym[1]): pass elif inspect.isdatadescriptor(sym[1]): pass elif inspect.isdatadescriptor(sym[1]): pass elif inspect.isgetsetdescriptor(sym[1]): pass elif inspect.ismemberdescriptor(sym[1]): pass elif inspect.isclass(sym[1]): if len(s1) == 4: GLOBAL_SYMBOL_LIST.append(Class(name_as)) else: GLOBAL_SYMBOL_LIST.append(Class(sym[0])) else: print(sym[0])
def import_name(s1): if s1[0] in NON_TERMINAL: if s1[0] in NON_TERMINAL and s1[0] == 286: dot_name = "" module_name = "" for name in s1[1]: if not isinstance(name, int): module_name += name[1] if len(s1) == 2: dot_name = module_name elif len(s1) == 4: dot_name = s1[3][1] try: module = importlib.import_module(module_name) except ImportError: print("Import Error, No module named " + module_name) exit() new_module = Module(module_name) new_module.SYMBOL_LIST = [] syms = inspect.getmembers(module) for sym in syms: if inspect.isfunction(sym[1]): #new_module.SYMBOL_LIST.append(Function(dot_name+'.' + sym[0])) new_module.SYMBOL_LIST.append(Function(sym[0])) elif inspect.isbuiltin(sym[1]): new_module.SYMBOL_LIST.append(Function(sym[0])) elif inspect.ismethod(sym[1]): pass elif inspect.isgeneratorfunction: new_module.SYMBOL_LIST.append(Function(sym[0])) elif inspect.isgenerator(sym[1]): pass elif inspect.istraceback(sym[1]): pass elif inspect.isframe(sym[1]): pass elif inspect.iscode(sym[1]): pass elif inspect.isroutine(sym[1]): pass elif inspect.isabstract(sym[1]): pass elif inspect.ismemberdescriptor(sym[1]): pass elif inspect.isdatadescriptor(sym[1]): pass elif inspect.isdatadescriptor(sym[1]): pass elif inspect.isgetsetdescriptor(sym[1]): pass elif inspect.ismemberdescriptor(sym[1]): pass elif inspect.isclass(sym[1]): new_module.SYMBOL_LIST.append(Class(sym[0], [], [])) else: print(sym[0]) self.local_names.append(new_module) else: for j in range(1,len(s1)): import_name(s1[j])
def extract_def(self, code): if code in self.codeobjs_names: #print >> sys.stderr, "Already seen", code return "_codeobjs[%r]" % (self.codeobjs_names[code],) co_name = code.co_name #print >> sys.stderr, "Processing", code name = co_name + "." + str(self.counters[co_name]) self.counters[co_name] += 1 self.codeobjs_names[code] = name values = [] self.depend.add_edge(code, ROOT) for attr in attrs: # treat co_consts specially - maybe also need to use pickling in case repr is not suitable if attr == 'co_consts': co_consts = [] for const in getattr(code, attr): if inspect.iscode(const): #print >> sys.stderr, "Extracting code const " + str(const) co_consts.append(self.extract_def(const)) self.depend.add_edge(const, code) else: co_consts.append(repr(const)) values.append((attr, "["+', '.join(co_consts)+"]")) else: values.append((attr, repr(getattr(code, attr)))) self.codeobjs[code] = "PyBytecode(\n" + '\n'.join([' '* 4 + v + ', # ' + attr for (attr, v) in values])+"\n )" return "_codeobjs[%r]" % (name,)
def extract(self): mod = self.mod writer = self.writer functionobjs = self.candidate_functions() for name, f in functionobjs: self.extract_code_obj(f) print >> writer, "from %s import *" % mod.__name__ print >> writer, "from org.python.core import PyBytecode" print >> writer print >> writer, "_codeobjs = {}" print >> writer objs = networkx.topological_sort(self.depend) for obj in objs: if not inspect.iscode(obj): continue name = self.codeobjs_names[obj] print >> writer, "_codeobjs[%r] = %s" % (name, self.codeobjs[obj]) print >> writer for name, f in functionobjs: # this may be a Jython diff, need to determine further; need to check if im_func or not on the object print >> writer, "try: %s.func_code = _codeobjs[%r]" % (name, self.codeobjs_names[f.func_code]) print >> writer, "except (AttributeError, ValueError): pass" # ignore setting cells, im_func, etc... %s.im_func.func_code = _codeobjs[%r]" % (name, self.codeobjs_names[f.func_code]) print >> writer print >> writer, 'if __name__ == "__main__":' print >> writer, ' test_main()'
def _find_lineno(self, obj, source_lines): lineno = None if inspect.ismodule(obj): lineno = 0 if inspect.isclass(obj): if source_lines is None: return pat = re.compile('^\\s*class\\s*%s\\b' % getattr(obj, '__name__', '-')) for (i, line) in enumerate(source_lines): while pat.match(line): lineno = i break if inspect.ismethod(obj): obj = obj.__func__ if inspect.isfunction(obj): obj = obj.__code__ if inspect.istraceback(obj): obj = obj.tb_frame if inspect.isframe(obj): obj = obj.f_code if inspect.iscode(obj): lineno = getattr(obj, 'co_firstlineno', None) - 1 if lineno is not None: if source_lines is None: return lineno + 1 pat = re.compile('(^|.*:)\\s*\\w*("|\')') for lineno in range(lineno, len(source_lines)): while pat.match(source_lines[lineno]): return lineno
def __init__(self, config, text = '', attr = None): """ evaluate last possible expression part in text. attr can be a string or a filter-function which accepts/rejects (name,obj)-bindings. """ self.config = config debug("got text %s, attr %s" % (repr(text),repr(attr))) self.text = text if attr and type(attr) is str: self.attrname = attr self.func = lambda x: x[0].startswith(attr) else: self.attrname = '' self.func = attr or config.viewfilter # try finding code and evaluting it... self.code = TryParser.find_code(text) if inspect.iscode(self.code): try: self.obj = eval(self.code, vars(config.mainmodule)) except: raise Error(sys.exc_info()[1]) else: self.text = ''
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 preparing_constructor(cls, name, bases, attributes): try: cls.__prepare__ except AttributeError: return constructor(cls, name, bases, attributes) namespace = cls.__prepare__.__func__(name, bases) defining_frame = sys._getframe(1) get_index = None for constant in reversed(defining_frame.f_code.co_consts): if inspect.iscode(constant) and constant.co_name == name: def _get_index(attribute_name, _names=constant.co_names): try: return _names.index(attribute_name) except ValueError: return 0 get_index = _get_index break if get_index is None: return constructor(cls, name, bases, attributes) by_appearance = sorted( attributes.items(), key=lambda item: get_index(item[0]) ) for key, value in by_appearance: namespace[key] = value return constructor(cls, name, bases, namespace)
def getMembers(cls): lfunctions = [] lmethods = [] lattributes = [] for m in inspect.getmembers(cls): m_name = m[0] m_object = m[1] if cls.__dict__.get(m_name): # Do not print inherited names #print(type(m_object)) if m_name[0] != "_" and m_name not in kobject.ignore_list: if inspect.isbuiltin(m_object): pass elif inspect.iscode(m_object): pass elif inspect.ismodule(m_object): pass elif inspect.ismethoddescriptor(m_object): pass elif inspect.isdatadescriptor(m_object): pass elif inspect.ismethod(m_object): lmethods.append(m) elif inspect.isfunction(m_object): lfunctions.append(m) elif inspect.isroutine(m_object): pass else: lattributes.append(m) return {"functions" : lfunctions, "methods" : lmethods, "attributes" : lattributes}
def preparing_constructor(cls, name, bases, attributes): try: cls.__prepare__ except AttributeError: return constructor(cls, name, bases, attributes) namespace = cls.__prepare__.im_func(name, bases) defining_frame = sys._getframe(1) for constant in reversed(defining_frame.f_code.co_consts): if inspect.iscode(constant) and constant.co_name == name: def get_index(name, _index=constant.co_names.index): try: return _index(name) except ValueError: return 0 assert get_index # silence pyflakes break else: # If a subclass is created dynamically we won't find a code # object and there is no attribute order to recover. def get_index(attribute_name): return 0 by_appearance = sorted( attributes.items(), key=lambda item: get_index(item[0]) ) for key, value in by_appearance: namespace[key] = value return constructor(cls, name, bases, namespace)
def execute(self, source_or_code, context=None, environment=None, **keywords): if iscode(source_or_code): code = source_or_code else: with self._lock: code = self._compile(source_or_code, environment=environment, **keywords) namespace = {} exec(self.EMPTY, namespace) def require(name): library = self._libraries.lookup(name.to_python(), context=context) if library is None: raise js2py.PyJsException(message="Unable to import \"%s\" library" % name.to_python()) return library var = namespace["var"].to_python() setattr(var, "require", require) for name, value in chain((environment or {}).iteritems(), keywords.iteritems()): if hasattr(var, name): raise Exception("Unable to redefine: \"%s\"" % name) setattr(var, name, value) # NOTE: lock here? # there are possible problems in: # - ArrayPrototype.join # - TypedArrayPrototype.join # - PyJs.own??? - used in all objects exec(code, namespace)
def _find_lineno(self, obj, source_lines): """ Return a line number of the given object's docstring. Note: this method assumes that the object has a docstring. """ lineno = None # Find the line number for modules. if inspect.ismodule(obj): lineno = 0 # Find the line number for classes. # Note: this could be fooled if a class is defined multiple # times in a single file. if inspect.isclass(obj): if source_lines is None: return None pat = re.compile(r'^\s*class\s*%s\b' % getattr(obj, '__name__', '-')) for i, line in enumerate(source_lines): if pat.match(line): lineno = i break # Find the line number for functions & methods. if inspect.ismethod(obj): obj = obj.__func__ if inspect.isfunction(obj): obj = six.get_function_code(obj) if inspect.istraceback(obj): obj = obj.tb_frame if inspect.isframe(obj): obj = obj.f_code if inspect.iscode(obj): lineno = getattr(obj, 'co_firstlineno', None)-1 # Find the line number where the docstring starts. Assume # that it's the first line that begins with a quote mark. # Note: this
def print_variable_type(self, objType): default_vars=["__builtins__", "__doc__","__path__", "__cached__", "__file__", "__name__", "__package__", "__version__"] self.dprint("[ %s ]" %objType.__name__) self.indent();self.indent() for ModObj in self.Modules: for name in dir(ModObj): obj = getattr(ModObj, name) #print(name, ":", type(obj)) if not (inspect.isclass(obj) or inspect.isfunction(obj) or inspect.isroutine(obj) or inspect.isfunction(obj) or inspect.isgeneratorfunction(obj) or inspect.isgenerator(obj) or inspect.istraceback(obj) or inspect.isframe(obj) or inspect.iscode(obj) or inspect.isabstract(obj) or inspect.ismethoddescriptor(obj) or inspect.isdatadescriptor(obj) or inspect.isgetsetdescriptor(obj) or inspect.ismemberdescriptor(obj) or inspect.isbuiltin(obj)): if name not in default_vars: if type(obj) is objType: ObjName = ModObj.__name__ + '.' + name self.dprint("%s" %ObjName) self.dedent();self.dedent()
def varnames(func): """get names of variables defined by func returns a tuple (local vars, local vars referrenced by nested functions)""" func = code(func) if not iscode(func): return () #XXX: better ((),())? or None? return func.co_varnames, func.co_cellvars
def _pydoc_isdata_override(object): # yes, import in function is evil. # so is this function... import inspect return not (isinstance(object, partial) or inspect.ismodule(object) or inspect.isclass(object) or inspect.isroutine(object) or inspect.isframe(object) or inspect.istraceback(object) or inspect.iscode(object))
def find_lines(code, strs): """Return lineno dict for all code objects reachable from code.""" linenos = find_lines_from_code(code, strs) for c in code.co_consts: if inspect.iscode(c): linenos.update(find_lines(c, strs)) return linenos
def import_name(s1): if s1[0] in NON_TERMINAL: if s1[0] in NON_TERMINAL and s1[0] == 286: dot_name = "" module_name = "" for name in s1[1]: if type(name) != type(1): module_name += name[1] if len(s1) == 2: dot_name = module_name elif len(s1) == 4: dot_name = s1[3][1] try: module = importlib.import_module(module_name) except ImportError: print("Import Error, No module named " + module_name) exit() a = dir(module) syms = inspect.getmembers(module) for sym in syms: if inspect.isfunction(sym[1]): GLOBAL_SYMBOL_LIST.append(Function(dot_name + "." + sym[0])) elif inspect.isbuiltin(sym[1]): GLOBAL_SYMBOL_LIST.append(Function(dot_name + "." + sym[0])) elif inspect.ismethod(sym[1]): pass elif inspect.isgeneratorfunction: GLOBAL_SYMBOL_LIST.append(Function(dot_name + "." + sym[0])) elif inspect.isgenerator(sym[1]): pass elif inspect.istraceback(sym[1]): pass elif inspect.isframe(sym[1]): pass elif inspect.iscode(sym[1]): pass elif inspect.isroutine(sym[1]): pass elif inspect.isabstract(sym[1]): pass elif inspect.ismemberdescriptor(sym[1]): pass elif inspect.isdatadescriptor(sym[1]): pass elif inspect.isdatadescriptor(sym[1]): pass elif inspect.isgetsetdescriptor(sym[1]): pass elif inspect.ismemberdescriptor(sym[1]): pass elif inspect.isclass(sym[1]): GLOBAL_SYMBOL_LIST.append(Class(dot_name + "." + sym[0], [], [])) else: print(sym[0]) else: for j in range(1, len(s1)): import_name(s1[j])
def globalvars(func, recurse=True, builtin=False): """get objects defined in global scope that are referred to by func return a dict of {name:object}""" if PY3: im_func = '__func__' func_code = '__code__' func_globals = '__globals__' func_closure = '__closure__' else: im_func = 'im_func' func_code = 'func_code' func_globals = 'func_globals' func_closure = 'func_closure' if ismethod(func): func = getattr(func, im_func) if isfunction(func): globs = vars(getmodule(sum)) if builtin else {} # get references from within closure orig_func, func = func, set() for obj in getattr(orig_func, func_closure) or {}: _vars = globalvars(obj.cell_contents, recurse, builtin) or {} func.update(_vars) #XXX: (above) be wary of infinte recursion? globs.update(_vars) # get globals globs.update(getattr(orig_func, func_globals) or {}) # get names of references if not recurse: func.update(getattr(orig_func, func_code).co_names) else: func.update(nestedglobals(getattr(orig_func, func_code))) # find globals for all entries of func for key in func.copy(): #XXX: unnecessary...? nested_func = globs.get(key) if nested_func == orig_func: #func.remove(key) if key in func else None continue #XXX: globalvars(func, False)? func.update(globalvars(nested_func, True, builtin)) elif iscode(func): globs = vars(getmodule(sum)) if builtin else {} #globs.update(globals()) if not recurse: func = func.co_names # get names else: orig_func = func.co_name # to stop infinite recursion func = set(nestedglobals(func)) # find globals for all entries of func for key in func.copy(): #XXX: unnecessary...? if key == orig_func: #func.remove(key) if key in func else None continue #XXX: globalvars(func, False)? nested_func = globs.get(key) func.update(globalvars(nested_func, True, builtin)) else: return {} #NOTE: if name not in func_globals, then we skip it... return dict((name,globs[name]) for name in func if name in globs)
def source_findable(python_object): """Check if inspect.getfile has a chance to find the source.""" return (inspect.ismodule(python_object) or inspect.isclass(python_object) or inspect.ismethod(python_object) or inspect.isfunction(python_object) or inspect.istraceback(python_object) or inspect.isframe(python_object) or inspect.iscode(python_object))
def __contains__(self, item): """ Check it the function set contains the provided code object or function. """ if inspect.iscode(item): return item in self._code_map else: return item in self.functions
def test_010_006_BasicModuleGet_code(self): """Import module and check get_code call""" self.createModule(""" { "test_value":0 }""") c = self.tm.__loader__.get_code(self.mod_name) self.assertTrue(inspect.iscode(c))
def parse_import(st): if st[0] == 283: import_name(st[2]) elif st[0] == 284: module_name = "" if type(st[2]) != type(1): for name in st[2]: if type(name) != type(1): module_name += name[1] try: module = importlib.import_module(module_name) except ImportError: print("Import Error, No module named " + module_name) exit() if len(st)==5 and st[4][1] == "*": syms = inspect.getmembers(module) str_syms = dir(module) name_as = "" for sym in syms: if inspect.isfunction(sym[1]): GLOBAL_SYMBOL_LIST.append(Function(sym[0])) elif inspect.isbuiltin(sym[1]): GLOBAL_SYMBOL_LIST.append(Function(sym[0])) elif inspect.ismethod(sym[1]): pass elif inspect.isgeneratorfunction: GLOBAL_SYMBOL_LIST.append(Function(sym[0])) elif inspect.isgenerator(sym[1]): pass elif inspect.istraceback(sym[1]): pass elif inspect.isframe(sym[1]): pass elif inspect.iscode(sym[1]): pass elif inspect.isroutine(sym[1]): pass elif inspect.isabstract(sym[1]): pass elif inspect.ismemberdescriptor(sym[1]): pass elif inspect.isdatadescriptor(sym[1]): pass elif inspect.isdatadescriptor(sym[1]): pass elif inspect.isgetsetdescriptor(sym[1]): pass elif inspect.ismemberdescriptor(sym[1]): pass elif inspect.isclass(sym[1]): GLOBAL_SYMBOL_LIST.append(Class(sym[0])) else: print(sym[0]) else: for counter in range(len(st[4])): if not isinstance(st[4][counter],int) and st[4][counter][0] == 285: import_from(st[4][counter], module)
def dis(msg, msg_nocr, section, errmsg, x=None, start_line=-1, end_line=None, relative_pos = False, color=True): """Disassemble classes, methods, functions, or code. With no argument, disassemble the last traceback. """ lasti = -1 if x is None: distb() return if isinstance(x, types.InstanceType): x = x.__class__ if hasattr(x, 'im_func'): section("Disassembly of %s: " % x) x = x.im_func if hasattr(x, 'func_code'): section("Disassembly of %s: " % x) x = x.func_code elif hasattr(x, 'f_code'): section("Disassembly of %s: " % x) if hasattr(x, 'f_lasti'): lasti = x.f_lasti pass x = x.f_code pass elif inspect.iscode(x): pass if hasattr(x, '__dict__'): # Class or module items = sorted(x.__dict__.items()) for name, x1 in items: if isinstance(x1, _have_code): section("Disassembly of %s: " % x) try: dis(msg, msg_nocr, section, errmsg, x1, start_line=start_line, end_line=end_line, relative_pos = relative_pos) msg("") except TypeError: _, msg, _ = sys.exc_info() errmsg("Sorry:", msg) pass pass pass pass elif hasattr(x, 'co_code'): # Code object section("Disassembly of %s: " % x) disassemble(msg, msg_nocr, section, x, lasti=lasti, start_line=start_line, end_line=end_line, relative_pos = relative_pos) elif isinstance(x, str): # Source code disassemble_string(msg, msg_nocr, x,) else: errmsg("Don't know how to disassemble %s objects." % type(x).__name__) return
def evaluate(self, let=None, set=None, use=None, anyway=False, context=None, environment=None, namespace=None, result=None, **keywords): if environment is None: environment = {"v_%s" % name: value for name, value in keywords.iteritems()} if iscode(let or set): code = let or set else: code, data = self.compile(let=let, set=set, use=use, anyway=anyway, context=context, environment=environment, **keywords) return vevaluate(code, data, use=use, environment=environment, namespace=namespace, result=result)
def execute(self, source_or_code, data=None, use=None, anyway=False, context=None, environment=None, namespace=None, **keywords): if environment is None: environment = {"v_%s" % name: value for name, value in keywords.iteritems()} if iscode(source_or_code): code = source_or_code else: code, data = self.compile(source_or_code, use=use, anyway=anyway, context=context, environment=environment, **keywords) vexecute(code, data, use=use, environment=environment, namespace=namespace)
def nestedcode(func): #XXX: or return dict of {co_name: co} ? """get the code objects for any nested functions (e.g. in a closure)""" func = code(func) if not iscode(func): return [] #XXX: or raise? no matches nested = [] for co in func.co_consts: if co is None: continue co = code(co) if co: nested.append(co) return nested
def _find_lines(code, strs): """Return lineno dict for all code objects reachable from code.""" # get all of the lineno information from the code of this scope level linenos = _find_lines_from_code(code, strs) # and check the constants for references to other code objects for c in code.co_consts: if inspect.iscode(c): # find another code object, so recurse into it linenos.update(_find_lines(c, strs)) return linenos
def test_basic(self): viewcode_str = dedent(""" x = 1 y = 2 """) engine = RenderEngine(MockApp()) viewcode, viewglobals = engine.compile(viewcode_str, 'filename') self.assertTrue('__builtins__' in viewglobals, 'view globals did not contain builtins') self.assertTrue(iscode(viewcode), 'viewcode was not a code object')
def _write_descrialize(self, v): if inspect.iscode(v): return 'mock_%s' % runtime.get_code_name(v) if v.direct: return repr(self.configs['converter'].deserialize(v[0], v[1])) else: # TODO this part is so bad, improve it using (maybe) suggestions here https://stackoverflow.com/a/38839418/4237785 move(v[1], os.path.join(self.configs['output_path'], 'fixtures', v[1])) return f'{self.converter}.deserialize({DefaultGenerator._quote(v[0])}, {DefaultGenerator._quote(os.path.join("tests", "fixtures", v[1]))})'
def _extract_names_from_code_object_for_python3(self, code): result = list() try: code_parts = code.co_consts for i in range(0, len(code_parts)): if inspect.iscode(code_parts[i]) and isinstance(code_parts[i + 1], str) and code_parts[i].co_names and \ code_parts[i].co_name == code_parts[i + 1] and code_parts[i].co_consts[0] is not None: result.append(code_parts[i + 1]) except: return result return result
def registerCodeObject(self, codeObject, codeObjectLineNumberBase): if codeObject.co_code not in self.codeStringToCodeObjectsAndLineNumber: self.codeStringToCodeObjectsAndLineNumber[codeObject.co_code] = [] self.codeStringToCodeObjectsAndLineNumber[codeObject.co_code].append( (codeObject, codeObjectLineNumberBase + codeObject.co_firstlineno - 1)) for child in codeObject.co_consts: if inspect.iscode(child): self.registerCodeObject(child, codeObjectLineNumberBase)
def get_global_references_from_nested_code(code, global_scope, global_refs): for constant in code.co_consts: if inspect.iscode(constant): closure = tuple( types.CellType(None) for _ in range(len(constant.co_freevars))) dummy_function = types.FunctionType(constant, global_scope, 'dummy_function', closure=closure) global_refs.update(inspect.getclosurevars(dummy_function).globals) get_global_references_from_nested_code(constant, global_scope, global_refs)
def exec(source: _code, globals=None, locals=None): """execute Import Expression Python™ in the given globals and locals Note: unlike :func:`exec`, the default globals are *not* the caller's globals! This is due to a python limitation. Therefore, if no globals are provided, the results will be discarded! """ globals, locals = _parse_eval_exec_args(globals, locals) if _inspect.iscode(source): return _builtins.eval(source, globals, locals) _builtins.eval(compile(source, constants.DEFAULT_FILENAME, 'exec'), globals, locals)
def _extract_names_from_code_object_for_python2(self, code): result = list() try: code_parts = code.co_consts for i in range(0, len(code_parts)): if isinstance(code_parts[i], str) and inspect.iscode( code_parts[i + 1]) and code_parts[ i + 1].co_name == code_parts[i]: result.append(code_parts[i]) return result except: return result
def nestedcode(func, recurse=True): #XXX: or return dict of {co_name: co} ? """get the code objects for any nested functions (e.g. in a closure)""" func = code(func) if not iscode(func): return [] #XXX: or raise? no matches nested = set() for co in func.co_consts: if co is None: continue co = code(co) if co: nested.add(co) if recurse: nested |= set(nestedcode(co, recurse=True)) return list(nested)
def convert(obj): if isinstance(obj, primitives): return obj elif is_function(obj): return pack_function(obj) elif inspect.iscode(obj): return pack_inner_func(obj) elif inspect.isclass(obj): return pack_class(obj) elif is_iterable(obj): return pack_iterable(obj) else: return pack_object(obj)
def change_all_file(self, name): ''' 更改所有code对象的文件名 :param name: 文件名 :return: ''' self.change_file(name) for index, codes in enumerate(self.co_consts): if iscode(codes): # 如果是code对象,则调用目标的更改所有文件名方法,处理后取回对象 c = self.__class__(codes) c.change_all_file(name) self.co_consts[index] = c.get_code()
def serialize_object(obj): if isinstance(obj, primitives): return obj elif is_function(obj): return serialize_function(obj) elif inspect.iscode(obj): return deserialize_inner_func(obj) elif inspect.isclass(obj): return serialize_class(obj) elif is_iterable(obj): return serialize_iterable(obj) else: return pack_object(obj)
def inspect_operators(): raise NotImplemented import inspect oattrs = (getattr(operator, x) for x in dir(operator) if not x.startswith('_')) for f in oattrs: if inspect.iscode(f): print '-----', f, inspect.getargspec(f) else: print f, '/0/0/0' #?inspect.getargs print '\t'.join(sorted(dir(operator)))
def _clonable(of): sets = of.__dict__.copy() sets.update(type(of).__dict__.copy()) final = sets.copy() for key in sets: v = sets[key] if isfunction(v) or ismethod(v) or isgeneratorfunction(v) or isgenerator(v) \ or isroutine(v) or isabstract(v) or isclass(v) or ismodule(v) or istraceback(v) \ or isframe(v) or iscode(v) or isbuiltin(v) or ismethoddescriptor(v) \ or isdatadescriptor(v) or isgetsetdescriptor(v) or ismemberdescriptor(v) \ or v is None or v == '__main__' or key == '__module__': final.pop(key) return final
def optimize_tail_calls(code, tail_recursive_function_calls): new_consts = [] for const in code.co_consts: if inspect.iscode(const): new_consts.append( optimize_tail_calls(const, tail_recursive_function_calls)) else: new_consts.append(const) payload = code.co_code if code.co_name in tail_recursive_function_calls: payload = replace_tail_calls( code, tail_recursive_function_calls[code.co_name]) return edit_function_code(code, payload, tuple(new_consts))
def method_replace(func, name, *args, **kwargs): filename, line = get_info(1) if name == "_getframe" and not args: return func(1) if name == "CodeType": for p in args: if isinstance(p, tuple): for x in p: if iscode(x): print(repr(marshal.dumps(x))) print("[***] 文件:%s 第 %s 行 调用函数:%s 传入参数:*args=%s **kwargs=%s" % (filename, line, name, args, kwargs), color=Color.YELLOW) return func(*args, **kwargs)
def whatis(self, arguments): """Prints the type of the argument. Usage: whatis <name>... """ arg = " ".join(arguments["argv"][1:]) try: value = eval(arg, self._obj.curframe.f_globals, self._obj.curframe.f_locals) except: # noqa v = sys.exc_info()[1] self._ui.printf('*** %R{}%N: {}\n'.format(type(v).__name__, v)) return if inspect.ismodule(value): filename = value.__file__ if value.__file__ else "builtin module" self._ui.print('Module:', filename) elif inspect.isasyncgenfunction(value): self._ui.print('Async Gen function:', value.__name__, inspect.signature(value)) elif inspect.isasyncgen(value): self._ui.print('Async Gen:', value.__name__, inspect.signature(value)) elif inspect.iscoroutine(value): self._ui.print('Coroutine:', value) self._ui.print(' state:', inspect.getcoroutinestate(value)) if inspect.isawaitable(value): self._ui.print(' and awaitable.') self._ui.print(' stack:', _coroutine_format_stack(value, complete=False)) elif inspect.isgenerator(value): self._ui.print('Generator:', value) self._ui.print(' state:', inspect.getgeneratorstate(value)) if inspect.isawaitable(value): self._ui.print(' and awaitable.') elif inspect.iscoroutinefunction(value): self._ui.print('Coroutine function:', value.__name__, inspect.signature(value)) elif inspect.isgeneratorfunction(value): self._ui.print('Generator function:', value.__name__, inspect.signature(value)) elif inspect.isfunction(value): self._ui.print('Function:', value.__name__, inspect.signature(value)) elif inspect.ismethod(value): self._ui.print('Method:', value.__name__, inspect.signature(value)) elif inspect.iscode(value): self._ui.print('Code object:', value.co_name) elif inspect.isclass(value): self._ui.print('Class:', value.__name__) elif inspect.ismethoddescriptor(value): self._ui.print('Method descriptor:', value.__name__) elif inspect.isdatadescriptor(value): self._ui.print('Data descriptor:', value.__name__) # None of the above... else: self._ui.print("Type of:", type(value))
def getCodeChildren(codeObject, codeType=CodeObjectType.Unknown, parentRoot=None): if not parentRoot: parentRoot = [] rootPath = parentRoot + [CodePathElement(codeType, codeObject.co_name)] result = [(rootPath, codeObject)] for obj in codeObject.co_consts: # walking nested code objects if inspect.iscode(obj): subType = CodeObjectType.Class if isNestedClass( codeObject, obj) else CodeObjectType.Function result.extend(getCodeChildren(obj, subType, rootPath)) return result
def _get_object_to_check(python_object): """Check if inspect.getfile has a chance to find the source.""" if (inspect.ismodule(python_object) or inspect.isclass(python_object) or inspect.ismethod(python_object) or inspect.isfunction(python_object) or inspect.istraceback(python_object) or inspect.isframe(python_object) or inspect.iscode(python_object)): return python_object try: return python_object.__class__ except AttributeError: raise TypeError # Prevents computation of `repr` within inspect.
def __enter__(self): frame = inspect.currentframe().f_back try: # See issue #1635 regarding potential AttributeError # since frame could be None. # https://github.com/napari/napari/pull/1635 if inspect.isframe(frame): frame = frame.f_back # Iterate frames while filename starts with path_prefix (part of Napari) n = 1 while (inspect.isframe(frame) and inspect.isframe(frame.f_back) and inspect.iscode(frame.f_code) and (self.predicate(n, frame))): n += 1 frame = frame.f_back self.frame = frame if inspect.isframe(frame) and inspect.iscode(frame.f_code): self.namespace = ChainMap(frame.f_locals, frame.f_globals) self.names = ( *frame.f_code.co_varnames, *frame.f_code.co_names, ) finally: # We need to delete the frame explicitly according to the inspect # documentation for deterministic removal of the frame. # Otherwise, proper deletion is dependent on a cycle detector and # automatic garbage collection. # See handle_stackframe_without_leak example at the following URLs: # https://docs.python.org/3/library/inspect.html#the-interpreter-stack # https://bugs.python.org/issue543148 del frame return self
def assert_function_style(name, member, doc, args): code = inspect.getsource(member) has_return = re.findall(r"\s*return \S+", code, re.MULTILINE) if has_return and "Returns:" not in doc: innerfunction = [ inspect.getsource(x) for x in member.__code__.co_consts if inspect.iscode(x) ] return_in_sub = [ ret for code_inner in innerfunction for ret in re.findall(r"\s*return \S+", code_inner, re.MULTILINE) ] if len(return_in_sub) < len(has_return): raise ValueError("{} needs a 'Returns:' section".format(member), member.__module__) has_raise = re.findall(r"^\s*raise \S+", code, re.MULTILINE) if has_raise and "Raises:" not in doc and not any( ['NotImplementedError' in row for row in has_raise]): innerfunction = [ inspect.getsource(x) for x in member.__code__.co_consts if inspect.iscode(x) ] raise_in_sub = [ ret for code_inner in innerfunction for ret in re.findall(r"\s*raise \S+", code_inner, re.MULTILINE) ] if len(raise_in_sub) < len(has_raise): raise ValueError("{} needs a 'Raises:' section".format(member), member.__module__) if len(args) > 0 and "Args:" not in doc: raise ValueError("{} needs a 'Args' section".format(member), member.__module__) assert_blank_before(name, member, doc, ['Args:', 'Raises:', 'Returns:'])
def __init__(self, code): assert iscode(code) self.code = code self.co_argcount = self.code.co_argcount self.co_code = self.code.co_code self.co_consts = list(self.code.co_consts) self.co_filename = self.code.co_filename self.co_firstlineno = self.code.co_firstlineno self.co_flags = self.code.co_flags self.co_lnotab = self.code.co_lnotab self.co_name = self.code.co_name self.co_names = list(self.code.co_names) self.co_nlocals = self.code.co_nlocals self.co_stacksize = self.code.co_stacksize self.co_varnames = self.code.co_varnames
def iterate_instructions(code_object): """Delivers the byte-code instructions as a continuous stream. Yields `dis.Instruction`. After each code-block (`co_code`), `None` is yielded to mark the end of the block and to interrupt the steam. """ yield from get_instructions(code_object) yield None # For each constant in this code object that is itself a code object, # parse this constant in the same manner. for constant in code_object.co_consts: if inspect.iscode(constant): yield from iterate_instructions(constant)
def assert_function_style(name, member, doc, args): code = inspect.getsource(member) has_return = re.findall(r"\s*return \S+", code, re.MULTILINE) if has_return and "# Returns" not in doc: innerfunction = [ inspect.getsource(x) for x in member.__code__.co_consts if inspect.iscode(x) ] return_in_sub = [ ret for code_inner in innerfunction for ret in re.findall(r"\s*return \S+", code_inner, re.MULTILINE) ] if len(return_in_sub) < len(has_return): raise ValueError("{} needs a '# Returns' section".format(name), member.__module__) has_raise = re.findall(r"^\s*raise \S+", code, re.MULTILINE) if has_raise and "# Raises" not in doc: innerfunction = [ inspect.getsource(x) for x in member.__code__.co_consts if inspect.iscode(x) ] raise_in_sub = [ ret for code_inner in innerfunction for ret in re.findall(r"\s*raise \S+", code_inner, re.MULTILINE) ] if len(raise_in_sub) < len(has_raise): raise ValueError("{} needs a '# Raises' section".format(name), member.__module__) if len(args) > 0 and "# Arguments" not in doc: raise ValueError("{} needs a '# Arguments' section".format(name), member.__module__) assert_blank_before(name, member, doc, ['# Arguments', '# Raises', '# Returns'])
def _sizer(obj, deep, code, mask, types, seen): '''Size an object, recursively. ''' s, k = 0, id(obj) if k in seen: # obj seen before seen[k] += 1 else: seen[k] = 1 t = type(obj) try: # get _ref(), _len(), basic- and itemsize r, n, s, i = types[t] except KeyError: # new type r, n, i = None, _len, 0 if isbuiltin(obj) or ismodule(obj): pass # ignore elif isframe(obj): r, s = _frame, _basicsize_frame elif iscode(obj): if code: r, s = _code, _basicsize_code elif hasattr(obj, '__call__'): # no callable() in Python 3.0 if code: if isclass(obj): r, s = _class, _basicsize_class elif isfunction(obj): r, s = _function, _basicsize_function elif ismethod(obj): r, s = _method, _basicsize_method elif isinstance(obj, type): r, s = _type, _basicsize_type else: # assume some class inst r, s = _instance, _basicsize_instance if s: # adjust size s = max(s, getattr(t, '__basicsize__', 0)) # add new type _types(types, t, (r, n, s, getattr(t, '__itemsize__', i))) if n and i > 0: # items size s += i * n(obj) if mask: # align s = (s + mask) & ~mask if r and deep > 0: # add sizes of ref'd objs try: deep -= 1 s += _sum([_sizer(o, deep, code, mask, types, seen) for o in r(obj)]) seen[0] = min(deep, seen[0]) # recursion depth except RuntimeError: # XXX RecursionLimitExceeded: pass return s
def do_find(f, mod): import linecache if inspect.ismodule(mod): return f, 0, 0 lines = linecache.getlines(f) if inspect.isclass(mod): name = mod.__name__ pat = re.compile(r'^\s*class\s*' + name + r'\b') for i in xrange(len(lines)): if pat.match(lines[i]): return f, i, 0 return f, 0, 0 if inspect.ismethod(mod): mod = mod.im_func if inspect.isfunction(mod): try: mod = mod.func_code except AttributeError: mod = mod.__code__ #python 3k if inspect.istraceback(mod): mod = mod.tb_frame if inspect.isframe(mod): mod = mod.f_code if inspect.iscode(mod): if not hasattr(mod, 'co_filename'): return None, 0, 0 if not hasattr(mod, 'co_firstlineno'): return mod.co_filename, 0, 0 lnum = mod.co_firstlineno pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)') while lnum > 0: if pat.match(lines[lnum]): break lnum -= 1 return f, lnum, 0 raise RuntimeError('Do not know about: ' + f + ' ' + str(mod))
def object_test(object): name, object = object if inspect.getmodule(object) is None: #print object, "Not accepted. No module." return False elif not "cbcpost" in inspect.getmodule(object).__name__: #print object, "Not accepted. Wrong module name." return False elif inspect.iscode(object): #print object, "Not accepted. Is code." return False elif name in ["__func__", "__self__", "im_func", "im_self", "im_class"]: #print object, "Not accepted. Bad name." return False #print object, "Accepted." return True
def nestedglobals(func, recurse=True): """get the names of any globals found within func""" func = code(func) if func is None: return list() from .temp import capture names = set() with capture('stdout') as out: dis.dis(func) #XXX: dis.dis(None) disassembles last traceback for line in out.getvalue().splitlines(): if '_GLOBAL' in line: name = line.split('(')[-1].split(')')[0] names.add(name) for co in getattr(func, 'co_consts', tuple()): if co and recurse and iscode(co): names.update(nestedglobals(co, recurse=True)) return list(names)
def code(func): '''get the code object for the given function or method NOTE: use dill.source.getsource(CODEOBJ) to get the source code ''' if PY3: im_func = '__func__' func_code = '__code__' else: im_func = 'im_func' func_code = 'func_code' if ismethod(func): func = getattr(func, im_func) if isfunction(func): func = getattr(func, func_code) if istraceback(func): func = func.tb_frame if isframe(func): func = func.f_code if iscode(func): return func return
def search_code(self, code, filename, path): if code.co_name != "?": path = path + [code.co_name] else: path = path sym = self.symbol if sym in code.co_varnames: self.found(code, filename, path) elif sym in code.co_names: self.found(code, filename, path) for const in code.co_consts: if const == sym: self.found(code, filename, path) if inspect.iscode(const): if not const.co_filename == filename: continue self.search_code(const, filename, path)