[pypy-svn] r55231 - in pypy/dist/pypy/module/zipimport: . test

fijal at codespeak.net fijal at codespeak.net
Mon May 26 03:18:05 CEST 2008


Author: fijal
Date: Mon May 26 03:18:03 2008
New Revision: 55231

Modified:
   pypy/dist/pypy/module/zipimport/__init__.py
   pypy/dist/pypy/module/zipimport/app_zipimport.py
   pypy/dist/pypy/module/zipimport/interp_zipimport.py
   pypy/dist/pypy/module/zipimport/test/test_undocumented.py
   pypy/dist/pypy/module/zipimport/test/test_zipimport.py
Log:
Whack, Whack, until it works
* Provide _zip_directory_cache as a view on our internal cache
* Update test_undocumented to work
* Fixes here and there


Modified: pypy/dist/pypy/module/zipimport/__init__.py
==============================================================================
--- pypy/dist/pypy/module/zipimport/__init__.py	(original)
+++ pypy/dist/pypy/module/zipimport/__init__.py	Mon May 26 03:18:03 2008
@@ -7,10 +7,12 @@
 class Module(MixedModule):
     applevelname = 'zipimport'
 
-    interpleveldefs = {'zipimporter':'interp_zipimport.W_ZipImporter'}
+    interpleveldefs = {
+        'zipimporter':'interp_zipimport.W_ZipImporter',
+        '_zip_directory_cache' : 'space.wrap(interp_zipimport.zip_cache)'
+    }
 
     appleveldefs = {
         'ZipImportError'      : 'app_zipimport.ZipImportError',
-        '_zip_directory_cache': 'app_zipimport._zip_directory_cache',
     }
     

Modified: pypy/dist/pypy/module/zipimport/app_zipimport.py
==============================================================================
--- pypy/dist/pypy/module/zipimport/app_zipimport.py	(original)
+++ pypy/dist/pypy/module/zipimport/app_zipimport.py	Mon May 26 03:18:03 2008
@@ -2,4 +2,3 @@
 class ZipImportError(ImportError):
     pass
 
-_zip_directory_cache = {}

Modified: pypy/dist/pypy/module/zipimport/interp_zipimport.py
==============================================================================
--- pypy/dist/pypy/module/zipimport/interp_zipimport.py	(original)
+++ pypy/dist/pypy/module/zipimport/interp_zipimport.py	Mon May 26 03:18:03 2008
@@ -25,12 +25,108 @@
      (True, False, '.pyo'),
      (False, False, '.py')])
 
+class W_ZipCache(Wrappable):
+    def __init__(self):
+        self.cache = {}
+
+    def get(self, name):
+        return self.cache[name]
+
+    def set(self, name, w_importer):
+        self.cache[name] = w_importer
+
+    # -------------- dict-like interface -----------------
+    # I don't care about speed of those, they're obscure anyway
+    # THIS IS A TERRIBLE HACK TO BE CPYTHON COMPATIBLE
+        
+    def getitem(self, space, name):
+        try:
+            w_zipimporter = self.cache[name]
+        except KeyError:
+            raise OperationError(space.w_KeyError, space.wrap(name))
+        assert isinstance(w_zipimporter, W_ZipImporter)
+        dir = w_zipimporter.dir
+        keys = [k.filename for k in dir.filelist]
+        w = space.wrap
+        values = {}
+        w_d = space.newdict()
+        for key in keys:
+            info = dir.NameToInfo[key]
+            w_values = space.newdict()
+            space.setitem(w_d, w(key), space.newtuple([
+                w(info.filename), w(info.compress_type), w(info.compress_size),
+                w(info.file_size), w(info.file_offset), w(info.dostime),
+                w(info.dosdate), w(info.CRC)]))
+        return w_d
+    getitem.unwrap_spec = ['self', ObjSpace, str]
+
+    def keys(self, space):
+        return space.newlist([space.wrap(s)
+                              for s in self.cache.keys()])
+    keys.unwrap_spec = ['self', ObjSpace]
+
+    def values(self, space):
+        keys = self.cache.keys()
+        values_w = [self.getitem(space, key) for key in keys]
+        return space.newlist(values_w)
+    values.unwrap_spec = ['self', ObjSpace]
+
+    def items(self, space):
+        w = space.wrap
+        items_w = [space.newtuple([w(key), self.getitem(space, key)])
+                   for key in self.cache.keys()]
+        return space.newlist(items_w)
+    items.unwrap_spec = ['self', ObjSpace]
+
+    def iterkeys(self, space):
+        return space.iter(self.keys(space))
+    iterkeys.unwrap_spec = ['self', ObjSpace]
+
+    def itervalues(self, space):
+        return space.iter(self.values(space))
+    itervalues.unwrap_spec = ['self', ObjSpace]
+
+    def iteritems(self, space):
+        return space.iter(self.items(space))
+    iteritems.unwrap_spec = ['self', ObjSpace]
+
+    def contains(self, space, name):
+        return space.newbool(name in self.cache)
+    contains.unwrap_spec = ['self', ObjSpace, str]
+
+    def clear(self, space):
+        self.cache = {}
+    clear.unwrap_spec = ['self', ObjSpace]
+
+    def delitem(self, space, name):
+        del self.cache[name]
+    delitem.unwrap_spec = ['self', ObjSpace, str]
+
+W_ZipCache.typedef = TypeDef(
+    'zip_dict',
+    __getitem__ = interp2app(W_ZipCache.getitem),
+    __contains__ = interp2app(W_ZipCache.contains),
+    items = interp2app(W_ZipCache.items),
+    iteritems = interp2app(W_ZipCache.iteritems),
+    keys = interp2app(W_ZipCache.keys),
+    iterkeys = interp2app(W_ZipCache.iterkeys),
+    values = interp2app(W_ZipCache.values),
+    itervalues = interp2app(W_ZipCache.itervalues),
+    clear = interp2app(W_ZipCache.clear),
+    __delitem__ = interp2app(W_ZipCache.delitem),
+)
+
+zip_cache = W_ZipCache()
+
 class W_ZipImporter(Wrappable):
     def __init__(self, space, name, dir, prefix):
         self.space = space
         self.name = name
         self.dir = dir
         self.prefix = prefix
