summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrett Cannon <bcannon@gmail.com>2009-02-02 19:19:36 (GMT)
committerBrett Cannon <bcannon@gmail.com>2009-02-02 19:19:36 (GMT)
commit1d376687b7176fc0e52e85f0a6cd98b53fd77d41 (patch)
tree8425e48e55c2e4290297a97bc672a875f5f4b818
parent7e11b3f52247f0a0fd8be8879873a74d4ec02b38 (diff)
downloadcpython-1d376687b7176fc0e52e85f0a6cd98b53fd77d41.zip
cpython-1d376687b7176fc0e52e85f0a6cd98b53fd77d41.tar.gz
cpython-1d376687b7176fc0e52e85f0a6cd98b53fd77d41.tar.bz2
To prevent another screw-up on my part where my prototype gets lost thanks to
an ``svn revert`` (gee, maybe more atomic commits by use of something like a DVCS would help with this? Wish someone would get on that ...), I am checking in an untested, work-in-progress meta path finder to handle sys.path.
-rw-r--r--Lib/importlib/_bootstrap.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
index ca62911..d59fa85 100644
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -589,6 +589,82 @@ class PyFileImporter(FileImporter):
super(PyFileImporter, self).__init__(path_entry)
+class SysPathFinder:
+
+ """Meta path finder for sys.(path|path_hooks|path_importer_cache)."""
+
+ def _default_hook(self, path):
+ """Use the default hook on 'path'.
+
+ If the path will not work for the default hook then raise ImportError.
+
+ """
+ # TODO(brett.cannon) Implement
+ raise ImportError
+
+ # The list of implicit hooks cannot be a class attribute because of
+ # bootstrapping issues for accessing imp.
+ def _implicit_hooks(self, path):
+ """Return a list of the implicit path hooks."""
+ return [self._default_hook, imp.NullImporter]
+
+ def _path_hooks(self, path):
+ """Search sys.path_hooks for a finder for 'path'.
+
+ Guaranteed to return a finder for the path as NullImporter is the
+ default importer for any path that does not have an explicit finder.
+
+ """
+ for hook in sys.path_hooks + self._implicit_hooks():
+ try:
+ return hook(path)
+ except ImportError:
+ continue
+ else:
+ # This point should never be reached thanks to NullImporter.
+ raise SystemError("no hook could find an importer for "
+ "{0}".format(path))
+
+ def _path_importer_cache(self, path):
+ """Get the finder for the path from sys.path_importer_cache.
+
+ If the path is not in the cache, find the appropriate finder and cache
+ it. If None is cached, get the default finder and cache that
+ (if applicable).
+
+ Because of NullImporter, some finder should be returned. The only
+ explicit fail case is if None is cached but the path cannot be used for
+ the default hook, for which ImportError is raised.
+
+ """
+ try:
+ finder = sys.path_importer_cache(path);
+ except KeyError:
+ finder = self._path_hooks(path)
+ sys.path_importer_cache[path] = finder
+ else:
+ if finder is None:
+ # Raises ImportError on failure.
+ finder = self._default_hook(path)
+ sys.path_importer_cache[path] = finder
+ return finder
+
+ def find_module(self, fullname, path=None):
+ """Find the module on sys.path or 'path'."""
+ if not path:
+ path = sys.path
+ for entry in path:
+ try:
+ finder = self._path_importer_cache(entry)
+ except ImportError:
+ continue
+ loader = finder.find_module(fullname)
+ if loader:
+ return loader
+ else:
+ return None
+
+
class ImportLockContext(object):
"""Context manager for the import lock."""