[Python-checkins] distutils2: Finishing documentation, examples are left

tarek.ziade python-checkins at python.org
Sun Jun 20 23:04:52 CEST 2010


tarek.ziade pushed 4618d201db9b to distutils2:

http://hg.python.org/distutils2/rev/4618d201db9b
changeset:   205:4618d201db9b
user:        Josip Djolonga
date:        Fri Jun 11 21:53:51 2010 +0200
summary:     Finishing documentation, examples are left
files:       docs/source/depgraph.rst, docs/source/index.rst, docs/source/metadata.rst, docs/source/pkgutil.rst, src/distutils2/_backport/pkgutil.py, src/distutils2/depgraph.py

diff --git a/docs/source/depgraph.rst b/docs/source/depgraph.rst
new file mode 100644
--- /dev/null
+++ b/docs/source/depgraph.rst
@@ -0,0 +1,25 @@
+===============================
+Dependency Graph Builder Module
+===============================
+
+Introduction
+------------
+
+This module provides the means to create a graph of dependencies from a list
+of :class:`distutils2._backport.pkgutil.Distribution` and
+:class:`distutils2._backport.pkgutil.EggInfoDistribution` instances. The graph
+is represented by the :class:`distutils2.depgraph.DependencyGraph` class that
+keeps internally an adjacency list. Several functions are provided that
+generate a graph in different manners. First, all of them are documented and
+then several use case examples are provided along with graphviz illustrations
+of the generated graphs.
+
+API
+---
+
+.. automodule:: distutils2.depgraph
+   :members:
+
+Example Usage
+-------------
+
diff --git a/docs/source/index.rst b/docs/source/index.rst
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -13,6 +13,7 @@
 
    metadata
    pkgutil
+   depgraph
 
 Indices and tables
 ==================
diff --git a/docs/source/metadata.rst b/docs/source/metadata.rst
--- a/docs/source/metadata.rst
+++ b/docs/source/metadata.rst
@@ -5,13 +5,13 @@
 Distutils2 provides a :class:`DistributionMetadata` class that can read and
 write Metadata files. This class is compatible with all versions of Metadata:
 
-- 1.0 : PEP 241
-- 1.1 : PEP 314
-- 1.2 : PEP 345
+* 1.0 : :pep:`241`
+* 1.1 : :pep:`314`
+* 1.2 : :pep:`345`
 
-The PEP 345 implementation supports the micro-language for the environment
+The :pep:`345` implementation supports the micro-language for the environment
 markers, and displays warnings when versions that are supposed to be
-PEP 386 are violating the scheme.
+:pep:`386` are violating the scheme.
 
 
 Reading metadata
@@ -78,7 +78,7 @@
 Conflict checking and best version
 ==================================
 
-Some fields in PEP 345 have to follow a version scheme in their versions
+Some fields in :pep:`345` have to follow a version scheme in their versions
 predicate. When the scheme is violated, a warning is emited::
 
     >>> from distutils2.metadata import DistributionMetadata
@@ -89,7 +89,7 @@
 
 
 
-XXX talk about check()
+.. TODO talk about check()
 
 
 
diff --git a/docs/source/pkgutil.rst b/docs/source/pkgutil.rst
--- a/docs/source/pkgutil.rst
+++ b/docs/source/pkgutil.rst
@@ -2,8 +2,44 @@
 pkgutil
 =======
 
+Introduction
+============
+
+This module provides the necessary functions to provide support for
+the "Importer Protocol" as described in :pep:`302` and for working with
+the database of installed Python distributions which is specified in
+:pep:`376`. In addition to the functions required in :pep:`376`, back support
+for older ``.egg`` and ``.egg-info`` distributions is provided as well. These
+distributions are represented by the class
+:class:`distutils2._backport.pkgutil.EggInfoDistribution` and
+most functions provide an extra argument ``use_egg_info`` which indicates if
+they should consider these old styled distributions. In this document,
+first a complete documentation of the functions and classes
+is provided and then several use cases are presented.
+
 API Reference
 =============
 
 .. automodule:: distutils2._backport.pkgutil
    :members:
