def readmodule(module, path=[], isPyFile = False): ''' Read a source file and return a dictionary of classes, functions, modules, etc. . The real work of parsing the source file is delegated to the individual file parsers. @param module name of the source file (string) @param path path the file should be searched in (list of strings) @return the resulting dictionary ''' ext = os.path.splitext(module)[1].lower() if ext in __extensions["IDL"]: import idlclbr dict = idlclbr.readmodule_ex(module, path) idlclbr._modules.clear() elif ext in __extensions["Ruby"]: import rbclbr dict = rbclbr.readmodule_ex(module, path) rbclbr._modules.clear() elif ext in Preferences.getPython("PythonExtensions") or \ ext in Preferences.getPython("Python3Extensions") or \ isPyFile: import pyclbr dict = pyclbr.readmodule_ex(module, path, isPyFile = isPyFile) pyclbr._modules.clear() else: # try Python if it is without extension import pyclbr dict = pyclbr.readmodule_ex(module, path) pyclbr._modules.clear() return dict
def find_functions_and_classes(modulename, path): """Parse the file and return [('lineno', 'class name', 'function')] >>> with open("test1.py", "w") as f: ... f.write(chr(10).join(["def hola():", " pass", "#", "def chau():", " pass", ""])) ... f.write(chr(10).join(["class Test:"," def __init__():",""," pass"])) >>> results = find_functions_and_classes("test1", ".") >>> results [[1, None, 'hola', 0], [4, None, 'chau', 0], [7, 'Test', '__init__', 0]] """ # Assumptions: there is only one function/class per line (syntax) # class attributes & decorators are ignored # imported functions should be ignored # inheritance clases from other modules is unhandled (super)doctest for results failed, exception NameError("name 'results' is not defined",) result = [] module = pyclbr.readmodule_ex(modulename, path=path and [path]) for obj in module.values(): if isinstance(obj, pyclbr.Function) and obj.module == modulename: # it is a top-level global function (no class) result.append([obj.lineno, None, obj.name, 0]) elif isinstance(obj, pyclbr.Class) and obj.module == modulename: # it is a class, look for the methods: for method, lineno in obj.methods.items(): result.append([lineno, obj.name, method, 0]) # sort using lineno: result.sort(key=lambda x: x[LINENO]) return result
def __init__(self,fullname): fn = fullname + '.py' if not os.path.exists(fn): raise ValueError,"Module source file %s does not exist" % fn m = imp.load_source(fullname,fn) d = pyclbr.readmodule_ex(fullname) # remove external defs d = dict([ (k,v) for k,v in d.items() if v.module == fullname ]) d = sortDict(d) self.module = m self.filename = fn self.fullname = fullname self.name = self.fullname.split('/')[-1] self.shortdoc,self.longdoc = splitDocString(sanitize(m.__doc__)) # get classes and functions self.classes,self.functions = splitDict(d) for f in self.functions.keys()[:]: if not hasattr(self.module,f): # function was probably defined in __main__ section del self.functions[f] prt("Classes: %s" % ', '.join(self.classes.keys())) prt("Functions: %s" % ', '.join(self.functions.keys())) self.args = self.get_arg_linenrs() self.set_class_method_args() self.set_function_args()
def monkey_patch(): """If the CONF.monkey_patch set as True, this function patches a decorator for all functions in specified modules. You can set decorators for each modules using CONF.monkey_patch_modules. The format is "Module path:Decorator function". Parameters of the decorator is as follows. name - name of the function function - object of the function """ # If CONF.monkey_patch is not True, this function do nothing. if not CONF.monkey_patch: return # Get list of modules and decorators for module_and_decorator in CONF.monkey_patch_modules: module, decorator_name = module_and_decorator.split(':') # import decorator function decorator = importutils.import_class(decorator_name) __import__(module) # Retrieve module information using pyclbr module_data = pyclbr.readmodule_ex(module) for key in module_data.keys(): # set the decorator for the class methods if isinstance(module_data[key], pyclbr.Class): clz = importutils.import_class("%s.%s" % (module, key)) for method, func in inspect.getmembers(clz, inspect.ismethod): setattr(clz, method, decorator("%s.%s.%s" % (module, key, method), func)) # set the decorator for the function if isinstance(module_data[key], pyclbr.Function): func = importutils.import_class("%s.%s" % (module, key)) setattr(sys.modules[module], key, decorator("%s.%s" % (module, key), func))
def listclasses(self): dir, file = os.path.split(self.file) name, ext = os.path.splitext(file) if os.path.normcase(ext) != ".py": return [] try: dict = pyclbr.readmodule_ex(name, [dir] + sys.path) except ImportError as msg: return [] items = [] self.classes = {} for key, cl in dict.items(): if cl.module == name: s = key if hasattr(cl, 'super') and cl.super: supers = [] for sup in cl.super: if type(sup) is type(''): sname = sup else: sname = sup.name if sup.module != cl.module: sname = "%s.%s" % (sup.module, sname) supers.append(sname) s = s + "(%s)" % ", ".join(supers) items.append((cl.lineno, s)) self.classes[s] = cl items.sort() list = [] for item, s in items: list.append(s) return list
def profile_cputime(module, decorator_name, status): try: if status: profile_cpu.add_module(module) else: profile_cpu.delete_module(module) # import decorator function decorator = importutils.import_class(decorator_name) __import__(module) # Retrieve module information using pyclbr module_data = pyclbr.readmodule_ex(module) for key in module_data.keys(): # set the decorator for the class methods if isinstance(module_data[key], pyclbr.Class): clz = importutils.import_class("%s.%s" % (module, key)) for method, func in inspect.getmembers(clz, inspect.ismethod): if func.func_code.co_name == 'profile_cputime': pass else: setattr(clz, method, decorator("%s.%s.%s" % (module, key, method), func)) LOG.info(_('Decorated method ' + method)) # set the decorator for the function if isinstance(module_data[key], pyclbr.Function): func = importutils.import_class("%s.%s" % (module, key)) if func.func_code.co_name == 'profile_cputime': pass else: setattr(sys.modules[module], key, decorator("%s.%s" % (module, key), func)) LOG.info(_('Decorated method ' + key)) except: LOG.error(_('Invalid module or decorator name ')) LOG.error(_('Exception occurred %s ') % traceback.format_exc())
def main(args, out_name): dict = {} for mod in args: if os.path.exists(mod): path = [os.path.dirname(mod)] mod = os.path.basename(mod) if mod.lower().endswith(".py"): mod = mod[:-3] else: path = [] dict.update(pyclbr.readmodule_ex(mod, path)) G = AGraph(strict=False,directed=True) G.graph_attr['fontname'] = 'Bitstream Vera Sans' G.graph_attr['fontsize'] = '8' G.graph_attr['rankdir'] = 'BT' G.node_attr['fontname'] = 'Bitstream Vera Sans' G.node_attr['fontsize'] = '8' G.node_attr['shape'] = 'record' G.edge_attr['fontname'] = 'Bitstream Vera Sans' G.edge_attr['fontsize'] = '8' G.edge_attr['arrowhead'] = 'empty' for obj in dict.values(): if isinstance(obj, pyclbr.Class): G.add_node(obj.name) n = G.get_node(obj.name) n.attr['label'] = '{%s|%s|%s}' % (obj.name, get_members(obj), get_methods(obj)) for sclass in obj.super: if isinstance(sclass, pyclbr.Class): G.add_edge(obj.name, sclass.name) G.layout('dot') G.draw(out_name)
def get_clbr_for_file(path): try: objects = clbr_modules[path] except KeyError: dir, filename = os.path.split(path) base, ext = os.path.splitext(filename) objects = pyclbr.readmodule_ex(base, [dir]) clbr_modules[path] = objects return objects
def listclasses(self): dir, file = os.path.split(self.file) name, ext = os.path.splitext(file) if os.path.normcase(ext) != ".py": return [] try: dict = pyclbr.readmodule_ex(name, [dir] + sys.path) except ImportError, msg: return []
def pyclbrTest( files ): " Loop for the library standard parser " count = 0 for item in files: tempObj = pyclbr.readmodule_ex( os.path.basename( item ).replace( ".py", "" ), [os.path.dirname( item )] ) count += 1 print "pyclbr: processed " + str(count) + " files" return
def readpackage_at(self, path): (modules, root) = self.projects.find_package(path) for module in modules: if not module: continue try: for item in pyclbr.readmodule_ex(module, [root]).items(): yield item except ImportError: pass
def listchildren(self): "Return sequenced classes and functions in the module." dir, base = os.path.split(self.file) name, ext = os.path.splitext(base) if os.path.normcase(ext) != ".py": return [] try: tree = pyclbr.readmodule_ex(name, [dir] + sys.path) except ImportError: return [] return transform_children(tree, name)
def readModule(filename, *paths): try: contents = readmodule_ex(filename, path=list(paths)) contents = contents.copy() except (ImportError, ): contents = {} try: del(contents['__path__']) except (KeyError, ): pass return contents
def listobjects(self): dir, file = os.path.split(self.file) name, ext = os.path.splitext(file) if os.path.normcase(ext) != ".py": return [] try: dict = pyclbr.readmodule_ex(name, [dir] + sys.path) except ImportError as msg: return [] self.classes, items = collect_objects(dict, name) items.sort() return [s for item, s in items]
def pyclbrTest( files ): " Loop for the library standard parser " # time.sleep( 0.1 ) # return count = 0 for item in files: try: tempObj = pyclbr.readmodule_ex( os.path.basename( item ).replace( ".py", "" ), [os.path.dirname( item )] ) except Exception, ex: print "Error parsing " + item print ex count += 1
def monkey_patch(): """Patch decorator. If the Flags.monkey_patch set as True, this function patches a decorator for all functions in specified modules. You can set decorators for each modules using CONF.monkey_patch_modules. The format is "Module path:Decorator function". Example: 'manila.api.ec2.cloud:' \ manila.openstack.common.notifier.api.notify_decorator' Parameters of the decorator is as follows. (See manila.openstack.common.notifier.api.notify_decorator) name - name of the function function - object of the function """ # If CONF.monkey_patch is not True, this function do nothing. if not CONF.monkey_patch: return # Get list of modules and decorators for module_and_decorator in CONF.monkey_patch_modules: module, decorator_name = module_and_decorator.split(':') # import decorator function decorator = importutils.import_class(decorator_name) __import__(module) # Retrieve module information using pyclbr module_data = pyclbr.readmodule_ex(module) for key in module_data.keys(): # set the decorator for the class methods if isinstance(module_data[key], pyclbr.Class): clz = importutils.import_class("%s.%s" % (module, key)) # NOTE(vponomaryov): we need to distinguish class methods types # for py2 and py3, because the concept of 'unbound methods' has # been removed from the python3.x if six.PY3: member_type = inspect.isfunction else: member_type = inspect.ismethod for method, func in inspect.getmembers(clz, member_type): setattr( clz, method, decorator("%s.%s.%s" % (module, key, method), func)) # set the decorator for the function if isinstance(module_data[key], pyclbr.Function): func = importutils.import_class("%s.%s" % (module, key)) setattr(sys.modules[module], key, decorator("%s.%s" % (module, key), func))
def checkModule(self, moduleName, module=None, ignore=()): ''' succeed iff pyclbr.readmodule_ex(modulename) corresponds to the actual module object, module. Any identifiers in ignore are ignored. If no module is provided, the appropriate module is loaded with __import__.''' if module == None: module = __import__(moduleName, globals(), {}, []) dict = pyclbr.readmodule_ex(moduleName) # Make sure the toplevel functions and classes are the same. for name, value in dict.items(): if name in ignore: continue self.assertHasattr(module, name, ignore) py_item = getattr(module, name) if isinstance(value, pyclbr.Function): self.assertEquals(type(py_item), FunctionType) else: self.assertEquals(type(py_item), ClassType) real_bases = [base.__name__ for base in py_item.__bases__] pyclbr_bases = [ getattr(base, 'name', base) for base in value.super ] self.assertListEq(real_bases, pyclbr_bases, ignore) actualMethods = [] for m in py_item.__dict__.keys(): if type(getattr(py_item, m)) == MethodType: actualMethods.append(m) foundMethods = [] for m in value.methods.keys(): if m[:2] == '__' and m[-2:] != '__': foundMethods.append('_'+name+m) else: foundMethods.append(m) self.assertListEq(foundMethods, actualMethods, ignore) self.assertEquals(py_item.__module__, value.module) self.assertEquals(py_item.__name__, value.name, ignore) # can't check file or lineno # Now check for missing stuff. for name in dir(module): item = getattr(module, name) if type(item) in (ClassType, FunctionType): self.assertHaskey(dict, name, ignore)
def scanfuncs(filename, prefixes, cython=False): """ Return list of function names from ``filename`` that begin with prefix. This *does not* import the Python file, so this is safe to use, but functionality is limited to retrieving names of basic functions defined within global scope of the file. This *does*, however, import Cython files (if applicable). """ # Used by: findarenas, findbenchmarks path, name = os.path.split(filename) name, ext = os.path.splitext(name) # Should `cython` be a keyword argument, or should we just infer it? cython = cython or ext == '.pyx' if not cython: funcs = pyclbr.readmodule_ex(name, [path]) funcnames = [] for key, val in funcs.items(): if (any(key.startswith(prefix) for prefix in prefixes) and val.file == filename): funcnames.append(key) return funcnames # Scan Cython file. We need to import it. import pyximport pyximport.install() sys.dont_write_bytecode = True # Make sure local imports work for the given file sys.path.insert(0, path) pyximport.build_module(name, filename) try: mod = pyximport.load_module(name, filename) except ImportError: # There is most likely a '*.py' file that shares the same # base name as the '*.pyx' file we are trying to import. # Removing the directory from sys.path should fix this, # but will disable local importing. sys.path.pop(0) mod = pyximport.load_module(name, filename) # Undo making local imports work if sys.path[0] == path: sys.path.pop(0) funcnames = [] for funcname in mod.__dict__: if any(funcname.startswith(prefix) for prefix in prefixes): funcnames.append(funcname) return funcnames
def monkey_patch(): """DEPRECATED: If the CONF.monkey_patch set as True, this function patches a decorator for all functions in specified modules. You can set decorators for each modules using CONF.monkey_patch_modules. The format is "Module path:Decorator function". Example: 'nova.api.ec2.cloud:nova.notifications.notify_decorator' Parameters of the decorator is as follows. (See nova.notifications.notify_decorator) name - name of the function function - object of the function """ # If CONF.monkey_patch is not True, this function do nothing. if not CONF.monkey_patch: return LOG.warning('Monkey patching nova is deprecated for removal.') if six.PY2: is_method = inspect.ismethod else: def is_method(obj): # Unbound methods became regular functions on Python 3 return inspect.ismethod(obj) or inspect.isfunction(obj) # Get list of modules and decorators for module_and_decorator in CONF.monkey_patch_modules: module, decorator_name = module_and_decorator.split(':') # import decorator function decorator = importutils.import_class(decorator_name) __import__(module) # Retrieve module information using pyclbr module_data = pyclbr.readmodule_ex(module) for key, value in module_data.items(): # set the decorator for the class methods if isinstance(value, pyclbr.Class): clz = importutils.import_class("%s.%s" % (module, key)) for method, func in inspect.getmembers(clz, is_method): setattr(clz, method, decorator("%s.%s.%s" % (module, key, method), func)) # set the decorator for the function if isinstance(value, pyclbr.Function): func = importutils.import_class("%s.%s" % (module, key)) setattr(sys.modules[module], key, decorator("%s.%s" % (module, key), func))
def monkey_patch(): """Patches decorators for all functions in a specified module. If the CONF.monkey_patch set as True, this function patches a decorator for all functions in specified modules. You can set decorators for each modules using CONF.monkey_patch_modules. The format is "Module path:Decorator function". Example: 'cinder.api.ec2.cloud:' \ cinder.openstack.common.notifier.api.notify_decorator' Parameters of the decorator is as follows. (See cinder.openstack.common.notifier.api.notify_decorator) :param name: name of the function :param function: object of the function """ # If CONF.monkey_patch is not True, this function do nothing. if not CONF.monkey_patch: return # Get list of modules and decorators for module_and_decorator in CONF.monkey_patch_modules: module, decorator_name = module_and_decorator.split(':') # import decorator function decorator = importutils.import_class(decorator_name) __import__(module) # Retrieve module information using pyclbr module_data = pyclbr.readmodule_ex(module) for key in module_data.keys(): # set the decorator for the class methods if isinstance(module_data[key], pyclbr.Class): clz = importutils.import_class("%s.%s" % (module, key)) # On Python 3, unbound methods are regular functions predicate = inspect.isfunction if six.PY3 else inspect.ismethod for method, func in inspect.getmembers(clz, predicate): setattr( clz, method, decorator("%s.%s.%s" % (module, key, method), func)) # set the decorator for the function elif isinstance(module_data[key], pyclbr.Function): func = importutils.import_class("%s.%s" % (module, key)) setattr(sys.modules[module], key, decorator("%s.%s" % (module, key), func))
def listclasses(self): """Return list of classes and functions in the module. The dictionary output from pyclbr is re-written as a list of tuples in the form (lineno, name) and then sorted so that the classes and functions are processed in line number order. The returned list only contains the name and not the line number. An instance variable self.classes contains the pyclbr dictionary values, which are instances of Class and Function. """ dir, file = os.path.split(self.file) name, ext = os.path.splitext(file) if os.path.normcase(ext) != ".py": return [] try: dict = pyclbr.readmodule_ex(name, [dir] + sys.path) except ImportError: return [] items = [] self.classes = {} for key, cl in dict.items(): if cl.module == name: s = key if hasattr(cl, 'super') and cl.super: supers = [] for sup in cl.super: if type(sup) is type(''): sname = sup else: sname = sup.name if sup.module != cl.module: sname = "%s.%s" % (sup.module, sname) supers.append(sname) s = s + "(%s)" % ", ".join(supers) items.append((cl.lineno, s)) self.classes[s] = cl items.sort() list = [] for item, s in items: list.append(s) return list
def __init__(self, name="", path=None, file_name="<unknown>", code=None): CKClass.__init__(self, name, None, None, None) self.path = path self.descriptor = pyclbr.readmodule_ex(self.name, path) self.file_name = file_name self.code = code if self.code: self.symbol_table = symtable.symtable(self.code, self.file_name, 'exec') self.ast_node = ast.parse(self.code, self.file_name) self.classes = {} class_node_finder = ClassNodeFinder(self.ast_node) for class_name in self.descriptor.keys(): class_descriptor = self.descriptor[class_name] if isinstance(class_descriptor, pyclbr.Class): if class_descriptor.module == self.name: class_table = self.symbol_table.lookup(class_name).get_namespace() class_node = class_node_finder.find(class_name) ck_class = CKClass(class_name, class_descriptor, class_table, class_node) ck_class.extract_references() self.classes[self.name + "." + class_name] = ck_class
def GetModuleFromPackage(pkgname, version): path = ['Projects'] for item in pkgname.split('.'): path.append(item) #path.append(pkgname) path.append(version) path.append('TestSuite') absmodulepath = GetFileStr(path,'') testsuite = {} for suitefile in os.listdir(absmodulepath): if suitefile[suitefile.rfind('.')+1::] == 'py' : suitename = suitefile[0:suitefile.rfind('.')] __import__('Projects.%s.%s.TestSuite.%s' % (pkgname, version, suitename),globals(),locals(),[suitename,''],-1) objects = pyclbr.readmodule_ex('Projects.%s.%s.TestSuite.%s' % (pkgname, version, suitename)) if objects : casename = [] for case in objects[suitename].methods: if case[0:4] == 'test': casename.append(case) testsuite[suitename]=casename return testsuite
def list_classes(self, buffer=None, fname=None): model = gtk.TreeStore(str, str, int) if not fname is None: fname = fname else: return model dir, file = os.path.split(fname) name, ext = os.path.splitext(file) dict = {} try: py_compile.compile(fname) except: # ~ print "isn't a valid file" return model if os.path.normcase(ext) != ".py": return model try: pyclbr._modules = {} dict = pyclbr.readmodule_ex(name, [dir] + sys.path) except ImportError, msg: return model
def monkey_patch(): """If the CONF.monkey_patch set as True, this function patches a decorator for all functions in specified modules. You can set decorators for each modules using CONF.monkey_patch_modules. The format is "Module path:Decorator function". Example: 'patron.api.ec2.cloud:patron.notifications.notify_decorator' Parameters of the decorator is as follows. (See patron.notifications.notify_decorator) name - name of the function function - object of the function """ # If CONF.monkey_patch is not True, this function do nothing. if not CONF.monkey_patch: return # Get list of modules and decorators for module_and_decorator in CONF.monkey_patch_modules: module, decorator_name = module_and_decorator.split(':') # import decorator function decorator = importutils.import_class(decorator_name) __import__(module) # Retrieve module information using pyclbr module_data = pyclbr.readmodule_ex(module) for key in module_data.keys(): # set the decorator for the class methods if isinstance(module_data[key], pyclbr.Class): clz = importutils.import_class("%s.%s" % (module, key)) for method, func in inspect.getmembers(clz, inspect.ismethod): setattr(clz, method, decorator("%s.%s.%s" % (module, key, method), func)) # set the decorator for the function if isinstance(module_data[key], pyclbr.Function): func = importutils.import_class("%s.%s" % (module, key)) setattr(sys.modules[module], key, decorator("%s.%s" % (module, key), func))
def __init__(self, name="", path=None, file_name="<unknown>", code=None): CKClass.__init__(self, name, None, None, None) self.path = path self.descriptor = pyclbr.readmodule_ex(self.name, path) self.file_name = file_name self.code = code if self.code: self.symbol_table = symtable.symtable(self.code, self.file_name, 'exec') self.ast_node = ast.parse(self.code, self.file_name) self.classes = {} class_node_finder = ClassNodeFinder(self.ast_node) for class_name in self.descriptor.keys(): class_descriptor = self.descriptor[class_name] if isinstance(class_descriptor, pyclbr.Class): if class_descriptor.module == self.name: class_table = self.symbol_table.lookup( class_name).get_namespaces()[0] class_node = class_node_finder.find(class_name) ck_class = CKClass(class_name, class_descriptor, class_table, class_node) ck_class.extract_references() self.classes[self.name + "." + class_name] = ck_class
def register_models(my_models, admins=None): """ Call this from your admin.py in your app, this will register all your models Example: # my_app/admin.py from my_app import models from utils.admin import register_models register_models(models) :param my_models: your models module :param admins: your custom admins, must be a dictionary like {'MyModel': <MyModelAdmin>} """ admins = {} if admins is None else admins classes = pyclbr.readmodule_ex(my_models.__name__) for model in classes: model = getattr(my_models, model) if inspect.isclass(model) and issubclass(model, models.Model): if model.__name__ in admins: admin.site.register(model, admins[model.__name__]) else: admin.site.register(model)
def _parse(buffer, errorsource): if buffer.mode.name == "python": tree = sidekick.SideKickParsedData(buffer.getName()) pyclbr._modules = {} # HACK: dump pyclbr module cache modname = os.path.splitext(buffer.getName())[0] moddir = os.path.split(buffer.getPath())[0] items = pyclbr.readmodule_ex(modname, [moddir]).items() # sort items by lineno items.sort(lambda a,b: a[1].lineno - b[1].lineno) for i in range(len(items)): name,klass = items[i] next_start = None try: next_start = items[i+1][-1].lineno # next 'klass' except IndexError: pass if isinstance(klass, pyclbr.Function): node = FunctionAsset(klass, tree.root, buffer, next_start) else: node = ClassAsset(klass, tree.root, buffer, next_start) return tree else: return None
def GetModuleFromPackage(pkgname, version): path = ['Projects'] for item in pkgname.split('.'): path.append(item) #path.append(pkgname) path.append(version) path.append('TestSuite') absmodulepath = GetFileStr(path, '') testsuite = {} for suitefile in os.listdir(absmodulepath): if suitefile[suitefile.rfind('.') + 1::] == 'py': suitename = suitefile[0:suitefile.rfind('.')] __import__( 'Projects.%s.%s.TestSuite.%s' % (pkgname, version, suitename), globals(), locals(), [suitename, ''], -1) objects = pyclbr.readmodule_ex('Projects.%s.%s.TestSuite.%s' % (pkgname, version, suitename)) if objects: casename = [] for case in objects[suitename].methods: if case[0:4] == 'test': casename.append(case) testsuite[suitename] = casename
def listclasses(self): dir, file = os.path.split(self.file) name, ext = os.path.splitext(file) if os.path.normcase(ext) != '.py': return [] try: dict = pyclbr.readmodule_ex(name, [dir] + sys.path) except ImportError as msg: return [] items = [] self.classes = {} for key, cl in dict.items(): if cl.module == name: s = key if hasattr(cl, 'super') and cl.super: supers = [] for sup in cl.super: if type(sup) is type(''): sname = sup else: sname = sup.name if sup.module != cl.module: sname = '%s.%s' % (sup.module, sname) supers.append(sname) s = s + '(%s)' % ', '.join(supers) items.append((cl.lineno, s)) self.classes[s] = cl items.sort() list = [] for item, s in items: list.append(s) return list
def parser_modulo(self, ruta, nombre_fichero): '''Método que devuelve clases de un módulo dado''' # Incluimos el fichero en el sys.path para que funcione el analizador. ruta_sin_fich = ruta[0:len(ruta) - len(nombre_fichero)] try: sys.path.remove(ruta_sin_fich) except: pass sys.path.insert(0, ruta_sin_fich) # Algunas constantes. enter = '\n' tabulador = '\t' blanco = ' ' # Módulo a analizar. modulo = nombre_fichero[0:len(nombre_fichero) - 3] # Nombre completo del fichero. nfich = ruta # Recogemos el código Python. cadena_f = f_open(nfich) # Lista para transformar el código Python. cadena = list() # Quitamos las líneas en blanco. cadena_aux = StringIO.StringIO(cadena_f) cadena_f = "" for i in cadena_aux: if len(i.strip()) != 0: cadena_f += i cadena.append(i) # Creamos buffer de cadena. texto = StringIO.StringIO(cadena_f) # Creamos tokens. tokens = tokenize.generate_tokens(texto.readline) for a, b, c, d, _ in tokens: if a == tokenize.STRING: if "property" in b or "self." in b: # Buscamos cadenas de texto. cadenas = list() if c[0] <> d[0]: cadenas.append((c, (c[0], -1))) for j in range(c[0] + 1, d[0]): cadenas.append(((j, 0), (j, -1))) cadenas.append(((d[0], 0), d)) else: cadenas.append((c, d)) # Cambiamos los items por blancos. for k in cadenas: linea = k[0][0] aux = cadena[linea - 1] aux = aux.replace('property', blanco) aux = aux.replace('self.', blanco) cadena[linea - 1] = aux if a == tokenize.COMMENT: if "property" in b or "self." in b: cadena[c[0] - 1] = cadena[c[0] - 1].split('#')[0] # Liberamos memoria. tokens.close() # Bolsa de funciones. bolsa_funciones = list() # Bolsa de clases instanciadas en atributos. bolsa_clases_inst = list() # Definimos bolsa de propiedades. bolsa_propiedades = list() # Definimos bolsa de clases. bolsa_clases = list() # Definimos bolsa para clases padre. bolsa_clases_padre = list() # Definimos bolsa para métodos de clase. bolsa_metodos = list() # Bolsa de atributos. bolsa_atributos = list() # Analizamos módulo. reload(pyclbr) ret = pyclbr.readmodule_ex(modulo) for nombre, objeto in ret.items(): # Es una función. if isinstance(objeto, pyclbr.Function): # Añadimos función. bolsa_funciones.append(nombre) # Es una clase. if isinstance(objeto, pyclbr.Class): # Añadimos clase. bolsa_clases.append(nombre) # Clases de las que hereda. lista_clases_padre = objeto.super for i in lista_clases_padre: if isinstance(i, pyclbr.Class): bolsa_clases_padre.append((nombre, i.name)) else: bolsa_clases_padre.append((nombre, i)) # Diccionario de métodos. dicc_metodos = objeto.methods # Incluimos método. for metodo, _ in dicc_metodos.items(): bolsa_metodos.append((nombre, metodo)) # Número de línea de la clase que está en el módulo. num_linea = objeto.lineno # Bolsa auxiliar de atributos y métodos. bolsa = list() # Testigo de recorrido. candidato = False # Recorremos las líneas del fichero. for i in cadena: # ¿Estamos dentro de una clase? if candidato and (i[0] == blanco or i[0] == tabulador): # Atributos. if 'self.' in i: # Buscamos primero clases instanciadas en código, no en atributos. self.__clases_instanciadas_en_codigo( i, nombre_clase, bolsa_clases, bolsa_clases_inst) # Ahora los atributos... atrib = i.split('self.')[1].strip().split( '=')[0].strip().split('(')[0].strip() # [28-09-2011] Si hay caracteres especiales, seguimos. if atrib.count('.') != 0 or \ atrib.count(',') != 0 or \ atrib.count(':') != 0 or \ atrib.count('!') != 0 or \ atrib.count('}') != 0 or \ atrib.count(']') != 0 or \ atrib.count(')') != 0 : continue if bolsa.count((nombre_clase, atrib)) == 0: bolsa.append((nombre_clase, atrib)) # Buscamos clases que se instancian en el atributo. aux = i.split('self.')[1].strip() # .split('=')[1].strip() # ¿Hay asignación?. aux = aux.split('=') if len(aux) > 1: # ¿Es una instanciación de clase?. aux = aux[1].split('(') if len(aux) > 1: clase_inst = aux[0].strip() # Buscamos si efectivamente lo es... for j in bolsa_clases: if j == clase_inst: bolsa_clases_inst.append( (nombre_clase, clase_inst)) break # Propiedades. if 'property' in i: prop = i.split('property')[0].split('=')[0].strip() # aux = '@%s' % nombre_clase bolsa_propiedades.append((nombre_clase, prop)) # [29-11-2011] Clases que se instancian en el código (no atributos ni propiedades). self.__clases_instanciadas_en_codigo(i, nombre_clase, bolsa_clases, bolsa_clases_inst) # Siguiente línea. continue # ¿Hay una clase? if i[0:5] == 'class': candidato = True # Nombre de la clase. nombre_clase = i[5:].split('(')[0].split(':')[0].strip() # print nombre_clase else: candidato = False # Atributos. for i in bolsa: if i not in bolsa_metodos: bolsa_atributos.append(i) # Construimos el resultado de cada clase. clases_c = list() for i in bolsa_clases: # Métodos. metodos_c = list() for j in bolsa_metodos: if j[0] == i: # Si es oculto, no se incluye. if j[1][0:2] == '__' and j[1] not in [ '__init__', '__del__' ]: continue metodos_c.append(j[1]) # Atributos. atributos_c = list() for j in bolsa_atributos: if j[0] == i: # Si es oculto, no se incluye. if j[1][0:2] == '__': continue atributos_c.append(j[1]) # Propiedades. propiedades_c = list() for j in bolsa_propiedades: if j[0] == i: # Incluimos una arroba para identificar la propiedad. aux = '@%s' % j[1] propiedades_c.append(aux) # Clases padre. clases_padre_c = list() for j in bolsa_clases_padre: if j[0] == i: clases_padre_c.append(j[1]) # Clases instanciadas en atributos. clases_inst_c = list() for j in bolsa_clases_inst: if j[0] == i: clases_inst_c.append(j[1]) # Incluimos clase. clases_c.append((i, metodos_c, atributos_c, propiedades_c, clases_padre_c, clases_inst_c)) return clases_c, bolsa_funciones
def test_module_has_no_spec(self): module_name = "doesnotexist" assert module_name not in pyclbr._modules with test_importlib_util.uncache(module_name): with self.assertRaises(ModuleNotFoundError): pyclbr.readmodule_ex(module_name)
def readmodule_at(self, path): (module, root) = self.projects.find_module(path) if module: return pyclbr.readmodule_ex(module, [root]).items() return [] # FIXME: there should be a way to get some info!
def checkModule(self, moduleName, module=None, ignore=()): ''' succeed iff pyclbr.readmodule_ex(modulename) corresponds to the actual module object, module. Any identifiers in ignore are ignored. If no module is provided, the appropriate module is loaded with __import__.''' if module is None: # Import it. # ('<silly>' is to work around an API silliness in __import__) module = __import__(moduleName, globals(), {}, ['<silly>']) dict = pyclbr.readmodule_ex(moduleName) def ismethod(oclass, obj, name): classdict = oclass.__dict__ if isinstance(obj, FunctionType): if not isinstance(classdict[name], StaticMethodType): return False else: if not isinstance(obj, MethodType): return False if obj.im_self is not None: if (not isinstance(classdict[name], ClassMethodType) or obj.im_self is not oclass): return False else: if not isinstance(classdict[name], FunctionType): return False objname = obj.__name__ if objname.startswith("__") and not objname.endswith("__"): objname = "_%s%s" % (obj.im_class.__name__, objname) return objname == name # Make sure the toplevel functions and classes are the same. for name, value in dict.items(): if name in ignore: continue self.assertHasattr(module, name, ignore) py_item = getattr(module, name) if isinstance(value, pyclbr.Function): self.assertIsInstance(py_item, (FunctionType, BuiltinFunctionType)) if py_item.__module__ != moduleName: continue # skip functions that came from somewhere else self.assertEqual(py_item.__module__, value.module) else: self.assertIsInstance(py_item, (ClassType, type)) if py_item.__module__ != moduleName: continue # skip classes that came from somewhere else real_bases = [base.__name__ for base in py_item.__bases__] pyclbr_bases = [ getattr(base, 'name', base) for base in value.super ] try: self.assertListEq(real_bases, pyclbr_bases, ignore) except: print >> sys.stderr, "class=%s" % py_item raise actualMethods = [] for m in py_item.__dict__.keys(): if ismethod(py_item, getattr(py_item, m), m): actualMethods.append(m) foundMethods = [] for m in value.methods.keys(): if m[:2] == '__' and m[-2:] != '__': foundMethods.append('_' + name + m) else: foundMethods.append(m) try: self.assertListEq(foundMethods, actualMethods, ignore) self.assertEqual(py_item.__module__, value.module) self.assertEqualsOrIgnored(py_item.__name__, value.name, ignore) # can't check file or lineno except: print >> sys.stderr, "class=%s" % py_item raise # Now check for missing stuff. def defined_in(item, module): if isinstance(item, ClassType): return item.__module__ == module.__name__ if isinstance(item, FunctionType): return item.func_globals is module.__dict__ return False for name in dir(module): item = getattr(module, name) if isinstance(item, (ClassType, FunctionType)): if defined_in(item, module): self.assertHaskey(dict, name, ignore)
'''
# Python模块浏览器支持 import pyclbr print(pyclbr.readmodule("176_modules")) print(pyclbr.readmodule_ex("176_modules")) func1 = pyclbr.readmodule_ex("176_modules")["demo"] print(func1.file) print(func1.module) print(func1.name) print(func1.lineno) print(func1.parent) print(func1.children)
import pyclbr pyclbr.readmodule_ex('admin')
def class_browser(modulepath): return pyclbr.readmodule_ex(modulepath)
def show_methods(class_name, class_data): for name, lineno in sorted(class_data.methods.items(), key=itemgetter(1)): print(f" Method: {name}[{lineno}]") def show_super_classes(name, class_data): super_class_names = [] for super_class in class_data.super: if super_class == "object": continue if isinstance(super_class, str): super_class_names.append(super_class) else: super_class_names.append(super_class.name) if super_class_names: print("Super classes:", super_class_names) example_data = pyclbr.readmodule("pyclbr_example") for name, class_data in sorted(example_data.items(), key=lambda x: x[1].lineno): show_class(name, class_data) print() example_data = pyclbr.readmodule_ex("pyclbr_example") for name, data in sorted(example_data.items(), key=lambda x: x[1].lineno): # if isinstance(data, pyclbr.Function): print(f"Function:{name}, [{data.lineno}]")
def listObject(self, tab): self.parent.listClassMethod.clear() if isinstance(tab, EditorTab): tabWidget = self.widget(self.indexOf(tab)) else: tabWidget = self.widget(tab) if tabWidget.path: pathFile, file = os.path.split(unicode(tabWidget.path)) module, ext = os.path.splitext(file) found = False if pathFile not in sys.path: sys.path.append(pathFile) found = True try: reload(pyclbr) dictObject = {} superClassName = [] readModule = pyclbr.readmodule(module) readModuleFunction = pyclbr.readmodule_ex(module) for name, class_data in sorted(readModule.items(), key=lambda x:x[1].lineno): if os.path.normpath(str(class_data.file)) == os.path.normpath(str(tabWidget.path)): for superClass in class_data.super: if superClass == 'object': continue if isinstance(superClass, basestring): superClassName.append(superClass) else: superClassName.append(superClass.name) classItem = QTreeWidgetItem() if superClassName: for i in superClassName: super = i classItem.setText(0, name + ' [' + super + ']') classItem.setToolTip(0, name + ' [' + super + ']') else: classItem.setText(0, name) classItem.setToolTip(0, name) classItem.setText(1, str(class_data.lineno)) iconClass = QgsApplication.getThemeIcon("console/iconClassTreeWidgetConsole.png") classItem.setIcon(0, iconClass) dictObject[name] = class_data.lineno for meth, lineno in sorted(class_data.methods.items(), key=itemgetter(1)): methodItem = QTreeWidgetItem() methodItem.setText(0, meth + ' ') methodItem.setText(1, str(lineno)) methodItem.setToolTip(0, meth) iconMeth = QgsApplication.getThemeIcon("console/iconMethodTreeWidgetConsole.png") methodItem.setIcon(0, iconMeth) classItem.addChild(methodItem) dictObject[meth] = lineno # if found: # sys.path.remove(os.path.split(unicode(str(class_data.file)))[0]) self.parent.listClassMethod.addTopLevelItem(classItem) for func_name, data in sorted(readModuleFunction.items(), key=lambda x:x[1].lineno): if isinstance(data, pyclbr.Function) and \ os.path.normpath(str(data.file)) == os.path.normpath(str(tabWidget.path)): funcItem = QTreeWidgetItem() funcItem.setText(0, func_name + ' ') funcItem.setText(1, str(data.lineno)) funcItem.setToolTip(0, func_name) iconFunc = QgsApplication.getThemeIcon("console/iconFunctionTreeWidgetConsole.png") funcItem.setIcon(0, iconFunc) dictObject[func_name] = data.lineno self.parent.listClassMethod.addTopLevelItem(funcItem) if found: sys.path.remove(pathFile) except: s = traceback.format_exc() print '## Error: ' sys.stderr.write(s)
def compile_index(indexname, resname, backlink=None): indexpath = os.path.join("./docsgen/index", indexname) resfile = os.path.join("./docs/", resname) index = dict() additional_index_files = set() modules = list() print(f"Parsing index {indexname}...") with open(indexpath, "r") as f: for line in f: if len(line) < 2: continue cmd, *data = quotesplit(line) if cmd == "INCLUDE": path, file = data index[path] = file elif cmd == "INDEX": opath, dpath = data compile_index( opath, dpath, backlink=indexname, ) index[opath] = dpath additional_index_files.add(opath) elif cmd == "MODULE": path = data[0] print(f"Importing module {path}") module = importlib.import_module(path) modules.append(module) index[path] = module elif cmd == "HEADER": path = data[0] index[path] = DataHeader(path) else: print("!!! Unrecognized command:", cmd) resindex = list() print(f"Generating index for {indexpath}") if backlink is not None: resindex.append(f'<p><a href="{backlink}.html">🔗 Back</a></p>') for key in index: if key in additional_index_files: resindex.append(f'<p><a href="{index[key]}">🔗 {key}</a></p>') else: if isinstance(index[key], DataHeader): resindex.append( f'<h1><a href="#{key.replace(" ", "-")}">{key}</a></h1>') else: resindex.append( f'<p><a href="#{key.replace(" ", "-")}">{key}</a></p>') if inspect.ismodule(index[key]): keys = pyclbr.readmodule_ex(key) tmp = [] for sk, sv in keys.items(): tmp.append( f'<li><a href=#{key+sk}>{sv.__class__.__name__} {sk}</a></li>' ) resindex.append( f'<ul class="modulelist">{"".join(tmp)}</ul>') resindex = "\n".join(resindex) resdata = list() print("Parsing files...") for key, value in index.items(): if key in additional_index_files: continue elif isinstance(value, DataHeader): resdata.append(f'<h1 id={key.replace(" ", "-")}>{key}</h1><hr>') elif not isinstance(value, str): html = gen_docs_for_module(value) resdata.append(f'<h1 id={key.replace(" ", "-")}>{key}</h1>') resdata.append(html) elif value.endswith(".md"): path = os.path.join("./docsgen/data", value) print(f"Parsing {path}") with open(path) as f: html = highlight(f.read()) resdata.append(f'<h1 id={key.replace(" ", "-")}>{key}</h1>') resdata.append(html) else: print(f"Unknown extension of {value}") resdata = "\n".join(resdata) print(f"Writing file {resfile}...") with open(resfile, "w") as f: data = patterndata % (resindex, resdata) f.write(data) print("Done!")
def generate_dependency_data(self): """generate dependency (inheritance and non-inheritance) data. """ # _ = GenerateSequenceDiagram(self.source_code_path[0]) agg_data = defaultdict(list) # dictionary to store all files: classes mapping. If a .py file has three classes, their name, start and end line will be stored here. files = {} class_index = defaultdict(lambda: defaultdict(int)) # to check if a class has already been covered due to some import in another file. self.classes_covered = defaultdict(lambda: defaultdict(int)) for source_code_module in self.source_code_modules: source_code_path = [ os.path.join(self.source_code_path[0], self.source_code_modules[source_code_module]) ] source_code_module = source_code_module.split('.')[-1] logging.debug( 'Source code module: {}, Source code path: {}'.format( source_code_module, source_code_path)) source_code_data = pyclbr.readmodule_ex(source_code_module, path=source_code_path) for name, class_data in source_code_data.items(): if name == '__path__': continue # if class_data.module == 'pickle': # print('Caught an outsider') if class_data.module not in self.source_code_modules: continue self.class_object_mapping[class_data.module]['{}'.format( class_data.name)] = class_data logging.debug('Class: Object indexing created successfully!') for source_code_module in self.source_code_modules: counter = 0 source_code_path = [ os.path.join(self.source_code_path[0], self.source_code_modules[source_code_module]) ] source_code_module = source_code_module.split('.')[-1] logging.debug( 'Source code module: {}, Source code path: {}'.format( source_code_module, source_code_path)) source_code_data = pyclbr.readmodule_ex(source_code_module, path=source_code_path) generate_hierarchy = GenerateHierarchy() for name, class_data in source_code_data.items(): # don't cover classes that are not in the source code modules if name == '__path__': continue if class_data.module not in self.source_code_modules: continue methods = [] parents = [] if isinstance(class_data, pyclbr.Class): methods = generate_hierarchy.show_methods(name, class_data) parents = generate_hierarchy.show_super_classes( name, class_data, self) file_ = class_data.file start_line = class_data.lineno, end_line = class_data.end_lineno module = class_data.module if module in self.classes_covered: if self.classes_covered[module].get(name): continue if module == 'pickle': print('here') agg_data[module].append({ "Class": name, "Methods": methods, "Parents": parents, "File": file_, "Start Line": start_line, "End Line": end_line, "Dependents": [] }) if files.get(class_data.file, None): files[class_data.file].append({ 'class': name, 'start_line': class_data.lineno, 'end_line': class_data.end_lineno }) else: files[class_data.file] = [{ 'class': name, 'start_line': class_data.lineno, 'end_line': class_data.end_lineno }] class_index[module][name] = len(agg_data[module]) - 1 counter += 1 self.classes_covered[module][name] = 1 logging.debug(' ---------------------------------- ') for _ in range(20): print('\n') logging.debug('Checking whether pickle is in agg_data') logging.debug(agg_data.get('pickle', 'Not in agg_data')) # extract inter-file dependencies i.e. if a file's classes have been used in other files. Files being modules here. for file_ in files.keys(): module = file_.replace('/', '.')[len(self.source_code_path[0]) + 1:].split('.py')[0] if module not in self.source_code_modules: continue for j in files.keys(): try: source = open(j).read() collector = ModuleUseCollector(module) collector.visit(ast.parse(source)) for use_ in collector.used_at: _class = use_[0].split(".")[-1] alias = use_[1] line_no = use_[2] for class_ in files[j]: logging.debug( 'Checking for class {} in file {} and _class is {}' .format(class_, files[j], _class)) if ((class_['start_line'] < line_no) and (class_['end_line'] > line_no)): dependent_module = j.split('/')[-1].split( '.py')[0] try: agg_data[module][class_index[module][ _class]]['Dependents'].append({ 'module': dependent_module, 'class': class_['class'] }) except IndexError: logging.debug( 'agg_data for the module: {} is: {}'. format(module, agg_data[module])) logging.debug( 'class_index of this class is: {}'. format(class_index[module][_class])) logging.debug( 'Checking whether pickle module is in source code modules: ' ) logging.debug( self.source_code_modules.get( module, 'Not here')) raise IndexError except AttributeError as ae: logging.error(ae) pass except KeyError as key_error: logging.debug( 'Class {} was not found in agg_data but was brought up while checking non-inheritance dependencies, generating error: {}' .format(_class, key_error)) # extract intra-file dependencies for file_ in files.keys(): module_name = file_.replace( '/', '.')[len(self.source_code_path[0]) + 1:].split('.py')[0] if module not in self.source_code_modules: continue with open(file_) as f: data = f.read() module = ast.parse(data) classes = [ obj for obj in module.body if isinstance(obj, ast.ClassDef) ] class_names = [obj.name for obj in classes] dependencies = {name: [] for name in class_names} for class_ in classes: for node in ast.walk(class_): if isinstance(node, ast.Call): if isinstance(node.func, ast.Name): if node.func.id != class_.name and node.func.id in class_names: dependencies[class_.name].append( node.func.id) logging.debug( 'Currently debugging the module: {}'.format(module_name)) for class_name, dependency in dependencies.items(): for dependee_class in dependency: agg_data[module_name][class_index[module_name][ dependee_class]]['Dependents'].append({ 'module': module_name, 'class': class_name }) self.skip_cols = 0 parents_or_dependees_set = set() for module in agg_data.keys(): for class_ in agg_data[module]: if class_['Dependents']: parents_or_dependees_set.add('{}.{}'.format( module, class_['Class'])) if class_['Parents']: for parent in class_['Parents']: parents_or_dependees_set.add('{}.{}'.format( parent['parent_module'], parent['parent_class'])) self.skip_cols = len(parents_or_dependees_set) # The whole data is now collected and we need to form the dataframe of it: self.write_in_excel = WriteInExcel(file_name='Dependency_2.xlsx') self.df = self.write_in_excel.create_pandas_dataframe( agg_data, self.skip_cols) logging.debug('Dataframe is: \n') logging.debug(self.df) self.write_in_excel.write_df_to_excel(self.df, 'sheet_one', self.skip_cols, self.classes_covered)
import pyclbr import sys source_code_module = 'contributors' sys.path.insert(1, '/tmp/pandas/pandas/') source_code_path = ['/tmp/pandas/pandas/doc/sphinxext'] print('sys.path is: ') print(sys.path) source_code_data = pyclbr.readmodule_ex( source_code_module, path=source_code_path) print(source_code_data)
import pyclbr # available in Python 2.0 and later mod = pyclbr.readmodule_ex("cgi") for k, v in list(mod.items()): print(k, v) ## MiniFieldStorage <pyclbr.Class instance at 00905D2C> ## parse_header <pyclbr.Function instance at 00905BD4> ## test <pyclbr.Function instance at 00906FBC> ## print_environ_usage <pyclbr.Function instance at 00907C94> ## parse_multipart <pyclbr.Function instance at 00905294> ## FormContentDict <pyclbr.Class instance at 008D3494> ## initlog <pyclbr.Function instance at 00904AAC> ## parse <pyclbr.Function instance at 00904EFC> ## StringIO <pyclbr.Class instance at 00903EAC> ## SvFormContentDict <pyclbr.Class instance at 00906824> ## ...
def _inspect_module(pkg_name, mod_name): full_mod_name = mod_name if not pkg_name else '.'.join((pkg_name, mod_name)) return pyclbr.readmodule_ex(full_mod_name) # return module_content
def checkModule(self, moduleName, module=None, ignore=()): ''' succeed iff pyclbr.readmodule_ex(modulename) corresponds to the actual module object, module. Any identifiers in ignore are ignored. If no module is provided, the appropriate module is loaded with __import__.''' ignore = set(ignore) | set(['object']) if module is None: # Import it. # ('<silly>' is to work around an API silliness in __import__) module = __import__(moduleName, globals(), {}, ['<silly>']) dict = pyclbr.readmodule_ex(moduleName) def ismethod(oclass, obj, name): classdict = oclass.__dict__ if isinstance(obj, MethodType): # could be a classmethod if (not isinstance(classdict[name], ClassMethodType) or obj.__self__ is not oclass): return False elif not isinstance(obj, FunctionType): return False objname = obj.__name__ if objname.startswith("__") and not objname.endswith("__"): objname = "_%s%s" % (oclass.__name__, objname) return objname == name # Make sure the toplevel functions and classes are the same. for name, value in dict.items(): if name in ignore: continue self.assertHasattr(module, name, ignore) py_item = getattr(module, name) if isinstance(value, pyclbr.Function): self.assertIsInstance(py_item, (FunctionType, BuiltinFunctionType)) if py_item.__module__ != moduleName: continue # skip functions that came from somewhere else self.assertEqual(py_item.__module__, value.module) else: self.assertIsInstance(py_item, type) if py_item.__module__ != moduleName: continue # skip classes that came from somewhere else real_bases = [base.__name__ for base in py_item.__bases__] pyclbr_bases = [ getattr(base, 'name', base) for base in value.super ] try: self.assertListEq(real_bases, pyclbr_bases, ignore) except: print("class=%s" % py_item, file=sys.stderr) raise actualMethods = [] for m in py_item.__dict__.keys(): if ismethod(py_item, getattr(py_item, m), m): actualMethods.append(m) foundMethods = [] for m in value.methods.keys(): if m[:2] == '__' and m[-2:] != '__': foundMethods.append('_'+name+m) else: foundMethods.append(m) try: self.assertListEq(foundMethods, actualMethods, ignore) self.assertEqual(py_item.__module__, value.module) self.assertEqualsOrIgnored(py_item.__name__, value.name, ignore) # can't check file or lineno except: print("class=%s" % py_item, file=sys.stderr) raise # Now check for missing stuff. def defined_in(item, module): if isinstance(item, type): return item.__module__ == module.__name__ if isinstance(item, FunctionType): return item.__globals__ is module.__dict__ return False for name in dir(module): item = getattr(module, name) if isinstance(item, (type, FunctionType)): if defined_in(item, module): self.assertHaskey(dict, name, ignore)
def registrar_modelos(my_models): classes = pyclbr.readmodule_ex(my_models.__name__) for model in classes: model = getattr(my_models, model) if inspect.isclass(model) and issubclass(model, models.Model): admin.site.register(model)
"""Class browser.
def update_event(self, inp=-1): self.set_output_val(0, pyclbr.readmodule_ex(self.input(0), self.input(1)))
import pyclbr for name, val in pyclbr.readmodule_ex("re").items(): print(name, vars(val))
def class_browser(module, path=None): return pyclbr.readmodule_ex(module, path or [])
#! /usr/bin/env/python # -*- coding:utf-8 -*- import pyclbr import os from operator import itemgetter example_data = pyclbr.readmodule_ex('pyclbr_example') for name, data in sorted(example_data.items(), key=lambda x: x[1].lineno): if isinstance(data, pyclbr.Function): print 'Function:{0} [{1}]'.format(name, data.lineno)
def _find_jinja_function(filename, verbose=True, ignore_errors=True): # for finding filters/tests module_name = os.path.splitext(os.path.basename(filename))[0] paths = [os.path.dirname(filename)] mdata = pyclbr.readmodule_ex(module_name, paths)
print(k, v) ''' Message <pyclbr.Class object at 0x02D37E90> Mapping <pyclbr.Class object at 0x02D21FD0> MiniFieldStorage <pyclbr.Class object at 0x02D37FD0> FieldStorage <pyclbr.Class object at 0x02DDC470> [Finished in 1.2s] ''' print('-------------------------------------------------') # 使用 pyclbr 模块读取类和函数 # readmodule_ex , 它还会读取全局函数. import pyclbr mod = pyclbr.readmodule_ex('cgi') for k, v in mod.items(): print(k, v) ''' parse_qsl <pyclbr.Function object at 0x02C88410> valid_boundary <pyclbr.Function object at 0x02C88630> nolog <pyclbr.Function object at 0x02C88390> parse_header <pyclbr.Function object at 0x02C88470> print_environ_usage <pyclbr.Function object at 0x02C88610> closelog <pyclbr.Function object at 0x02C88370> _parseparam <pyclbr.Function object at 0x02C88450> escape <pyclbr.Function object at 0x02C88690> print_exception <pyclbr.Function object at 0x02C88590> test <pyclbr.Function object at 0x02C88570> MiniFieldStorage <pyclbr.Class object at 0x02BE7FF0>
def checkModule(self, moduleName, module=None, ignore=()): """ succeed iff pyclbr.readmodule_ex(modulename) corresponds to the actual module object, module. Any identifiers in ignore are ignored. If no module is provided, the appropriate module is loaded with __import__.""" ignore = set(ignore) | set(['object']) if module is None: module = __import__(moduleName, globals(), {}, ['<silly>']) dict = pyclbr.readmodule_ex(moduleName) def ismethod(oclass, obj, name): classdict = oclass.__dict__ if isinstance(obj, MethodType): if not isinstance(classdict[name], ClassMethodType ) or obj.__self__ is not oclass: return False elif not isinstance(obj, FunctionType): return False objname = obj.__name__ if objname.startswith('__') and not objname.endswith('__'): objname = '_%s%s' % (oclass.__name__, objname) return objname == name for name, value in dict.items(): if name in ignore: continue self.assertHasattr(module, name, ignore) py_item = getattr(module, name) if isinstance(value, pyclbr.Function): self.assertIsInstance(py_item, (FunctionType, BuiltinFunctionType)) if py_item.__module__ != moduleName: continue self.assertEqual(py_item.__module__, value.module) else: self.assertIsInstance(py_item, type) if py_item.__module__ != moduleName: continue real_bases = [base.__name__ for base in py_item.__bases__] pyclbr_bases = [getattr(base, 'name', base) for base in value.super] try: self.assertListEq(real_bases, pyclbr_bases, ignore) except: print('class=%s' % py_item, file=sys.stderr) raise actualMethods = [] for m in py_item.__dict__.keys(): if ismethod(py_item, getattr(py_item, m), m): actualMethods.append(m) foundMethods = [] for m in value.methods.keys(): if m[:2] == '__' and m[-2:] != '__': foundMethods.append('_' + name + m) else: foundMethods.append(m) try: self.assertListEq(foundMethods, actualMethods, ignore) self.assertEqual(py_item.__module__, value.module) self.assertEqualsOrIgnored(py_item.__name__, value.name, ignore) except: print('class=%s' % py_item, file=sys.stderr) raise def defined_in(item, module): if isinstance(item, type): return item.__module__ == module.__name__ if isinstance(item, FunctionType): return item.__globals__ is module.__dict__ return False for name in dir(module): item = getattr(module, name) if isinstance(item, (type, FunctionType)): if defined_in(item, module): self.assertHaskey(dict, name, ignore)