⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modulegraph.py

📁 属性sosuo算法
💻 PY
📖 第 1 页 / 共 2 页
字号:
                self.msgout(2, "raise ImportError: Bad magic number", pathname)                raise ImportError, "Bad magic number in %s" % pathname            fp.read(4)            co = marshal.load(fp)            cls = CompiledModule        elif typ == imp.C_BUILTIN:            cls = BuiltinModule            co = None        else:            cls = Extension            co = None        m = self.createNode(cls, fqname)        m.filename = pathname        if co:            if self.replace_paths:                co = self.replace_paths_in_code(co)            m.code = co            self.scan_code(co, m)        self.msgout(2, "load_module ->", m)        return m    def _safe_import_hook(self, name, caller, fromlist):        # wrapper for self.import_hook() that won't raise ImportError        try:            m = self.import_hook(name, caller).pop()        except ImportError, msg:            self.msg(2, "ImportError:", str(msg))            m = self.createNode(MissingModule, name)        subs = set([m])        for sub in set(fromlist or ()):            if sub in m:                subs.add(m[sub])                continue            fullname = name + '.' + sub            sm = self.findNode(fullname)            if sm is None:                try:                    sm = self.import_hook(name, caller, [sub])                except ImportError, msg:                    self.msg(2, "ImportError:", str(msg))                    sm = self.createNode(MissingModule, fullname)                else:                    sm = self.findNode(fullname)            m[sub] = sm            if sm is not None:                self.createReference(sm, m)                subs.add(sm)        return subs    def scan_code(self, co, m):        code = co.co_code        n = len(code)        i = 0        fromlist = None        while i < n:            c = code[i]            i = i+1            op = ord(c)            if op >= dis.HAVE_ARGUMENT:                oparg = ord(code[i]) + ord(code[i+1])*256                i = i+2            if op == LOAD_CONST:                # An IMPORT_NAME is always preceded by a LOAD_CONST, it's                # a tuple of "from" names, or None for a regular import.                # The tuple may contain "*" for "from <mod> import *"                fromlist = co.co_consts[oparg]            elif op == IMPORT_NAME:                assert fromlist is None or type(fromlist) is tuple                name = co.co_names[oparg]                have_star = False                if fromlist is not None:                    fromlist = set(fromlist)                    if '*' in fromlist:                        fromlist.remove('*')                        have_star = True                self._safe_import_hook(name, m, fromlist)                if have_star:                    # We've encountered an "import *". If it is a Python module,                    # the code has already been parsed and we can suck out the                    # global names.                    mm = None                    if m.packagepath:                        # At this point we don't know whether 'name' is a                        # submodule of 'm' or a global module. Let's just try                        # the full name first.                        mm = self.findNode(m.identifier + '.' + name)                    if mm is None:                        mm = self.findNode(name)                    if mm is not None:                        m.globalnames.update(mm.globalnames)                        m.starimports.update(mm.starimports)                        if mm.code is None:                            m.starimports.add(name)                    else:                        m.starimports.add(name)            elif op in STORE_OPS:                # keep track of all global names that are assigned to                name = co.co_names[oparg]                m.globalnames.add(name)        for c in co.co_consts:            if isinstance(c, type(co)):                self.scan_code(c, m)    def load_package(self, fqname, pathname):        self.msgin(2, "load_package", fqname, pathname)        newname = replacePackageMap.get(fqname)        if newname:            fqname = newname        m = self.createNode(Package, fqname)        m.filename = pathname        m.packagepath = [pathname]        # As per comment at top of file, simulate runtime packagepath additions.        m.packagepath = m.packagepath + packagePathMap.get(fqname, [])        fp, buf, stuff = self.find_module("__init__", m.packagepath)        self.load_module(fqname, fp, buf, stuff)        self.msgout(2, "load_package ->", m)        return m    def find_module(self, name, path, parent=None):        if parent is not None:            # assert path is not None            fullname = parent.identifier+'.'+name        else:            fullname = name        node = self.findNode(fullname)        if node is not None:            self.msgout(3, "find_module -> already included?", node)            raise ImportError, name        if path is None:            if name in sys.builtin_module_names:                return (None, None, ("", "", imp.C_BUILTIN))            path = self.path        fp, buf, stuff = imp.find_module(name, path)        if buf:            buf = os.path.realpath(buf)        return (fp, buf, stuff)    def itergraphreport(self, name='G', flatpackages=()):        nodes = map(self.graph.describe_node, self.graph.iterdfs(self))        describe_edge = self.graph.describe_edge        edges = deque()        packagenodes = set()        packageidents = {}        nodetoident = {}        inpackages = {}        mainedges = set()        # XXX - implement        flatpackages = dict(flatpackages)        def nodevisitor(node, data, outgoing, incoming):            if not isinstance(data, Node):                return {'label': str(node)}            #if isinstance(d, (ExcludedModule, MissingModule, BadModule)):            #    return None            s = '<f0> ' + type(data).__name__            for i,v in izip(count(1), data.infoTuple()[:1]):                s += '| <f%d> %s' % (i,v)            return {'label':s, 'shape':'record'}        def edgevisitor(edge, data, head, tail):            if data == 'orphan':                return {'style':'dashed'}            elif data == 'pkgref':                return {'style':'dotted'}            return {}        yield 'digraph %s {\n' % (name,)        attr = dict(rankdir='LR', concentrate='true')        cpatt  = '%s="%s"'        for item in attr.iteritems():            yield '\t%s;\n' % (cpatt % item,)        # find all packages (subgraphs)        for (node, data, outgoing, incoming) in nodes:            nodetoident[node] = getattr(data, 'identifier', None)            if isinstance(data, Package):                packageidents[data.identifier] = node                inpackages[node] = set([node])                packagenodes.add(node)        # create sets for subgraph, write out descriptions        for (node, data, outgoing, incoming) in nodes:            # update edges            for edge in imap(describe_edge, outgoing):                edges.append(edge)            # describe node            yield '\t"%s" [%s];\n' % (                node,                ','.join([                    (cpatt % item) for item in                    nodevisitor(node, data, outgoing, incoming).iteritems()                ]),            )            inside = inpackages.get(node)            if inside is None:                inside = inpackages[node] = set()            ident = nodetoident[node]            if ident is None:                continue            pkgnode = packageidents.get(ident[:ident.rfind('.')])            if pkgnode is not None:                inside.add(pkgnode)        graph = []        subgraphs = {}        for key in packagenodes:            subgraphs[key] = []        while edges:            edge, data, head, tail = edges.popleft()            if ((head, tail)) in mainedges:                continue            mainedges.add((head, tail))            tailpkgs = inpackages[tail]            common = inpackages[head] & tailpkgs            if not common and tailpkgs:                usepkgs = sorted(tailpkgs)                if len(usepkgs) != 1 or usepkgs[0] != tail:                    edges.append((edge, data, head, usepkgs[0]))                    edges.append((edge, 'pkgref', usepkgs[-1], tail))                    continue            if common:                common = common.pop()                if tail == common:                    edges.append((edge, data, tail, head))                elif head == common:                    subgraphs[common].append((edge, 'pkgref', head, tail))                else:                    edges.append((edge, data, common, head))                    edges.append((edge, data, common, tail))            else:                graph.append((edge, data, head, tail))        def do_graph(edges, tabs):            edgestr = tabs + '"%s" -> "%s" [%s];\n'            # describe edge            for (edge, data, head, tail) in edges:                attribs = edgevisitor(edge, data, head, tail)                yield edgestr % (                    head,                    tail,                    ','.join([(cpatt % item) for item in attribs.iteritems()]),                )        for g, edges in subgraphs.iteritems():            yield '\tsubgraph "cluster_%s" {\n' % (g,)            yield '\t\tlabel="%s";\n' % (nodetoident[g],)            for s in do_graph(edges, '\t\t'):                yield s            yield '\t}\n'        for s in do_graph(graph, '\t'):            yield s        yield '}\n'    def graphreport(self, fileobj=None, flatpackages=()):        if fileobj is None:            fileobj = sys.stdout        fileobj.writelines(self.itergraphreport(flatpackages=flatpackages))    def report(self):        """Print a report to stdout, listing the found modules with their        paths, as well as modules that are missing, or seem to be missing.        """        print        print "%-15s %-25s %s" % ("Class", "Name", "File")        print "%-15s %-25s %s" % ("----", "----", "----")        # Print modules found        sorted = [(os.path.basename(mod.identifier), mod) for mod in self.flatten()]        sorted.sort()        for (name, m) in sorted:            print "%-15s %-25s %s" % (type(m).__name__, name, m.filename or "")    def replace_paths_in_code(self, co):        new_filename = original_filename = os.path.normpath(co.co_filename)        for f, r in self.replace_paths:            f = os.path.join(f, '')            r = os.path.join(r, '')            if original_filename.startswith(f):                new_filename = r + original_filename[len(f):]                break        consts = list(co.co_consts)        for i in range(len(consts)):            if isinstance(consts[i], type(co)):                consts[i] = self.replace_paths_in_code(consts[i])        return new.code(co.co_argcount, co.co_nlocals, co.co_stacksize,                         co.co_flags, co.co_code, tuple(consts), co.co_names,                         co.co_varnames, new_filename, co.co_name,                         co.co_firstlineno, co.co_lnotab,                         co.co_freevars, co.co_cellvars)def main():    # Parse command line    import getopt    try:        opts, args = getopt.getopt(sys.argv[1:], "dgmp:qx:")    except getopt.error, msg:        print msg        return    # Process options    debug = 1    domods = 0    dodot = False    addpath = []    exclude = []    for o, a in opts:        if o == '-d':            debug = debug + 1        if o == '-m':            domods = 1        if o == '-p':            addpath = addpath + a.split(os.pathsep)        if o == '-q':            debug = 0        if o == '-x':            exclude.append(a)        if o == '-g':            dodot = True    # Provide default arguments    if not args:        script = "hello.py"    else:        script = args[0]    # Set the path based on sys.path and the script directory    path = sys.path[:]    path[0] = os.path.dirname(script)    path = addpath + path    if debug > 1:        print "path:"        for item in path:            print "   ", repr(item)    # Create the module finder and turn its crank    mf = ModuleGraph(path, debug, exclude)    for arg in args[1:]:        if arg == '-m':            domods = 1            continue        if domods:            if arg[-2:] == '.*':                mf.import_hook(arg[:-2], None, ["*"])            else:                mf.import_hook(arg)        else:            mf.run_script(arg)    mf.run_script(script)    if dodot:        mf.graphreport()    else:        mf.report()    return mf  # for -i debuggingif __name__ == '__main__':    try:        mf = main()    except KeyboardInterrupt:        print "\n[interrupt]"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -