Commits

Ryan Macy  committed fd6e672

- Attempted to increase readability
- Fixed various typos
- Consistent spacing and styling

  • Participants
  • Parent commits 253a7fd

Comments (0)

Files changed (10)

File docs/database.rst

 =================================================================
 
 .. module:: distlib.database
-   :synopsis: Functions to query and manipulate installed distributions.
-
+    :synopsis: Functions to query and manipulate installed distributions.
 
 This module provides an implementation of :PEP:`376`.
 
 .. warning:: This documentation has not been updated since being copied over
-   from ``distutils2``, and may not be up to date.
+   from ``distutils2`` and may not be up to date.
 
 Installed Python distributions are represented by instances of
 :class:`Distribution`, or :class:`EggInfoDistribution` for legacy egg formats.
 distributions into account.
 
 For the purpose of this module, "installed" means that the distribution's
-:file:`.dist-info`, :file:`.egg-info` or :file:`egg` directory or file is found
+:file:`.dist-info` or :file:`.egg-info` or :file:`egg` directory is found
 on :data:`sys.path`.  For example, if the parent directory of a
-:file:`dist-info` directory  is added to :envvar:`PYTHONPATH`, then it will be
+:file:`dist-info` directory is added to :envvar:`PYTHONPATH`, then it will be
 available in the database.
 
 Classes representing installed distributions
 
 .. class:: InstalledDistribution(path)
 
-   Class representing an installed distribution.
+    Class representing an installed distribution.
 
-   Instantiate with the *path* to a ``.dist-info`` directory.  Instances can be
-   compared and sorted.  Other available methods are:
+    Instantiate with the *path* to a ``.dist-info`` directory.  Instances can be
+    compared and sorted.  Other available methods are:
 
-   .. XXX describe how comparison works
+    .. XXX describe how comparison works
 
-   .. method:: get_distinfo_file(path, binary=False)
+    .. method:: get_distinfo_file(path, binary=False)
 
-      Return a read-only file object for a file located at
-      :file:`{project}-{version}.dist-info/{path}`.  *path* should be a
-      ``'/'``-separated path relative to the ``.dist-info`` directory or an
-      absolute path; if it is an absolute path and doesn't start with the path
-      to the :file:`.dist-info` directory, a :class:`DistlibException` is
-      raised.
+        Return a read-only file object for a file located at
+        :file:`{project}-{version}.dist-info/{path}`.  *path* should be a
+        ``'/'``-separated path relative to the ``.dist-info`` directory or an
+        absolute path; if it is an absolute path and doesn't start with the path
+        to the :file:`.dist-info` directory, a :class:`DistlibException` is
+        raised.
 
-      If *binary* is ``True``, the file is opened in binary mode.
+        If *binary* is ``True``, the file is opened in binary mode.
 
-   .. method:: get_resource_path(relative_path)
+    .. method:: get_resource_path(relative_path)
 
-      .. TODO
+        .. TODO
 
-   .. method:: list_distinfo_files(local=False)
+    .. method:: list_distinfo_files(local=False)
 
-      Return an iterator over all files located in the :file:`.dist-info`
-      directory.  If *local* is ``True``, each returned path is transformed into
-      a local absolute path, otherwise the raw value found in the :file:`RECORD`
-      file is returned.
+        Return an iterator over all files located in the :file:`.dist-info`
+        directory.  If *local* is ``True``, each returned path is transformed into
+        a local absolute path, otherwise the raw value found in the :file:`RECORD`
+        file is returned.
 
-   .. method::  list_installed_files(local=False)
+    .. method::  list_installed_files(local=False)
 
-      Iterate over the files installed with the distribution and registered in
-      the :file:`RECORD` file and yield 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 is returned.
+        Iterate over the files installed with the distribution and registered in
+        the :file:`RECORD` file and yield 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 is returned.
 
-      A local absolute path is an absolute path in which occurrences of ``'/'``
-      have been replaced by :data:`os.sep`.
+        A local absolute path is an absolute path in which occurrences of ``'/'``
+        have been replaced by :data:`os.sep`.
 
-   .. method:: uses(path)
+    .. method:: uses(path)
 
-      Check whether *path* was installed by this distribution (i.e. if the path
-      is present in the :file:`RECORD` file).  *path* can be a local absolute
-      path or a relative ``'/'``-separated path.  Returns a boolean.
+        Check whether *path* was installed by this distribution (i.e. if the path
+        is present in the :file:`RECORD` file). *path* can be a local absolute
+        path or a relative ``'/'``-separated path. Returns a boolean.
 
-   Available attributes:
+    Available attributes:
 
-   .. attribute:: metadata
+    .. attribute:: metadata
 
-      Instance of :class:`distlib.metadata.Metadata` filled with the contents
-      of the :file:`{project}-{version}.dist-info/METADATA` file.
+        Instance of :class:`distlib.metadata.Metadata` filled with the contents
+        of the :file:`{project}-{version}.dist-info/METADATA` file.
 
-   .. attribute:: name
+    .. attribute:: name
 
-      Shortcut for ``metadata['Name']``.
+        Shortcut for ``metadata['Name']``.
 
-   .. attribute:: version
+    .. attribute:: version
 
-      Shortcut for ``metadata['Version']``.
+        Shortcut for ``metadata['Version']``.
 
-   .. attribute:: requested
+    .. attribute:: requested
 
-      Boolean indicating whether this distribution was requested by the user of
-      automatically installed as a dependency.
-
+        Boolean indicating whether this distribution was requested by the user of
+        automatically installed as a dependency.
 
 .. class:: EggInfoDistribution(path)
 
-   Class representing a legacy distribution.  It is compatible with distutils'
-   and setuptools' :file:`.egg-info` and :file:`.egg` files and directories.
+    Class representing a legacy distribution.  It is compatible with distutils'
+    and setuptools' :file:`.egg-info` and :file:`.egg` files and directories.
 
-   .. FIXME should be named EggDistribution
+    .. FIXME should be named EggDistribution
 
-   Instantiate with the *path* to an egg file or directory.  Instances can be
-   compared and sorted.  Other available methods are:
+    Instantiate with the *path* to an egg file or directory. Instances can be
+    compared and sorted. Other available methods are:
 
-   .. method:: list_installed_files(local=False)
+    .. method:: list_installed_files(local=False)
 
-   .. method:: uses(path)
+    .. method:: uses(path)
 
-   Available attributes:
+    Available attributes:
 
-   .. attribute:: metadata
+    .. attribute:: metadata
 
-      Instance of :class:`distlib.metadata.Metadata` filled with the contents
-      of the :file:`{project-version}.egg-info/PKG-INFO` or
-      :file:`{project-version}.egg` file.
+        Instance of :class:`distlib.metadata.Metadata` filled with the contents
+        of the :file:`{project-version}.egg-info/PKG-INFO` or
+        :file:`{project-version}.egg` file.
 
-   .. attribute:: name
+    .. attribute:: name
 
-      Shortcut for ``metadata['Name']``.
+        Shortcut for ``metadata['Name']``.
 
-   .. attribute:: version
+    .. attribute:: version
 
-      Shortcut for ``metadata['Version']``.
-
+        Shortcut for ``metadata['Version']``.
 
 Functions to work with the database
 -----------------------------------
 
 .. function:: get_distribution(name, use_egg_info=False, paths=None)
 
-   Return an instance of :class:`Distribution` or :class:`EggInfoDistribution`
-   for the first installed distribution matching *name*.  Egg distributions are
-   considered only if *use_egg_info* is true; if both a dist-info and an egg
-   file are found, the dist-info prevails.  The directories to be searched are
-   given in *paths*, which defaults to :data:`sys.path`.  Returns ``None`` if no
-   matching distribution is found.
+    Return an instance of :class:`Distribution` or :class:`EggInfoDistribution`
+    for the first installed distribution matching *name*.  Egg distributions are
+    considered only if *use_egg_info* is true; if both a dist-info and an egg
+    file are found, the dist-info prevails.  The directories to be searched are
+    given in *paths*, which defaults to :data:`sys.path`.  Returns ``None`` if no
+    matching distribution is found.
 
-   .. FIXME param should be named use_egg
-
+    .. FIXME param should be named use_egg
 
 .. function:: get_distributions(use_egg_info=False, paths=None)
 
-   Return an iterator of :class:`Distribution` instances for all installed
-   distributions found in *paths* (defaults to :data:`sys.path`).  If
-   *use_egg_info* is true, also return instances of :class:`EggInfoDistribution`
-   for legacy distributions found.
-
+    Return an iterator of :class:`Distribution` instances for all installed
+    distributions found in *paths* (defaults to :data:`sys.path`).  If
+    *use_egg_info* is true, also return instances of :class:`EggInfoDistribution`
+    for legacy distributions found.
 
 .. function:: get_file_users(path)
 
-   Return an iterator over all distributions using *path*, a local absolute path
-   or a relative ``'/'``-separated path.
+    Return an iterator over all distributions using *path*, a local absolute path
+    or a relative ``'/'``-separated path.
 
-   .. XXX does this work with prefixes or full file path only?
-
+    .. XXX does this work with prefixes or full file path only?
 
 .. function:: obsoletes_distribution(name, version=None, use_egg_info=False)
 
-   Return an iterator over all distributions that declare they obsolete *name*.
-   *version* is an optional argument to match only specific releases (see
-   :mod:`distlib.version`).  If *use_egg_info* is true, legacy egg
-   distributions will be considered as well.
-
+    Return an iterator over all distributions that declare they obsolete *name*.
+    *version* is an optional argument to match only specific releases (see
+    :mod:`distlib.version`).  If *use_egg_info* is true, legacy egg
+    distributions will be considered as well.
 
 .. function:: provides_distribution(name, version=None, use_egg_info=False)
 
-   Return an iterator over all distributions that declare they provide *name*.
-   *version* is an optional argument to match only specific releases (see
-   :mod:`distlib.version`).  If *use_egg_info* is true, legacy egg
-   distributions will be considered as well.
-
+    Return an iterator over all distributions that declare they provide *name*.
+    *version* is an optional argument to match only specific releases (see
+    :mod:`distlib.version`).  If *use_egg_info* is true, legacy egg
+    distributions will be considered as well.
 
 Utility functions
 -----------------
 
 .. function:: distinfo_dirname(name, version)
 