+        self.w_ZipImportError = space.getattr(
+            space.getbuiltinmodule('zipimport'),
+            space.wrap('ZipImportError'))
 
     def getprefix(space, self):
         return space.wrap(self.prefix)
@@ -111,8 +207,6 @@
         except OperationError, e:
             pass
         filename = self.mangle(fullname)
-        w_ZipImportError = space.getattr(space.getbuiltinmodule('zipimport'),
-                                         w('ZipImportError'))
         last_exc = None
         for compiled, is_package, ext in ENUMERATE_EXTS:
             try:
@@ -133,7 +227,7 @@
                 w_mods = space.sys.get('modules')
                 space.call_method(w_mods, 'pop', w(fullname), space.w_None)
         if last_exc:
-            raise OperationError(space.w_ImportError, last_exc.w_value)
+            raise OperationError(self.w_ZipImportError, last_exc.w_value)
         # should never happen I think
         return space.w_None
     load_module.unwrap_spec = ['self', ObjSpace, str]
@@ -159,8 +253,8 @@
                     w_source = self.get_data(space, filename + ext)
                     w_code = space.builtin.call('compile', w_source,
                                                 w(filename + ext), w('exec'))
-                    return w_code 
-        raise OperationError(space.w_ImportError, space.wrap(
+                    return w_code
+        raise OperationError(space.self.w_ZipImportError, space.wrap(
             "Cannot find source or code for %s in %s" % (filename, self.name)))
     get_code.unwrap_spec = ['self', ObjSpace, str]
 
@@ -171,7 +265,7 @@
                 fname = filename + ext
                 if self.have_modulefile(space, fname):
                     return self.get_data(space, fname)
-        raise OperationError(space.w_ImportError, space.wrap(
+        raise OperationError(self.w_ZipImportError, space.wrap(
             "Cannot find source for %s in %s" % (filename, self.name)))
     get_source.unwrap_spec = ['self', ObjSpace, str]
 
@@ -180,7 +274,7 @@
         for _, is_package, ext in ENUMERATE_EXTS:
             if self.have_modulefile(space, filename + ext):
                 return space.wrap(is_package)
-        raise OperationError(space.w_ImportError, space.wrap(
+        raise OperationError(self.w_ZipImportError, space.wrap(
             "Cannot find module %s in %s" % (filename, self.name)))
     is_package.unwrap_spec = ['self', ObjSpace, str]
 
@@ -189,20 +283,9 @@
         return space.wrap(self.dir.filename)
 
 def descr_new_zipimporter(space, w_type, name):
-    w_zip_cache = space.getattr(space.getbuiltinmodule('zipimport'),
-                                space.wrap('_zip_directory_cache'))
-    try:
-        w_result = space.getitem(w_zip_cache, space.wrap(name))
-        if space.is_w(w_result, space.w_None):
-            raise OperationError(space.w_ImportError, space.wrap(
-                "Cannot import %s from zipfile, recursion detected or"
-                "already tried and failed" % (name,)))
-        return w_result
-    except OperationError, o:
-        if not o.match(space, space.w_KeyError):
-            raise
-        # XXX think about what to do here
-        space.setitem(w_zip_cache, space.wrap(name), space.w_None)
+    w = space.wrap
+    w_ZipImportError = space.getattr(space.getbuiltinmodule('zipimport'),
+                                     w('ZipImportError'))
     ok = False
     parts = name.split(os.path.sep)
     filename = "" # make annotator happy
@@ -213,27 +296,35 @@
         try:
             s = os.stat(filename)
         except OSError:
-            raise OperationError(space.w_ImportError, space.wrap(
+            raise OperationError(w_ZipImportError, space.wrap(
                 "Cannot find name %s" % (filename,)))
         if not stat.S_ISDIR(s.st_mode):
             ok = True
             break
     if not ok:
-        raise OperationError(space.w_ImportError, space.wrap(
+        raise OperationError(w_ZipImportError, space.wrap(
             "Did not find %s to be a valid zippath" % (name,)))
-    last_elem = filename.split(os.path.sep)[-1]
-    stop = len(filename)-len(last_elem)
-    assert stop > 0
-    prefix = filename[:stop]
+    try:
+        w_result = zip_cache.get(filename)
+        if w_result is None:
+            raise OperationError(w_ZipImportError, space.wrap(
+                "Cannot import %s from zipfile, recursion detected or"
+                "already tried and failed" % (name,)))
+        return w_result
+    except KeyError:
+        zip_cache.cache[filename] = None
     try:
         dir = RZipFile(filename, 'r')
     except (BadZipfile, OSError):
-        raise OperationError(space.w_ImportError, space.wrap(
+        raise OperationError(w_ZipImportError, space.wrap(
             "%s seems not to be a zipfile" % (filename,)))
+    prefix = name[len(filename):]
+    if prefix.startswith(os.sep):
+        prefix = prefix[1:]
     w_result = space.wrap(W_ZipImporter(space, name, dir, prefix))
-    space.setitem(w_zip_cache, space.wrap(name), w_result)
+    zip_cache.set(filename, w_result)
     return w_result
-    
+
 descr_new_zipimporter.unwrap_spec = [ObjSpace, W_Root, str]
 
 W_ZipImporter.typedef = TypeDef(

Modified: pypy/dist/pypy/module/zipimport/test/test_undocumented.py
==============================================================================
--- pypy/dist/pypy/module/zipimport/test/test_undocumented.py	(original)
+++ pypy/dist/pypy/module/zipimport/test/test_undocumented.py	Mon May 26 03:18:03 2008
@@ -8,26 +8,27 @@
 import zipfile
 from pypy.conftest import gettestobjspace
 
-example_code = 'attr = None'
+TESTFN = '@test'
 
-created_paths = set(['_top_level',
+created_paths = dict.fromkeys(['_top_level',
                      os.path.join('_pkg', '__init__'),
                      os.path.join('_pkg', 'submodule'),
                      os.path.join('_pkg', '_subpkg', '__init__'),
                      os.path.join('_pkg', '_subpkg', 'submodule')
-                    ])
+                               ])
 
-py.test.skip("Completely broken")
-
-def temp_zipfile(source=True, bytecode=True):
+def temp_zipfile(created_paths, source=True, bytecode=True):
     """Create a temporary zip file for testing.
 
     Clears zipimport._zip_directory_cache.
 
     """
-    zipimport._zip_directory_cache = {}
-    zip_path = test_support.TESTFN + '.zip'
-    bytecode_suffix = 'c' if __debug__ else 'o'
+    import zipimport, os, shutil, zipfile, py_compile
+    example_code = 'attr = None'
+    TESTFN = '@test'
+    zipimport._zip_directory_cache.clear()
+    zip_path = TESTFN + '.zip'
+    bytecode_suffix = 'c'# if __debug__ else 'o'
     zip_file = zipfile.ZipFile(zip_path, 'w')
     try:
         for path in created_paths:
@@ -57,14 +58,17 @@
                     shutil.rmtree(directory)
             else:
                 for suffix in ('.py', '.py' + bytecode_suffix):
-                    test_support.unlink(path + suffix)
-        test_support.unlink(zip_path)
-
+                    if os.path.exists(path + suffix):
+                        os.unlink(path + suffix)
+        os.unlink(zip_path)
 
 class AppTestZipImport:
     def setup_class(cls):
         space = gettestobjspace(usemodules=['zipimport', 'zlib', 'rctime'])
         cls.space = space
+        source = "():\n" + str(py.code.Source(temp_zipfile).indent()) + "\n    return temp_zipfile"
+        cls.w_temp_zipfile = space.appexec([], source)
+        cls.w_created_paths = space.wrap(created_paths)
 
     def test_inheritance(self):
         # Should inherit from ImportError.
@@ -72,40 +76,42 @@
         assert issubclass(zipimport.ZipImportError, ImportError)
 
     def test_nonzip(self):
+        import os
+        import zipimport
         # ZipImportError should be raised if a non-zip file is specified.
+        TESTFN = '@test'
+        test_file = open(TESTFN, 'w')
         try:
-            test_file = open(test_support.TESTFN, 'w')
             test_file.write("# Test file for zipimport.")
             try:
                 raises(zipimport.ZipImportError,
-                        zipimport.zipimporter, test_support.TESTFN)
+                        zipimport.zipimporter, TESTFN)
             finally:
-                test_support.unlink(test_support.TESTFN)
+                os.unlink(TESTFN)
         finally:
             test_file.close()
 
     def test_root(self):
+        import zipimport, os
         raises(zipimport.ZipImportError, zipimport.zipimporter,
                             os.sep)
 
 
     def test_direct_path(self):
         # A zipfile should return an instance of zipimporter.
-        try:
-            zip_path = temp_zipfile()
+        import zipimport
+        for zip_path in self.temp_zipfile(self.created_paths):
             zip_importer = zipimport.zipimporter(zip_path)
             assert isinstance(zip_importer, zipimport.zipimporter)
             assert zip_importer.archive == zip_path
             assert zip_importer.prefix == ''
             assert zip_path in zipimport._zip_directory_cache
-        finally:
-            zip_path.close()
 
     def test_pkg_path(self):
         # Thanks to __path__, need to be able to work off of a path with a zip
         # file at the front and a path for the rest.
-        try:
-            zip_path = temp_zipfile()
+        import zipimport, os
+        for zip_path in self.temp_zipfile(self.created_paths):
             prefix = '_pkg'
             path = os.path.join(zip_path, prefix)
             zip_importer = zipimport.zipimporter(path)
@@ -113,18 +119,14 @@
             assert zip_importer.archive == zip_path
             assert zip_importer.prefix == prefix
             assert zip_path in zipimport._zip_directory_cache
-        finally:
-            zip_path.close()
 
     def test_zip_directory_cache(self):
         # Test that _zip_directory_cache is set properly.
         # Using a package entry to test using a hard example.
-        try:
-            zip_path = temp_zipfile(bytecode=False)
+        import zipimport, os
+        for zip_path in self.temp_zipfile(self.created_paths, bytecode=False):
             importer = zipimport.zipimporter(os.path.join(zip_path, '_pkg'))
             assert zip_path in zipimport._zip_directory_cache
             file_set = set(zipimport._zip_directory_cache[zip_path].iterkeys())
-            compare_set = set(path + '.py' for path in created_paths)
+            compare_set = set(path + '.py' for path in self.created_paths)
             assert file_set == compare_set
-        finally:
-            zip_path.close()

Modified: pypy/dist/pypy/module/zipimport/test/test_zipimport.py
==============================================================================
--- pypy/dist/pypy/module/zipimport/test/test_zipimport.py	(original)
+++ pypy/dist/pypy/module/zipimport/test/test_zipimport.py	Mon May 26 03:18:03 2008
@@ -81,9 +81,9 @@
         space.appexec([space.wrap(self)], """(self):
         self.write_files = []
         """)
-        space.setattr(space.getbuiltinmodule('zipimport'),
-                      space.wrap('_zip_directory_cache'),
-                      space.newdict({}))
+        w_cache = space.getattr(space.getbuiltinmodule('zipimport'),
+                                space.wrap('_zip_directory_cache'))
+        space.call_function(space.getattr(w_cache, space.wrap('clear')))
 
     def teardown_method(self, meth):
         space = self.space
@@ -228,7 +228,7 @@
         # directly. -exarkun
         archive = importer.archive
         allbutlast = self.zipfile.split(os.path.sep)[:-1]
-        prefix = os.path.sep.join(allbutlast + [''])
+        prefix = 'directory'
         assert archive == self.zipfile
         assert importer.prefix == prefix
 



More information about the Pypy-commit mailing list