+
+Example Usage
+=============
+
+* Doing this and that::
+
+    import sys
+
+    # first compute a
+    a = x+2
+    # then print it out to stdin
+    print(a)
+
+* And that and this::
+
+    from foo import bar
+
+    z = lambda x,y: x^2 + y
+
+
+
diff --git a/src/distutils2/_backport/pkgutil.py b/src/distutils2/_backport/pkgutil.py
--- a/src/distutils2/_backport/pkgutil.py
+++ b/src/distutils2/_backport/pkgutil.py
@@ -1,4 +1,4 @@
-"""Utilities to support packages."""
+# Utilities to support packages.
 
 # NOTE: This module must remain compatible with Python 2.3, as it is shared
 # by setuptools for distribution with Python 2.3 and up.
@@ -22,7 +22,7 @@
 
 __all__ = [
     'get_importer', 'iter_importers', 'get_loader', 'find_loader',
-    'walk_packages', 'iter_modules',
+    'walk_packages', 'iter_modules', 'get_data',
     'ImpImporter', 'ImpLoader', 'read_code', 'extend_path',
     'Distribution', 'EggInfoDistribution', 'distinfo_dirname',
     'get_distributions', 'get_distribution', 'get_file_users',
@@ -31,7 +31,7 @@
 
 
 def read_code(stream):
-    # This helper is needed in order for the PEP 302 emulation to
+    # This helper is needed in order for the :pep:`302` emulation to
     # correctly handle compiled files
     import marshal
 
@@ -86,32 +86,34 @@
 
 
 def walk_packages(path=None, prefix='', onerror=None):
-    """Yields (module_loader, name, ispkg) for all modules recursively
-    on path, or, if path is None, all accessible modules.
+    """Yields ``(module_loader, name, ispkg)`` for all modules recursively
+    on *path*, or, if *path* is ``None``, all accessible modules.
 
-    'path' should be either None or a list of paths to look for
-    modules in.
+    :parameter path: should be either ``None`` or a list of paths to look for
+                     modules in.
+    :parameter prefix: is a string to output on the front of every module name
+                       on output.
 
-    'prefix' is a string to output on the front of every module name
-    on output.
-
-    Note that this function must import all *packages* (NOT all
-    modules!) on the given path, in order to access the __path__
+    Note that this function must import all packages (NOT all
+    modules!) on the given path, in order to access the ``__path__``
     attribute to find submodules.
 
-    'onerror' is a function which gets called with one argument (the
+    *onerror* is a function which gets called with one argument (the
     name of the package which was being imported) if any exception
     occurs while trying to import a package.  If no onerror function is
-    supplied, ImportErrors are caught and ignored, while all other
+    supplied, ``ImportErrors`` are caught and ignored, while all other
     exceptions are propagated, terminating the search.
 
     Examples:
 
-    # list all modules python can access
-    walk_packages()
+    * list all modules python can access::
 
-    # list all submodules of ctypes
-    walk_packages(ctypes.__path__, ctypes.__name__+'.')
+        walk_packages()
+
+    * list all submodules of ctypes::
+
+        walk_packages(ctypes.__path__, ctypes.__name__+'.')
+
     """
 
     def seen(p, m={}):
@@ -144,14 +146,14 @@
 
 
 def iter_modules(path=None, prefix=''):
-    """Yields (module_loader, name, ispkg) for all submodules on path,
-    or, if path is None, all top-level modules on sys.path.
+    """Yields ``(module_loader, name, ispkg)`` for all submodules on path,
+    or, if *path* is ``None``, all top-level modules on ``sys.path``.
 
-    'path' should be either None or a list of paths to look for
-    modules in.
+    :parameter path: should be either None or a list of paths to look for
+                     modules in.
+    :parameter prefix: is a string to output on the front of every module name
+                       on output.
 
-    'prefix' is a string to output on the front of every module name
-    on output.
     """
 
     if path is None:
@@ -169,6 +171,7 @@
 
 #@simplegeneric
 def iter_importer_modules(importer, prefix=''):
+    ""
     if not hasattr(importer, 'iter_modules'):
         return []
     return importer.iter_modules(prefix)
@@ -177,14 +180,15 @@
 
 
 class ImpImporter:
-    """PEP 302 Importer that wraps Python's "classic" import algorithm
+    """:pep:`302` Importer that wraps Python's "classic" import algorithm
 
-    ImpImporter(dirname) produces a PEP 302 importer that searches that
-    directory.  ImpImporter(None) produces a PEP 302 importer that searches
-    the current sys.path, plus any modules that are frozen or built-in.
+    ``ImpImporter(dirname)`` produces a :pep:`302` importer that searches that
+    directory. ``ImpImporter(None)`` produces a :pep:`302` importer that
+    searches the current ``sys.path``, plus any modules that are frozen
+    or built-in.
 
-    Note that ImpImporter does not currently support being used by placement
-    on sys.meta_path.
+    Note that :class:`ImpImporter` does not currently support being used by placement
+    on ``sys.meta_path``.
     """
 
     def __init__(self, path=None):
@@ -239,8 +243,8 @@
 
 
 class ImpLoader:
-    """PEP 302 Loader that wraps Python's "classic" import algorithm
-    """
+    """:pep:`302` Loader that wraps Python's "classic" import algorithm """
+
     code = source = None
 
     def __init__(self, fullname, file, filename, etc):
@@ -372,17 +376,17 @@
 
 
 def get_importer(path_item):
-    """Retrieve a PEP 302 importer for the given path item
+    """Retrieve a  :pep:`302` importer for the given path item
 
-    The returned importer is cached in sys.path_importer_cache
+    The returned importer is cached in ``sys.path_importer_cache``
     if it was newly created by a path hook.
 
     If there is no importer, a wrapper around the basic import
     machinery is returned. This wrapper is never inserted into
-    the importer cache (None is inserted instead).
+    the importer cache (``None`` is inserted instead).
 
     The cache (or part of it) can be cleared manually if a
-    rescan of sys.path_hooks is necessary.
+    rescan of ``sys.path_hooks`` is necessary.
     """
     try:
         importer = sys.path_importer_cache[path_item]
@@ -406,7 +410,7 @@
 
 
 def iter_importers(fullname=""):
-    """Yield PEP 302 importers for the given module name
+    """Yield :pep:`302` importers for the given module name
 
     If fullname contains a '.', the importers will be for the package
     containing fullname, otherwise they will be importers for sys.meta_path,
@@ -414,20 +418,20 @@
     the named module is in a package, that package is imported as a side
     effect of invoking this function.
 
-    Non PEP 302 mechanisms (e.g. the Windows registry) used by the
+    Non :pep:`302` mechanisms (e.g. the Windows registry) used by the
     standard import machinery to find files in alternative locations
-    are partially supported, but are searched AFTER sys.path. Normally,
-    these locations are searched BEFORE sys.path, preventing sys.path
+    are partially supported, but are searched AFTER ``sys.path``. Normally,
+    these locations are searched BEFORE sys.path, preventing ``sys.path``
     entries from shadowing them.
 
     For this to cause a visible difference in behaviour, there must
     be a module or package name that is accessible via both sys.path
-    and one of the non PEP 302 file system mechanisms. In this case,
+    and one of the non :pep:`302` file system mechanisms. In this case,
     the emulation will find the former version, while the builtin
     import mechanism will find the latter.
 
     Items of the following types can be affected by this discrepancy:
-        imp.C_EXTENSION, imp.PY_SOURCE, imp.PY_COMPILED, imp.PKG_DIRECTORY
+        ``imp.C_EXTENSION, imp.PY_SOURCE, imp.PY_COMPILED, imp.PKG_DIRECTORY``
     """
     if fullname.startswith('.'):
         raise ImportError("Relative module names not supported")
@@ -448,15 +452,15 @@
 
 
 def get_loader(module_or_name):
-    """Get a PEP 302 "loader" object for module_or_name
+    """Get a :pep:`302` "loader" object for module_or_name
 
     If the module or package is accessible via the normal import
     mechanism, a wrapper around the relevant part of that machinery
     is returned.  Returns None if the module cannot be found or imported.
     If the named module is not already imported, its containing package
-    (if any) is imported, in order to establish the package __path__.
+    (if any) is imported, in order to establish the package ``__path__``.
 
-    This function uses iter_importers(), and is thus subject to the same
+    This function uses :func:`iter_importers`, and is thus subject to the same
     limitations regarding platform-specific special import locations such
     as the Windows registry.
     """
@@ -474,12 +478,13 @@
 
 
 def find_loader(fullname):
-    """Find a PEP 302 "loader" object for fullname
+    """Find a :pep:`302` "loader" object for fullname
 
-    If fullname contains dots, path must be the containing package's __path__.
-    Returns None if the module cannot be found or imported. This function uses
-    iter_importers(), and is thus subject to the same limitations regarding
-    platform-specific special import locations such as the Windows registry.
+    If fullname contains dots, path must be the containing package's
+    ``__path__``. Returns ``None`` if the module cannot be found or imported.
+    This function uses :func:`iter_importers`, and is thus subject to the same
+    limitations regarding platform-specific special import locations such as
+    the Windows registry.
     """
     for importer in iter_importers(fullname):
         loader = importer.find_module(fullname)
@@ -492,21 +497,22 @@
 def extend_path(path, name):
     """Extend a package's path.
 
-    Intended use is to place the following code in a package's __init__.py:
+    Intended use is to place the following code in a package's
+    ``__init__.py``::
 
         from pkgutil import extend_path
         __path__ = extend_path(__path__, __name__)
 
-    This will add to the package's __path__ all subdirectories of
-    directories on sys.path named after the package.  This is useful
+    This will add to the package's ``__path__`` all subdirectories of
+    directories on ``sys.path`` named after the package.  This is useful
     if one wants to distribute different parts of a single logical
     package as multiple directories.
 
-    It also looks for \*.pkg files beginning where \* matches the name
-    argument.  This feature is similar to \*.pth files (see site.py),
-    except that it doesn't special-case lines starting with 'import'.
-    A \*.pkg file is trusted at face value: apart from checking for
-    duplicates, all entries found in a \*.pkg file are added to the
+    It also looks for ``*.pkg`` files beginning where ``*`` matches the name
+    argument.  This feature is similar to ``*.pth`` files (see ``site.py``),
+    except that it doesn't special-case lines starting with ``import``.
+    A ``*.pkg`` file is trusted at face value: apart from checking for
+    duplicates, all entries found in a ``*.pkg`` file are added to the
     path, regardless of whether they are exist the filesystem.  (This
     is a feature.)
 
@@ -519,7 +525,7 @@
     are not (unicode or 8-bit) strings referring to existing
     directories are ignored.  Unicode items of sys.path that cause
     errors when used as filenames may cause this function to raise an
-    exception (in line with os.path.isdir() behavior).
+    exception (in line with ``os.path.isdir()`` behavior).
     """
 
     if not isinstance(path, list):
@@ -567,23 +573,23 @@
 def get_data(package, resource):
     """Get a resource from a package.
 
-    This is a wrapper round the PEP 302 loader get_data API. The package
+    This is a wrapper round the :pep:`302` loader get_data API. The package
     argument should be the name of a package, in standard module format
-    (foo.bar). The resource argument should be in the form of a relative
-    filename, using '/' as the path separator. The parent directory name '..'
-    is not allowed, and nor is a rooted name (starting with a '/').
+    (``foo.bar``). The resource argument should be in the form of a relative
+    filename, using ``'/'`` as the path separator. The parent directory name
+    ``'..'`` is not allowed, and nor is a rooted name (starting with a ``'/'``).
 
     The function returns a binary string, which is the contents of the
     specified resource.
 
     For packages located in the filesystem, which have already been imported,
-    this is the rough equivalent of
+    this is the rough equivalent of::
 
         d = os.path.dirname(sys.modules[package].__file__)
         data = open(os.path.join(d, resource), 'rb').read()
 
-    If the package cannot be located or loaded, or it uses a PEP 302 loader
-    which does not support get_data(), then None is returned.
+    If the package cannot be located or loaded, or it uses a :pep:`302` loader
+    which does not support :func:`get_data`, then ``None`` is returned.
     """
 
     loader = get_loader(package)
@@ -610,7 +616,7 @@
 
 class Distribution(object):
     """Created with the *path* of the ``.dist-info`` directory provided to the
-    constructor. It reads the metadata contained in METADATA when it is
+    constructor. It reads the metadata contained in ``METADATA`` when it is
     instantiated."""
 
     # Attribute documenting for Sphinx style documentation, see for more info:
@@ -619,9 +625,9 @@
     """The name of the distribution."""
     metadata = None
     """A :class:`distutils2.metadata.DistributionMetadata` instance loaded with
-    the distribution's METADATA file."""
+    the distribution's ``METADATA`` file."""
     requested = False
-    """A boolean that indicates whether the REQUESTED metadata file is present
+    """A boolean that indicates whether the ``REQUESTED`` metadata file is present
     (in other words, whether the package was installed by user request)."""
 
     def __init__(self, path):
@@ -642,10 +648,10 @@
 
     def get_installed_files(self, local=False):
         """
-        Iterates over the RECORD entries and returns a tuple (path, md5, size)
-        for each line. If *local* is ``True``, the returned path is transformed
-        into a local absolute path. Otherwise the raw value from RECORD is
-        returned.
+        Iterates over the ``RECORD`` entries and returns a tuple
+        ``(path, md5, size)`` for each line. If *local* is ``True``,
+        the returned path is transformed into a local absolute path.
+        Otherwise the raw value from RECORD is returned.
 
         A local absolute path is an absolute path in which occurrences of
         ``'/'`` have been replaced by the system separator given by ``os.sep``.
@@ -660,7 +666,7 @@
 
     def uses(self, path):
         """
-        Returns ``True`` if path is listed in RECORD. *path* can be a local
+        Returns ``True`` if path is listed in ``RECORD``. *path* can be a local
         absolute path or a relative ``'/'``-separated path.
 
         :rtype: boolean
@@ -682,8 +688,8 @@
                          directory path, a :class:`DistutilsError` is raised
         :type path: string
         :parameter binary: If *binary* is ``True``, opens the file in read-only
-                           binary mode (rb), otherwise opens it in read-only
-                           mode (r).
+                           binary mode (``rb``), otherwise opens it in read-only
+                           mode (``r``).
         :rtype: file object
         """
         open_flags = 'r'
@@ -710,13 +716,13 @@
 
     def get_distinfo_files(self, local=False):
         """
-        Iterates over the RECORD entries and returns paths for each line if the
-        path is pointing to a file located in the ``.dist-info`` directory or
-        one of its subdirectories.
+        Iterates over the ``RECORD`` entries and returns paths for each line if
+        the path is pointing to a file located in the ``.dist-info`` directory
+        or one of its subdirectories.
 
         :parameter local: If *local* is ``True``, each returned path is
                           transformed into a local absolute path. Otherwise the
-                          raw value from RECORD is returned.
+                          raw value from ``RECORD`` is returned.
         :type local: boolean
         :returns: iterator of paths
         """
@@ -728,13 +734,13 @@
     """Created with the *path* of the ``.egg-info`` directory or file provided
     to the constructor. It reads the metadata contained in the file itself, or
     if the given path happens to be a directory, the metadata is read from the
-    file PKG-INFO under that directory."""
+    file ``PKG-INFO`` under that directory."""
 
     name = ''
     """The name of the distribution."""
     metadata = None
     """A :class:`distutils2.metadata.DistributionMetadata` instance loaded with
-    the distribution's METADATA file."""
+    the distribution's ``METADATA`` file."""
     _REQUIREMENT = re.compile( \
         r'(?P<name>[-A-Za-z0-9_.]+)\s*' \
         r'(?P<first>(?:<|<=|!=|==|>=|>)[-A-Za-z0-9_.]+)?\s*' \
@@ -896,8 +902,8 @@
     """
     Scans all elements in ``sys.path`` and looks for all directories ending with
     ``.dist-info``. Returns a :class:`Distribution` corresponding to the
-    ``.dist-info`` directory that contains the METADATA that matches *name* for
-    the *name* metadata field.
+    ``.dist-info`` directory that contains the ``METADATA`` that matches *name*
+    for the *name* metadata field.
     If no distribution exists with the given *name* and the parameter
     *use_egg_info* is set to ``True``, then all files and directories ending
     with ``.egg-info`` are scanned. A :class:`EggInfoDistribution` instance is
diff --git a/src/distutils2/depgraph.py b/src/distutils2/depgraph.py
--- a/src/distutils2/depgraph.py
+++ b/src/distutils2/depgraph.py
@@ -7,7 +7,7 @@
 from distutils2.errors import DistutilsError
 from distutils2.version import VersionPredicate
 
-__all__ = ['DependencyGraph', 'generate_graph']
+__all__ = ['DependencyGraph', 'generate_graph', 'dependent_dists']
 
 
 class DependencyGraph(object):

--
Repository URL: http://hg.python.org/distutils2


More information about the Python-checkins mailing list