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