-   Escape *name* and *version* into a filename-safe form and return the
-   directory name built from them, for example
-   :file:`{safename}-{safeversion}.dist-info.`  In *name*, runs of
-   non-alphanumeric characters are replaced with one ``'_'``; in *version*,
-   spaces become dots, and runs of other non-alphanumeric characters (except
-   dots) a replaced by one ``'-'``.
+    Escape *name* and *version* into a filename-safe form and return the
+    directory name built from them, for example
+    :file:`{safename}-{safeversion}.dist-info.`  In *name* runs of
+    non-alphanumeric characters are replaced with one ``'_'``, in *version*
+    spaces become dots, and runs of other non-alphanumeric characters (except
+    dots) are replaced by one ``'-'``.
 
-   .. XXX wth spaces in version numbers?
+    .. XXX wth spaces in version numbers?
 
 For performance purposes, the list of distributions is being internally
-cached.   Caching is enabled by default, but you can control it with these
+cached. Caching is enabled by default, but you can control it with these
 functions:
 
 .. function:: clear_cache()
 
-   Clear the cache.
+    Clear the cache.
 
 .. function:: disable_cache()
 
-   Disable the cache, without clearing it.
+    Disable the cache, without clearing it.
 
 .. function:: enable_cache()
 
-   Enable the internal cache, without clearing it.
-
+    Enable the internal cache, without clearing it.
 
 Examples
 --------
 Given the name of an installed distribution, we shall print out all
 information that can be obtained using functions provided in this module::
 
-   import sys
-   import distlib.database
+    import sys
+    import distlib.database
 
-   try:
-       name = sys.argv[1]
-   except ValueError:
-       sys.exit('Not enough arguments')
+    try:
+        name = sys.argv[1]
+    except ValueError:
+        sys.exit('Not enough arguments')
 
-   # first create the Distribution instance
-   dist = distlib.database.Distribution(path)
-   if dist is None:
-       sys.exit('No such distribution')
+    # first create the Distribution instance
+    dist = distlib.database.Distribution(path)
+    if dist is None:
+        sys.exit('No such distribution')
 
-   print('Information about %r' % dist.name)
-   print()
+    print('Information about %r' % dist.name)
+    print()
 
-   print('Files')
-   print('=====')
-   for path, md5, size in dist.list_installed_files():
-       print('* Path: %s' % path)
-       print('  Hash %s, Size: %s bytes' % (md5, size))
-   print()
+    print('Files')
+    print('=====')
+    for path, md5, size in dist.list_installed_files():
+        print('* Path: %s' % path)
+        print('  Hash %s, Size: %s bytes' % (md5, size))
+    print()
 
-   print('Metadata')
-   print('========')
-   for key, value in dist.metadata.items():
-       print('%20s: %s' % (key, value))
-   print()
+    print('Metadata')
+    print('========')
+    for key, value in dist.metadata.items():
+        print('%20s: %s' % (key, value))
+    print()
 
-   print('Extra')
-   print('=====')
-   if dist.requested:
-       print('* It was installed by user request')
-   else:
-       print('* It was installed as a dependency')
+    print('Extra')
+    print('=====')
+    if dist.requested:
+        print('* It was installed by user request')
+    else:
+        print('* It was installed as a dependency')
 
 If we save the script above as ``print_info.py``, we can use it to extract
 information from a :file:`.dist-info` directory.  By typing in the console:
 
 .. code-block:: sh
 
-   python print_info.py choxie
+    python print_info.py choxie
 
 we get the following output:
 
 .. code-block:: none
 
-   Information about 'choxie'
+    Information about 'choxie'
 
-   Files
-   =====
-   * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/truffles.py
-     Hash 5e052db6a478d06bad9ae033e6bc08af, Size: 111 bytes
-   * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/chocolate.py
-     Hash ac56bf496d8d1d26f866235b95f31030, Size: 214 bytes
-   * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/__init__.py
-     Hash 416aab08dfa846f473129e89a7625bbc, Size: 25 bytes
-   * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/INSTALLER
-     Hash d41d8cd98f00b204e9800998ecf8427e, Size: 0 bytes
-   * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/METADATA
-     Hash 696a209967fef3c8b8f5a7bb10386385, Size: 225 bytes
-   * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/REQUESTED
-     Hash d41d8cd98f00b204e9800998ecf8427e, Size: 0 bytes
-   * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/RECORD
-     Hash None, Size: None bytes
+    Files
+    =====
+    * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/truffles.py
+    Hash 5e052db6a478d06bad9ae033e6bc08af, Size: 111 bytes
+    * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/chocolate.py
+    Hash ac56bf496d8d1d26f866235b95f31030, Size: 214 bytes
+    * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/__init__.py
+    Hash 416aab08dfa846f473129e89a7625bbc, Size: 25 bytes
+    * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/INSTALLER
+    Hash d41d8cd98f00b204e9800998ecf8427e, Size: 0 bytes
+    * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/METADATA
+    Hash 696a209967fef3c8b8f5a7bb10386385, Size: 225 bytes
+    * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/REQUESTED
+    Hash d41d8cd98f00b204e9800998ecf8427e, Size: 0 bytes
+    * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/RECORD
+    Hash None, Size: None bytes
 
-   Metadata
-   ========
+    Metadata
+    ========
        Metadata-Version: 1.2
                    Name: choxie
                 Version: 2.0.0.9
         Requires-Python: UNKNOWN
       Requires-External: []
 
-  Extra
-  =====
-  * It was installed as a dependency
-
+    Extra
+    =====
+    * It was installed as a dependency
 
 Getting metadata about a distribution
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 full :class:`Distribution` object but just want to do something with its
 :attr:`~Distribution.metadata`::
 
-   >>> from distlib.database import get_distribution
-   >>> info = get_distribution('chocolate').metadata
-   >>> info['Keywords']
-   ['cooking', 'happiness']
-
+    >>> from distlib.database import get_distribution
+    >>> info = get_distribution('chocolate').metadata
+    >>> info['Keywords']
+    ['cooking', 'happiness']
+    >>>
 
 Finding out obsoleted distributions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 Now, we tackle a different problem, we are interested in finding out
 which distributions have been obsoleted. This can be easily done as follows::
 
-  import distlib.database
+    import distlib.database
 
-  # iterate over all distributions in the system
-  for dist in distlib.database.get_distributions():
-      name, version = dist.name, dist.version
-      # find out which distributions obsolete this name/version combination
-      replacements = distlib.database.obsoletes_distribution(name, version)
-      if replacements:
-          print('%r %s is obsoleted by' % (name, version),
-                ', '.join(repr(r.name) for r in replacements))
+    # iterate over all distributions in the system
+    for dist in distlib.database.get_distributions():
+        name, version = dist.name, dist.version
+        # find out which distributions obsolete this name/version combination
+        replacements = distlib.database.obsoletes_distribution(name, version)
+        if replacements:
+            print('%r %s is obsoleted by' % (name, version),
+                    ', '.join(repr(r.name) for r in replacements))
 
 This is how the output might look like:
 
 .. code-block:: none
 
-  'strawberry' 0.6 is obsoleted by 'choxie'
-  'grammar' 1.0a4 is obsoleted by 'towel-stuff'
+    'strawberry' 0.6 is obsoleted by 'choxie'
+    'grammar' 1.0a4 is obsoleted by 'towel-stuff'

File docs/depgraph.rst

 ======================================================
 
 .. module:: distlib.depgraph
-   :synopsis: Graph builder for dependencies between releases.
-
+    :synopsis: Graph builder for dependencies between releases.
 
 This module provides the means to analyse the dependencies between various
 distributions and to create a graph representing these dependency relationships.
 :class:`distlib.database.EggInfoDistribution`.
 
 .. warning:: This documentation has not been updated since being copied over
-   from ``distutils2``, and may not be up to date.
+   from ``distutils2`` and may not be up to date.
 
 .. XXX terminology problem with dist vs. release: dists are installed, but deps
    use releases
 
 .. XXX functions should accept and return iterators, not lists
 
-
 The :class:`DependencyGraph` class
 ----------------------------------
 
 .. class:: DependencyGraph
 
-   Represent a dependency graph between releases.  The nodes are distribution
-   instances; the edge model dependencies.  An edge from ``a`` to ``b`` means
-   that ``a`` depends on ``b``.
+    Represent a dependency graph between releases.  The nodes are distribution
+    instances, the edge model dependencies.  An edge from ``a`` to ``b`` means
+    that ``a`` depends on ``b``.
 
-   .. method:: add_distribution(distribution)
+    .. method:: add_distribution(distribution)
 
-      Add *distribution* to the graph.
+        Add *distribution* to the graph.
 
-   .. method:: add_edge(x, y, label=None)
+    .. method:: add_edge(x, y, label=None)
 
-      Add an edge from distribution *x* to distribution *y* with the given
-      *label* (string).
+        Add an edge from distribution *x* to distribution *y* with the given
+        *label* (string).
 
-   .. method:: add_missing(distribution, requirement)
+    .. method:: add_missing(distribution, requirement)
 
-      Add a missing *requirement* (string) for the given *distribution*.
+        Add a missing *requirement* (string) for the given *distribution*.
 
-   .. method:: repr_node(dist, level=1)
+    .. method:: repr_node(dist, level=1)
 
-      Print a subgraph starting from *dist*.  *level* gives the depth of the
-      subgraph.
+        Print a subgraph starting from *dist*.  *level* gives the depth of the
+        subgraph.
 
-   Direct access to the graph nodes and edges is provided through these
-   attributes:
+    Direct access to the graph nodes and edges is provided through these
+    attributes:
 
-   .. attribute:: adjacency_list
+    .. attribute:: adjacency_list
 
-      Dictionary mapping distributions to a list of ``(other, label)`` tuples
-      where  ``other`` is a distribution and the edge is labeled with ``label``
-      (i.e. the version specifier, if such was provided).
+        Dictionary mapping distributions to a list of ``(other, label)`` tuples
+        where  ``other`` is a distribution and the edge is labeled with ``label``
+        (i.e. the version specifier, if such was provided).
 
-   .. attribute:: reverse_list
+    .. attribute:: reverse_list
 
-      Dictionary mapping distributions to a list of predecessors.  This allows
-      efficient traversal.
+        Dictionary mapping distributions to a list of predecessors.  This allows
+        efficient traversal.
 
-   .. attribute:: missing
+    .. attribute:: missing
 
-      Dictionary mapping distributions to a list of requirements that were not
-      provided by any distribution.
-
+        Dictionary mapping distributions to a list of requirements that were not
+        provided by any distribution.
 
 Auxiliary functions
 -------------------
 
 .. function:: get_dependent_dists(dists, dist)
 
-   Recursively generate a list of distributions from *dists* that are dependent
-   on *dist*.
+    Recursively generate a list of distributions from *dists* that are dependent
+    on *dist*.
 
-   .. XXX what does member mean here: "dist is a member of *dists* for which we
-      are interested"
+    .. XXX what does member mean here: "dist is a member of *dists* for which we
+    are interested"
 
 .. function:: make_graph(dists)
 
