0001 """Utilities to support packages.""" 0002 0003 import os 0004 import sys 0005 0006 def extend_path(path, name): 0007 """Extend a package's path. 0008 0009 Intended use is to place the following code in a package's __init__.py: 0010 0011 from pkgutil import extend_path 0012 __path__ = extend_path(__path__, __name__) 0013 0014 This will add to the package's __path__ all subdirectories of 0015 directories on sys.path named after the package. This is useful 0016 if one wants to distribute different parts of a single logical 0017 package as multiple directories. 0018 0019 It also looks for *.pkg files beginning where * matches the name 0020 argument. This feature is similar to *.pth files (see site.py), 0021 except that it doesn't special-case lines starting with 'import'. 0022 A *.pkg file is trusted at face value: apart from checking for 0023 duplicates, all entries found in a *.pkg file are added to the 0024 path, regardless of whether they are exist the filesystem. (This 0025 is a feature.) 0026 0027 If the input path is not a list (as is the case for frozen 0028 packages) it is returned unchanged. The input path is not 0029 modified; an extended copy is returned. Items are only appended 0030 to the copy at the end. 0031 0032 It is assumed that sys.path is a sequence. Items of sys.path that 0033 are not (unicode or 8-bit) strings referring to existing 0034 directories are ignored. Unicode items of sys.path that cause 0035 errors when used as filenames may cause this function to raise an 0036 exception (in line with os.path.isdir() behavior). 0037 """ 0038 0039 if not isinstance(path, list): 0040 # This could happen e.g. when this is called from inside a 0041 # frozen package. Return the path unchanged in that case. 0042 return path 0043 0044 pname = os.path.join(*name.split('.')) # Reconstitute as relative path 0045 # Just in case os.extsep != '.' 0046 sname = os.extsep.join(name.split('.')) 0047 sname_pkg = sname + os.extsep + "pkg" 0048 init_py = "__init__" + os.extsep + "py" 0049 0050 path = path[:] # Start with a copy of the existing path 0051 0052 for dir in sys.path: 0053 if not isinstance(dir, basestring) or not os.path.isdir(dir): 0054 continue 0055 subdir = os.path.join(dir, pname) 0056 # XXX This may still add duplicate entries to path on 0057 # case-insensitive filesystems 0058 initfile = os.path.join(subdir, init_py) 0059 if subdir not in path and os.path.isfile(initfile): 0060 path.append(subdir) 0061 # XXX Is this the right thing for subpackages like zope.app? 0062 # It looks for a file named "zope.app.pkg" 0063 pkgfile = os.path.join(dir, sname_pkg) 0064 if os.path.isfile(pkgfile): 0065 try: 0066 f = open(pkgfile) 0067 except IOError, msg: 0068 sys.stderr.write("Can't open %s: %s\n" % 0069 (pkgfile, msg)) 0070 else: 0071 for line in f: 0072 line = line.rstrip('\n') 0073 if not line or line.startswith('#'): 0074 continue 0075 path.append(line) # Don't check for existence! 0076 f.close() 0077 0078 return path 0079
Generated by PyXR 0.9.4