[Python-checkins] r50921 - sandbox/trunk/setuptools/_pkgutil.py

phillip.eby python-checkins at python.org
Sat Jul 29 01:58:15 CEST 2006


Author: phillip.eby
Date: Sat Jul 29 01:58:14 2006
New Revision: 50921

Modified:
   sandbox/trunk/setuptools/_pkgutil.py
Log:
Sync pkgutil from trunk


Modified: sandbox/trunk/setuptools/_pkgutil.py
==============================================================================
--- sandbox/trunk/setuptools/_pkgutil.py	(original)
+++ sandbox/trunk/setuptools/_pkgutil.py	Sat Jul 29 01:58:14 2006
@@ -31,7 +31,7 @@
 def simplegeneric(func):
     """Make a trivial single-dispatch generic function"""
     registry = {}
-    def wrapper(*args,**kw):
+    def wrapper(*args, **kw):
         ob = args[0]
         try:
             cls = ob.__class__
@@ -41,18 +41,19 @@
             mro = cls.__mro__
         except AttributeError:
             try:
-                class cls(cls,object): pass
+                class cls(cls, object):
+                    pass
                 mro = cls.__mro__[1:]
             except TypeError:
                 mro = object,   # must be an ExtensionClass or some such  :(
         for t in mro:
             if t in registry:
-                return registry[t](*args,**kw)
+                return registry[t](*args, **kw)
         else:
-            return func(*args,**kw)
+            return func(*args, **kw)
     try:
         wrapper.__name__ = func.__name__
-    except (TypeError,AttributeError):
+    except (TypeError, AttributeError):
         pass    # Python 2.3 doesn't allow functions to be renamed
 
     def register(typ, func=None):
@@ -68,10 +69,37 @@
 
 
 def walk_packages(path=None, prefix='', onerror=None):
-    """Yield submodule names+loaders recursively, for path or sys.path"""
+    """Yields (module_loader, name, ispkg) for all modules recursively
+    on path, or, if path is None, all accessible modules.
 
-    def seen(p,m={}):
-        if p in m: return True
+    'path' should be either None or a list of paths to look for
+    modules in.
+
+    'prefix' is a string to output on the front of every module name
+    on output.
+
+    Note that this function must import all *packages* (NOT all
+    modules!) on the given path, in order to access the __path__
+    attribute to find submodules.
+
+    'onerror' is a function which gets called with one argument (the
+    name of the package which was being imported) if any exception
+    occurs while trying to import a package.  If no onerror function is
+    supplied, ImportErrors are caught and ignored, while all other
+    exceptions are propagated, terminating the search.
+
+    Examples:
+
+    # list all modules python can access
+    walk_packages()
+
+    # list all submodules of ctypes
+    walk_packages(ctypes.__path__, ctypes.__name__+'.')
+    """
+
+    def seen(p, m={}):
+        if p in m:
+            return True
         m[p] = True
 
     for importer, name, ispkg in iter_modules(path, prefix):
@@ -82,19 +110,33 @@
                 __import__(name)
             except ImportError:
                 if onerror is not None:
-                    onerror()
+                    onerror(name)
+            except Exception:
+                if onerror is not None:
+                    onerror(name)
+                else:
+                    raise
             else:
                 path = getattr(sys.modules[name], '__path__', None) or []
 
                 # don't traverse path items we've seen before
                 path = [p for p in path if not seen(p)]
 
-                for item in walk_packages(path, name+'.'):
+                for item in walk_packages(path, name+'.', onerror):
                     yield item
 
 
 def iter_modules(path=None, prefix=''):
-    """Yield submodule names+loaders for path or sys.path"""
+    """Yields (module_loader, name, ispkg) for all submodules on path,
+    or, if path is None, all top-level modules on sys.path.
+
+    'path' should be either None or a list of paths to look for
+    modules in.
+
+    'prefix' is a string to output on the front of every module name
+    on output.
+    """
+
     if path is None:
         importers = iter_importers()
     else:
@@ -110,7 +152,7 @@
 
 #@simplegeneric
 def iter_importer_modules(importer, prefix=''):
-    if not hasattr(importer,'iter_modules'):
+    if not hasattr(importer, 'iter_modules'):
         return []
     return importer.iter_modules(prefix)
 
@@ -206,6 +248,7 @@
 
     def _reopen(self):
         if self.file and self.file.closed:
+            mod_type = self.etc[2]
             if mod_type==imp.PY_SOURCE:
                 self.file = open(self.filename, 'rU')
             elif mod_type in (imp.PY_COMPILED, imp.C_EXTENSION):
@@ -336,13 +379,13 @@
                 pass
         else:
             importer = None
-        sys.path_importer_cache.setdefault(path_item,importer)
+        sys.path_importer_cache.setdefault(path_item, importer)
 
     if importer is None:
         try:
             importer = ImpImporter(path_item)
         except ImportError:
-            pass
+            importer = None
     return importer
 
 
@@ -377,7 +420,7 @@
         pkg = '.'.join(fullname.split('.')[:-1])
         if pkg not in sys.modules:
             __import__(pkg)
-        path = getattr(sys.modules[pkg],'__path__',None) or []
+        path = getattr(sys.modules[pkg], '__path__', None) or []
     else:
         for importer in sys.meta_path:
             yield importer
@@ -404,7 +447,7 @@
         module_or_name = sys.modules[module_or_name]
     if isinstance(module_or_name, ModuleType):
         module = module_or_name
-        loader = getattr(module,'__loader__',None)
+        loader = getattr(module, '__loader__', None)
         if loader is not None:
             return loader
         fullname = module.__name__


More information about the Python-checkins mailing list