Commit 1f43ab9b authored by Philip Thiem's avatar Philip Thiem

This changes distribute to use zipfile for obtaining a manifest of zip files

instead of zipimpot._zip_directory_cache.  As I don't see any place that the
cache is being clear, should in effect remove the zipimport private variable
dependency

--HG--
branch : distribute
extra : rebase_source : 275dd3d5a2f55dba541f7f12a1bf8ee7c3465825
parent c0a6a134
...@@ -13,7 +13,8 @@ The package resource API is designed to work with normal filesystem packages, ...@@ -13,7 +13,8 @@ The package resource API is designed to work with normal filesystem packages,
method. method.
""" """
import sys, os, zipimport, time, re, imp, types import sys, os, zipimport, time, re, imp, types
import zipfile
from urlparse import urlparse, urlunparse from urlparse import urlparse, urlunparse
try: try:
...@@ -1348,7 +1349,33 @@ class EmptyProvider(NullProvider): ...@@ -1348,7 +1349,33 @@ class EmptyProvider(NullProvider):
empty_provider = EmptyProvider() empty_provider = EmptyProvider()
def build_zipmanifest(path):
"""
This builds a similar dictionary to the zipimport directory
caches. However instead of tuples, ZipInfo objects are stored.
The translation of the tuple is as follows:
* [0] - zipinfo.filename on stock pythons this needs "/" --> os.sep
on pypy it is the same (one reason why distribute did work
in some cases on pypy and win32).
* [1] - zipinfo.compress_type
* [2] - zipinfo.compress_size
* [3] - zipinfo.file_size
* [4] - len(utf-8 encoding of filename) if zipinfo & 0x800
len(ascii encoding of filename) otherwise
* [5] - (zipinfo.date_time[0] - 1980) << 9 |
zipinfo.date_time[1] << 5 | zipinfo.date_time[2]
* [6] - (zipinfo.date_time[3] - 1980) << 11 |
zipinfo.date_time[4] << 5 | (zipinfo.date_time[5] // 2)
* [7] - zipinfo.CRC
"""
zipinfo = dict()
with zipfile.ZipFile(path) as zfile:
for zitem in zfile.namelist():
zpath = zitem.replace('/', os.sep)
zipinfo[zpath] = zfile.getinfo(zitem)
assert zipinfo[zpath] is not None
return zipinfo
class ZipProvider(EggProvider): class ZipProvider(EggProvider):
...@@ -1358,7 +1385,7 @@ class ZipProvider(EggProvider): ...@@ -1358,7 +1385,7 @@ class ZipProvider(EggProvider):
def __init__(self, module): def __init__(self, module):
EggProvider.__init__(self,module) EggProvider.__init__(self,module)
self.zipinfo = zipimport._zip_directory_cache[self.loader.archive] self.zipinfo = build_zipmanifest(self.load.archive)
self.zip_pre = self.loader.archive+os.sep self.zip_pre = self.loader.archive+os.sep
def _zipinfo_name(self, fspath): def _zipinfo_name(self, fspath):
...@@ -1393,12 +1420,10 @@ class ZipProvider(EggProvider): ...@@ -1393,12 +1420,10 @@ class ZipProvider(EggProvider):
return self._extract_resource(manager, zip_path) return self._extract_resource(manager, zip_path)
@staticmethod @staticmethod
def _get_date_and_size(zip_stat): def _get_date_and_size(zip_stat):
t,d,size = zip_stat[5], zip_stat[6], zip_stat[3] size = zip_stat.file_size
date_time = ( date_time = zip_stat.date_time + (0, 0, -1) #ymdhms+wday, yday, dst
(d>>9)+1980, (d>>5)&0xF, d&0x1F, # ymd #1980 offset already done
(t&0xFFFF)>>11, (t>>5)&0x3F, (t&0x1F) * 2, 0, 0, -1 # hms, etc.
)
timestamp = time.mktime(date_time) timestamp = time.mktime(date_time)
return timestamp, size return timestamp, size
...@@ -1411,7 +1436,7 @@ class ZipProvider(EggProvider): ...@@ -1411,7 +1436,7 @@ class ZipProvider(EggProvider):
) )
return os.path.dirname(last) # return the extracted directory name return os.path.dirname(last) # return the extracted directory name
timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) timestamp, size = self._get_date_and_size(self.zipinfo[zip_path])
if not WRITE_SUPPORT: if not WRITE_SUPPORT:
raise IOError('"os.rename" and "os.unlink" are not supported ' raise IOError('"os.rename" and "os.unlink" are not supported '
...@@ -1610,7 +1635,7 @@ class EggMetadata(ZipProvider): ...@@ -1610,7 +1635,7 @@ class EggMetadata(ZipProvider):
def __init__(self, importer): def __init__(self, importer):
"""Create a metadata provider from a zipimporter""" """Create a metadata provider from a zipimporter"""
self.zipinfo = zipimport._zip_directory_cache[importer.archive] self.zipinfo = build_zipmanifest(importer.archive)
self.zip_pre = importer.archive+os.sep self.zip_pre = importer.archive+os.sep
self.loader = importer self.loader = importer
if importer.prefix: if importer.prefix:
...@@ -2841,3 +2866,4 @@ run_main = run_script # backward compatibility ...@@ -2841,3 +2866,4 @@ run_main = run_script # backward compatibility
add_activation_listener(lambda dist: dist.activate()) add_activation_listener(lambda dist: dist.activate())
working_set.entries=[]; map(working_set.add_entry,sys.path) # match order working_set.entries=[]; map(working_set.add_entry,sys.path) # match order
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment