[Python-checkins] r57542 - sandbox/trunk/import_in_py/zipimport_/tests.py sandbox/trunk/import_in_py/zipimport_/zipimport.py

brett.cannon python-checkins at python.org
Mon Aug 27 04:21:12 CEST 2007


Author: brett.cannon
Date: Mon Aug 27 04:21:12 2007
New Revision: 57542

Modified:
   sandbox/trunk/import_in_py/zipimport_/tests.py
   sandbox/trunk/import_in_py/zipimport_/zipimport.py
Log:
Re-implement find_module.


Modified: sandbox/trunk/import_in_py/zipimport_/tests.py
==============================================================================
--- sandbox/trunk/import_in_py/zipimport_/tests.py	(original)
+++ sandbox/trunk/import_in_py/zipimport_/tests.py	Mon Aug 27 04:21:12 2007
@@ -233,7 +233,7 @@
 def test_main():
     test_support.run_unittest(ZipImportErrorTests,
                                 ZipImportCreation,
-                                #FindModule,
+                                FindModule,
                                 #GetData,
                                 #IsPackage,
                                 #GetSource,

Modified: sandbox/trunk/import_in_py/zipimport_/zipimport.py
==============================================================================
--- sandbox/trunk/import_in_py/zipimport_/zipimport.py	(original)
+++ sandbox/trunk/import_in_py/zipimport_/zipimport.py	Mon Aug 27 04:21:12 2007
@@ -3,7 +3,7 @@
 
 import contextlib
 #import datetime
-#import imp
+import imp
 import os
 #import time
 import zipfile
@@ -11,9 +11,9 @@
 
 # XXX Import lock prevents concurrency issues during importation use, but does
 #  not make any guarantees for non-import uses.
-# XXX Keyed on archive path with a value of a dict keyed on internal paths to
-#  files within the archive and values of zipfile.ZipInfo (different than C
-#  version which uses tuples instead).
+# XXX Use zipfile.ZipInfo instances for values of file paths (C version uses
+#  tuples).
+# XXX Prevents any dynamic update to the zip file from being detected.
 _zip_directory_cache = {}
 
 
@@ -57,29 +57,25 @@
         raise NotImplementedError
         return '<zipimport.zipimporter instance for %r>' % self._path_entry
 
-    def _check_paths(self, base_path):
-        raise NotImplementedError
+    def _check_paths(self, tail, pkg=False):
+        """Check if the module (or package) is contained within the package
+        represented by the importer."""
         source_suffixes = importlib.suffix_list(imp.PY_SOURCE)
         bytecode_suffixes = importlib.suffix_list(imp.PY_COMPILED)
         source, bytecode = None, None
-        with contextlib.closing(zipfile.ZipFile(self._zip_path)) as zip_:
-            for suffix in source_suffixes:
-                path = base_path + suffix
-                try:
-                    zip_.getinfo(path)
-                except KeyError:
-                    continue
-                else:
-                    source = path
-                    break
-            for suffix in bytecode_suffixes:
-                path = base_path + suffix
-                try:
-                    zip_.getinfo(path)
-                except KeyError:
-                    continue
-                else:
-                    bytecode = path
+        files_in_zip = _zip_directory_cache[self.archive]
+        if pkg:
+            tail = os.path.join(tail, pkg)
+        for suffix in source_suffixes:
+            path = os.path.join(self.prefix, tail + suffix)
+            if path in files_in_zip:
+                source = path
+                break
+        for suffix in bytecode_suffixes:
+            path = os.path.join(self.prefix, tail + suffix)
+            if path in files_in_zip:
+                bytecode = path
+                break
         if source is not None or bytecode is not None:
             return source, bytecode
         else:
@@ -88,17 +84,13 @@
     def find_module(self, fullname, path=None):
         """Check if the specified module is contained within the zip file,
         returning self if it is or None if it is not."""
-        raise NotImplementedError
-        path_name = fullname.replace('.', os.sep)
+        tail = fullname.rpartition('.')[2]
         # Look for a package.
-        base_path = os.path.join(path_name, '__init__')
-        results = self._check_paths(base_path)
+        results = self._check_paths(tail, '__init__')
         if results is not None:
-            self._path_cache[fullname] = results + (True,)
             return self
-        results = self._check_paths(path_name)
+        results = self._check_paths(tail)
         if results is not None:
-            self._path_cache[fullname] = results + (False,)
             return self
         return None
 


More information about the Python-checkins mailing list