[Python-Dev] Proposing PEP 376

P.J. Eby pje at telecommunity.com
Wed Apr 7 19:40:35 CEST 2010


At 12:48 AM 4/4/2010 +0200, Tarek Ziadé wrote:
>The implementation so far will load zip files founded in the paths,
>see ZippedDistributionDir/ZippedDistribution.

I was saying that it doesn't support sys.path entries of the form:

   "some/path/to/somezipfile.zip/subdir1"

Python works correctly for importing with this, but the ZipFinder 
class in the implementation throws away 'subdir1' and only scans the 
root of the zipfile, silently generating incorrect results in such a case.

To fix the problem, you would need to make use of the .archive and 
.prefix attributes of defined by the underlying zipimporter 
class.  After you call the super().__init__ method, .archive points 
to the actual zipfile path, and .prefix contains the portion of the 
path that's inside the zipfile.  You can then just adjust your path 
usage in ZipFinder and ZippedDistribution accordingly.

Also, as far as I can tell from the source, ZipFinder instances are 
never actually created, except through explicit usage in some of the 
tests.  i.e., it doesn't work out of the box right now.  However, 
this could be fixed with the addition of the code snippets below...


>I am wondering though, if we shouldn't omit this zip story for PEP 376
>altogether, and work later on
>something more generic wrt import protocols where modules/packages
>could be stored anywhere.

Essentially, you could do something like:

     @simplegeneric  # <-already in stdlib pkgutil since 2.5
     def dist_finder_for(importer):
         if hasattr(importer, 'list_distributions'):
             return importer
         return None

     dist_finder_for.register(ImpImporter, FSFinder)
     dist_finder_for.register(zipimporter, ZipFinder)

And then your all_finders() function would be reduced to:

     def all_finders():
         for importer in iter_importers():  # <-already in stdlib pkgutil
             finder = dist_finder_for(importer)
             if finder is not None:
                  yield finder

As you can see, it's pretty easy to integrate with your existing 
code.  simplegeneric and iter_importers (as well as a 
get_importer(pathentry) function, ImpImporter, etc.) have been in 
pkgutil since 2.5, but you can always backport them if you're making 
a standalone version for 2.4.





More information about the Python-Dev mailing list