1 # This module provides standard support for "packages".
3 # The idea is that large groups of related modules can be placed in
4 # their own subdirectory, which can be added to the Python search path
5 # in a relatively easy way.
7 # The current version takes a package name and searches the Python
8 # search path for a directory by that name, and if found adds it to
9 # the module search path (sys.path). It maintains a list of packages
10 # that have already been added so adding the same package many times
13 # It is intended to be used in a fairly stylized manner: each module
14 # that wants to use a particular package, say 'Foo', is supposed to
15 # contain the following code:
17 # from addpack import addpack
19 # <import modules from package Foo>
21 # Additional arguments, when present, provide additional places where
22 # to look for the package before trying sys.path (these may be either
23 # strings or lists/tuples of strings). Also, if the package name is a
24 # full pathname, first the last component is tried in the usual way,
25 # then the full pathname is tried last. If the package name is a
26 # *relative* pathname (UNIX: contains a slash but doesn't start with
27 # one), then nothing special is done. The packages "/foo/bar/bletch"
28 # and "bletch" are considered the same, but unrelated to "bar/bletch".
30 # If the algorithm finds more than one suitable subdirectory, all are
31 # added to the search path -- this makes it possible to override part
32 # of a package. The same path will not be added more than once.
34 # If no directory is found, ImportError is raised.
36 _packs
= {} # {pack: [pathname, ...], ...}
38 def addpack(pack
, *locations
):
40 if os
.path
.isabs(pack
):
41 base
= os
.path
.basename(pack
)
44 if _packs
.has_key(base
):
48 for loc
in _flatten(locations
) + sys
.path
:
49 fn
= os
.path
.join(loc
, base
)
50 if fn
not in path
and os
.path
.isdir(fn
):
52 if pack
!= base
and pack
not in path
and os
.path
.isdir(pack
):
54 if not path
: raise ImportError, 'package ' + pack
+ ' not found'
57 if fn
not in sys
.path
:
60 def _flatten(locations
):
63 if type(loc
) == type(''):
66 locs
= locs
+ _flatten(loc
)