Commits

Vinay Sajip committed 86768f5

Merge Ryan Macy's changes, plus further edits.

Comments (0)

Files changed (11)

docs/database.rst

 .. module:: distlib.database
    :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
    .. 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.
+      is present in the :file:`RECORD` file). *path* can be a local absolute
+      path or a relative ``'/'``-separated path. Returns a boolean.
 
    Available attributes:
 
       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'
 
    .. 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)
 
 
       Shortcut for ``metadata['Version']``.
 
-
 Functions to work with the database
 -----------------------------------
 
    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
+   given in *paths*, which defaults to :data:`sys.path`. Returns ``None`` if no
    matching distribution is found.
 
    .. 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
    *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
 
    .. 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*.
    :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*.
    :mod:`distlib.version`).  If *use_egg_info* is true, legacy egg
    distributions will be considered as well.
 
-
 Utility functions
 -----------------
 
 
    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
+   :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 ``'-'``.
+   dots) are replaced by one ``'-'``.
 
    .. 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()
 
    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:
+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:
 
         Requires-Python: UNKNOWN
       Requires-External: []
 
-  Extra
-  =====
-  * It was installed as a dependency
-
+   Extra
+   =====
+   * It was installed as a dependency
 
 Getting metadata about a 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'

docs/depgraph.rst

 .. module:: distlib.depgraph
    :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.
 In this document, "distribution" refers to an instance of
 :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
+   Represent a dependency graph between releases. The nodes are distribution
+   instances, the edges model dependencies. An edge from ``a`` to ``b`` means
    that ``a`` depends on ``b``.
 
    .. method:: add_distribution(distribution)
 
    .. method:: repr_node(dist, level=1)
 
-      Print a subgraph starting from *dist*.  *level* gives the depth of the
+      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
 
    .. attribute:: reverse_list
 
-      Dictionary mapping distributions to a list of predecessors.  This allows
+      Dictionary mapping distributions to a list of predecessors. This allows
       efficient traversal.
 
    .. attribute:: missing
       Dictionary mapping distributions to a list of requirements that were not
       provided by any distribution.
 
-
 Auxiliary functions
 -------------------
 
 Example Usage
 -------------
 
-Depict all dependenciess in the system
+Depict all dependencies in the system
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 First, we shall generate a graph of all the distributions on the system
 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:
 
 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 -T png output.dot > output.png
 
 An example result is:
 
 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
 
    .. image:: depgraph_big.png
 
-
 List all dependent distributions
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-We will list all distributions that are dependent on some given distibution.
+We will list all distributions that are dependent on some given distribution.
 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:
 
 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

docs/internals.rst

 To consider how to provide a minimal uniform API to access resources in Python
 packages, we'll assume that the requirements are as follows:
 
-* All resources are regarded as binary. The using application is expected to
+* All resources are regarded as binary. The consuming application is expected to
   know how to convert resources to text, where appropriate.
 * All resources are read-only.
 * It should be possible to access resources either as streams, or as their
   entire data as a byte-string.
 * Resources will have a unique, identifying name which is text. Resources will
-  be hierarchical, and named using filesystem-like paths using '/' as a
+  be hierarchical and named using filesystem-like paths using '/' as a
   separator. The library will be responsible for converting resource names
   to the names of the underlying representations (e.g. encoding of file names
   corresponding to resource names).
-* Some resources are containers of other resoures, some are not. For
+* Some resources are containers of other resources, some are not. For
   example, a resource ``nested/nested_resource.bin`` in a package would not
   contain other resources, but implies the existence of a resource
   ``nested``, which contains ``nested_resource.bin``.
   linking using ``dlopen()`` on POSIX, or any APIs which need access to
   resource data via OS-level file handles rather than Python streams).
 