-   Generate a :class:`DependencyGraph` from the given list of distributions.
+    Generate a :class:`DependencyGraph` from the given list of distributions.
 
 Example Usage
 -------------
 and then create an image out of it using the tools provided by
 `Graphviz <http://www.graphviz.org/>`_::
 
-   from distlib.database import get_distributions
-   from distlib.depgraph import generate_graph
+    from distlib.database import get_distributions
+    from distlib.depgraph import generate_graph
 
-   dists = list(get_distributions())
-   graph = generate_graph(dists)
+    dists = list(get_distributions())
+    graph = generate_graph(dists)
 
 It would be interesting to print out the missing requirements.  This can be done
 as follows::
 
-   for dist, reqs in graph.missing.items():
-       if reqs:
-           reqs = ' ,'.join(repr(req) for req in reqs)
-           print('Missing dependencies for %r: %s' % (dist.name, reqs))
+    for dist, reqs in graph.missing.items():
+        if reqs:
+             reqs = ' ,'.join(repr(req) for req in reqs)
+             print('Missing dependencies for %r: %s' % (dist.name, reqs))
 
 Example output is:
 
 .. code-block:: none
 
-   Missing dependencies for 'TurboCheetah': 'Cheetah'
-   Missing dependencies for 'TurboGears': 'ConfigObj', 'DecoratorTools', 'RuleDispatch'
-   Missing dependencies for 'jockey': 'PyKDE4.kdecore', 'PyKDE4.kdeui', 'PyQt4.QtCore', 'PyQt4.QtGui'
-   Missing dependencies for 'TurboKid': 'kid'
-   Missing dependencies for 'TurboJson: 'DecoratorTools', 'RuleDispatch'
+     Missing dependencies for 'TurboCheetah': 'Cheetah'
+     Missing dependencies for 'TurboGears': 'ConfigObj', 'DecoratorTools', 'RuleDispatch'
+     Missing dependencies for 'jockey': 'PyKDE4.kdecore', 'PyKDE4.kdeui', 'PyQt4.QtCore', 'PyQt4.QtGui'
+     Missing dependencies for 'TurboKid': 'kid'
+     Missing dependencies for 'TurboJson: 'DecoratorTools', 'RuleDispatch'
 
 Now, we proceed with generating a graphical representation of the graph. First
 we write it to a file, and then we generate a PNG image using the
 :program:`dot` command-line tool::
 
-   from distlib.depgraph import graph_to_dot
-   with open('output.dot', 'w') as f:
-      # only show the interesting distributions, skipping the disconnected ones
-      graph_to_dot(graph, f, skip_disconnected=True)
+    from distlib.depgraph import graph_to_dot
+    with open('output.dot', 'w') as f:
+        # only show the interesting distributions, skipping the disconnected ones
+        graph_to_dot(graph, f, skip_disconnected=True)
 
 We can create the final picture using:
 
 .. code-block:: sh
 
-   $ dot -Tpng output.dot > output.png
+    $ dot -Tpng output.dot > output.png
 
 An example result is:
 
 .. figure:: depgraph-output.png
-   :alt: Example PNG output from distlib.depgraph and dot
+    :alt: Example PNG output from distlib.depgraph and dot
 
 If you want to include egg distributions as well, then the code requires only
 one change, namely the line::
 
-   dists = list(distlib.database.get_distributions())
+    dists = list(distlib.database.get_distributions())
 
 has to be replaced with::
 
-   dists = list(distlib.database.get_distributions(use_egg_info=True))
+    dists = list(distlib.database.get_distributions(use_egg_info=True))
 
 On many platforms, a richer graph is obtained because at the moment most
 distributions are provided in the egg rather than the new standard
 
 .. XXX missing image
 
-   An example of a more involved graph for illustrative reasons can be seen
-   here:
+    An example of a more involved graph for illustrative reasons can be seen
+    here:
 
-   .. image:: depgraph_big.png
-
+    .. image:: depgraph_big.png
 
 List all dependent distributions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 We will list all distributions that are dependent on some given distibution.
 This time, egg distributions will be considered as well::
 
-   import sys
-   from distlib.database import get_distribution, get_distributions
-   from distlib.depgraph import dependent_dists
+    import sys
+    from distlib.database import get_distribution, get_distributions
+    from distlib.depgraph import dependent_dists
 
-   dists = list(get_distributions(use_egg_info=True))
-   dist = get_distribution('bacon', use_egg_info=True)
-   if dist is None:
-       sys.exit('No such distribution in the system')
+    dists = list(get_distributions(use_egg_info=True))
+    dist = get_distribution('bacon', use_egg_info=True)
+    if dist is None:
+        sys.exit('No such distribution in the system')
 
-   deps = dependent_dists(dists, dist)
-   deps = ', '.join(repr(x.name) for x in deps)
-   print('Distributions depending on %r: %s' % (dist.name, deps))
+    deps = dependent_dists(dists, dist)
+    deps = ', '.join(repr(x.name) for x in deps)
+    print('Distributions depending on %r: %s' % (dist.name, deps))
 
 And this is example output:
 
 
 .. code-block:: none
 
-   Distributions depending on 'bacon': 'towel-stuff', 'choxie', 'grammar'
+    Distributions depending on 'bacon': 'towel-stuff', 'choxie', 'grammar'

File docs/dist.rst

 ================================================
 
 .. module:: packaging.dist
-   :synopsis: Core Distribution class.
+    :synopsis: Core Distribution class.
 
 
 This module provides the :class:`Distribution` class, which represents the
 
 .. class:: Distribution(arguments)
 
-   A :class:`Distribution` describes how to build, package, distribute and
-   install a Python project.
+    A :class:`Distribution` describes how to build, package, distribute and
+    install a Python project.
 
-   The arguments accepted by the constructor are laid out in the following
-   table.  Some of them will end up in a metadata object, the rest will become
-   data attributes of the :class:`Distribution` instance.
+    The arguments accepted by the constructor are laid out in the following
+    table.  Some of them will end up in a metadata object, the rest will become
+    data attributes of the :class:`Distribution` instance.
 
