Commit b84464da authored by Philip Thiem's avatar Philip Thiem

caching the zip manifests Fixes #154

--HG--
extra : rebase_source : 0f32792e01b6a1b746a1e07ffa4d7a85eeda1595
parent 5c08ba7d
...@@ -1530,33 +1530,48 @@ class EmptyProvider(NullProvider): ...@@ -1530,33 +1530,48 @@ class EmptyProvider(NullProvider):
empty_provider = EmptyProvider() empty_provider = EmptyProvider()
def build_zipmanifest(path): class ZipManifests(object):
"""
This builds a similar dictionary to the zipimport directory def __init__(self):
caches. However instead of tuples, ZipInfo objects are stored. self.known = dict()
The translation of the tuple is as follows: def __call__(self, path):
* [0] - zipinfo.filename on stock pythons this needs "/" --> os.sep path = os.path.normpath(path)
on pypy it is the same (one reason why distribute did work stat = os.stat(path)
in some cases on pypy and win32).
* [1] - zipinfo.compress_type if path not in self.known or self.known[path][0] != stat.st_mtime:
* [2] - zipinfo.compress_size self.known[path] = (stat.st_mtime, self.build_manifest(path))
* [3] - zipinfo.file_size
* [4] - len(utf-8 encoding of filename) if zipinfo & 0x800 return self.known[path][1]
len(ascii encoding of filename) otherwise
* [5] - (zipinfo.date_time[0] - 1980) << 9 | def build_manifest(self, path):
zipinfo.date_time[1] << 5 | zipinfo.date_time[2] """
* [6] - (zipinfo.date_time[3] - 1980) << 11 | This builds a similar dictionary to the zipimport directory
zipinfo.date_time[4] << 5 | (zipinfo.date_time[5] // 2) caches. However instead of tuples, ZipInfo objects are stored.
* [7] - zipinfo.CRC
""" The translation of the tuple is as follows:
zipinfo = dict() * [0] - zipinfo.filename on stock pythons this needs "/" --> os.sep
with ContextualZipFile(path) as zfile: on pypy it is the same (one reason why distribute did work
for zitem in zfile.namelist(): in some cases on pypy and win32).
zpath = zitem.replace('/', os.sep) * [1] - zipinfo.compress_type
zipinfo[zpath] = zfile.getinfo(zitem) * [2] - zipinfo.compress_size
assert zipinfo[zpath] is not None * [3] - zipinfo.file_size
return zipinfo * [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 ContextualZipFile(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
build_zipmanifest = ZipManifests()
class ContextualZipFile(zipfile.ZipFile): class ContextualZipFile(zipfile.ZipFile):
...@@ -1586,7 +1601,6 @@ class ZipProvider(EggProvider): ...@@ -1586,7 +1601,6 @@ class ZipProvider(EggProvider):
def __init__(self, module): def __init__(self, module):
EggProvider.__init__(self, module) EggProvider.__init__(self, module)
self.zipinfo = build_zipmanifest(self.loader.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):
...@@ -1802,7 +1816,6 @@ class EggMetadata(ZipProvider): ...@@ -1802,7 +1816,6 @@ 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 = 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:
......
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