[Python-Dev] Implementing PEP 382, Namespace Packages

"Martin v. Löwis" martin at v.loewis.de
Mon May 31 09:24:22 CEST 2010


> Looking at that proposal, I don't follow how changing *loaders* (vs.
> importers) would help. If an importer's find_module doesn't natively
> support PEP 382, then there's no way to get a loader for the package in
> the first place.

True. However, this requires no changes to the API, AFAICT. The *finder*
(there are no importers, right?) will need to accept a folder with just 
a pth file as a package, but then still return a loader.

The issue is then how to make the loader scan the folder for .pth files.
One option would be to ask it "give me the contents of all the pth 
files", the other would be to have a method "load all the pth files".

> In the PEP 302 scheme, then, it's either importers that have to change,
> or the process that invokes them. Being able to ask an importer the
> equivalents of os.path.join, listdir, and get_data would suffice to make
> an import process that could do the trick.

That would also work, but it would make a fairly wide interface. IIRC, 
MAL complained that doing so would break importers which can't do listdir.

> Essentially, you'd ask each importer to first attempt to find the
> module, and then asking it (or the loader, if the find worked) whether
> packagename/*.pth exists, and then processing their contents.

The latter is my proposal, yes: ask the loader to process all pth files.

> If at any point the find_module() call succeeds, then subsequent
> importers will just be asked for .pth files, which can then be processed
> into the __path__ of the now-loaded module.
>
> IOW, something like this (very rough draft):


 >    pth_contents = []
 >    module = None
 >
 >    for pathitem in syspath_or_parent__path__:
 >
 >        importer = pkgutil.get_importer(pathitem)
 >        if importer is None:
 >            continue
 >
 >        if module is None:
 >            try:
 >                loader = importer.find_module(fullname)
 >            except ImportError:
 >                pass

Is this really how it works today? Shouldn't it abort here
if there is an ImportError?

 >            else:
 >                # errors here should propagate
 >                module = loader.load_module(fullname)
 >                if not hasattr(module, '__path__'):
 >                    # found, but not a package
 >                    return module
 >
 >        pc = get_pth_contents(importer)

Assuming we always get here with a loader, I'd rather call this
on the loader.

Regards,
Martin


More information about the Python-Dev mailing list