-   .. TODO improve constructor to take a Metadata object + named params?
-      (i.e. Distribution(metadata, cmdclass, py_modules, etc)
-   .. TODO also remove obsolete(?) script_name, etc. parameters?  see what
-      py2exe and other tools need
+    .. TODO improve constructor to take a Metadata object + named params?
+       (i.e. Distribution(metadata, cmdclass, py_modules, etc)
+    .. TODO also remove obsolete(?) script_name, etc. parameters?  see what
+       py2exe and other tools need
 
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | argument name      | value                          | type                                                        |
-   +====================+================================+=============================================================+
-   | *name*             | The name of the project        | a string                                                    |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *version*          | The version number of the      | a string                                                    |
-   |                    | release; see                   |                                                             |
-   |                    | :mod:`packaging.version`       |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *summary*          | A single line describing the   | a string                                                    |
-   |                    | project                        |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *description*      | Longer description of the      | a string                                                    |
-   |                    | project                        |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *author*           | The name of the project author | a string                                                    |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *author_email*     | The email address of the       | a string                                                    |
-   |                    | project author                 |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *maintainer*       | The name of the current        | a string                                                    |
-   |                    | maintainer, if different from  |                                                             |
-   |                    | the author                     |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *maintainer_email* | The email address of the       | a string                                                    |
-   |                    | current maintainer, if         |                                                             |
-   |                    | different from the author      |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *home_page*        | A URL for the proejct          | a string                                                    |
-   |                    | (homepage)                     |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *download_url*     | A URL to download the project  | a string                                                    |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *packages*         | A list of Python packages that | a list of strings                                           |
-   |                    | packaging will manipulate      |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *py_modules*       | A list of Python modules that  | a list of strings                                           |
-   |                    | packaging will manipulate      |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *scripts*          | A list of standalone scripts   | a list of strings                                           |
-   |                    | to be built and installed      |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *ext_modules*      | A list of Python extensions to | a list of instances of                                      |
-   |                    | be built                       | :class:`packaging.compiler.extension.Extension`             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *classifiers*      | A list of categories for the   | a list of strings; valid classifiers are listed on `PyPi    |
-   |                    | distribution                   | <http://pypi.python.org/pypi?:action=list_classifiers>`_.   |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *distclass*        | the :class:`Distribution`      | a subclass of                                               |
-   |                    | class to use                   | :class:`packaging.dist.Distribution`                        |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *script_name*      | The name of the setup.py       | a string                                                    |
-   |                    | script - defaults to           |                                                             |
-   |                    | ``sys.argv[0]``                |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *script_args*      | Arguments to supply to the     | a list of strings                                           |
-   |                    | setup script                   |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *options*          | default options for the setup  | a string                                                    |
-   |                    | script                         |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *license*          | The license for the            | a string                                                    |
-   |                    | distribution; should be used   |                                                             |
-   |                    | when there is no suitable      |                                                             |
-   |                    | License classifier, or to      |                                                             |
-   |                    | refine a classifier            |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *keywords*         | Descriptive keywords; used by  | a list of strings or a comma-separated string               |
-   |                    | catalogs such as PyPI          |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *platforms*        | Platforms compatible with this | a list of strings or a comma-separated string               |
-   |                    | distribution; should be used   |                                                             |
-   |                    | when there is no suitable      |                                                             |
-   |                    | Platform classifier            |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *cmdclass*         | A mapping of command names to  | a dictionary                                                |
-   |                    | :class:`Command` subclasses    |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *data_files*       | A list of data files to        | a list                                                      |
-   |                    | install                        |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
-   | *package_dir*      | A mapping of Python packages   | a dictionary                                                |
-   |                    | to directory names             |                                                             |
-   +--------------------+--------------------------------+-------------------------------------------------------------+
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | argument name      | value                          | type                                                        |
+    +====================+================================+=============================================================+
+    | *name*             | The name of the project        | a string                                                    |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *version*          | The version number of the      | a string                                                    |
+    |                    | release; see                   |                                                             |
+    |                    | :mod:`packaging.version`       |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *summary*          | A single line describing the   | a string                                                    |
+    |                    | project                        |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *description*      | Longer description of the      | a string                                                    |
+    |                    | project                        |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *author*           | The name of the project author | a string                                                    |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *author_email*     | The email address of the       | a string                                                    |
+    |                    | project author                 |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *maintainer*       | The name of the current        | a string                                                    |
+    |                    | maintainer, if different from  |                                                             |
+    |                    | the author                     |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *maintainer_email* | The email address of the       | a string                                                    |
+    |                    | current maintainer, if         |                                                             |
+    |                    | different from the author      |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *home_page*        | A URL for the proejct          | a string                                                    |
+    |                    | (homepage)                     |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *download_url*     | A URL to download the project  | a string                                                    |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *packages*         | A list of Python packages that | a list of strings                                           |
+    |                    | packaging will manipulate      |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *py_modules*       | A list of Python modules that  | a list of strings                                           |
+    |                    | packaging will manipulate      |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *scripts*          | A list of standalone scripts   | a list of strings                                           |
+    |                    | to be built and installed      |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *ext_modules*      | A list of Python extensions to | a list of instances of                                      |
+    |                    | be built                       | :class:`packaging.compiler.extension.Extension`             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *classifiers*      | A list of categories for the   | a list of strings; valid classifiers are listed on `PyPi    |
+    |                    | distribution                   | <http://pypi.python.org/pypi?:action=list_classifiers>`_.   |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *distclass*        | the :class:`Distribution`      | a subclass of                                               |
+    |                    | class to use                   | :class:`packaging.dist.Distribution`                        |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *script_name*      | The name of the setup.py       | a string                                                    |
+    |                    | script - defaults to           |                                                             |
+    |                    | ``sys.argv[0]``                |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *script_args*      | Arguments to supply to the     | a list of strings                                           |
+    |                    | setup script                   |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *options*          | default options for the setup  | a string                                                    |
+    |                    | script                         |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *license*          | The license for the            | a string                                                    |
+    |                    | distribution; should be used   |                                                             |
+    |                    | when there is no suitable      |                                                             |
+    |                    | License classifier, or to      |                                                             |
+    |                    | refine a classifier            |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *keywords*         | Descriptive keywords; used by  | a list of strings or a comma-separated string               |
+    |                    | catalogs such as PyPI          |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *platforms*        | Platforms compatible with this | a list of strings or a comma-separated string               |
+    |                    | distribution; should be used   |                                                             |
+    |                    | when there is no suitable      |                                                             |
+    |                    | Platform classifier            |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *cmdclass*         | A mapping of command names to  | a dictionary                                                |
+    |                    | :class:`Command` subclasses    |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *data_files*       | A list of data files to        | a list                                                      |
+    |                    | install                        |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+
+    | *package_dir*      | A mapping of Python packages   | a dictionary                                                |
+    |                    | to directory names             |                                                             |
+    +--------------------+--------------------------------+-------------------------------------------------------------+

File docs/index.rst

 packaging tools. Using a common low-level layer will improve interoperability
 and consistency of user experience across those tools which use the library.
 
-**Please note:** this documentation is *work in progress*.
+**Please note:** this documentation is a *work in progress*.
 
 .. toctree::
-   :maxdepth: 4
+    :maxdepth: 4
 
-   overview
-   tutorial
-   internals
-   reference
-   migration
+    overview
+    tutorial
+    internals
+    reference
+    migration

File docs/metadata.rst

 ===============================================
 
 .. module:: distlib.metadata
-   :synopsis: Class holding the metadata of a release.
-
+    :synopsis: Class holding the metadata of a release.
 
 .. warning:: This documentation has not been updated since being copied over
-   from ``distutils2``, and may not be up to date.
+   from ``distutils2`` and may not be up to date.
 
 .. TODO use sphinx-autogen to generate basic doc from the docstrings
 
 .. class:: Metadata
 
-   This class can read and write metadata files complying with any of the
-   defined versions: 1.0 (:PEP:`241`), 1.1 (:PEP:`314`) and 1.2 (:PEP:`345`).  It
-   implements methods to parse Metadata files and write them, and a mapping
-   interface to its contents.
+    This class can read and write metadata files complying with any of the
+    defined versions: 1.0 (:PEP:`241`), 1.1 (:PEP:`314`) and 1.2 (:PEP:`345`).
+    It implements methods to parse Metadata files and write them and a mapping
+    interface to its contents.
 
-   The :PEP:`345` implementation supports the micro-language for the environment
-   markers, and displays warnings when versions that are supposed to be
-   :PEP:`386`-compliant are violating the specification.
-
+    The :PEP:`345` implementation supports the micro-language for the environment
+    markers and displays warnings when versions that are supposed to be
+    :PEP:`386`-compliant are violating the specification.
 
 Reading metadata
 ----------------
 
-The :class:`Metadata` class can be instantiated
-with the path of the metadata file, and provides a dict-like interface to the
-values::
+The :class:`Metadata` class can be instantiated with the path of the
+metadata file and provides a dict-like interface to the values::
 
-   >>> from distlib.metadata import Metadata
-   >>> metadata = Metadata('PKG-INFO')
-   >>> metadata.keys()[:5]
-   ('Metadata-Version', 'Name', 'Version', 'Platform', 'Supported-Platform')
-   >>> metadata['Name']
-   'CLVault'
-   >>> metadata['Version']
-   '0.5'
-   >>> metadata['Requires-Dist']
-   ["pywin32; sys.platform == 'win32'", "Sphinx"]
-
+    >>> from distlib.metadata import Metadata
+    >>> metadata = Metadata('PKG-INFO')
+    >>> metadata.keys()[:5]
+    ('Metadata-Version', 'Name', 'Version', 'Platform', 'Supported-Platform')
+    >>> metadata['Name']
+    'CLVault'
+    >>> metadata['Version']
+    '0.5'
+    >>> metadata['Requires-Dist']
+    ["pywin32; sys.platform == 'win32'", "Sphinx"]
+    >>>
 
 The fields that support environment markers can be automatically ignored if
 the object is instantiated using the ``platform_dependent`` option.
-:class:`Metadata` will interpret in this case
-the markers and will automatically remove the fields that are not compliant
-with the running environment. Here's an example under Mac OS X. The win32
-dependency we saw earlier is ignored::
+:class:`Metadata` will interpret in this case the markers and will automatically
+remove the fields that are not compliant with the running environment. Here's an
+example under Mac OS X. The win32 dependency we saw earlier is ignored::
 
-   >>> from distlib.metadata import Metadata
-   >>> metadata = Metadata('PKG-INFO', platform_dependent=True)
-   >>> metadata['Requires-Dist']
-   ['Sphinx']
-
+    >>> from distlib.metadata import Metadata
+    >>> metadata = Metadata('PKG-INFO', platform_dependent=True)
+    >>> metadata['Requires-Dist']
+    ['Sphinx']
+    >>>
 
 If you want to provide your own execution context, let's say to test the
 metadata under a particular environment that is not the current environment,
 
 Here's an example, simulating a win32 environment::
 
-   >>> from distlib.metadata import Metadata
-   >>> context = {'sys.platform': 'win32'}
-   >>> metadata = Metadata('PKG-INFO', platform_dependent=True,
-   ...                     execution_context=context)
-   ...
-   >>> metadata['Requires-Dist'] = ["pywin32; sys.platform == 'win32'",
-   ...                              "Sphinx"]
-   ...
-   >>> metadata['Requires-Dist']
-   ['pywin32', 'Sphinx']
-
+    >>> from distlib.metadata import Metadata
+    >>> context = {'sys.platform': 'win32'}
+    >>> metadata = Metadata('PKG-INFO', platform_dependent=True,
+    ...                     execution_context=context)
+    ...
+    >>> metadata['Requires-Dist'] = ["pywin32; sys.platform == 'win32'",
+    ...                              "Sphinx"]
+    ...
+    >>> metadata['Requires-Dist']
+    ['pywin32', 'Sphinx']
+    >>>
 
 Writing metadata
 ----------------
 
 Writing metadata can be done using the ``write`` method::
 
-   >>> metadata.write('/to/my/PKG-INFO')
+    >>> metadata.write('/to/my/PKG-INFO')
+    >>>
 
 The class will pick the best version for the metadata, depending on the values
 provided. If all the values provided exist in all versions, the class will
-use :attr:`PKG_INFO_PREFERRED_VERSION`.  It is set by default to 1.0, the most
+use :attr:`PKG_INFO_PREFERRED_VERSION`. It is set by default to 1.0, the most
 widespread version.
 
-
 Conflict checking and best version
 ----------------------------------
 
 Some fields in :PEP:`345` have to comply with the version number specification
 defined in :PEP:`386`.  When they don't comply, a warning is emitted::
 
-   >>> from distlib.metadata import Metadata
-   >>> metadata = Metadata()
-   >>> metadata['Requires-Dist'] = ['Funky (Groovie)']
-   "Funky (Groovie)" is not a valid predicate
-   >>> metadata['Requires-Dist'] = ['Funky (1.2)']
+    >>> from distlib.metadata import Metadata
+    >>> metadata = Metadata()
+    >>> metadata['Requires-Dist'] = ['Funky (Groovie)']
+    "Funky (Groovie)" is not a valid predicate
+    >>> metadata['Requires-Dist'] = ['Funky (1.2)']
+    >>>
 
 See also :mod:`distlib.version`.
 
-
 .. TODO talk about check()
 
-
 :mod:`distlib.markers` --- Environment markers
 ================================================
 
 .. module:: distlib.markers
-   :synopsis: Micro-language for environment markers
-
+    :synopsis: Micro-language for environment markers
 
 This is an implementation of environment markers `as defined in PEP 345
 <http://www.python.org/dev/peps/pep-0345/#environment-markers>`_.  It is used
 
 .. function:: interpret(marker, execution_context=None)
 
-   Interpret a marker and return a boolean result depending on the environment.
-   Example:
+    Interpret a marker and return a boolean result depending on the environment.
+    Example::
 
-      >>> interpret("python_version > '1.0'")
-      True
+        >>> interpret("python_version > '1.0'")
+        True
+        >>>
+

File docs/migration.rst

 Migrating from older APIs
 =========================
 
-This section has information on migration from older APIs.
+This section has information on migrating from older APIs.
 
 The ``pkg_resources`` resource API
 ----------------------------------
 ~~~~~~~~~~~~~~~~~~
 
 You can provide an ``XXXResourceFinder`` class which finds resources in custom
-storage containers, and works like ``ResourceFinder``. Although it shouldn't
+storage containers and works like ``ResourceFinder``. Although it shouldn't
 be necessary, you could also return a subclass of :class:`Resource` from your
 finders, to deal with custom requirements which aren't catered for.
 
 These keys are called *groups* in ``pkg_resources`` documentation, though that
 term is a little ambiguous. In Eclipse, for example, they are called *extension
 point IDs*, which is a little closer to the intended usage, but a bit of a
-mouthful. In ``distlib``, we'll use the term ``category`` or
-``export category``.
+mouthful. In ``distlib``, we'll use the term ``category`` or ``export category``.
 
 In ``distlib``, the implementation of exports is slightly different from
 entry points of ``pkg_resources``. A :class:`Distribution` instance has an
  ``exports`` attribute, which is a dictionary keyed by category and whose values
-are dictionaries which map names to :class:`ExportEntry` instances.
+are dictionaries that map names to :class:`ExportEntry` instances.
 
-Below are the ``pkg_resources`` functions, and how to achieve the equivalent
-in ``distlib``. In cases where the ``pkg_resources`` functions take
-distribution names, in ``distlib`` you get the corresponding
-:class:`Distribution` instance, using::
+Below are the ``pkg_resources`` functions and how to achieve the equivalent
+in ``distlib``. In cases where the ``pkg_resources`` functions take distribution
+names, in ``distlib`` you get the corresponding :class:`Distribution` instance,
+using::
 
     dist = dist_path.get_distribution(distname)
 

File docs/overview.rst

 Distlib evolved out of ``packaging``
 ------------------------------------
 
-Distlib is a library which implements low-level functions which relate to
-packaging and distribution of Python software. It consists in part of some of
+Distlib is a library which implements low-level functions that relate to
+packaging and distribution of Python software. It consists in part of
 the functions in the ``packaging`` Python package, which was intended to be
-released as part of Python 3.3, but which was removed shortly before Python
+released as part of Python 3.3, but was removed shortly before Python
 3.3 entered beta testing.
 
 What was the problem with ``packaging``?
 The ``packaging`` software just wasn't ready for inclusion in the Python
 standard library. The amount of work needed to get it into the desired
 state was too great, given the number of people able to work on the project,
-the time they could devote to it and the Python 3.3 release schedule.
+the time they could devote to it, and the Python 3.3 release schedule.
 
 The approach taken by ``packaging`` was seen to be a good one: to ensure
 interoperability and consistency between different tools in the packaging
 While some very good work was done in defining PEPs to codify some of the
 best practices, ``packaging`` suffered from some drawbacks, too:
 
-* Not all the PEPs may have been complete, because some important use
-  cases were not considered -- for example, built (binary) distributions for
+* Not all the PEPs may have been functionality complete, because some important
+  use cases were not considered -- for example, built (binary) distributions for
   Windows.
 
 * It continued the command-based design of ``distutils``, which had resulted
-  in ``distutils`` being difficult to extend in a consistent and easily
-  understood, maintainable fashion.
+  in ``distutils`` being difficult to extend in a consistent, easily
+  understood, and maintainable fashion.
 
 * Some important features required by distribution authors were not considered
   -- for example:
 * There were a lot of rough edges in the ``packaging`` implementation, both
   in terms of bugs and in terms of incompletely implemented features. This
   can be seen (with the benefit of hindsight) as due to the goals being set too
-  ambitiously; the project developers bit off more than they could chew.
+  ambitiously, the project developers bit off more than they could chew.
 
 How Distlib can help
 --------------------
 <http://mail.python.org/pipermail/python-dev/2012-September/121716.html>`_,
 though a different name was suggested for the library. Basically, Distlib
 contains the implementations of the packaging PEPs and other low-level
-features which relate to packaging, distribution and deployment of Python
+features which relate to packaging, distribution, and deployment of Python
 software. If Distlib can be made genuinely useful, then it is possible for
 third-party packaging tools to transition to using it. Their developers and
 users then benefit from standardised implementation of low-level functions,
 How you can help
 ----------------
 
-If you have some time abd the inclination to improve the state of Python
+If you have some time and the inclination to improve the state of Python
 packaging, then you can help by trying out Distlib, raising issues where
 you find problems, contributing feedback and/or patches to the
-implementation, documentation and underlying PEPs.
+implementation, documentation, and underlying PEPs.
 
 Main features
 -------------
 -----------------------------------------
 
 Distlib is intended to be used on any Python version >= 2.6 and is tested on
-Python versions 2.6, 2.7, 3.1, 3.2 and 3.3 on Linux, Windows, and Mac OS X (not
+Python versions 2.6, 2.7, 3.1, 3.2, and 3.3 on Linux, Windows, and Mac OS X (not
 all versions are tested on all platforms, but are expected to work correctly).
 
-
 Project status
 --------------
 

File docs/tutorial.rst

 ------------
 
 .. note:: Since ``distlib`` has not received its first release yet, you can't
-   currently install it from PyPI - the documentation below is a little
-   premature. Instead, you need to clone the Mercurial repository at
+  currently install it from PyPI - the documentation below is a little
+  premature. Instead, you need to clone the Mercurial repository at
 
-   https://bitbucket.org/vinay.sajip/distlib/
+  https://bitbucket.org/vinay.sajip/distlib/
 
-   or
+  or
 
-   http://hg.python.org/distlib/
+  http://hg.python.org/distlib/
 
-   followed by doing a ``python setup.py install`` invocation, ideally in a
-   virtual environment (venv).
+  followed by doing a ``python setup.py install`` invocation, ideally in a
+  virtual environment (like venv).
 
 Distlib is a pure-Python library. You should be able to install it using::
 
 Testing
 -------
 
-A full test suite is included with ``distlib``. To run it, you'll need to
-unpack a source tarball and run ``python setup.py test`` in the top-level
-directory of the unpack location. You can of course also run
+A full test suite is included with ``distlib``. To run it, you'll need to clone
+the repository or download a tarball and run ``python setup.py test``
+in the top-level directory of the package. You can of course also run
 ``python setup.py install``
-to install from the source tarball (perhaps invoking with ``sudo`` if you need
+to install the package (perhaps invoking with ``sudo`` if you need
 to install to a protected location).
 
 First steps
 
 .. currentmodule:: distlib.database
 
-You can use the ``distlib.database`` package to access information about
-installed distributions. This information is available through the
-following classes:
+    You can use the ``distlib.database`` package to access information about
+    installed distributions. This information is available through the
+    following classes:
 
-* :class:`DistributionPath`, which represents a set of distributions installed
-  on a path.
-
-* :class:`Distribution`, which represents an individual distribution,
-  conforming to recent packaging PEPs (:pep:`386`, :pep:`376`, :pep:`345`,
-  :pep:`314` and :pep:`241`).
-* :class:`EggInfoDistribution`, which represents a legacy distribution in
-  egg format.
+    * :class:`DistributionPath`, which represents a set of distributions installed
+      on a path.
+    * :class:`Distribution`, which represents an individual distribution,
+      conforming to recent packaging PEPs (:pep:`386`, :pep:`376`, :pep:`345`,
+      :pep:`314` and :pep:`241`).
+    * :class:`EggInfoDistribution`, which represents a legacy distribution in
+      egg format.
 
 Distribution paths
 ~~~~~~~~~~~~~~~~~~
 
     >>> from distlib.database import DistributionPath
     >>> dist_path = DistributionPath()
+    >>>
 
 Querying a path for distributions
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     []
     >>>
 
-This may seem surprising, but that's only because, if you've just started
-looking at ``distlib``, you won't *have* any non-legacy distributions.
+This may seem surprising if you've just started looking at ``distlib``,
+as you won't *have* any non-legacy distributions.
 
 Including legacy distributions in the search results
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 additional keyword argument, like so::
 
     >>> dist_path = DistributionPath(include_egg=True)
+    >>>
 
 and then you'll get a less surprising result::
 
     >>> len(list(dist_path.get_distributions()))
     77
+    >>>
 
 The exact number returned will be different for you, of course. You can ask
 for a particular distribution by name, using the :meth:`get_distribution`
     <EggInfoDistribution u'setuptools' 0.6c11 at '/usr/lib/python2.7/dist-packages/setuptools.egg-info'>
     >>>
 
-If you want to look at a specific path other than ``sys.path``, you specify it as a
-positional argument to the :class:`DistributionPath` constructor::
+If you want to look at a specific path other than ``sys.path``, you specify it
+as a positional argument to the :class:`DistributionPath` constructor::
 
     >>> from pprint import pprint
     >>> special_dists = DistributionPath(['tests/fake_dists'], include_egg=True)
 
     >>> special_dists = DistributionPath(['tests/fake_dists'])
     >>> pprint([d.name for d in special_dists.get_distributions()])
-    ['babar', 'choxie', 'towel-stuff', 'grammar']
+    ['babar',
+    'choxie',
+    'towel-stuff',
+    'grammar']
     >>>
 
 Distribution properties
 for internationalisation support provides a mechanism for extracting, from a
 variety of sources, message text to be internationalised. Babel itself provides
 functionality to extract messages from e.g. Python and JavaScript source code,
-but helpfully provides a mechanism whereby providers of other sources of
-message text can provide their own extractors. It does this by providing a
+but helpfully offers a mechanism whereby providers of other sources of
+message text can offer their own extractors. It does this by providing a
 category ``'babel.extractors'``, under which other software can register
 extractors for their sources. The `Jinja2 <http://jinja2.pocoo.org/>`_ template
 engine, for example, makes use of this to provide a message extractor for
 
     name = prefix [ ":" suffix ] [ "[" flags "]" ]
 
-where ``name``, ``prefix`` and ``suffix`` are ``pkgnames``, ``suffix`` and
-``flags`` are optional, and ``flags`` follow the description in
+where ``name``, ``prefix``, and ``suffix`` are ``pkgnames``. ``suffix`` and
+``flags`` are optional and ``flags`` follow the description in
 :ref:`flag-formats`.
 
 Any installed distribution can offer up values for any category, and
 This entry format is used in the :mod:`distlib.scripts` package for installing
 scripts based on Python callables.
 
-
 Distribution dependencies
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
 * :func:`make_graph`, which generates a dependency graph from a list of
   distributions.
-
 * :func:`get_dependent_dists`, which takes a list of distributions and a
   specific distribution in that list, and returns the distributions that
   are dependent on that specific distribution.
-
 * :func:`get_required_dists`, which takes a list of distributions and a
   specific distribution in that list, and returns the distributions that
   are required by that specific distribution.
 
 .. currentmodule:: distlib.scripts
 
-
 You can use the ``distlib.scripts`` API to install scripts. Installing scripts
 is slightly more involved than just copying files:
 
 * You may need to adjust shebang lines in scripts to point to the interpreter
-  to be used to run scripts. This is important in virtual environments (venvs),
-  and also in other situations where you may have multiple Python installations
-  on a single computer.
-
-* On Windows, on systems where the :pep:`397` launcher isn't installed, it is not
-  easy to ensure that the correct Python interpreter is used for a script. You
-  may wish to install native Windows executable launchers which run the correct
-  interpreter, based on a shebang line in the script.
+  that will be used to run scripts. This is important in virtual environments
+  (venvs), and also in other situations where you may have multiple Python
+  installations on a single computer.
+* On Windows or on systems where the :pep:`397` launcher isn't installed, it is
+  not easy to ensure that the correct Python interpreter is used for a script.
+  You may wish to install native Windows executable launchers which run the
+  correct interpreter, based on a shebang line in the script.
 
 Specifying scripts to install
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 To install scripts, create a :class:`ScriptMaker` instance,
-giving it
-the source and target directories for scripts::
+giving it the source and target directories for scripts::
 
     >>> from distlib.scripts import ScriptMaker
     >>> maker = ScriptMaker(source_dir, target_dir)
+    >>>
 
-You can then install a script ``foo.py`` like this:
+You can then install a script ``foo.py`` like this::
 
     >>> maker.make('foo.py')
+    >>>
 
 The string passed to make can take one of the following forms:
 
   or ``subdir/bar.py``.
 * A reference to a callable, given in the form::
 
-      name = some_package.some_module:some_callable [flags]
+    name = some_package.some_module:some_callable [flags]
 
   where the *flags* part is optional. The only flag currently in use is
   ``'gui'``, which indicates on Windows that a Windows executable launcher
   (rather than a launcher which is a console application) should be used.
-  (This only applies if ``add_launchers`` is true.)
+  (this only applies if ``add_launchers`` is true)
 
   For more information about flags, see :ref:`flag-formats`.
 
 
 .. currentmodule:: distlib.version
 
-Overview
-~~~~~~~~
+    Overview
+    ~~~~~~~~
 
-The :class:`NormalizedVersion` class implements a :pep:`386` compatible
-version::
+    The :class:`NormalizedVersion` class implements a :pep:`386` compatible
+    version::
 
-    >>> from distlib.version import NormalizedVersion
-    >>> v1 = NormalizedVersion('1.0')
-    >>> v2 = NormalizedVersion('1.0a1')
-    >>> v3 = NormalizedVersion('1.0b1')
-    >>> v4 = NormalizedVersion('1.0c1')
-    >>> v5 = NormalizedVersion('1.0.post1')
+        >>> from distlib.version import NormalizedVersion
+        >>> v1 = NormalizedVersion('1.0')
+        >>> v2 = NormalizedVersion('1.0a1')
+        >>> v3 = NormalizedVersion('1.0b1')
+        >>> v4 = NormalizedVersion('1.0c1')
+        >>> v5 = NormalizedVersion('1.0.post1')
+        >>>
 
-These sort in the expected order::
+    These sort in the expected order::
 
-    >>> v2 < v3 < v4 < v1 < v5
-    True
+        >>> v2 < v3 < v4 < v1 < v5
+        True
+        >>>
 
-You can't pass any old thing as a version number::
+    You can't pass any old thing as a version number::
 
-    >>> NormalizedVersion('foo')
-    Traceback (most recent call last):
-      File "<stdin>", line 1, in <module>
-      File "distlib/version.py", line 49, in __init__
-        self._parts = parts = self.parse(s)
-      File "distlib/version.py", line 254, in parse
-        def parse(self, s): return normalized_key(s)
-      File "distlib/version.py", line 199, in normalized_key
-        raise UnsupportedVersionError(s)
-    distlib.version.UnsupportedVersionError: foo
+        >>> NormalizedVersion('foo')
+        Traceback (most recent call last):
+          File "<stdin>", line 1, in <module>
+          File "distlib/version.py", line 49, in __init__
+            self._parts = parts = self.parse(s)
+          File "distlib/version.py", line 254, in parse
+            def parse(self, s): return normalized_key(s)
+          File "distlib/version.py", line 199, in normalized_key
+            raise UnsupportedVersionError(s)
+        distlib.version.UnsupportedVersionError: foo
+        >>>
 
-Matching versions against constraints
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    Matching versions against constraints
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The :class:`NormalizedMatcher` is used to match version constraints against
-versions::
+    The :class:`NormalizedMatcher` is used to match version constraints against
+    versions::
 
-    >>> from distlib.version import NormalizedMatcher
-    >>> m = NormalizedMatcher('foo (1.0b1)')
-    >>> m
-    NormalizedMatcher('foo (1.0b1)')
-    >>> [m.match(v) for v in v1, v2, v3, v4, v5]
-    [False, False, True, False, False]
+        >>> from distlib.version import NormalizedMatcher
+        >>> m = NormalizedMatcher('foo (1.0b1)')
+        >>> m
+        NormalizedMatcher('foo (1.0b1)')
+        >>> [m.match(v) for v in v1, v2, v3, v4, v5]
+        [False, False, True, False, False]
+        >>>
 
-Specifying ``'foo (1.0b1)'`` is equivalent to specifying ``'foo (==1.0b1)'``,
-i.e. only the exact version is matched. You can also specify inequality
-constraints::
+    Specifying ``'foo (1.0b1)'`` is equivalent to specifying ``'foo (==1.0b1)'``,
+    i.e. only the exact version is matched. You can also specify inequality
+    constraints::
 
-    >>> m = NormalizedMatcher('foo (<1.0c1)')
-    >>> [m.match(v) for v in v1, v2, v3, v4, v5]
-    [False, True, True, False, False]
+        >>> m = NormalizedMatcher('foo (<1.0c1)')
+        >>> [m.match(v) for v in v1, v2, v3, v4, v5]
+        [False, True, True, False, False]
+        >>>
 
-and multiple constraints::
+    and multiple constraints::
 
-    >>> m = NormalizedMatcher('foo (>= 1.0b1, <1.0.post1)')
-    >>> [m.match(v) for v in v1, v2, v3, v4, v5]
-    [True, False, True, True, False]
+        >>> m = NormalizedMatcher('foo (>= 1.0b1, <1.0.post1)')
+        >>> [m.match(v) for v in v1, v2, v3, v4, v5]
+        [True, False, True, True, False]
+        >>>
 
-You can do exactly the same thing as above with ``setuptools``/
-``distribute`` version numbering (use ``LegacyVersion`` and ``LegacyMatcher``)
-or with semantic versioning (use ``SemanticVersion`` and ``SemanticMatcher``).
-However, you can't mix and match versions of different types::
+    You can do exactly the same thing as above with ``setuptools``/
+    ``distribute`` version numbering (use ``LegacyVersion`` and ``LegacyMatcher``)
+    or with semantic versioning (use ``SemanticVersion`` and ``SemanticMatcher``).
+    However, you can't mix and match versions of different types::
 
-    >>> from distlib.version import SemanticVersion, LegacyVersion
-    >>> nv = NormalizedVersion('1.0.0')
-    >>> lv = LegacyVersion('1.0.0')
-    >>> sv = SemanticVersion('1.0.0')
-    >>> lv == sv
-    Traceback (most recent call last):
-      File "<stdin>", line 1, in <module>
-      File "distlib/version.py", line 61, in __eq__
-        self._check_compatible(other)
-      File "distlib/version.py", line 58, in _check_compatible
-        raise TypeError('cannot compare %r and %r' % (self, other))
-    TypeError: cannot compare LegacyVersion('1.0.0') and SemanticVersion('1.0.0')
-    >>> nv == sv
-    Traceback (most recent call last):
-      File "<stdin>", line 1, in <module>
-      File "distlib/version.py", line 61, in __eq__
-        self._check_compatible(other)
-      File "distlib/version.py", line 58, in _check_compatible
-        raise TypeError('cannot compare %r and %r' % (self, other))
-    TypeError: cannot compare NormalizedVersion('1.0.0') and SemanticVersion('1.0.0')
-
+        >>> from distlib.version import SemanticVersion, LegacyVersion
+        >>> nv = NormalizedVersion('1.0.0')
+        >>> lv = LegacyVersion('1.0.0')
+        >>> sv = SemanticVersion('1.0.0')
+        >>> lv == sv
+        Traceback (most recent call last):
+          File "<stdin>", line 1, in <module>
+          File "distlib/version.py", line 61, in __eq__
+            self._check_compatible(other)
+          File "distlib/version.py", line 58, in _check_compatible
+            raise TypeError('cannot compare %r and %r' % (self, other))
+        TypeError: cannot compare LegacyVersion('1.0.0') and SemanticVersion('1.0.0')
+        >>> nv == sv
+        Traceback (most recent call last):
+          File "<stdin>", line 1, in <module>
+          File "distlib/version.py", line 61, in __eq__
+            self._check_compatible(other)
+          File "distlib/version.py", line 58, in _check_compatible
+            raise TypeError('cannot compare %r and %r' % (self, other))
+        TypeError: cannot compare NormalizedVersion('1.0.0') and SemanticVersion('1.0.0')
+        >>>
 
 Using the locators API
 ^^^^^^^^^^^^^^^^^^^^^^
 
 .. currentmodule:: distlib.locators
 
-Overview
-~~~~~~~~
+    Overview
+    ~~~~~~~~
 
-To locate a distribution in an index, we can use the :func:`locate` function.
-This returns a potentially downloadable distribution (in the sense that it
-has a download URL - of course, there are no guarantees that there will
-actually be a downloadable resource at that URL). The return value is an
-instance of :class:`distlib.database.Distribution` which can be queried for
-any distributions it requires, so that they can also be located if desired.
-Here is a basic example::
+    To locate a distribution in an index, we can use the :func:`locate` function.
+    This returns a potentially downloadable distribution (in the sense that it
+    has a download URL - of course, there are no guarantees that there will
+    actually be a downloadable resource at that URL). The return value is an
+    instance of :class:`distlib.database.Distribution` which can be queried for
+    any distributions it requires, so that they can be located if desired.
+    Here is a basic example::
 
-    >>> from distlib.locators import locate
-    >>> flask = locate('flask')
-    >>> flask
-    <Distribution Flask (0.9) [http://pypi.python.org/packages/source/F/Flask/Flask-0.9.tar.gz]>
-    >>> dependencies = [locate(r) for r in flask.get_requirements('install')]
-    >>> from pprint import pprint
-    >>> pprint(dependencies)
-    [<Distribution Werkzeug (0.8.3) [http://pypi.python.org/packages/source/W/Werkzeug/Werkzeug-0.8.3.tar.gz]>,
-     <Distribution Jinja2 (2.6) [http://pypi.python.org/packages/source/J/Jinja2/Jinja2-2.6.tar.gz]>]
-    >>>
+        >>> from distlib.locators import locate
+        >>> flask = locate('flask')
+        >>> flask
+        <Distribution Flask (0.9) [http://pypi.python.org/packages/source/F/Flask/Flask-0.9.tar.gz]>
+        >>> dependencies = [locate(r) for r in flask.get_requirements('install')]
+        >>> from pprint import pprint
+        >>> pprint(dependencies)
+        [<Distribution Werkzeug (0.8.3) [http://pypi.python.org/packages/source/W/Werkzeug/Werkzeug-0.8.3.tar.gz]>,
+         <Distribution Jinja2 (2.6) [http://pypi.python.org/packages/source/J/Jinja2/Jinja2-2.6.tar.gz]>]
+        >>>
 
-The values returned by :meth:`get_requirements` are just strings. Here's another example,
-showing a little more detail::
+    The values returned by :meth:`get_requirements` are just strings. Here's another
+    example, showing a little more detail::
 
-    >>> authy = locate('authy')
-    >>> authy.get_requirements('install')
-    [u'httplib2 (>= 0.7, < 0.8)', u'simplejson']
-    >>> authy
-    <Distribution authy (0.0.4) [http://pypi.python.org/packages/source/a/authy/authy-0.0.4.tar.gz]>
-    >>> deps = [locate(r) for r in authy.get_requirements('install')]
-    >>> pprint(deps)
-    [<Distribution httplib2 (0.7.6) [http://pypi.python.org/packages/source/h/httplib2/httplib2-0.7.6.tar.gz]>,
-     <Distribution simplejson (2.6.2) [http://pypi.python.org/packages/source/s/simplejson/simplejson-2.6.2.tar.gz]>]
-    >>>
+        >>> authy = locate('authy')
+        >>> authy.get_requirements('install')
+        [u'httplib2 (>= 0.7, < 0.8)', u'simplejson']
+        >>> authy
+        <Distribution authy (0.0.4) [http://pypi.python.org/packages/source/a/authy/authy-0.0.4.tar.gz]>
+        >>> deps = [locate(r) for r in authy.get_requirements('install')]
+        >>> pprint(deps)
+        [<Distribution httplib2 (0.7.6) [http://pypi.python.org/packages/source/h/httplib2/httplib2-0.7.6.tar.gz]>,
+         <Distribution simplejson (2.6.2) [http://pypi.python.org/packages/source/s/simplejson/simplejson-2.6.2.tar.gz]>]
+        >>>
 
-Note that the constraints on the dependencies were honoured by :func:`locate`.
+    Note that the constraints on the dependencies were honoured by :func:`locate`.
 
+    Under the hood
+    ~~~~~~~~~~~~~~
 
-Under the hood
-~~~~~~~~~~~~~~
+    Under the hood, :func:`locate` uses *locators*. Locators are a mechanism for
+    finding distributions from a range of sources. Although the ``pypi`` subpackage
+    has been copied from ``distutils2`` to ``distlib``, there may be benefits in a
+    higher-level API, and so the ``distlib.locators`` package has been created as
+    an experiment. Locators are objects which locate distributions. A locators
+    instance's :meth:`get_project` method is called, passing in a project name: The
+    method returns a dictionary containing information about distribution releases
+    found for that project. The keys of the returned dictionary are versions, and
+    the values are instances of :class:`distlib.database.Distribution`.
 
-Under the hood, :func:`locate` uses *locators*. Locators are a mechanism for
-finding distributions from a range of sources. Although the ``pypi`` subpackage
-has been copied from ``distutils2`` to ``distlib``, there may be benefits in a
-higher-level API, and so the ``distlib.locators`` package has been created as
-an experiment. Locators are objects which locate distributions. A locator
-instance's :meth:`get_project` method is called, passing in a project name: The
-method returns a dictionary containing information about distribution releases
-found for that project. The keys of the returned dictionary are versions, and
-the values are instances of :class:`distlib.database.Distribution`.
+    The following locators are provided:
 
-The following locators are provided:
+    * :class:`DirectoryLocator` -- this is instantiated with a base directory and
+      will look for archives in the file system tree under that directory. Name
+      and version information is inferred from the filenames of archives and the
+      amount of information returned about the download is minimal.
+    * :class:`PyPIRPCLocator`. -- This takes a base URL for the RPC service and
+      will locate packages using PyPI's XML-RPC API. This locator is a little slow
+      (the scraping interface seems to work faster) and case-sensitive. For
+      example, searching for ``'flask'`` will throw up no results, but you get the
+      expected results when searching for ``'Flask'``. This appears to be a
+      limitation of the underlying XML-RPC API. Note that 20 versions of a
+      project necessitate 41 network calls (one to get the versions and
+      two more for each version -- one to get the metadata, and another to get the
+      downloads information).
+    * :class:`PyPIJSONLocator`. -- This takes a base URL for the JSON service and
+      will locate packages using PyPI's JSON API. This locator is case-sensitive. For
+      example, searching for ``'flask'`` will throw up no results, but you get the
+      expected results when searching for ``'Flask'``. This appears to be a
+      limitation of the underlying JSON API. Note that unlike the XML-RPC service,
+      only non-hidden releases will be returned.
+    * :class:`SimpleScrapingLocator` -- this takes a base URL for the site to
+      scrape, and locates packages using a similar approach to the
+      ``PackageFinder`` class in ``pip``, or as documented in ``setuptools``
+      as the approach used by ``easy_install``.
+    * :class:`DistPathLocator` -- this takes a :class:`DistributionPath` instance
+      and locates installed distributions. This can be used with
+      :class:`AggregatingLocator` to satisfy requirements from installed
+      distributions before looking elsewhere for them.
+    * :class:`AggregatingLocator` -- this takes a list of other aggregators and
+      delegates finding projects to them. It can either return the first result
+      found (i.e. from the first aggregator in the list provided which returns a
+      non-empty result) or a merged result from all the aggregators in the list.
 
-* :class:`DirectoryLocator` -- this is instantiated with a base directory and
-  will look for archives in the file system tree under that directory. Name
-  and version information is inferred from the filenames of archives, and the
-  amount of information returned about the download is minimal.
+    There is a default locator, available at :attr:`distlib.locators.default_locator`.
 
-* :class:`PyPIRPCLocator`. -- This takes a base URL for the RPC service and
-  will locate packages using PyPI's XML-RPC API. This locator is a little slow
-  (the scraping interface seems to work faster) and case-sensitive. For
-  example, searching for ``'flask'`` will throw up no results, but you get the
-  expected results when searching from ``'Flask'``. This appears to be a
-  limitation of the underlying XML-RPC API. Note that 20 versions of a
-  project necessitate 41 network calls (one to get the versions, and
-  two more for each version -- one to get the metadata, and another to get the
-  downloads information).
+    An example of usage of locator instances is given below::
 
-* :class:`PyPIJSONLocator`. -- This takes a base URL for the JSON service and
-  will locate packages using PyPI's JSON API. This locator is case-sensitive. For
-  example, searching for ``'flask'`` will throw up no results, but you get the
-  expected results when searching from ``'Flask'``. This appears to be a
-  limitation of the underlying JSON API. Note that unlike the XML-RPC service,
-  only non-hidden releases will be returned.
+        >>> from distlib.locators import SimpleScrapingLocator
+        >>> from pprint import pprint
+        >>> locator = SimpleScrapingLocator('http://pypi.python.org/simple/')
+        >>> result = locator.get_project('python-gnupg')
+        >>> pprint(result)
+        {u'0.2.3': <Distribution python-gnupg (0.2.3) [http://python-gnupg.googlecode.com/files/python-gnupg-0.2.3.tar.gz]>,
+         u'0.2.4': <Distribution python-gnupg (0.2.4) [http://python-gnupg.googlecode.com/files/python-gnupg-0.2.4.tar.gz]>,
+         u'0.2.9': <Distribution python-gnupg (0.2.9) [http://python-gnupg.googlecode.com/files/python-gnupg-0.2.9.tar.gz]>,
+         u'0.3.0': <Distribution python-gnupg (0.3.0) [http://python-gnupg.googlecode.com/files/python-gnupg-0.3.0.tar.gz]>,
+         u'0.3.1': <Distribution python-gnupg (0.3.1) [http://python-gnupg.googlecode.com/files/python-gnupg-0.3.1.tar.gz]>}
+        >>>
 
-* :class:`SimpleScrapingLocator` -- this takes a base URL for the site to
-  scrape, and locates packages using a similar approach to the
-  ``PackageFinder`` class in ``pip``, or as documented in the ``setuptools``
-  documentation as the approach used by ``easy_install``.
+    Now the same project, using the XML-RPC API::
 
-* :class:`DistPathLocator` -- this takes a :class:`DistributionPath` instance
-  and locates installed distributions. This can be used with
-  :class:`AggregatingLocator` to satisfy requirements from installed
-  distributions before looking elsewhere for them.
+        >>> from distlib.locators import PyPIRPCLocator
+        >>> locator = PyPIRPCLocator('http://python.org/pypi')
+        >>> result = locator.get_project('python-gnupg')
+        >>> pprint(result)
+        {'0.2.3': <Distribution python-gnupg (0.2.3) [http://python-gnupg.googlecode.com/files/python-gnupg-0.2.3.tar.gz]>,
+         '0.2.4': <Distribution python-gnupg (0.2.4) [http://python-gnupg.googlecode.com/files/python-gnupg-0.2.4.tar.gz]>,
+         '0.2.6': <Distribution python-gnupg (0.2.6) [UNKNOWN]>,
+         '0.2.7': <Distribution python-gnupg (0.2.7) [UNKNOWN]>,
+         '0.2.8': <Distribution python-gnupg (0.2.8) [UNKNOWN]>,
+         '0.2.9': <Distribution python-gnupg (0.2.9) [http://python-gnupg.googlecode.com/files/python-gnupg-0.2.9.tar.gz]>,
+         '0.3.0': <Distribution python-gnupg (0.3.0) [http://python-gnupg.googlecode.com/files/python-gnupg-0.3.0.tar.gz]>,
+         '0.3.1': <Distribution python-gnupg (0.3.1) [http://python-gnupg.googlecode.com/files/python-gnupg-0.3.1.tar.gz]>}
+        >>>
 
-* :class:`AggregatingLocator` -- this takes a list of other aggregators and
-  delegates finding projects to them. It can either return the first result
-  found (i.e. from the first aggregator in the list provided which returns a
-  non-empty result), or a merged result from all the aggregators in the list.
+    .. note::
+        The reason why some of the download URLs come up as UNKNOWN is that some of
+        the PyPI metadata is incomplete.
 
-There is a default locator, available at :attr:`distlib.locators.default_locator`.
+    Locators also have a method, :meth:`get_distribution_names`, which returns a
+    set of all the distribution names known to that locator instance. Note that
+    the base :class:`Locator` and :class:`JSONLocator` classes don't implement this
+    method, so they will raise a :class:`NotImplementedError`.
 
-An example of usage of locator instances is given below::
+    The ``locators`` package also contains a function,
+    :func:`get_all_distribution_names`, which retrieves the names of all
+    distributions registered on PyPI::
 
-    >>> from distlib.locators import SimpleScrapingLocator
-    >>> from pprint import pprint
-    >>> locator = SimpleScrapingLocator('http://pypi.python.org/simple/')
-    >>> result = locator.get_project('python-gnupg')
-    >>> pprint(result)
-    {u'0.2.3': <Distribution python-gnupg (0.2.3) [http://python-gnupg.googlecode.com/files/python-gnupg-0.2.3.tar.gz]>,
-     u'0.2.4': <Distribution python-gnupg (0.2.4) [http://python-gnupg.googlecode.com/files/python-gnupg-0.2.4.tar.gz]>,
-     u'0.2.9': <Distribution python-gnupg (0.2.9) [http://python-gnupg.googlecode.com/files/python-gnupg-0.2.9.tar.gz]>,
-     u'0.3.0': <Distribution python-gnupg (0.3.0) [http://python-gnupg.googlecode.com/files/python-gnupg-0.3.0.tar.gz]>,
-     u'0.3.1': <Distribution python-gnupg (0.3.1) [http://python-gnupg.googlecode.com/files/python-gnupg-0.3.1.tar.gz]>}
-    >>>
+        >>> from distlib.locators import get_all_distribution_names
+        >>> names = get_all_package_names()
+        >>> len(names)
+        24801
+        >>>
 
-Now the same project, using the XML-RPC API::
+    This is implemented using the XML-RPC API.
 
-    >>> from distlib.locators import PyPIRPCLocator
-    >>> locator = PyPIRPCLocator('http://python.org/pypi')
-    >>> result = locator.get_project('python-gnupg')
-    >>> pprint(result)
-    {'0.2.3': <Distribution python-gnupg (0.2.3) [http://python-gnupg.googlecode.com/files/python-gnupg-0.2.3.tar.gz]>,
-     '0.2.4': <Distribution python-gnupg (0.2.4) [http://python-gnupg.googlecode.com/files/python-gnupg-0.2.4.tar.gz]>,
-     '0.2.6': <Distribution python-gnupg (0.2.6) [UNKNOWN]>,
-     '0.2.7': <Distribution python-gnupg (0.2.7) [UNKNOWN]>,
-     '0.2.8': <Distribution python-gnupg (0.2.8) [UNKNOWN]>,
-     '0.2.9': <Distribution python-gnupg (0.2.9) [http://python-gnupg.googlecode.com/files/python-gnupg-0.2.9.tar.gz]>,
-     '0.3.0': <Distribution python-gnupg (0.3.0) [http://python-gnupg.googlecode.com/files/python-gnupg-0.3.0.tar.gz]>,
-     '0.3.1': <Distribution python-gnupg (0.3.1) [http://python-gnupg.googlecode.com/files/python-gnupg-0.3.1.tar.gz]>}
-    >>>
+    The Locator API is very bare-bones at the moment, but additional features will
+    be added in due course. A very bare-bones command-line script which exercises
+    these locators is to be found `here <https://gist.github.com/3886402>`_, and
+    feedback will be gratefully received from anyone who tries it out.
 
-The reason why some of the download URLs come up as UNKNOWN is that some of
-the PyPI metadata is incomplete.
+    None of the locators currently returns enough metadata to allow dependency
+    resolution to be carried out, but that is a result of the fact that metadata
+    relating to dependencies are not indexed, and would require not just downloading
+    the distribution archives and inspection of contained metadata files, but
+    potentially also introspecting setup.py! This is the downside of having vital
+    information only available via keyword arguments to the :func:`setup` call:
+    hopefully, a move to fully declarative metadata will facilitate indexing it and
+    allowing the provision of features currently provided by ``setuptools`` (e.g.
+    hints for downloads -- ``'dependency _links'``).
 
-Locators also have a method, :meth:`get_distribution_names`, which returns a
-set of all the distribution names known to that locator instance. Note that
-the base :class:`Locator` and :class:`JSONLocator` classes don't implement this
-method, so they will raise a :class:`NotImplementedError`.
+    The locators will skip binary distributions (``.egg`` files are currently
+    treated as binary distributions).
 
-The ``locators`` package also contains a function,
-:func:`get_all_distribution_names`, which retrieves the names of all
-distributions registered on PyPI::
-
-    >>> from distlib.locators import get_all_distribution_names
-    >>> names = get_all_package_names()
-    >>> len(names)
-    24801
-    >>>
-
-This is implemented using the XML-RPC API.
-
-The Locator API is very bare-bones at the moment, but additional features will
-be added in due course. A very bare-bones command-line script which exercises
-these locators is to be found `here <https://gist.github.com/3886402>`_, and
-feedback will be gratefully received from anyone who tries it out.
-
-None of the locators currently returns enough metadata to allow dependency
-resolution to be carried out, but that is a function of the fact that metadata
-relating to dependencies is not indexed, and would require not just downloading
-the distribution archives and inspection of contained metadata files, but
-potentially also introspecting setup.py! This is the downside of having vital
-information only available via keyword arguments to the :func:`setup` call:
-hopefully, a move to fully declarative metadata will facilitate indexing it and
-allowing the provision of features currently provided by ``setuptools`` (e.g.
-hints for downloads -- ``'dependency _links'``).
-
-The locators skip binary distributions (``.egg`` files are currently treated
-as binary distributions).
-
-The PyPI locator classes don't yet support the use of mirrors, but that can be
-added in due course -- once the basic functionality is working satisfactorily.
+    The PyPI locator classes don't yet support the use of mirrors, but that can be
+    added in due course -- once the basic functionality is working satisfactorily.
 
 Next steps
 ----------

File docs/util.rst

 =========================================================
 
 .. module:: packaging.util
-   :synopsis: Miscellaneous utility functions.
+  :synopsis: Miscellaneous utility functions.
 
 
 This module contains various helpers for the other modules.
 
 .. XXX a number of functions are missing, but the module may be split first
-   (it's ginormous right now, some things could go to compat for example)
+  (it's ginormous right now, some things could go to compat for example)
 
 .. function:: get_platform()
 
-   Return a string that identifies the current platform.  This is used mainly to
-   distinguish platform-specific build directories and platform-specific built
-   distributions.  Typically includes the OS name and version and the
-   architecture (as supplied by 'os.uname()'), although the exact information
-   included depends on the OS; e.g. for IRIX the architecture isn't particularly
-   important (IRIX only runs on SGI hardware), but for Linux the kernel version
-   isn't particularly important.
+    Return a string that identifies the current platform. This is used mainly to
+    distinguish platform-specific build directories and platform-specific built
+    distributions. Typically includes the OS name and version and the
+    architecture (as supplied by 'os.uname()'), although the exact information
+    included depends on the OS; e.g. for IRIX the architecture isn't particularly
+    important (IRIX only runs on SGI hardware), but for Linux the kernel version
+    isn't particularly important.
 
-   Examples of returned values:
+    Examples of returned values:
 
-   * ``linux-i586``
-   * ``linux-alpha``
-   * ``solaris-2.6-sun4u``
-   * ``irix-5.3``
-   * ``irix64-6.2``
+    * ``linux-i586``
+    * ``linux-alpha``
+    * ``solaris-2.6-sun4u``
+    * ``irix-5.3``
+    * ``irix64-6.2``
 
-   For non-POSIX platforms, currently just returns ``sys.platform``.
+    For non-POSIX platforms, currently just returns ``sys.platform``.
 
-   For Mac OS X systems the OS version reflects the minimal version on which
-   binaries will run (that is, the value of ``MACOSX_DEPLOYMENT_TARGET``
-   during the build of Python), not the OS version of the current system.
+    For Mac OS X systems the OS version reflects the minimal version on which
+    binaries will run (that is, the value of ``MACOSX_DEPLOYMENT_TARGET``
+    during the build of Python), not the OS version of the current system.
 
-   For universal binary builds on Mac OS X the architecture value reflects
-   the univeral binary status instead of the architecture of the current
-   processor. For 32-bit universal binaries the architecture is ``fat``,
-   for 64-bit universal binaries the architecture is ``fat64``, and
-   for 4-way universal binaries the architecture is ``universal``. Starting
-   from Python 2.7 and Python 3.2 the architecture ``fat3`` is used for
-   a 3-way universal build (ppc, i386, x86_64) and ``intel`` is used for
-   a univeral build with the i386 and x86_64 architectures
+    For universal binary builds on Mac OS X the architecture value reflects
+    the universal binary status instead of the architecture of the current
+    processor. For 32-bit universal binaries the architecture is ``fat``,
+    for 64-bit universal binaries the architecture is ``fat64``, and
+    for 4-way universal binaries the architecture is ``universal``. Starting
+    from Python 2.7 and Python 3.2 the architecture ``fat3`` is used for
+    a 3-way universal build (ppc, i386, x86_64) and ``intel`` is used for
+    a universal build with the i386 and x86_64 architectures
 
-   Examples of returned values on Mac OS X:
+    Examples of returned values on Mac OS X:
 
-   * ``macosx-10.3-ppc``
+    * ``macosx-10.3-ppc``
 
-   * ``macosx-10.3-fat``
+    * ``macosx-10.3-fat``
 
-   * ``macosx-10.5-universal``
+    * ``macosx-10.5-universal``
 
-   * ``macosx-10.6-intel``
+    * ``macosx-10.6-intel``
 
-   .. XXX reinvention of platform module?
-
+    .. XXX reinvention of platform module?
 
 .. function:: convert_path(pathname)
 
-   Return 'pathname' as a name that will work on the native filesystem, i.e.
-   split it on '/' and put it back together again using the current directory
-   separator. Needed because filenames in the setup script are always supplied
-   in Unix style, and have to be converted to the local convention before we
-   can actually use them in the filesystem.  Raises :exc:`ValueError` on
-   non-Unix-ish systems if *pathname* either starts or ends with a slash.
-
+    Return 'pathname' as a name that will work on the native filesystem, i.e.
+    split it on '/' and put it back together again using the current directory
+    separator. Needed because filenames in the setup script are always supplied
+    in Unix style, and have to be converted to the local convention before we
+    can actually use them in the filesystem.  Raises :exc:`ValueError` on
+    non-Unix-ish systems if *pathname* either starts or ends with a slash.
 
 .. function:: change_root(new_root, pathname)
 
-   Return *pathname* with *new_root* prepended.  If *pathname* is relative, this
-   is equivalent to ``os.path.join(new_root,pathname)`` Otherwise, it requires
-   making *pathname* relative and then joining the two, which is tricky on