1 """Utilities to support packages."""
6 def extend_path(path
, name
):
7 """Extend a package's path.
9 Intended use is to place the following code in a package's __init__.py:
11 from pkgutil import extend_path
12 __path__ = extend_path(__path__, __name__)
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.
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
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.
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).
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.
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"
50 path
= path
[:] # Start with a copy of the existing path
53 if not isinstance(dir, (str, unicode)) or not os
.path
.isdir(dir):
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
):
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
):
68 sys
.stderr
.write("Can't open %s: %s\n" %
72 line
= line
.rstrip('\n')
73 if not line
or line
.startswith('#'):
75 path
.append(line
) # Don't check for existence!