Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Unified Diff: tools/telemetry/third_party/modulegraph/modulegraph/modulegraph.py

Issue 1647513002: Delete tools/telemetry. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/third_party/modulegraph/modulegraph/modulegraph.py
diff --git a/tools/telemetry/third_party/modulegraph/modulegraph/modulegraph.py b/tools/telemetry/third_party/modulegraph/modulegraph/modulegraph.py
deleted file mode 100644
index 2795cc416196318324b7db4bfff26950aa1310ba..0000000000000000000000000000000000000000
--- a/tools/telemetry/third_party/modulegraph/modulegraph/modulegraph.py
+++ /dev/null
@@ -1,1686 +0,0 @@
-"""
-Find modules used by a script, using bytecode analysis.
-
-Based on the stdlib modulefinder by Thomas Heller and Just van Rossum,
-but uses a graph data structure and 2.3 features
-
-XXX: Verify all calls to import_hook (and variants) to ensure that
-imports are done in the right way.
-"""
-from __future__ import absolute_import, print_function
-
-import pkg_resources
-
-import dis
-import imp
-import marshal
-import os
-import sys
-import struct
-import zipimport
-import re
-from collections import deque, namedtuple
-import ast
-
-from altgraph.ObjectGraph import ObjectGraph
-from altgraph import GraphError
-
-from itertools import count
-
-from modulegraph import util
-from modulegraph import zipio
-
-if sys.version_info[0] == 2:
- from StringIO import StringIO as BytesIO
- from StringIO import StringIO
- from urllib import pathname2url
- def _Bchr(value):
- return chr(value)
-
-else:
- from urllib.request import pathname2url
- from io import BytesIO, StringIO
-
- def _Bchr(value):
- return value
-
-
-# File open mode for reading (univeral newlines)
-if sys.version_info[0] == 2:
- _READ_MODE = "rU"
-else:
- _READ_MODE = "r"
-
-
-
-
-# Modulegraph does a good job at simulating Python's, but it can not
-# handle packagepath modifications packages make at runtime. Therefore there
-# is a mechanism whereby you can register extra paths in this map for a
-# package, and it will be honored.
-#
-# Note this is a mapping is lists of paths.
-_packagePathMap = {}
-
-# Prefix used in magic .pth files used by setuptools to create namespace
-# packages without an __init__.py file.
-#
-# The value is a list of such prefixes as the prefix varies with versions of
-# setuptools.
-_SETUPTOOLS_NAMESPACEPKG_PTHs=(
- "import sys,types,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('",
- "import sys,new,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('",
- "import sys, types, os;p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('",
-)
-
-
-def _namespace_package_path(fqname, pathnames, path=None):
- """
- Return the __path__ for the python package in *fqname*.
-
- This function uses setuptools metadata to extract information
- about namespace packages from installed eggs.
- """
- working_set = pkg_resources.WorkingSet(path)
-
- path = list(pathnames)
-
- for dist in working_set:
- if dist.has_metadata('namespace_packages.txt'):
- namespaces = dist.get_metadata(
- 'namespace_packages.txt').splitlines()
- if fqname in namespaces:
- nspath = os.path.join(dist.location, *fqname.split('.'))
- if nspath not in path:
- path.append(nspath)
-
- return path
-
-_strs = re.compile(r'''^\s*["']([A-Za-z0-9_]+)["'],?\s*''') # "<- emacs happy
-
-def _eval_str_tuple(value):
- """
- Input is the repr of a tuple of strings, output
- is that tuple.
-
- This only works with a tuple where the members are
- python identifiers.
- """
- if not (value.startswith('(') and value.endswith(')')):
- raise ValueError(value)
-
- orig_value = value
- value = value[1:-1]
-
- result = []
- while value:
- m = _strs.match(value)
- if m is None:
- raise ValueError(orig_value)
-
- result.append(m.group(1))
- value = value[len(m.group(0)):]
-
- return tuple(result)
-
-def _path_from_importerror(exc, default):
- # This is a hack, but sadly enough the necessary information
- # isn't available otherwise.
- m = re.match('^No module named (\S+)$', str(exc))
- if m is not None:
- return m.group(1)
-
- return default
-
-def os_listdir(path):
- """
- Deprecated name
- """
- warnings.warn("Use zipio.listdir instead of os_listdir",
- DeprecationWarning)
- return zipio.listdir(path)
-
-
-def _code_to_file(co):
- """ Convert code object to a .pyc pseudo-file """
- return BytesIO(
- imp.get_magic() + b'\0\0\0\0' + marshal.dumps(co))
-
-
-def find_module(name, path=None):
- """
- A version of imp.find_module that works with zipped packages.
- """
- if path is None:
- path = sys.path
-
- # Support for the PEP302 importer for normal imports:
- # - Python 2.5 has pkgutil.ImpImporter
- # - In setuptools 0.7 and later there's _pkgutil.ImpImporter
- # - In earlier setuptools versions you pkg_resources.ImpWrapper
- #
- # XXX: This is a bit of a hack, should check if we can just rely on
- # PEP302's get_code() method with all recent versions of pkgutil and/or
- # setuptools (setuptools 0.6.latest, setuptools trunk and python2.[45])
- #
- # For python 3.3 this code should be replaced by code using importlib,
- # for python 3.2 and 2.7 this should be cleaned up a lot.
- try:
- from pkgutil import ImpImporter
- except ImportError:
- try:
- from _pkgutil import ImpImporter
- except ImportError:
- ImpImporter = pkg_resources.ImpWrapper
-
- namespace_path =[]
- fp = None
- for entry in path:
- importer = pkg_resources.get_importer(entry)
- if importer is None:
- continue
-
- if sys.version_info[:2] >= (3,3) and hasattr(importer, 'find_loader'):
- loader, portions = importer.find_loader(name)
-
- else:
- loader = importer.find_module(name)
- portions = []
-
- namespace_path.extend(portions)
-
- if loader is None: continue
-
- if isinstance(importer, ImpImporter):
- filename = loader.filename
- if filename.endswith('.pyc') or filename.endswith('.pyo'):
- fp = open(filename, 'rb')
- description = ('.pyc', 'rb', imp.PY_COMPILED)
- return (fp, filename, description)
-
- elif filename.endswith('.py'):
- if sys.version_info[0] == 2:
- fp = open(filename, _READ_MODE)
- else:
- with open(filename, 'rb') as fp:
- encoding = util.guess_encoding(fp)
-
- fp = open(filename, _READ_MODE, encoding=encoding)
- description = ('.py', _READ_MODE, imp.PY_SOURCE)
- return (fp, filename, description)
-
- else:
- for _sfx, _mode, _type in imp.get_suffixes():
- if _type == imp.C_EXTENSION and filename.endswith(_sfx):
- description = (_sfx, 'rb', imp.C_EXTENSION)
- break
- else:
- description = ('', '', imp.PKG_DIRECTORY)
-
- return (None, filename, description)
-
- if hasattr(loader, 'path'):
- if loader.path.endswith('.pyc') or loader.path.endswith('.pyo'):
- fp = open(loader.path, 'rb')
- description = ('.pyc', 'rb', imp.PY_COMPILED)
- return (fp, loader.path, description)
-
-
- if hasattr(loader, 'get_source'):
- source = loader.get_source(name)
- fp = StringIO(source)
- co = None
-
- else:
- source = None
-
- if source is None:
- if hasattr(loader, 'get_code'):
- co = loader.get_code(name)
- fp = _code_to_file(co)
-
- else:
- fp = None
- co = None
-
- pathname = os.path.join(entry, *name.split('.'))
-
- if isinstance(loader, zipimport.zipimporter):
- # Check if this happens to be a wrapper module introduced by
- # setuptools, if it is we return the actual extension.
- zn = '/'.join(name.split('.'))
- for _sfx, _mode, _type in imp.get_suffixes():
- if _type == imp.C_EXTENSION:
- p = loader.prefix + zn + _sfx
- if loader._files is None:
- loader_files = zipimport._zip_directory_cache[loader.archive]
- else:
- loader_files = loader._files
-
- if p in loader_files:
- description = (_sfx, 'rb', imp.C_EXTENSION)
- return (None, pathname + _sfx, description)
-
- if hasattr(loader, 'is_package') and loader.is_package(name):
- return (None, pathname, ('', '', imp.PKG_DIRECTORY))
-
- if co is None:
- if hasattr(loader, 'path'):
- filename = loader.path
- elif hasattr(loader, 'get_filename'):
- filename = loader.get_filename(name)
- if source is not None:
- if filename.endswith(".pyc") or filename.endswith(".pyo"):
- filename = filename[:-1]
- else:
- filename = None
-
- if filename is not None and (filename.endswith('.py') or filename.endswith('.pyw')):
- return (fp, filename, ('.py', 'rU', imp.PY_SOURCE))
- else:
- if fp is not None:
- fp.close()
- return (None, filename, (os.path.splitext(filename)[-1], 'rb', imp.C_EXTENSION))
-
- else:
- if hasattr(loader, 'path'):
- return (fp, loader.path, ('.pyc', 'rb', imp.PY_COMPILED))
- else:
- return (fp, pathname + '.pyc', ('.pyc', 'rb', imp.PY_COMPILED))
-
- if namespace_path:
- if fp is not None:
- fp.close()
- return (None, namespace_path[0], ('', namespace_path, imp.PKG_DIRECTORY))
-
- raise ImportError(name)
-
-def moduleInfoForPath(path):
- for (ext, readmode, typ) in imp.get_suffixes():
- if path.endswith(ext):
- return os.path.basename(path)[:-len(ext)], readmode, typ
- return None
-
-# A Public interface
-import warnings
-def AddPackagePath(packagename, path):
- warnings.warn("Use addPackagePath instead of AddPackagePath",
- DeprecationWarning)
-
- addPackagePath(packagename, path)
-
-def addPackagePath(packagename, path):
- paths = _packagePathMap.get(packagename, [])
- paths.append(path)
- _packagePathMap[packagename] = paths
-
-_replacePackageMap = {}
-
-# This ReplacePackage mechanism allows modulefinder to work around the
-# way the _xmlplus package injects itself under the name "xml" into
-# sys.modules at runtime by calling ReplacePackage("_xmlplus", "xml")
-# before running ModuleGraph.
-def ReplacePackage(oldname, newname):
- warnings.warn("use replacePackage instead of ReplacePackage",
- DeprecationWarning)
- replacePackage(oldname, newname)
-
-def replacePackage(oldname, newname):
- _replacePackageMap[oldname] = newname
-
-
-class DependencyInfo (namedtuple("DependencyInfo", ["conditional", "function", "tryexcept", "fromlist"])):
- __slots__ = ()
-
- def _merged(self, other):
- if (not self.conditional and not self.function and not self.tryexcept) \
- or (not other.conditional and not other.function and not other.tryexcept):
- return DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=self.fromlist and other.fromlist)
-
- else:
- return DependencyInfo(
- conditional=self.conditional or other.conditional,
- function=self.function or other.function,
- tryexcept=self.tryexcept or other.tryexcept,
- fromlist=self.fromlist and other.fromlist)
-
-
-class Node(object):
- def __init__(self, identifier):
- self.debug = 0
- self.graphident = identifier
- self.identifier = identifier
- self._namespace = {}
- self.filename = None
- self.packagepath = None
- self.code = None
- # The set of global names that are assigned to in the module.
- # This includes those names imported through starimports of
- # Python modules.
- self.globalnames = set()
- # The set of starimports this module did that could not be
- # resolved, ie. a starimport from a non-Python module.
- self.starimports = set()
-
- def __contains__(self, name):
- return name in self._namespace
-
- def __getitem__(self, name):
- return self._namespace[name]
-
- def __setitem__(self, name, value):
- self._namespace[name] = value
-
- def get(self, *args):
- return self._namespace.get(*args)
-
- def __cmp__(self, other):
- try:
- otherIdent = getattr(other, 'graphident')
- except AttributeError:
- return NotImplemented
-
- return cmp(self.graphident, otherIdent)
-
- def __eq__(self, other):
- try:
- otherIdent = getattr(other, 'graphident')
- except AttributeError:
- return False
-
- return self.graphident == otherIdent
-
- def __ne__(self, other):
- try:
- otherIdent = getattr(other, 'graphident')
- except AttributeError:
- return True
-
- return self.graphident != otherIdent
-
- def __lt__(self, other):
- try:
- otherIdent = getattr(other, 'graphident')
- except AttributeError:
- return NotImplemented
-
- return self.graphident < otherIdent
-
- def __le__(self, other):
- try:
- otherIdent = getattr(other, 'graphident')
- except AttributeError:
- return NotImplemented
-
- return self.graphident <= otherIdent
-
- def __gt__(self, other):
- try:
- otherIdent = getattr(other, 'graphident')
- except AttributeError:
- return NotImplemented
-
- return self.graphident > otherIdent
-
- def __ge__(self, other):
- try:
- otherIdent = getattr(other, 'graphident')
- except AttributeError:
- return NotImplemented
-
- return self.graphident >= otherIdent
-
-
- def __hash__(self):
- return hash(self.graphident)
-
- def infoTuple(self):
- return (self.identifier,)
-
- def __repr__(self):
- return '%s%r' % (type(self).__name__, self.infoTuple())
-
-class Alias(str):
- pass
-
-class AliasNode(Node):
- def __init__(self, name, node):
- super(AliasNode, self).__init__(name)
- for k in 'identifier', 'packagepath', '_namespace', 'globalnames', 'starimports':
- setattr(self, k, getattr(node, k, None))
-
- def infoTuple(self):
- return (self.graphident, self.identifier)
-
-class BadModule(Node):
- pass
-
-class ExcludedModule(BadModule):
- pass
-
-class MissingModule(BadModule):
- pass
-
-class Script(Node):
- def __init__(self, filename):
- super(Script, self).__init__(filename)
- self.filename = filename
-
- def infoTuple(self):
- return (self.filename,)
-
-class BaseModule(Node):
- def __init__(self, name, filename=None, path=None):
- super(BaseModule, self).__init__(name)
- self.filename = filename
- self.packagepath = path
-
- def infoTuple(self):
- return tuple(filter(None, (self.identifier, self.filename, self.packagepath)))
-
-class BuiltinModule(BaseModule):
- pass
-
-class SourceModule(BaseModule):
- pass
-
-class InvalidSourceModule(SourceModule):
- pass
-
-class CompiledModule(BaseModule):
- pass
-
-class InvalidCompiledModule(BaseModule):
- pass
-
-class Package(BaseModule):
- pass
-
-class NamespacePackage(Package):
- pass
-
-class Extension(BaseModule):
- pass
-
-class FlatPackage(BaseModule): # nocoverage
- def __init__(self, *args, **kwds):
- warnings.warn("This class will be removed in a future version of modulegraph",
- DeprecationWarning)
- super(FlatPackage, *args, **kwds)
-
-class ArchiveModule(BaseModule): # nocoverage
- def __init__(self, *args, **kwds):
- warnings.warn("This class will be removed in a future version of modulegraph",
- DeprecationWarning)
- super(FlatPackage, *args, **kwds)
-
-# HTML templates for ModuleGraph generator
-header = """\
-<html>
- <head>
- <title>%(TITLE)s</title>
- <style>
- .node { margin:1em 0; }
- </style>
- </head>
- <body>
- <h1>%(TITLE)s</h1>"""
-entry = """
-<div class="node">
- <a name="%(NAME)s" />
- %(CONTENT)s
-</div>"""
-contpl = """<tt>%(NAME)s</tt> %(TYPE)s"""
-contpl_linked = """\
-<a target="code" href="%(URL)s" type="text/plain"><tt>%(NAME)s</tt></a>"""
-imports = """\
- <div class="import">
-%(HEAD)s:
- %(LINKS)s
- </div>
-"""
-footer = """
- </body>
-</html>"""
-
-def _ast_names(names):
- result = []
- for nm in names:
- if isinstance(nm, ast.alias):
- result.append(nm.name)
- else:
- result.append(nm)
- return result
-
-
-if sys.version_info[0] == 2:
- DEFAULT_IMPORT_LEVEL= -1
-else:
- DEFAULT_IMPORT_LEVEL= 0
-
-class _Visitor (ast.NodeVisitor):
- def __init__(self, graph, module):
- self._graph = graph
- self._module = module
- self._level = DEFAULT_IMPORT_LEVEL
- self._in_if = [False]
- self._in_def = [False]
- self._in_tryexcept = [False]
-
- @property
- def in_if(self):
- return self._in_if[-1]
-
- @property
- def in_def(self):
- return self._in_def[-1]
-
- @property
- def in_tryexcept(self):
- return self._in_tryexcept[-1]
-
- def _process_import(self, name, fromlist, level):
-
- if sys.version_info[0] == 2:
- if name == '__future__' and 'absolute_import' in (fromlist or ()):
- self._level = 0
-
- have_star = False
- if fromlist is not None:
- fromlist = set(fromlist)
- if '*' in fromlist:
- fromlist.remove('*')
- have_star = True
-
- imported_module = self._graph._safe_import_hook(name,
- self._module, fromlist, level, attr=DependencyInfo(
- conditional=self.in_if,
- tryexcept=self.in_tryexcept,
- function=self.in_def,
- fromlist=False,
- ))[0]
- if have_star:
- self._module.globalnames.update(imported_module.globalnames)
- self._module.starimports.update(imported_module.starimports)
- if imported_module.code is None:
- self._module.starimports.add(name)
-
-
- def visit_Import(self, node):
- for nm in _ast_names(node.names):
- self._process_import(nm, None, self._level)
-
- def visit_ImportFrom(self, node):
- level = node.level if node.level != 0 else self._level
- self._process_import(node.module or '', _ast_names(node.names), level)
-
- def visit_If(self, node):
- self._in_if.append(True)
- self.generic_visit(node)
- self._in_if.pop()
-
- def visit_FunctionDef(self, node):
- self._in_def.append(True)
- self.generic_visit(node)
- self._in_def.pop()
-
- def visit_Try(self, node):
- self._in_tryexcept.append(True)
- self.generic_visit(node)
- self._in_tryexcept.pop()
-
- def visit_ExceptHandler(self, node):
- self._in_tryexcept.append(True)
- self.generic_visit(node)
- self._in_tryexcept.pop()
-
- def visit_TryExcept(self, node):
- self._in_tryexcept.append(True)
- self.generic_visit(node)
- self._in_tryexcept.pop()
-
- def visit_ExceptHandler(self, node):
- self._in_tryexcept.append(True)
- self.generic_visit(node)
- self._in_tryexcept.pop()
-
- def visit_Expression(self, node):
- # Expression node's cannot contain import statements or
- # other nodes that are relevant for us.
- pass
-
- # Expression isn't actually used as such in AST trees,
- # therefore define visitors for all kinds of expression nodes.
- visit_BoolOp = visit_Expression
- visit_BinOp = visit_Expression
- visit_UnaryOp = visit_Expression
- visit_Lambda = visit_Expression
- visit_IfExp = visit_Expression
- visit_Dict = visit_Expression
- visit_Set = visit_Expression
- visit_ListComp = visit_Expression
- visit_SetComp = visit_Expression
- visit_ListComp = visit_Expression
- visit_GeneratorExp = visit_Expression
- visit_Compare = visit_Expression
- visit_Yield = visit_Expression
- visit_YieldFrom = visit_Expression
- visit_Await = visit_Expression
- visit_Call = visit_Expression
-
-
-
-class ModuleGraph(ObjectGraph):
- def __init__(self, path=None, excludes=(), replace_paths=(), implies=(), graph=None, debug=0):
- super(ModuleGraph, self).__init__(graph=graph, debug=debug)
- if path is None:
- path = sys.path
- self.path = path
- self.lazynodes = {}
- # excludes is stronger than implies
- self.lazynodes.update(dict(implies))
- for m in excludes:
- self.lazynodes[m] = None
- self.replace_paths = replace_paths
-
- self.nspackages = self._calc_setuptools_nspackages()
-
- def _calc_setuptools_nspackages(self):
- # Setuptools has some magic handling for namespace
- # packages when using 'install --single-version-externally-managed'
- # (used by system packagers and also by pip)
- #
- # When this option is used namespace packages are writting to
- # disk *without* an __init__.py file, which means the regular
- # import machinery will not find them.
- #
- # We therefore explicitly look for the hack used by
- # setuptools to get this kind of namespace packages to work.
-
- pkgmap = {}
-
- try:
- from pkgutil import ImpImporter
- except ImportError:
- try:
- from _pkgutil import ImpImporter
- except ImportError:
- ImpImporter = pkg_resources.ImpWrapper
-
- if sys.version_info[:2] >= (3,3):
- import importlib.machinery
- ImpImporter = importlib.machinery.FileFinder
-
- for entry in self.path:
- importer = pkg_resources.get_importer(entry)
-
- if isinstance(importer, ImpImporter):
- try:
- ldir = os.listdir(entry)
- except os.error:
- continue
-
- for fn in ldir:
- if fn.endswith('-nspkg.pth'):
- fp = open(os.path.join(entry, fn), 'rU')
- try:
- for ln in fp:
- for pfx in _SETUPTOOLS_NAMESPACEPKG_PTHs:
- if ln.startswith(pfx):
- try:
- start = len(pfx)-2
- stop = ln.index(')', start)+1
- except ValueError:
- continue
-
- pkg = _eval_str_tuple(ln[start:stop])
- identifier = ".".join(pkg)
- subdir = os.path.join(entry, *pkg)
- if os.path.exists(os.path.join(subdir, '__init__.py')):
- # There is a real __init__.py, ignore the setuptools hack
- continue
-
- if identifier in pkgmap:
- pkgmap[identifier].append(subdir)
- else:
- pkgmap[identifier] = [subdir]
- break
- finally:
- fp.close()
-
- return pkgmap
-
- def implyNodeReference(self, node, other, edge_data=None):
- """
- Imply that one node depends on another.
- other may be a module name or another node.
-
- For use by extension modules and tricky import code
- """
- if isinstance(other, Node):
- self._updateReference(node, other, edge_data)
-
- else:
- if isinstance(other, tuple):
- raise ValueError(other)
-
- others = self._safe_import_hook(other, node, None)
- for other in others:
- self._updateReference(node, other, edge_data)
-
-
- def getReferences(self, fromnode):
- """
- Yield all nodes that 'fromnode' dependes on (that is,
- all modules that 'fromnode' imports.
- """
- node = self.findNode(fromnode)
- out_edges, _ = self.get_edges(node)
- return out_edges
-
- def getReferers(self, tonode, collapse_missing_modules=True):
- node = self.findNode(tonode)
- _, in_edges = self.get_edges(node)
-
- if collapse_missing_modules:
- for n in in_edges:
- if isinstance(n, MissingModule):
- for n in self.getReferers(n, False):
- yield n
-
- else:
- yield n
-
- else:
- for n in in_edges:
- yield n
-
- def hasEdge(self, fromnode, tonode):
- """ Return True iff there is an edge from 'fromnode' to 'tonode' """
- fromnode = self.findNode(fromnode)
- tonode = self.findNode(tonode)
-
- return self.graph.edge_by_node(fromnode, tonode) is not None
-
-
- def foldReferences(self, packagenode):
- """
- Create edges to/from 'packagenode' based on the
- edges to/from modules in package. The module nodes
- are then hidden.
- """
- pkg = self.findNode(packagenode)
-
- for n in self.nodes():
- if not n.identifier.startswith(pkg.identifier + '.'):
- continue
-
- iter_out, iter_inc = n.get_edges()
- for other in iter_out:
- if other.identifier.startswith(pkg.identifier + '.'):
- continue
-
- if not self.hasEdge(pkg, other):
- # Ignore circular dependencies
- self._updateReference(pkg, other, 'pkg-internal-import')
-
- for other in iter_in:
- if other.identifier.startswith(pkg.identifier + '.'):
- # Ignore circular dependencies
- continue
-
- if not self.hasEdge(other, pkg):
- self._updateReference(other, pkg, 'pkg-import')
-
- self.graph.hide_node(n)
-
- # TODO: unfoldReferences(pkg) that restore the submodule nodes and
- # removes 'pkg-import' and 'pkg-internal-import' edges. Care should
- # be taken to ensure that references are correct if multiple packages
- # are folded and then one of them in unfolded
-
-
- def _updateReference(self, fromnode, tonode, edge_data):
- try:
- ed = self.edgeData(fromnode, tonode)
- except (KeyError, GraphError): # XXX: Why 'GraphError'
- return self.createReference(fromnode, tonode, edge_data)
-
- if not (isinstance(ed, DependencyInfo) and isinstance(edge_data, DependencyInfo)):
- self.updateEdgeData(fromnode, tonode, edge_data)
- else:
- self.updateEdgeData(fromnode, tonode, ed._merged(edge_data))
-
-
- def createReference(self, fromnode, tonode, edge_data='direct'):
- """
- Create a reference from fromnode to tonode
- """
- return super(ModuleGraph, self).createReference(fromnode, tonode, edge_data=edge_data)
-
- def findNode(self, name):
- """
- Find a node by identifier. If a node by that identifier exists,
- it will be returned.
-
- If a lazy node exists by that identifier with no dependencies (excluded),
- it will be instantiated and returned.
-
- If a lazy node exists by that identifier with dependencies, it and its
- dependencies will be instantiated and scanned for additional dependencies.
- """
- data = super(ModuleGraph, self).findNode(name)
- if data is not None:
- return data
- if name in self.lazynodes:
- deps = self.lazynodes.pop(name)
- if deps is None:
- # excluded module
- m = self.createNode(ExcludedModule, name)
- elif isinstance(deps, Alias):
- other = self._safe_import_hook(deps, None, None).pop()
- m = self.createNode(AliasNode, name, other)
- self.implyNodeReference(m, other)
-
- else:
- m = self._safe_import_hook(name, None, None).pop()
- for dep in deps:
- self.implyNodeReference(m, dep)
- return m
-
- if name in self.nspackages:
- # name is a --single-version-externally-managed
- # namespace package (setuptools/distribute)
- pathnames = self.nspackages.pop(name)
- m = self.createNode(NamespacePackage, name)
-
- # FIXME: The filename must be set to a string to ensure that py2app
- # works, it is not clear yet why that is. Setting to None would be
- # cleaner.
- m.filename = '-'
- m.packagepath = _namespace_package_path(name, pathnames, self.path)
-
- # As per comment at top of file, simulate runtime packagepath additions.
- m.packagepath = m.packagepath + _packagePathMap.get(name, [])
- return m
-
- return None
-
- def run_script(self, pathname, caller=None):
- """
- Create a node by path (not module name). It is expected to be a Python
- source file, and will be scanned for dependencies.
- """
- self.msg(2, "run_script", pathname)
- pathname = os.path.realpath(pathname)
- m = self.findNode(pathname)
- if m is not None:
- return m
-
- if sys.version_info[0] != 2:
- with open(pathname, 'rb') as fp:
- encoding = util.guess_encoding(fp)
-
- with open(pathname, _READ_MODE, encoding=encoding) as fp:
- contents = fp.read() + '\n'
-
- else:
- with open(pathname, _READ_MODE) as fp:
- contents = fp.read() + '\n'
-
- co = compile(contents, pathname, 'exec', ast.PyCF_ONLY_AST, True)
- m = self.createNode(Script, pathname)
- self._updateReference(caller, m, None)
- self._scan_code(co, m)
- m.code = compile(co, pathname, 'exec', 0, True)
- if self.replace_paths:
- m.code = self._replace_paths_in_code(m.code)
- return m
-
- def import_hook(self, name, caller=None, fromlist=None, level=DEFAULT_IMPORT_LEVEL, attr=None):
- """
- Import a module
-
- Return the set of modules that are imported
- """
- self.msg(3, "import_hook", name, caller, fromlist, level)
- parent = self._determine_parent(caller)
- q, tail = self._find_head_package(parent, name, level)
- m = self._load_tail(q, tail)
- modules = [m]
- if fromlist and m.packagepath:
- for s in self._ensure_fromlist(m, fromlist):
- if s not in modules:
- modules.append(s)
- for m in modules:
- self._updateReference(caller, m, edge_data=attr)
- return modules
-
- def _determine_parent(self, caller):
- """
- Determine the package containing a node
- """
- self.msgin(4, "determine_parent", caller)
- parent = None
- if caller:
- pname = caller.identifier
-
- if isinstance(caller, Package):
- parent = caller
-
- elif '.' in pname:
- pname = pname[:pname.rfind('.')]
- parent = self.findNode(pname)
-
- elif caller.packagepath:
- # XXX: I have no idea why this line
- # is necessary.
- parent = self.findNode(pname)
-
-
- self.msgout(4, "determine_parent ->", parent)
- return parent
-
- def _find_head_package(self, parent, name, level=DEFAULT_IMPORT_LEVEL):
- """
- Given a calling parent package and an import name determine the containing
- package for the name
- """
- self.msgin(4, "find_head_package", parent, name, level)
- if '.' in name:
- head, tail = name.split('.', 1)
- else:
- head, tail = name, ''
-
- if level == -1:
- if parent:
- qname = parent.identifier + '.' + head
- else:
- qname = head
-
- elif level == 0:
- qname = head
-
- # Absolute import, ignore the parent
- parent = None
-
- else:
- if parent is None:
- self.msg(2, "Relative import outside of package")
- raise ImportError("Relative import outside of package (name=%r, parent=%r, level=%r)"%(name, parent, level))
-
- for i in range(level-1):
- if '.' not in parent.identifier:
- self.msg(2, "Relative import outside of package")
- raise ImportError("Relative import outside of package (name=%r, parent=%r, level=%r)"%(name, parent, level))
-
- p_fqdn = parent.identifier.rsplit('.', 1)[0]
- new_parent = self.findNode(p_fqdn)
- if new_parent is None:
- self.msg(2, "Relative import outside of package")
- raise ImportError("Relative import outside of package (name=%r, parent=%r, level=%r)"%(name, parent, level))
-
- assert new_parent is not parent, (new_parent, parent)
- parent = new_parent
-
- if head:
- qname = parent.identifier + '.' + head
- else:
- qname = parent.identifier
-
-
- q = self._import_module(head, qname, parent)
- if q:
- self.msgout(4, "find_head_package ->", (q, tail))
- return q, tail
- if parent:
- qname = head
- parent = None
- q = self._import_module(head, qname, parent)
- if q:
- self.msgout(4, "find_head_package ->", (q, tail))
- return q, tail
- self.msgout(4, "raise ImportError: No module named", qname)
- raise ImportError("No module named " + qname)
-
- def _load_tail(self, mod, tail):
- self.msgin(4, "load_tail", mod, tail)
- result = mod
- while tail:
- i = tail.find('.')
- if i < 0: i = len(tail)
- head, tail = tail[:i], tail[i+1:]
- mname = "%s.%s" % (result.identifier, head)
- result = self._import_module(head, mname, result)
- if result is None:
- result = self.createNode(MissingModule, mname)
- #self.msgout(4, "raise ImportError: No module named", mname)
- #raise ImportError("No module named " + mname)
- self.msgout(4, "load_tail ->", result)
- return result
-
- def _ensure_fromlist(self, m, fromlist):
- fromlist = set(fromlist)
- self.msg(4, "ensure_fromlist", m, fromlist)
- if '*' in fromlist:
- fromlist.update(self._find_all_submodules(m))
- fromlist.remove('*')
- for sub in fromlist:
- submod = m.get(sub)
- if submod is None:
- if sub in m.globalnames:
- # Name is a global in the module
- continue
- # XXX: ^^^ need something simular for names imported
- # by 'm'.
-
- fullname = m.identifier + '.' + sub
- submod = self._import_module(sub, fullname, m)
- if submod is None:
- raise ImportError("No module named " + fullname)
- yield submod
-
- def _find_all_submodules(self, m):
- if not m.packagepath:
- return
- # 'suffixes' used to be a list hardcoded to [".py", ".pyc", ".pyo"].
- # But we must also collect Python extension modules - although
- # we cannot separate normal dlls from Python extensions.
- suffixes = [triple[0] for triple in imp.get_suffixes()]
- for path in m.packagepath:
- try:
- names = zipio.listdir(path)
- except (os.error, IOError):
- self.msg(2, "can't list directory", path)
- continue
- for info in (moduleInfoForPath(p) for p in names):
- if info is None: continue
- if info[0] != '__init__':
- yield info[0]
-
- def _import_module(self, partname, fqname, parent):
- # XXX: Review me for use with absolute imports.
- self.msgin(3, "import_module", partname, fqname, parent)
- m = self.findNode(fqname)
- if m is not None:
- self.msgout(3, "import_module ->", m)
- if parent:
- self._updateReference(m, parent, edge_data=DependencyInfo(
- conditional=False, fromlist=False, function=False, tryexcept=False
- ))
- return m
-
- if parent and parent.packagepath is None:
- self.msgout(3, "import_module -> None")
- return None
-
- try:
- searchpath = None
- if parent is not None and parent.packagepath:
- searchpath = parent.packagepath
-
- fp, pathname, stuff = self._find_module(partname,
- searchpath, parent)
-
- except ImportError:
- self.msgout(3, "import_module ->", None)
- return None
-
- try:
- m = self._load_module(fqname, fp, pathname, stuff)
-
- finally:
- if fp is not None:
- fp.close()
-
- if parent:
- self.msgout(4, "create reference", m, "->", parent)
- self._updateReference(m, parent, edge_data=DependencyInfo(
- conditional=False, fromlist=False, function=False, tryexcept=False
- ))
- parent[partname] = m
-
- self.msgout(3, "import_module ->", m)
- return m
-
- def _load_module(self, fqname, fp, pathname, info):
- suffix, mode, typ = info
- self.msgin(2, "load_module", fqname, fp and "fp", pathname)
-
- if typ == imp.PKG_DIRECTORY:
- if isinstance(mode, (list, tuple)):
- packagepath = mode
- else:
- packagepath = []
-
- m = self._load_package(fqname, pathname, packagepath)
- self.msgout(2, "load_module ->", m)
- return m
-
- if typ == imp.PY_SOURCE:
- contents = fp.read()
- if isinstance(contents, bytes):
- contents += b'\n'
- else:
- contents += '\n'
-
- try:
- co = compile(contents, pathname, 'exec', ast.PyCF_ONLY_AST, True)
- #co = compile(contents, pathname, 'exec', 0, True)
- except SyntaxError:
- co = None
- cls = InvalidSourceModule
-
- else:
- cls = SourceModule
-
- elif typ == imp.PY_COMPILED:
- if fp.read(4) != imp.get_magic():
- self.msgout(2, "raise ImportError: Bad magic number", pathname)
- co = None
- cls = InvalidCompiledModule
-
- else:
- fp.read(4)
- try:
- co = marshal.loads(fp.read())
- cls = CompiledModule
- except Exception:
- co = None
- cls = InvalidCompiledModule
-
- elif typ == imp.C_BUILTIN:
- cls = BuiltinModule
- co = None
-
- else:
- cls = Extension
- co = None
-
- m = self.createNode(cls, fqname)
- m.filename = pathname
- if co is not None:
- self._scan_code(co, m)
-
- if isinstance(co, ast.AST):
- co = compile(co, pathname, 'exec', 0, True)
- if self.replace_paths:
- co = self._replace_paths_in_code(co)
- m.code = co
-
-
- self.msgout(2, "load_module ->", m)
- return m
-
- def _safe_import_hook(self, name, caller, fromlist, level=DEFAULT_IMPORT_LEVEL, attr=None):
- # wrapper for self.import_hook() that won't raise ImportError
- try:
- mods = self.import_hook(name, caller, level=level, attr=attr)
- except ImportError as msg:
- self.msg(2, "ImportError:", str(msg))
- m = self.createNode(MissingModule, _path_from_importerror(msg, name))
- self._updateReference(caller, m, edge_data=attr)
-
- else:
- assert len(mods) == 1
- m = list(mods)[0]
-
- subs = [m]
- if isinstance(attr, DependencyInfo):
- attr = attr._replace(fromlist=True)
- for sub in (fromlist or ()):
- # If this name is in the module namespace already,
- # then add the entry to the list of substitutions
- if sub in m:
- sm = m[sub]
- if sm is not None:
- if sm not in subs:
- self._updateReference(caller, sm, edge_data=attr)
- subs.append(sm)
- continue
-
- elif sub in m.globalnames:
- # Global variable in the module, ignore
- continue
-
-
- # See if we can load it
- # fullname = name + '.' + sub
- fullname = m.identifier + '.' + sub
- #else:
- # print("XXX", repr(name), repr(sub), repr(caller), repr(m))
- sm = self.findNode(fullname)
- if sm is None:
- try:
- sm = self.import_hook(name, caller, fromlist=[sub], level=level, attr=attr)
- except ImportError as msg:
- self.msg(2, "ImportError:", str(msg))
- #sm = self.createNode(MissingModule, _path_from_importerror(msg, fullname))
- sm = self.createNode(MissingModule, fullname)
- else:
- sm = self.findNode(fullname)
- if sm is None:
- sm = self.createNode(MissingModule, fullname)
-
- m[sub] = sm
- if sm is not None:
- self._updateReference(m, sm, edge_data=attr)
- self._updateReference(caller, sm, edge_data=attr)
- if sm not in subs:
- subs.append(sm)
- return subs
-
- def _scan_code(self, co, m):
- if isinstance(co, ast.AST):
- #return self._scan_bytecode(compile(co, '-', 'exec', 0, True), m)
- self._scan_ast(co, m)
- self._scan_bytecode_stores(
- compile(co, '-', 'exec', 0, True), m)
-
- else:
- self._scan_bytecode(co, m)
-
- def _scan_ast(self, co, m):
- visitor = _Visitor(self, m)
- visitor.visit(co)
-
- def _scan_bytecode_stores(self, co, m,
- STORE_NAME=_Bchr(dis.opname.index('STORE_NAME')),
- STORE_GLOBAL=_Bchr(dis.opname.index('STORE_GLOBAL')),
- HAVE_ARGUMENT=_Bchr(dis.HAVE_ARGUMENT),
- unpack=struct.unpack):
-
- extended_import = bool(sys.version_info[:2] >= (2,5))
-
- code = co.co_code
- constants = co.co_consts
- n = len(code)
- i = 0
-
- while i < n:
- c = code[i]
- i += 1
- if c >= HAVE_ARGUMENT:
- i = i+2
-
- if c == STORE_NAME or c == STORE_GLOBAL:
- # keep track of all global names that are assigned to
- oparg = unpack('<H', code[i - 2:i])[0]
- name = co.co_names[oparg]
- m.globalnames.add(name)
-
- cotype = type(co)
- for c in constants:
- if isinstance(c, cotype):
- self._scan_bytecode_stores(c, m)
-
- def _scan_bytecode(self, co, m,
- HAVE_ARGUMENT=_Bchr(dis.HAVE_ARGUMENT),
- LOAD_CONST=_Bchr(dis.opname.index('LOAD_CONST')),
- IMPORT_NAME=_Bchr(dis.opname.index('IMPORT_NAME')),
- IMPORT_FROM=_Bchr(dis.opname.index('IMPORT_FROM')),
- STORE_NAME=_Bchr(dis.opname.index('STORE_NAME')),
- STORE_GLOBAL=_Bchr(dis.opname.index('STORE_GLOBAL')),
- unpack=struct.unpack):
-
- # Python >=2.5: LOAD_CONST flags, LOAD_CONST names, IMPORT_NAME name
- # Python < 2.5: LOAD_CONST names, IMPORT_NAME name
- extended_import = bool(sys.version_info[:2] >= (2,5))
-
- code = co.co_code
- constants = co.co_consts
- n = len(code)
- i = 0
-
- level = None
- fromlist = None
-
- while i < n:
- c = code[i]
- i += 1
- if c >= HAVE_ARGUMENT:
- i = i+2
-
- if c == IMPORT_NAME:
- if extended_import:
- assert code[i-9] == LOAD_CONST
- assert code[i-6] == LOAD_CONST
- arg1, arg2 = unpack('<xHxH', code[i-9:i-3])
- level = co.co_consts[arg1]
- fromlist = co.co_consts[arg2]
- else:
- assert code[-6] == LOAD_CONST
- arg1, = unpack('<xH', code[i-6:i-3])
- level = -1
- fromlist = co.co_consts[arg1]
-
- assert fromlist is None or type(fromlist) is tuple
- oparg, = unpack('<H', code[i - 2:i])
- 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.msgin(2, "Before import hook", repr(name), repr(m), repr(fromlist), repr(level))
-
- imported_module = self._safe_import_hook(name, m, fromlist, level)[0]
-
- if have_star:
- m.globalnames.update(imported_module.globalnames)
- m.starimports.update(imported_module.starimports)
- if imported_module.code is None:
- m.starimports.add(name)
-
- elif c == STORE_NAME or c == STORE_GLOBAL:
- # keep track of all global names that are assigned to
- oparg = unpack('<H', code[i - 2:i])[0]
- name = co.co_names[oparg]
- m.globalnames.add(name)
-
- cotype = type(co)
- for c in constants:
- if isinstance(c, cotype):
- self._scan_bytecode(c, m)
-
- def _load_package(self, fqname, pathname, pkgpath):
- """
- Called only when an imp.PACKAGE_DIRECTORY is found
- """
- self.msgin(2, "load_package", fqname, pathname, pkgpath)
- newname = _replacePackageMap.get(fqname)
- if newname:
- fqname = newname
-
- ns_pkgpath = _namespace_package_path(fqname, pkgpath or [], self.path)
- if ns_pkgpath or pkgpath:
- # this is a namespace package
- m = self.createNode(NamespacePackage, fqname)
- m.filename = '-'
- m.packagepath = ns_pkgpath
- else:
- m = self.createNode(Package, fqname)
- m.filename = pathname
- m.packagepath = [pathname] + ns_pkgpath
-
- # As per comment at top of file, simulate runtime packagepath additions.
- m.packagepath = m.packagepath + _packagePathMap.get(fqname, [])
-
-
-
- try:
- self.msg(2, "find __init__ for %s"%(m.packagepath,))
- fp, buf, stuff = self._find_module("__init__", m.packagepath, parent=m)
- except ImportError:
- pass
-
- else:
- try:
- self.msg(2, "load __init__ for %s"%(m.packagepath,))
- self._load_module(fqname, fp, buf, stuff)
- finally:
- if fp is not None:
- fp.close()
- 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 = find_module(name, path)
- try:
- if buf:
- buf = os.path.realpath(buf)
-
- return (fp, buf, stuff)
- except:
- fp.close()
- raise
-
- def create_xref(self, out=None):
- global header, footer, entry, contpl, contpl_linked, imports
- if out is None:
- out = sys.stdout
- scripts = []
- mods = []
- for mod in self.flatten():
- name = os.path.basename(mod.identifier)
- if isinstance(mod, Script):
- scripts.append((name, mod))
- else:
- mods.append((name, mod))
- scripts.sort()
- mods.sort()
- scriptnames = [name for name, m in scripts]
- scripts.extend(mods)
- mods = scripts
-
- title = "modulegraph cross reference for " + ', '.join(scriptnames)
- print(header % {"TITLE": title}, file=out)
-
- def sorted_namelist(mods):
- lst = [os.path.basename(mod.identifier) for mod in mods if mod]
- lst.sort()
- return lst
- for name, m in mods:
- content = ""
- if isinstance(m, BuiltinModule):
- content = contpl % {"NAME": name,
- "TYPE": "<i>(builtin module)</i>"}
- elif isinstance(m, Extension):
- content = contpl % {"NAME": name,\
- "TYPE": "<tt>%s</tt>" % m.filename}
- else:
- url = pathname2url(m.filename or "")
- content = contpl_linked % {"NAME": name, "URL": url}
- oute, ince = map(sorted_namelist, self.get_edges(m))
- if oute:
- links = ""
- for n in oute:
- links += """ <a href="#%s">%s</a>\n""" % (n, n)
- content += imports % {"HEAD": "imports", "LINKS": links}
- if ince:
- links = ""
- for n in ince:
- links += """ <a href="#%s">%s</a>\n""" % (n, n)
- content += imports % {"HEAD": "imported by", "LINKS": links}
- print(entry % {"NAME": name,"CONTENT": content}, file=out)
- print(footer, file=out)
-
-
- def itergraphreport(self, name='G', flatpackages=()):
- # XXX: Can this be implemented using Dot()?
- 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 enumerate(data.infoTuple()[:1], 1):
- s += '| <f%d> %s' % (i,v)
- return {'label':s, 'shape':'record'}
-
-
- def edgevisitor(edge, data, head, tail):
- # XXX: This method nonsense, the edge
- # data is never initialized.
- 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.items():
- 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 (describe_edge(e) for e in outgoing):
- edges.append(edge)
-
- # describe node
- yield '\t"%s" [%s];\n' % (
- node,
- ','.join([
- (cpatt % item) for item in
- nodevisitor(node, data, outgoing, incoming).items()
- ]),
- )
-
- 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.items()]),
- )
-
- for g, edges in subgraphs.items():
- 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
-
- else:
- return co
-
- 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])
-
- code_func = type(co)
-
- if hasattr(co, 'co_kwonlyargcount'):
- return code_func(co.co_argcount, co.co_kwonlyargcount, 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)
- else:
- return code_func(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)

Powered by Google App Engine
This is Rietveld 408576698