#!/usr/bin/env python # -*- coding: utf-8 -*- __library__ = "pyflowctrl" __dependencies__ = [] __training_set__ = "" __links__ = [] __author__ = ["Andrey Usov ",] __version__ = "20120116" __all__ = ['PyMetaInfo',] __doc__ = '''Generate meta description for python module. Based on lib/pydoc.py''' import pkgutil import inspect from pydoc import locate, isdata, visiblename from pyflowctrl.core4 import Stream, Process, EmptyStream from pyflowctrl.core4 import WAITING, PROCESSING STREAM = {} class PyMetaInfo(Process): ''' Extact metadata information about module/class ''' input = Stream() output = Stream() def __init__(self): super(PyMetaInfo, self).__init__() #self.input = Stream() #self.output = Stream() def get_elements(self, obj, element_type): ''' get list of object's elements by type''' try: all = obj.__all__ except AttributeError: all = None elements = [] for key, value in inspect.getmembers(obj, element_type): if visiblename(key, all, value): elements.append((key, value)) return elements def get_classes(self, obj): ''' get list of classes ''' classes = [] for c in self.get_elements(obj, inspect.isclass): c = list(c) c.extend(c[1].__bases__) classes.append(tuple(c)) return classes def get_modpkgs(self, obj): ''' get list of module's packages ''' modpkgs = [] modpkgs_names = set() if hasattr(obj, '__path__'): for importer, modname, ispkg in pkgutil.iter_modules(obj.__path__): modpkgs_names.add(modname) if ispkg: modpkgs.append(modname + ' (package)') else: modpkgs.append(modname) modpkgs.sort() return modpkgs def get_metadata(self, obj): ''' get dictionary of object's metadata ''' metadata = {} if obj == None: return metadata metadata['name'] = obj.__name__ metadata['type'] = type(obj) metadata['description'] = inspect.getdoc(obj) or inspect.getcomments(obj) metadata['classes'] = self.get_classes(obj) metadata['funcs'] = self.get_elements(obj, inspect.isroutine) metadata['data'] = self.get_elements(obj, isdata) metadata['module_packages'] = self.get_modpkgs(obj) metadata['submodules'] = self.get_elements(obj, inspect.ismodule) if hasattr(obj, '__bases__'): metadata['based_on'] = obj.__bases__ cleared_meta = {} for k in metadata: if metadata[k]: cleared_meta[k] = metadata[k] return cleared_meta def main(self): while True: try: packet = self.input.get() except EmptyStream: yield WAITING continue obj = locate(packet.module) packet.meta = self.get_metadata(obj) self.output.put(packet) yield PROCESSING