Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / tools / telemetry / third_party / modulegraph / doc / modulegraph.rst
blob60566e7e73b9d94742fff6bc8bd4e0eb3f003620
1 :mod:`modulegraph.modulegraph` --- Find modules used by a script
2 ================================================================
4 .. module:: modulegraph.modulegraph
5    :synopsis: Find modules used by a script
7 This module defines :class:`ModuleGraph`, which is used to find
8 the dependencies of scripts using bytecode analysis.
10 A number of APIs in this module refer to filesystem path. Those paths can refer to
11 files inside zipfiles (for example when there are zipped egg files on :data:`sys.path`).
12 Filenames referring to entries in a zipfile are not marked any way, if ``"somepath.zip"``
13 refers to a zipfile, that is ``"somepath.zip/embedded/file"`` will be used to refer to
14 ``embedded/file`` inside the zipfile.
16 The actual graph
17 ----------------
19 .. class:: ModuleGraph([path[, excludes[, replace_paths[, implies[, graph[, debug]]]]]])
21    Create a new ModuleGraph object. Use the :meth:`run_script` method to add scripts,
22    and their dependencies to the graph.
24    :param path: Python search path to use, defaults to :data:`sys.path`
25    :param excludes: Iterable with module names that should not be included as a dependency
26    :param replace_paths: List of pathname rewrites ``(old, new)``. When this argument is
27      supplied the ``co_filename`` attributes of code objects get rewritten before scanning
28      them for dependencies.
29    :param implies: Implied module dependencies, a mapping from a module name to the list
30      of modules it depends on. Use this to tell modulegraph about dependencies that cannot
31      be found by code inspection (such as imports from C code or using the :func:`__import__`
32      function).
33    :param graph: A precreated :class:`Graph <altgraph.Graph.Graph>` object to use, the
34      default is to create a new one.
35    :param debug: The :class:`ObjectGraph <altgraph.ObjectGraph.ObjectGraph>` debug level.
38 .. method:: run_script(pathname[, caller])
40    Create, and return,  a node by path (not module name). The *pathname* should
41    refer to a Python source file and will be scanned for dependencies.
43    The optional argument *caller* is the the node that calls this script,
44    and is used to add a reference in the graph.
46 .. method:: import_hook(name[[, caller[, fromlist[, level, [, attr]]]])
48    Import a module and analyse its dependencies
50    :arg name:     The module name
51    :arg caller:   The node that caused the import to happen
52    :arg fromlist: The list of names to import, this is an empty list for
53       ``import name`` and a list of names for ``from name import a, b, c``.
54    :arg level:    The import level. The value should be ``-1`` for classical Python 2
55      imports, ``0`` for absolute imports and a positive number for relative imports (
56      where the value is the number of leading dots in the imported name).
57    :arg attr:     Attributes for the graph edge.
60 .. method:: implyNodeReference(node, other, edgeData=None)
62    Explictly mark that *node* depends on *other*. Other is either
63    a :class:`node <Node>` or the name of a module that will be
64    searched for as if it were an absolute import.
67 .. method:: createReference(fromnode, tonode[, edge_data])
69    Create a reference from *fromnode* to *tonode*, with optional edge data.
71    The default for *edge_data* is ``"direct"``.
73 .. method:: getReferences(fromnode)
75    Yield all nodes that *fromnode* refers to. That is, all modules imported
76    by *fromnode*.
78    Node :data:`None` is the root of the graph, and refers to all notes that were
79    explicitly imported by :meth:`run_script` or :meth:`import_hook`, unless you use
80    an explicit parent with those methods.
82    .. versionadded:: 0.11
84 .. method:: getReferers(tonode, collapse_missing_modules=True)
86    Yield all nodes that refer to *tonode*. That is, all modules that import
87    *tonode*.
89    If *collapse_missing_modules* is false this includes refererences from
90    :class:`MissingModule` nodes, otherwise :class:`MissingModule` nodes
91    are replaced by the "real" nodes that reference this missing node.
93    .. versionadded:: 0.12
95 .. method:: foldReferences(pkgnode)
97    Hide all submodule nodes for package *pkgnode* and add ingoing and outgoing
98    edges to *pkgnode* based on the edges from the submodule nodes.
100    This can be used to simplify a module graph: after folding 'email' all
101    references to modules in the 'email' package are references to the package.
103    .. versionadded: 0.11
105 .. method:: findNode(name)
107    Find a node by identifier.  If a node by that identifier exists, it will be returned.
109    If a lazy node exists by that identifier with no dependencies (excluded), it will be
110    instantiated and returned.
112    If a lazy node exists by that identifier with dependencies, it and its
113    dependencies will be instantiated and scanned for additional depende
117 .. method:: create_xref([out])
119    Write an HTML file to the *out* stream (defaulting to :data:`sys.stdout`).
121    The HTML file contains a textual description of the dependency graph.
125 .. method:: graphreport([fileobj[, flatpackages]])
127    .. todo:: To be documented
131 .. method:: report()
133    Print a report to stdout, listing the found modules with their
134    paths, as well as modules that are missing, or seem to be missing.
137 Mostly internal methods
138 .......................
140 The methods in this section should be considered as methods for subclassing at best,
141 please let us know if you need these methods in your code as they are on track to be
142 made private methods before the 1.0 release.
144 .. warning:: The methods in this section will be refactored in a future release,
145    the current architecture makes it unnecessarily hard to write proper tests.
147 .. method:: determine_parent(caller)
149    Returns the node of the package root voor *caller*. If *caller* is a package
150    this is the node itself, if the node is a module in a package this is the
151    node of for the package and otherwise the *caller* is not a package and
152    the result is :data:`None`.
154 .. method:: find_head_package(parent, name[, level])
156    .. todo:: To be documented
159 .. method:: load_tail(mod, tail)
161    This method is called to load the rest of a dotted name after loading the root
162    of a package. This will import all intermediate modules as well (using
163    :meth:`import_module`), and returns the module :class:`node <Node>` for the
164    requested node.
166    .. note:: When *tail* is empty this will just return *mod*.
168    :arg mod:   A start module (instance of :class:`Node`)
169    :arg tail:  The rest of a dotted name, can be empty
170    :raise ImportError: When the requested (or one of its parents) module cannot be found
171    :returns: the requested module
175 .. method:: ensure_fromlist(m, fromlist)
177    Yield all submodules that would be imported when importing *fromlist*
178    from *m* (using ``from m import fromlist...``).
180    *m* must be a package and not a regular module.
182 .. method:: find_all_submodules(m)
184    Yield the filenames for submodules of in the same package as *m*.
188 .. method:: import_module(partname, fqname, parent)
190    Perform import of the module with basename *partname* (``path``) and
191    full name *fqname* (``os.path``). Import is performed by *parent*.
193    This will create a reference from the parent node to the
194    module node and will load the module node when it is not already
195    loaded.
199 .. method:: load_module(fqname, fp, pathname, (suffix, mode, type))
201    Load the module named *fqname* from the given *pathame*. The
202    argument *fp* is either :data:`None`, or a stream where the
203    code for the Python module can be loaded (either byte-code or
204    the source code). The *(suffix, mode, type)* tuple are the
205    suffix of the source file, the open mode for the file and the
206    type of module.
208    Creates a node of the right class and processes the dependencies
209    of the :class:`node <Node>` by scanning the byte-code for the node.
211    Returns the resulting :class:`node <Node>`.
215 .. method:: scan_code(code, m)
217    Scan the *code* object for module *m* and update the dependencies of
218    *m* using the import statemets found in the code.
220    This will automaticly scan the code for nested functions, generator
221    expressions and list comprehensions as well.
225 .. method:: load_package(fqname, pathname)
227    Load a package directory.
231 .. method:: find_module(name, path[, parent])
233    Locates a module named *name* that is not yet part of the
234    graph. This method will raise :exc:`ImportError` when
235    the module cannot be found or when it is already part
236    of the graph. The *name* can not be a dotted name.
238    The *path* is the search path used, or :data:`None` to
239    use the default path.
241    When the *parent* is specified *name* refers to a
242    subpackage of *parent*, and *path* should be the
243    search path of the parent.
245    Returns the result of the global function
246    :func:`find_module <modulegraph.modulegraph.find_module>`.
249 .. method:: itergraphreport([name[, flatpackages]])
251    .. todo:: To be documented
255 .. method:: replace_paths_in_code(co)
257    Replace the filenames in code object *co* using the *replace_paths* value that
258    was passed to the contructor. Returns the rewritten code object.
262 .. method:: calc_setuptools_nspackages()
264    Returns a mapping from package name to a list of paths where that package
265    can be found in ``--single-version-externally-managed`` form.
267    This method is used to be able to find those packages: these use
268    a magic ``.pth`` file to ensure that the package is added to :data:`sys.path`,
269    as they do not contain an ``___init__.py`` file.
271    Packages in this form are used by system packages and the "pip"
272    installer.
275 Graph nodes
276 -----------
278 The :class:`ModuleGraph` contains nodes that represent the various types of modules.
280 .. class:: Alias(value)
282    This is a subclass of string that is used to mark module aliases.
286 .. class:: Node(identifier)
288    Base class for nodes, which provides the common functionality.
290    Nodes can by used as mappings for storing arbitrary data in the node.
292    Nodes are compared by comparing their *identifier*.
294 .. data:: debug
296    Debug level (integer)
298 .. data:: graphident
300    The node identifier, this is the value of the *identifier* argument
301    to the constructor.
303 .. data:: identifier
305    The node identifier, this is the value of the *identifier* argument
306    to the constructor.
308 .. data:: filename
310    The filename associated with this node.
312 .. data:: packagepath
314    The value of ``__path__`` for this node.
316 .. data:: code
318    The :class:`code object <types.CodeObject>` associated with this node
320 .. data:: globalnames
322    The set of global names that are assigned to in this module. This
323    includes those names imported through startimports of Python modules.
325 .. data:: startimports
327    The set of startimports this module did that could not be resolved,
328    ie. a startimport from a non-Python module.
331 .. method:: __contains__(name)
333    Return if there is a value associated with *name*.
335    This method is usually accessed as ``name in aNode``.
337 .. method:: __setitem__(name, value)
339    Set the value of *name* to *value*.
341    This method is usually accessed as ``aNode[name] = value``.
343 .. method:: __getitem__(name)
345    Returns the value of *name*, raises :exc:`KeyError` when
346    it cannot be found.
348    This method is usually accessed as ``value = aNode[name]``.
350 .. method:: get(name[, default])
352    Returns the value of *name*, or the default value when it
353    cannot be found. The *default* is :data:`None` when not specified.
355 .. method:: infoTuple()
357    Returns a tuple with information used in the :func:`repr`
358    output for the node. Subclasses can add additional informations
359    to the result.
362 .. class:: AliasNode (name, node)
364    A node that represents an alias from a name to another node.
366    The value of attribute *graphident* for this node will be the
367    value of *name*, the other :class:`Node` attributed are
368    references to those attributed in *node*.
370 .. class:: BadModule(identifier)
372    Base class for nodes that should be ignored for some reason
374 .. class:: ExcludedModule(identifier)
376    A module that is explicitly excluded.
378 .. class:: MissingModule(identifier)
380    A module that is imported but cannot be located.
384 .. class:: Script(filename)
386    A python script.
388    .. data:: filename
390       The filename for the script
392 .. class:: BaseModule(name[, filename[, path]])
394     The base class for actual modules. The *name* is
395     the possibly dotted module name, *filename* is the
396     filesystem path to the module and *path* is the
397     value of ``__path__`` for the module.
399 .. data:: graphident
401    The name of the module
403 .. data:: filename
405    The filesystem path to the module.
407 .. data:: path
409    The value of ``__path__`` for this module.
411 .. class:: BuiltinModule(name)
413    A built-in module (on in :data:`sys.builtin_module_names`).
415 .. class:: SourceModule(name)
417    A module for which the python source code is available.
419 .. class:: InvalidSourceModule(name)
421    A module for which the python source code is available, but where
422    that source code cannot be compiled (due to syntax errors).
424    This is a subclass of :class:`SourceModule`.
426    .. versionadded:: 0.12
428 .. class:: CompiledModule(name)
430    A module for which only byte-code is available.
432 .. class:: Package(name)
434    Represents a python package
436 .. class:: NamespacePackage(name)
438    Represents a python namespace package.
440    This is a subclass of :class:`Package`.
442 .. class:: Extension(name)
444    A native extension
447 .. warning:: A number of other node types are defined in the module. Those modules aren't
448    used by modulegraph and will be removed in a future version.
451 Edge data
452 ---------
454 The edges in a module graph by default contain information about the edge, represented
455 by an instance of :class:`DependencyInfo`.
457 .. class:: DependencyInfo(conditional, function, tryexcept, fromlist)
459    This class is a :func:`namedtuple <collections.namedtuple>` for representing
460    the information on a dependency between two modules.
462    All attributes can be used to deduce if a dependency is essential or not, and
463    are particularly useful when reporting on missing modules (dependencies on
464    :class:`MissingModule`).
466    .. data:: fromlist
468       A boolean that is true iff the target of the edge is named in the "import"
469       list of a "from" import ("from package import module").
471       When the target module is imported multiple times this attribute is false
472       unless all imports are in "import" list of a "from" import.
474    .. data:: function
476       A boolean that is true iff the import is done inside a function definition,
477       and is false for imports in module scope (or class scope for classes that
478       aren't definined in a function).
480    .. data:: tryexcept
482       A boolean that is true iff the import that is done in the "try" or "except"
483       block of a try statement (but not in the "else" block).
485    .. data:: conditional
487       A boolean that is true iff the import is done in either block of an "if"
488       statement.
490    When the target of the edge is imported multiple times the :data:`function`,
491    :data:`tryexcept` and :data:`conditional` attributes of all imports are
492    merged: when there is an import where all these attributes are false the
493    attributes are false, otherwise each attribute is set to true if it is
494    true for at least one of the imports.
496    For example, when a module is imported both in a try-except statement and
497    furthermore is imported in a function (in two separate statements),
498    both :data:`tryexcept` and :data:`function` will be true.  But if there
499    is a third unconditional toplevel import for that module as well all
500    three attributes are false.
502    .. warning::
504       All attributes but :data:`fromlist` will be false when the source of
505       a dependency is scanned from a byte-compiled module instead of a python
506       source file. The :data:`fromlist` attribute will stil be set correctly.
508 Utility functions
509 -----------------
511 .. function:: find_module(name[, path])
513    A version of :func:`imp.find_module` that works with zipped packages (and other
514    :pep:`302` importers).
516 .. function:: moduleInfoForPath(path)
518    Return the module name, readmode and type for the file at *path*, or
519    None if it doesn't seem to be a valid module (based on its name).
521 .. function:: addPackagePath(packagename, path)
523    Add *path* to the value of ``__path__`` for the package named *packagename*.
525 .. function:: replacePackage(oldname, newname)
527    Rename *oldname* to *newname* when it is found by the module finder. This
528    is used as a workaround for the hack that the ``_xmlplus`` package uses
529    to inject itself in the ``xml`` namespace.