[Zope3-dev] Zip import and sys.path manipulation (was Re: directory hierarchy proposal)
Guido van Rossum
guido@python.org
Mon, 16 Dec 2002 11:54:27 -0500
> At 10:47 AM 12/16/02 -0500, Guido van Rossum wrote:
>
> >Time's running short (we're close to releasing Python 2.3 alpha 1);
> >we should decide on a name and a specific policy ASAP. I propose the
> >following:
> >
> > from pkgutil import extended_path
> > __path__ = extended_path(__path__, __name__)
>
> How would that work for say, 'zope.app'?
Good point. Back to the drawing board; I'll have to turn dots in the
name into os.sep.
> >Where pkgutil.py could be something like this:
> >
> > import sys.path
> >
> > def extended_path(path, name):
> > """Extend a package's path. (XXX more.)"""
> > path = path[:]
> > for dir in sys.path:
> > if isinstance(dir, (str, unicode)):
> > dir = os.path.join(dir, name)
> > if dir not in path and os.path.isdir(dir):
> > path.append(dir)
> > return path
>
> The 'isdir()' part isn't going to work on zipfiles... unless os.path is
> going to have zipfile support in 2.3. :)
I tried putting Zope3 in a zipfile, and it's hopeless; lots and lots
of code expects to find data files (at least page templates and zcml
files; probably also style sheets and other stuff that I don't even
know about) by taking a module's __file__, stripping the filename to
get a directory, and concatenating the directory with the name of a
known data file. Plus there's the issue of extension modules.
So I think the isdir() not working for zip files can be considered a
feature. :-)
BTW, here's a more recent draft, incorporating a search for .pth
files and with a different place for the isdir():
## pkgutil.py #################################################################
"""Utilities to support packages."""
import os
import sys
def extend_path(path, name):
"""Extend a package's path.
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
if one wants to distribute different parts of a single logical
package as multiple directories.
"""
path = path[:]
for dir in sys.path:
if isinstance(dir, (str, unicode)) and os.path.isdir(dir):
subdir = os.path.join(dir, name)
if subdir not in path and os.path.isdir(subdir):
path.append(subdir)
pthfile = os.path.join(dir, name + os.extsep + "pth")
if os.path.isfile(pthfile):
try:
f = open(pthfile)
except IOError, msg:
sys.stderr.write("Can't open %s: %s\n" %
(pthfile, msg))
else:
for line in f:
line = line.strip()
if not line or line.startswith('#'):
continue
path.append(line) # Don't check for existence!
f.close()
return path
###############################################################################
--Guido van Rossum (home page: http://www.python.org/~guido/)