[Python-checkins] python/nondist/sandbox/setuptools pkg_resources.py, 1.17, 1.18

pje@users.sourceforge.net pje at users.sourceforge.net
Wed May 25 02:50:42 CEST 2005


Update of /cvsroot/python/python/nondist/sandbox/setuptools
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32239

Modified Files:
	pkg_resources.py 
Log Message:
Support registering distribution finders for arbitrary PEP 302 importer
types, so that the directory scanner isn't a hardcoded case.


Index: pkg_resources.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/setuptools/pkg_resources.py,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- pkg_resources.py	24 May 2005 01:15:24 -0000	1.17
+++ pkg_resources.py	25 May 2005 00:50:39 -0000	1.18
@@ -1,5 +1,4 @@
-"""\
-Package resource API
+"""Package resource API
 --------------------
 
 A resource is a logical file contained within a package, or a logical
@@ -21,6 +20,7 @@
     'compatible_platforms', 'get_platform', 'IMetadataProvider',
     'ResolutionError', 'VersionConflict', 'DistributionNotFound',
     'InvalidOption', 'Distribution', 'Requirement', 'yield_lines',
+    'get_importer', 'find_distributions', 'find_on_path', 'register_finder',
     'split_sections', # 'glob_resources'
 ]
 
@@ -654,6 +654,107 @@
         self.egg_info = os.path.join(self.module_path, 'EGG-INFO')
 
 
+class ImpWrapper:
+    """PEP 302 Importer that wraps Python's "normal" import algorithm"""
+
+    def __init__(self, path=None):
+        if path is not None and not os.path.isdir(path):
+            raise ImportError
+        self.path = path
+
+    def find_module(self, fullname, path=None):
+        subname = fullname.split(".")[-1]
+        if subname != fullname and self.path is None:
+            return None
+        if self.path is None:
+            path = None
+        else:
+            path = [self.path]
+        try:
+            file, filename, etc = imp.find_module(subname, path)
+        except ImportError:
+            return None
+        return ImpLoader(file, filename, etc)
+
+
+class ImpLoader:
+    """PEP 302 Loader that wraps Python's "normal" import algorithm"""
+
+    def __init__(self, file, filename, etc):
+        self.file = file
+        self.filename = filename
+        self.etc = etc
+
+    def load_module(self, fullname):
+        try:
+            mod = imp.load_module(fullname, self.file, self.filename, self.etc)
+        finally:
+            if self.file: self.file.close()
+        # Note: we don't set __loader__ because we want the module to look
+        # normal; i.e. this is just a wrapper for standard import machinery
+        return mod
+
+
+def get_importer(path_item):
+    """Retrieve a PEP 302 "importer" for the given path item
+
+    If there is no importer, this returns a wrapper around the builtin import
+    machinery.  The returned importer is only cached if it was created by a
+    path hook.
+    """
+    try:
+        importer = sys.path_importer_cache[path_item]
+    except KeyError:
+        for hook in sys.path_hooks:
+            try:
+                importer = hook(path_item)
+            except ImportError:
+                pass
+            else:
+                break
+        else:
+            importer = None
+
+    sys.path_importer_cache.setdefault(path_item,importer)
+    if importer is None:
+        try:
+            importer = ImpWrapper(path_item)
+        except ImportError:
+            pass
+    return importer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_distribution_finders = {}
+
+def register_finder(importer_type, distribution_finder):
+    """Register `distribution_finder` to find distributions in sys.path items
+
+    `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item
+    handler), and `distribution_finder_type` is a callable that, passed a path
+    item and the importer instance, yields ``Distribution`` instances found on
+    that path item.  See ``pkg_resources.find_on_path`` for an example."""
+    _distribution_finders[importer_type] = distribution_finder
+
+
+def find_distributions(path_item):
+    """Yield distributions accessible via `path_item`"""
+    importer = get_importer(path_item)
+    finder = _find_adapter(_distribution_finders, importer)
+    return finder(importer,path_item)
+
+
 def StringIO(*args, **kw):
     """Thunk to load the real StringIO on demand"""
     global StringIO
@@ -664,8 +765,26 @@
     return StringIO(*args,**kw)
 
 
-def find_distributions(path_item):
-    """Yield distributions accessible via `path_item`"""
+
+
+
+
+
+
+
+
+
+
+
+
+def find_nothing(importer,path_item):
+    return ()
+
+register_finder(object,find_nothing)
+
+
+def find_on_path(importer,path_item):
+    """Yield distributions accessible on a sys.path directory"""
     if not os.path.exists(path_item):
         return
     elif os.path.isdir(path_item):
@@ -681,7 +800,7 @@
             for entry in os.listdir(path_item):
                 fullpath = os.path.join(path_item, entry)
                 if entry.lower().endswith('.egg'):
-                    for dist in find_distributions(fullpath):
+                    for dist in find_on_path(importer,fullpath):
                         yield dist
                 elif entry.lower().endswith('.egg-info'):
                     if os.path.isdir(fullpath):
@@ -694,6 +813,10 @@
         metadata = EggMetadata(zipimport.zipimporter(path_item))
         yield Distribution.from_filename(path_item, metadata=metadata)
 
+register_finder(ImpWrapper,find_on_path)
+
+
+
 
 def yield_lines(strs):
     """Yield non-empty/non-comment lines of a ``basestring`` or sequence"""



More information about the Python-checkins mailing list