home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 June / PCWorld_2005-06_cd.bin / software / vyzkuste / firewally / firewally.exe / framework-2.3.exe / pkgutil.py < prev    next >
Text File  |  2003-12-30  |  3KB  |  79 lines

  1. """Utilities to support packages."""
  2.  
  3. import os
  4. import sys
  5.  
  6. def extend_path(path, name):
  7.     """Extend a package's path.
  8.  
  9.     Intended use is to place the following code in a package's __init__.py:
  10.  
  11.         from pkgutil import extend_path
  12.         __path__ = extend_path(__path__, __name__)
  13.  
  14.     This will add to the package's __path__ all subdirectories of
  15.     directories on sys.path named after the package.  This is useful
  16.     if one wants to distribute different parts of a single logical
  17.     package as multiple directories.
  18.  
  19.     It also looks for *.pkg files beginning where * matches the name
  20.     argument.  This feature is similar to *.pth files (see site.py),
  21.     except that it doesn't special-case lines starting with 'import'.
  22.     A *.pkg file is trusted at face value: apart from checking for
  23.     duplicates, all entries found in a *.pkg file are added to the
  24.     path, regardless of whether they are exist the filesystem.  (This
  25.     is a feature.)
  26.  
  27.     If the input path is not a list (as is the case for frozen
  28.     packages) it is returned unchanged.  The input path is not
  29.     modified; an extended copy is returned.  Items are only appended
  30.     to the copy at the end.
  31.  
  32.     It is assumed that sys.path is a sequence.  Items of sys.path that
  33.     are not (unicode or 8-bit) strings referring to existing
  34.     directories are ignored.  Unicode items of sys.path that cause
  35.     errors when used as filenames may cause this function to raise an
  36.     exception (in line with os.path.isdir() behavior).
  37.     """
  38.  
  39.     if not isinstance(path, list):
  40.         # This could happen e.g. when this is called from inside a
  41.         # frozen package.  Return the path unchanged in that case.
  42.         return path
  43.  
  44.     pname = os.path.join(*name.split('.')) # Reconstitute as relative path
  45.     # Just in case os.extsep != '.'
  46.     sname = os.extsep.join(name.split('.'))
  47.     sname_pkg = sname + os.extsep + "pkg"
  48.     init_py = "__init__" + os.extsep + "py"
  49.  
  50.     path = path[:] # Start with a copy of the existing path
  51.  
  52.     for dir in sys.path:
  53.         if not isinstance(dir, (str, unicode)) or not os.path.isdir(dir):
  54.             continue
  55.         subdir = os.path.join(dir, pname)
  56.         # XXX This may still add duplicate entries to path on
  57.         # case-insensitive filesystems
  58.         initfile = os.path.join(subdir, init_py)
  59.         if subdir not in path and os.path.isfile(initfile):
  60.             path.append(subdir)
  61.         # XXX Is this the right thing for subpackages like zope.app?
  62.         # It looks for a file named "zope.app.pkg"
  63.         pkgfile = os.path.join(dir, sname_pkg)
  64.         if os.path.isfile(pkgfile):
  65.             try:
  66.                 f = open(pkgfile)
  67.             except IOError, msg:
  68.                 sys.stderr.write("Can't open %s: %s\n" %
  69.                                  (pkgfile, msg))
  70.             else:
  71.                 for line in f:
  72.                     line = line.rstrip('\n')
  73.                     if not line or line.startswith('#'):
  74.                         continue
  75.                     path.append(line) # Don't check for existence!
  76.                 f.close()
  77.  
  78.     return path
  79.