-
 A minimal solution
 ^^^^^^^^^^^^^^^^^^
 
             (relative) resource names
             """
 
-
 Dealing with the requirement for access via file system files
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 * A constructor which takes an optional base directory for the cache. If
   none is provided, we'll construct a base directory of the form::
 
-  <rootdir>/.distlib/resource-cache
+     <rootdir>/.distlib/resource-cache
 
   where ``<rootdir>`` is the user's home directory. On Windows, if the
   environment specifies a variable named ``LOCALAPPDATA``, its value
-  will be used as ``<rootdir>``; otherwise, the user's home directory
+  will be used as ``<rootdir>`` -- otherwise, the user's home directory
   will be used.
 
 * A :meth:`get` method which takes a ``Resource`` and returns a file system
   and returns a (``prefix``, ``subpath``) tuple.
 
   The default implementation will use :func:`os.splitdrive` to see if there's
-  a Windows drive, and convert its ``':'`` to ``'---'``. The rest of the
-  prefix will be converted by replacing ``'/'`` by ``'--'``, and appending
-  ``'.cache'`` to the result.
+  a Windows drive, if present, and convert its ``':'`` to ``'---'``. The rest
+  of the prefix will be converted by replacing ``'/'`` by ``'--'``, and
+  appending ``'.cache'`` to the result.
 
 The cache will be activated when the ``file_path`` property of a ``Resource``
 is accessed. This will be a cached property, and will call the cache's
 :meth:`get` method to obtain the file system path.
 
-
 The ``scripts`` API
 -------------------
 
 * On Windows systems, which don't support shebang lines natively, some
   alternate means of finding the correct interpreter need to be provided.
   Following the acceptance and implementation of PEP 397, a shebang-
-  interpreting launcher will be available in Python 3.3 and later, and a
+  interpreting launcher will be available in Python 3.3 and later and a
   standalone version of it for use with earlier Python versions is also
   available. However, where this can't be used, an alternative approach
   using executable launchers installed with the scripts may be necessary.
   (That is the approach taken by ``setuptools``.)
-
   Windows also has two types of launchers - console applications and
   Windows applications. The appropriate launcher needs to be used for
   scripts.
 
 * A :meth:`~ScriptMaker.make_multiple` method, which takes an iterable of
   specifications and just runs calls :meth:`~ScriptMaker.make` on each
-  item iterated over, aggregatig the results to return a list of absolute paths
+  item iterated over, aggregating the results to return a list of absolute paths
   of all files that were installed (or would have been installed, but for the
   dry-run mode being in effect).
 
   analysis tool, over all the installed files.
 
 * The details of the callable specification can be encapsulated in a utility
-  function, :func:`~distlib.util.get_exports_entry`. This would take a specification
-  and return ``None``, if the specification didn't match the callable format,
-  or an instance of :class:`ExportEntry` if it did match.
+  function, :func:`~distlib.util.get_exports_entry`. This would take a
+  specification and return ``None``, if the specification didn't match the
+  callable format, or an instance of :class:`ExportEntry` if it did match.
 
 In addition, the following attributes on a ``ScriptMaker`` could be further used
 to refine its behaviour:
 value (with no intervening spaces). Multiple flags can be separated by ','
 and whitespace. The following would be valid flag sections::
 
-  [a,b,c]
-  [a, b, c]
-  [a=b, c=d, e, f=g, 9=8]
+   [a,b,c]
+   [a, b, c]
+   [a=b, c=d, e, f=g, 9=8]
 
 whereas the following would be invalid::
 
- []
- [\]
- [a,]
- [a,,b]
- [a=,b,c]
-
+  []
+  [\]
+  [a,]
+  [a,,b]
+  [a=,b,c]
 
 The ``version`` API
 -------------------
 The problem we're trying to solve
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Distribution releases are named by versions, and versions have two principal
+Distribution releases are named by versions and versions have two principal
 uses:
 
-* Identifying a particular release, and determining whether or not it is
+* Identifying a particular release and determining whether or not it is
   earlier or later than some other release.
 
 * When specifying other distributions that a distribution release depends on,
 but due to their ubiquity in projects registered on PyPI. Below are some
 results from testing actual projects on PyPI::
 
-    Packages processed: 24891
-    Packages with no versions: 217
-    Packages with versions: 24674
-    Number of packages clean for all schemes: 19010 (77%)
-    Number of packages clean for PEP 386: 21072 (85%)
-    Number of packages clean for PEP 386 + suggestion: 23685 (96%)
-    Number of packages clean for legacy: 24674 (100%, by you would expect)
-    Number of packages clean for semantic: 19278 (78%)
+   Packages processed: 24891
+   Packages with no versions: 217
+   Packages with versions: 24674
+   Number of packages clean for all schemes: 19010 (77%)
+   Number of packages clean for PEP 386: 21072 (85%)
+   Number of packages clean for PEP 386 + suggestion: 23685 (96%)
+   Number of packages clean for legacy: 24674 (100%, by you would expect)
+   Number of packages clean for semantic: 19278 (78%)
 
 where "+ suggestion" refers to using the suggested version algorithm to derive
 a version from a version which would otherwise be incompatible with :pep:`386`.
 
-
 A minimal solution
 ^^^^^^^^^^^^^^^^^^
 
 Of course, the version class is also available through the matcher's
 ``version_class`` attribute.
 
-:class:`VersionScheme` make it easier to work with alternative version schemes.
+:class:`VersionScheme` makes it easier to work with alternative version schemes.
 For example, say we decide to experiment with an "adaptive" version scheme,
 which is based on the PEP 386 scheme, but when handed a non-conforming version,
 automatically tries to convert it to a normalized version using
 If an unrecognised name is passed in, a ``ValueError`` is raised.
 
 The reimplemented ``distlib.version`` module is shorter than the corresponding
-module in ``distutils2``, but the entire test suite passes, and there is support
+module in ``distutils2``, but the entire test suite passes and there is support
 for working with three versioning schemes as opposed to just one. However, the
 concept of "final" versions, which is not in the PEP but which was in the
 ``distutils2`` implementation, has been removed because it appears of little
 value (there's no way to determine the "final" status of versions for many of
 the project releases registered on PyPI).
 
-
 Next steps
 ----------
 

docs/metadata.rst

 .. module:: distlib.metadata
    :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.
+   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 provide 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
+   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')
    '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']
-
+   >>>
 
 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,
    ...
    >>> metadata['Requires-Dist']
    ['pywin32', 'Sphinx']
-
+   >>>
 
 Writing metadata
 ----------------
 Writing metadata can be done using the ``write`` method::
 
    >>> 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
 ----------------------------------
 
    >>> 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
 
-
 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
 for some metadata fields.
 .. function:: interpret(marker, execution_context=None)
 
    Interpret a marker and return a boolean result depending on the environment.
-   Example:
+   Example::
 
       >>> interpret("python_version > '1.0'")
       True
+      >>>
+

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
 ----------------------------------
 ~~~~~~~~~~~~~~~~~~~~~
 
 ``resource_exists(package, resource_name)``
-    ``finder(package).find(resource_name) is not None``
+   ``finder(package).find(resource_name) is not None``
 
 ``resource_stream(package, resource_name)``
-    ``finder(package).find(resource_name).as_stream()``
+   ``finder(package).find(resource_name).as_stream()``
 
 ``resource_string(package, resource_name)``
-    ``finder(package).find(resource_name).bytes``
+   ``finder(package).find(resource_name).bytes``
 
 ``resource_isdir(package, resource_name)``
-    ``finder(package).find(resource_name).is_container``
+   ``finder(package).find(resource_name).is_container``
 
 ``resource_listdir(package, resource_name)``
-    ``finder(package).find(resource_name).resources``
+   ``finder(package).find(resource_name).resources``
 
 Resource extraction
 ~~~~~~~~~~~~~~~~~~~
 
 ``resource_filename(package, resource_name)``
-    ``finder(package).find(resource_name).file_path``
+   ``finder(package).find(resource_name).file_path``
 
 ``set_extraction_path(extraction_path)``
-    This has no direct analogue, but you can achieve equivalent results by
-    doing something like the following::
+   This has no direct analogue, but you can achieve equivalent results by
+   doing something like the following::
 
-        from distlib import resources
+    from distlib import resources
 
-        resources.cache = resources.Cache(extraction_path)
+    resources.cache = resources.Cache(extraction_path)
 
-    before accessing the ``file_path`` property of any :class:`Resource`.
-    Note that if you have accessed the ``file_path`` property for a resource
-    *before* doing this, the cache may already have extracted files.
+   before accessing the ``file_path`` property of any :class:`Resource`.
+   Note that if you have accessed the ``file_path`` property for a resource
+   *before* doing this, the cache may already have extracted files.
 
 ``cleanup_resources(force=False)``
-    This is not actually implemented in ``pkg_resources`` -- it's a no-op.
-    You could achieve the analogous result using::
+   This is not actually implemented in ``pkg_resources`` -- it's a no-op.
+   You could achieve the analogous result using::
 
-        from distlib import resources
+    from distlib import resources
 
-        not_removed = resources.cache.clear()
+    not_removed = resources.cache.clear()
 
 Provider interface
 ~~~~~~~~~~~~~~~~~~
 finders, to deal with custom requirements which aren't catered for.
 
 ``get_cache_path(archive_name, names=())``
-    There's no analogue for this, as you shouldn't need to care about whether
-    particular resources are implemented in archives or not. If you need this
-    API, please give feedback with more information about your use cases.
+   There's no analogue for this, as you shouldn't need to care about whether
+   particular resources are implemented in archives or not. If you need this
+   API, please give feedback with more information about your use cases.
 
 ``extraction_error()``
-    There's no analogue for this. The :meth:`Cache.get` method, which writes
-    a resource's bytes to a file in the cache, will raise any exception caused
-    by underlying I/O. If you need to handle this in the cache layer, you can
-    subclass :class:`Cache` and override :meth:`get`. If that doesn't work for
-    you, please give feedback with more information about your use cases.
+   There's no analogue for this. The :meth:`Cache.get` method, which writes
+   a resource's bytes to a file in the cache, will raise any exception caused
+   by underlying I/O. If you need to handle this in the cache layer, you can
+   subclass :class:`Cache` and override :meth:`get`. If that doesn't work for
+   you, please give feedback with more information about your use cases.
 
 ``postprocess(tempname, filename)``
-    There's no analogue for this. The :meth:`Cache.get` method, which writes
-    a resource's bytes to a file in the cache, can be overridden to perform any
-    custom post-processing. If that doesn't work for you, please give feedback
-    with more information about your use cases.
+   There's no analogue for this. The :meth:`Cache.get` method, which writes
+   a resource's bytes to a file in the cache, can be overridden to perform any
+   custom post-processing. If that doesn't work for you, please give feedback
+   with more information about your use cases.
 
 The ``pkg_resources`` entry point API
 -------------------------------------
 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.
+``exports`` attribute, which is a dictionary keyed by category and whose values
+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)
 
 need.
 
 ``load_entry_point(distname, groupname, name)``
-    ``dist.exports[groupname][name].value``
+   ``dist.exports[groupname][name].value``
 
 ``get_entry_info(distname, groupname, name)``
-    ``dist.exports[groupname][name]``
+   ``dist.exports[groupname][name]``
 
 ``get_entry_map(distname, groupname=None)``
-    ``dist.exports`` or ``dist.exports[groupname]``
+   ``dist.exports`` or ``dist.exports[groupname]``
 
 ``iter_entry_points(groupname, name=None)``
-    ``dist_path.get_exported_entries(groupname, name=None)``
+   ``dist_path.get_exported_entries(groupname, name=None)``

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 functionally 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:
 <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
 --------------
 
 The project has reached alpha status in its development: there is a test
 suite and it has been exercised on Windows, Ubuntu and Mac OS X. No release
-has yet been made: to work with the proejct, you need to clone the source
+has yet been made: to work with the project, you need to clone the source
 repository or download a tarball from it.
 
 The source repository for the project is on BitBucket:

docs/reference.rst

 
    This class represents a set of distributions which are installed on a Python
    path (like ``PYTHONPATH`` / ``sys.path``). Both new-style (``distlib``) and
-   legacy (egg) distibutions are catered for.
+   legacy (egg) distributions are catered for.
 
    Methods:
 
 
       Looks for a distribution by name. It returns the first one found with
       that name (there should only be one distribution with a given name on a
-      given search path). Returns ``None`` if no distrubution was found, or
+      given search path). Returns ``None`` if no distribution was found, or
       else an instance of :class:`Distribution` (or, if ``include_egg`` was
       specified as ``True`` for the instance, an instance of
       :class:`EggInfoDistribution` if a legacy distribution was found with that
       :returns: An iterator which iterates over exported entries (instances of
                 :class:`ExportEntry`).
 
-
 .. class:: Distribution
 
    A class representing a distribution, typically one which hasn't been
       The locator for an instance which has been retrieved through a locator.
       This is ``None`` for an installed distribution.
 
-
 .. class:: InstalledDistribution(Distribution)
 
    A class representing an installed distribution. This class is not
                        default location.
       :type filename: str
 
-
 .. class:: EggInfoDistribution
 
    Analogous to :class:`Distribution`, but covering legacy distributions. This
                     (i.e. with platform-specific directory separators as
                     indicated by ``os.sep``).
 
-
-
 The :class:`DependencyGraph` class
 ----------------------------------
 
 .. class:: DependencyGraph
 
-   This class represents a dependency graph between releases.  The nodes are
-   distribution instances; the edge model dependencies.  An edge from ``a``
+   This class represents a dependency graph between releases. The nodes are
+   distribution instances; the edges model dependencies. An edge from ``a``
    to ``b`` means that ``a`` depends on ``b``.
 
    .. method:: add_distribution(distribution)
 
    .. attribute:: reverse_list
 
-      Dictionary mapping distributions to a list of predecessors.  This allows
+      Dictionary mapping distributions to a list of predecessors. This allows
       efficient traversal.
 
    .. attribute:: missing
       Dictionary mapping distributions to a list of requirements that were not
       provided by any distribution.
 
-
 The ``distlib.resources`` package
 ---------------------------------
 
 .. attribute:: cache
 
    An instance of :class:`Cache`, which uses the default base location for the
-   cache (as descibed in the documentation for :meth:`Cache.__init__`).
+   cache (as described in the documentation for :meth:`Cache.__init__`).
 
 Functions
 ^^^^^^^^^
       .zip) into a directory name in the cache. This implementation
       delegates the work to :func:`~distlib.util.path_to_cache_dir`.
 
-
 The ``distlib.scripts`` package
 -------------------------------
 
 
 .. currentmodule:: distlib.locators
 
-
 Classes
 ^^^^^^^^
 
 
        See :meth:`Locator.get_project`.
 
-
 .. class:: PyPIJSONLocator(Locator)
 
    This locator uses the PyPI JSON interface to locate distribution
 
        See :meth:`Locator.get_project`.
 
-
 .. class:: SimpleScrapingLocator
 
    This locator uses the PyPI 'simple' interface -- a Web scraping interface --
       :type num_workers: int
       :param  kwargs: Passed to base class constructor.
 
-
 .. class:: DistPathLocator
 
    This locator uses a :class:`DistributionPath` instance to locate installed
       :type distpath: :class:`DistributionPath`
       :param  kwargs: Passed to base class constructor.
 
-
 .. class:: AggregatingLocator(Locator)
 
    This locator uses a list of other aggregators and delegates finding projects
                     passed in.
       :type merge: bool
 
-
 .. class:: DependencyFinder
 
    This class allows you to recursively find all the distributions which a
              Note that some of the names may be Unicode.
    :rtype: list
 
-
 .. function:: locate(requirement)
 
    This convenience function returns the latest version of a potentially
    downloadable distribution which matches a requirement (name and version
    constraints). If a potentially downloadable distribution (i.e. one with
-   a download URL) is not found, ``None`` is returned; otherwise, an
+   a download URL) is not found, ``None`` is returned -- otherwise, an
    instance of :class:`~distlib.database.Distribution` is returned. The
    returned instance will have, at a minimum, ``name``, ``version`` and
    ``download_url``.
    This attribute holds a locator which is used by :func:`locate` to locate
    distributions.
 
-
 The ``distlib.util`` package
 -------------------------------
 
 .. currentmodule:: distlib.util
 
-
 Classes
 ^^^^^^^^
 
                        ``'path.supports_unicode_filenames'``.
    :type dotted_path: str
 
-
-
 Next steps
 ----------
 

docs/tutorial.rst

 
 Distlib is a pure-Python library. You should be able to install it using::
 
-    pip install distlib
+   pip install distlib
 
 for installing ``distlib`` into a virtualenv or other directory where you have
 write permissions. On Posix platforms, you may need to invoke using ``sudo``
 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
 :class:`DistributionPath` for distributions. To create a ``DistributionPath``
 instance, you can do ::
 
-    >>> from distlib.database import DistributionPath
-    >>> dist_path = DistributionPath()
+   >>> from distlib.database import DistributionPath
+   >>> dist_path = DistributionPath()
+   >>>
 
 Querying a path for distributions
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 distributions on ``sys.path``. To get these distributions, you invoke the
 :meth:`get_distributions` method, which returns an iterable. Let's try it::
 
-    >>> list(dist_path.get_distributions())
-    []
-    >>>
+   >>> list(dist_path.get_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
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ``distribute``, you need to create the ``DistributionPath`` by specifying an
 additional keyword argument, like so::
 
-    >>> dist_path = DistributionPath(include_egg=True)
+   >>> dist_path = DistributionPath(include_egg=True)
+   >>>
 
 and then you'll get a less surprising result::
 
-    >>> len(list(dist_path.get_distributions()))
-    77
+   >>> 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`
 method::
 
-    >>> dist_path.get_distribution('setuptools')
-    <EggInfoDistribution u'setuptools' 0.6c11 at '/usr/lib/python2.7/dist-packages/setuptools.egg-info'>
-    >>>
+   >>> dist_path.get_distribution('setuptools')
+   <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)
-    >>> pprint([d.name for d in special_dists.get_distributions()])
-    ['babar',
-     'choxie',
-     'towel-stuff',
-     'grammar',
-     'truffles',
-     'coconuts-aster',
-     'nut',
-     'bacon',
-     'banana',
-     'cheese',
-     'strawberry']
-    >>>
+   >>> from pprint import pprint
+   >>> special_dists = DistributionPath(['tests/fake_dists'], include_egg=True)
+   >>> pprint([d.name for d in special_dists.get_distributions()])
+   ['babar',
+    'choxie',
+    'towel-stuff',
+    'grammar',
+    'truffles',
+    'coconuts-aster',
+    'nut',
+    'bacon',
+    'banana',
+    'cheese',
+    'strawberry']
+   >>>
 
 or, if you leave out egg-based distributions::
 
-    >>> special_dists = DistributionPath(['tests/fake_dists'])
-    >>> pprint([d.name for d in special_dists.get_distributions()])
-    ['babar', 'choxie', 'towel-stuff', 'grammar']
-    >>>
+   >>> special_dists = DistributionPath(['tests/fake_dists'])
+   >>> pprint([d.name for d in special_dists.get_distributions()])
+   ['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
+but helpfully offers a mechanism whereby providers of other sources of
 message text can provide 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
 
     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.
 packages, whether in the file system or .zip files. Consider a package
 which contains data alongside Python code::
 
-    foofoo
-    ├── bar
-    │   ├── bar_resource.bin
-    │   ├── baz.py
-    │   └── __init__.py
-    ├── foo_resource.bin
-    ├── __init__.py
-    └── nested
-        └── nested_resource.bin
+   foofoo
+   ├── bar
+   │   ├── bar_resource.bin
+   │   ├── baz.py
+   │   └── __init__.py
+   ├── foo_resource.bin
+   ├── __init__.py
+   └── nested
+       └── nested_resource.bin
 
 Access to resources in the file system
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 You can access these resources like so::
 
-    >>> from distlib.resources import finder
-    >>> f = finder('foofoo')
-    >>> r = f.find('foo_resource.bin')
-    >>> r.is_container
-    False
-    >>> r.size
-    10
-    >>> r.bytes
-    b'more_data\n'
-    >>> s = r.as_stream()
-    >>> s.read()
-    b'more_data\n'
-    >>> s.close()
-    >>> r = f.find('nested')
-    >>> r.is_container
-    True
-    >>> r.resources
-    {'nested_resource.bin'}
-    >>> r = f.find('nested/nested_resource.bin')
-    >>> r.size
-    12
-    >>> r.bytes
-    b'nested data\n'
-    >>> f = finder('foofoo.bar')
-    >>> r = f.find('bar_resource.bin')
-    >>> r.is_container
-    False
-    >>> r.bytes
-    b'data\n'
-    >>>
+   >>> from distlib.resources import finder
+   >>> f = finder('foofoo')
+   >>> r = f.find('foo_resource.bin')
+   >>> r.is_container
+   False
+   >>> r.size
+   10
+   >>> r.bytes
+   b'more_data\n'
+   >>> s = r.as_stream()
+   >>> s.read()
+   b'more_data\n'
+   >>> s.close()
+   >>> r = f.find('nested')
+   >>> r.is_container
+   True
+   >>> r.resources
+   {'nested_resource.bin'}
+   >>> r = f.find('nested/nested_resource.bin')
+   >>> r.size
+   12
+   >>> r.bytes
+   b'nested data\n'
+   >>> f = finder('foofoo.bar')
+   >>> r = f.find('bar_resource.bin')
+   >>> r.is_container
+   False
+   >>> r.bytes
+   b'data\n'
+   >>>
 
 Access to resources in the ``.zip`` files
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 It works the same way if the package is in a .zip file. Given the zip file
 ``foo.zip``::
 
-    $ unzip -l foo.zip
-    Archive:  foo.zip
-      Length      Date    Time    Name
-    ---------  ---------- -----   ----
-           10  2012-09-20 21:34   foo/foo_resource.bin
-            8  2012-09-20 21:42   foo/__init__.py
-           14  2012-09-20 21:42   foo/bar/baz.py
-            8  2012-09-20 21:42   foo/bar/__init__.py
-            5  2012-09-20 21:33   foo/bar/bar_resource.bin
-    ---------                     -------
-           45                     5 files
+   $ unzip -l foo.zip
+   Archive:  foo.zip
+     Length      Date    Time    Name
+   ---------  ---------- -----   ----
+          10  2012-09-20 21:34   foo/foo_resource.bin
+           8  2012-09-20 21:42   foo/__init__.py
+          14  2012-09-20 21:42   foo/bar/baz.py
+           8  2012-09-20 21:42   foo/bar/__init__.py
+           5  2012-09-20 21:33   foo/bar/bar_resource.bin
+   ---------                     -------
+          45                     5 files
 
 You can access its resources as follows::
 
-    >>> import sys
-    >>> sys.path.append('foo.zip')
-    >>> from distlib.resources import finder
-    >>> f = finder('foo')
-    >>> r = f.find('foo_resource.bin')
-    >>> r.is_container
-    False
-    >>> r.size
-    10
-    >>> r.bytes
-    'more_data\n'
-    >>>
+   >>> import sys
+   >>> sys.path.append('foo.zip')
+   >>> from distlib.resources import finder
+   >>> f = finder('foo')
+   >>> r = f.find('foo_resource.bin')
+   >>> r.is_container
+   False
+   >>> r.size
+   10
+   >>> r.bytes
+   'more_data\n'
+   >>>
 
 and so on.
 
 
 .. currentmodule:: distlib.scripts
 
-
 You can use the ``distlib.scripts`` API to install scripts. Installing scripts
 is slightly more involved than just copying files:
 
 Let's see how wrapping a callable works. Consider the following file::
 
     $ cat scripts/foo.py
-    def main():
+      def main():
         print('Hello from foo')
 
     def other_main():
         print('Hello again from foo')
 
-we can try wrapping ``main`` and ``other_main`` as callables::
+   we can try wrapping ``main`` and ``other_main`` as callables::
 
-    >>> from distlib.scripts import ScriptMaker
-    >>> maker = ScriptMaker('scripts', '/tmp/scratch')
-    >>> maker.make_multiple(('foo = foo:main', 'bar = foo:other_main'))
-    ['/tmp/scratch/foo', '/tmp/scratch/bar']
-    >>>
+      >>> from distlib.scripts import ScriptMaker
+      >>> maker = ScriptMaker('scripts', '/tmp/scratch')
+      >>> maker.make_multiple(('foo = foo:main', 'bar = foo:other_main'))
+      ['/tmp/scratch/foo', '/tmp/scratch/bar']
+      >>>
 
-we can inspect the resulting scripts. First, ``foo``::
+   we can inspect the resulting scripts. First, ``foo``::
 
     $ ls /tmp/scratch/
     bar  foo
 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::
 
-    >>> v2 < v3 < v4 < v1 < v5
-    True
+      >>> v2 < v3 < v4 < v1 < v5
+      True
+      >>>
 
 You can't pass any old thing as a version number::
 
-    >>> NormalizedVersion('foo')
-    Traceback (most recent call last):
+      >>> 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)
+       self._parts = parts = self.parse(s)
       File "distlib/version.py", line 254, in parse
-        def parse(self, s): return normalized_key(s)
+       def parse(self, s): return normalized_key(s)
       File "distlib/version.py", line 199, in normalized_key
-        raise UnsupportedVersionError(s)
-    distlib.version.UnsupportedVersionError: foo
+       raise UnsupportedVersionError(s)
+      distlib.version.UnsupportedVersionError: foo
+      >>>
 
 Matching versions against constraints
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 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::
 
-    >>> 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::
 
-    >>> 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::
 
-    >>> 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):
+      >>> 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)
+       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):
+      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)
+       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')
-
+      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
 ^^^^^^^^^^^^^^^^^^^^^^
 any distributions it requires, so that they can also 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::
 
-    >>> 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`.
 
 
 There is a default locator, available at :attr:`distlib.locators.default_locator`.
 
-An example of usage of locator instances is given below::
-
-    >>> 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]>}
-    >>>
-
-Now the same project, 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 reason why some of the download URLs come up as UNKNOWN is that some of
-the PyPI metadata is incomplete.
-
-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`` 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
-    >>>
+      >>> 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.
+   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'``).
+   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'``).
 
-The locators skip binary distributions (``.egg`` files are currently treated
-as binary distributions).
+   The locators will 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
 ----------
 
 .. function:: get_platform()
 
-   Return a string that identifies the current platform.  This is used mainly to
+   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
+   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
    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
+   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 univeral build with the i386 and x86_64 architectures
+   a universal build with the i386 and x86_64 architectures
 
    Examples of returned values on Mac OS X:
 
    * ``macosx-10.3-ppc``
-
    * ``macosx-10.3-fat``
-
    * ``macosx-10.5-universal``
-
    * ``macosx-10.6-intel``
 
    .. XXX reinvention of platform module?
 
-
 .. function:: convert_path(pathname)
 
    Return 'pathname' as a name that will work on the native filesystem, i.e.
    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
    making *pathname* relative and then joining the two, which is tricky on
    DOS/Windows.
 
-
 .. function:: check_environ()
 
    Ensure that 'os.environ' has all the environment variables we guarantee that
    * :envvar:`PLAT` - description of the current platform, including hardware
      and OS (see :func:`get_platform`)
 
-
 .. function:: find_executable(executable, path=None)
 
    Search the path for a given executable name.
 
-
 .. function:: execute(func, args, msg=None, dry_run=False)
 
    Perform some action that affects the outside world (for instance, writing to
-   the filesystem).  Such actions are special because they are disabled by the
-   *dry_run* flag.  This method takes care of all that bureaucracy for you;
-   all you have to do is supply the function to call and an argument tuple for
-   it (to embody the "external action" being performed), and an optional message
+   the filesystem). Such actions are special because they are disabled by the
+   *dry_run* flag. This method takes care of all that bureaucracy for you,
+   all you have to do is supply the function to call, an argument tuple
+   (to embody the "external action" being performed), and an optional message
    to print.
 
-
 .. function:: newer(source, target)
 
-   Return true if *source* exists and is more recently modified than *target*,
+   Return true if *source* exists and is more recently modified than *target*
    or if *source* exists and *target* doesn't. Return false if both exist and
    *target* is the same age or newer than *source*. Raise
    :exc:`PackagingFileError` if *source* does not exist.
 
-
 .. function:: strtobool(val)
 
    Convert a string representation of truth to true (1) or false (0).
    versions older than 3.2.
 
    *py_files* is a list of files to compile; any files that don't end in
-   :file:`.py` are silently skipped.  *optimize* must be one of the following:
+   :file:`.py` are silently skipped. *optimize* must be one of the following:
 
    * ``0`` - don't optimize (generate :file:`.pyc`)
    * ``1`` - normal optimization (like ``python -O``)
 
    If *force* is true, all files are recompiled regardless of timestamps.
 
-   The source filename encoded in each :term:`bytecode` file defaults to the filenames
-   listed in *py_files*; you can modify these with *prefix* and *basedir*.
-   *prefix* is a string that will be stripped off of each source filename, and
-   *base_dir* is a directory name that will be prepended (after *prefix* is
-   stripped).  You can supply either or both (or neither) of *prefix* and
-   *base_dir*, as you wish.
+   The source filename encoded in each :term:`bytecode` file defaults to the
+   filenames listed in *py_files*; you can modify these with *prefix* and
+   *basedir*. *prefix* is a string that will be stripped off of each source
+   filename, and *base_dir* is a directory name that will be prepended (after
+   *prefix* is stripped). You can supply either or both (or neither) of
+   *prefix* and *base_dir*, as you wish.
 
-   If *dry_run* is true, doesn't actually do anything that would affect the
+   If *dry_run* is true, it doesn't actually do anything that would affect the
    filesystem.
 
-   Byte-compilation is either done directly in this interpreter process with the
+   Byte-compilation is either done directly in the interpreter process with the
    standard :mod:`py_compile` module, or indirectly by writing a temporary
    script and executing it.  Normally, you should let :func:`byte_compile`
-   figure out to use direct compilation or not (see the source for details).
-   The *direct* flag is used by the script generated in indirect mode; unless
-   you know what you're doing, leave it set to ``None``.
+   figure out whether to use direct compilation or not (see the source for
+   details). The *direct* flag is used by the script generated in indirect
+   mode, unless you know what you're doing, leave it set to ``None``.
 .. module:: packaging.version
    :synopsis: Classes that represent project version numbers.
 
-
 This module contains classes and functions useful to deal with version numbers.
 It's an implementation of version specifiers `as defined in PEP 345
 <http://www.python.org/dev/peps/pep-0345/#version-specifiers>`_.
 
 .. class:: NormalizedVersion(self, s, error_on_huge_major_num=True)
 
-   A specific version of a distribution, as described in PEP 345.  *s* is a
+   A specific version of a distribution, as described in PEP 345. *s* is a
    string object containing the version number (for example ``'1.2b1'``),
    *error_on_huge_major_num* a boolean specifying whether to consider an
    apparent use of a year or full date as the major version number an error.
 
-   The rationale for the second argument is that there were projects using years
-   or full dates as version numbers, which could cause problems with some
+   The rationale for the second argument is that there were projects using
+   years or full dates as version numbers, which could cause problems with some
    packaging systems sorting.
 
    Instances of this class can be compared and sorted::
 
       >>> NormalizedVersion('1.2b1') < NormalizedVersion('1.2')
       True
+      >>>
 
-   :class:`NormalizedVersion` is used internally by :class:`VersionPredicate` to
-   do its work.
-
+   :class:`NormalizedVersion` is used internally by :class:`VersionPredicate`
+   to do its work.
 
 .. class:: IrrationalVersionError
 
    Exception raised when an invalid string is given to
-   :class:`NormalizedVersion`.
+   :class:`NormalizedVersion`::
 
       >>> NormalizedVersion("irrational_version_number")
       ...
       IrrationalVersionError: irrational_version_number
-
+      >>>
 
 .. function:: suggest_normalized_version(s)
 
-   Before standardization in PEP 386, various schemes were in use.  Packaging
+   Before standardization in PEP 386, various schemes were in use. Packaging
    provides a function to try to convert any string to a valid, normalized
    version::
 
       >>> suggest_normalized_version('2.1-rc1')
       2.1c1
-
+      >>>
 
    If :func:`suggest_normalized_version` can't make sense of the given string,
    it will return ``None``::
 
       >>> print(suggest_normalized_version('not a version'))
       None
-
+      >>>
 
 Version predicates
 ------------------
 
    .. method:: match(version)
 
-      Test if a version number matches the predicate:
+      Test if a version number matches the predicate::
 
          >>> version = VersionPredicate("ProjectName (<1.2, >1.0)")
          >>> version.match("1.2.1")
          False
          >>> version.match("1.1.1")
          True
-
+         >>>
 
 Validation helpers
 ------------------
    Check whether the given string is a valid version number.  Example of valid
    strings: ``'1.2'``,  ``'4.2.0.dev4'``, ``'2.5.4.post2'``.
 
-
 .. function:: is_valid_versions(predicate)
 
    Check whether the given string is a valid value for specifying multiple
    versions, such as in the Requires-Python field.  Example: ``'2.7, >=3.2'``.
 
-
 .. function:: is_valid_predicate(predicate)
 
    Check whether the given string is a valid version predicate.  Examples: