Created
August 12, 2014 12:27
-
-
Save aliles/9bb375a9f889c2e584b5 to your computer and use it in GitHub Desktop.
PEP 302 import hook to caching system path contents
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""PEP 302 import hook to caching system path contents. | |
Implements an import hook using a finder and loader class to load Python | |
modules from system paths while caching the path contents. | |
""" | |
from __future__ import print_function | |
import glob | |
import imp | |
import os | |
import sys | |
class CachingLoader(object): | |
"""Import hook loader. | |
Used by the CachingFinder class. Implemented using the imp module. | |
""" | |
def __init__(self, fobject, pathname, description): | |
self.fobject = fobject | |
self.pathname = pathname | |
self.description = description | |
def load_module(self, fullname): | |
"Import hook protocol." | |
try: | |
print('CachingLoader loading "{0}"'.format(fullname)) | |
return imp.load_module(fullname, self.fobject, self,pathname, self.description) | |
finally: | |
if hasattr(self.fobject, 'close'): | |
self.fobject.close() | |
class CachingFinder(object): | |
"""Import hook loader with directory caching. | |
Finds modules to load using the CachingLoader. Directory listings from | |
systems paths are cached so they don't require repeated enumeration. | |
NOTE: Limited to Python modules only. | |
""" | |
SUFFIX = '.py' | |
MODE = 'U' | |
def __init__(self): | |
self.cache = {} | |
def find_module(self, fullname, paths=None): | |
source = fullname.split('.')[-1] + self.SUFFIX | |
paths = sys.path if paths is None else paths | |
for path in paths: | |
print("Find {0} on {1}".format(fullname, path)) | |
if path not in self.cache: | |
print("List {0}".format(path)) | |
self.cache[path] = set(glob.iglob(os.path.join(path, '*' + self.SUFFIX))) | |
if source not in self.cache[path]: | |
continue | |
print("Found at {0} in {1]".format(source, path)) | |
pathname = os.path.join(path, source) | |
fobject = open(pathname, 'U') | |
description = (self.SUFFIX, self.MODE, imp.PY_SOURCE) | |
return CachingLoader(fobject, pathname, description) | |
def load_module(self, fullname): | |
print("Loading {0}".format(fullname)) | |
return imp.load_module(fullname) | |
# create and register the import hook | |
finder = CachingFinder() | |
sys.meta_path.append(finder) | |
if __name__ == '__main__': | |
# import submodule from package | |
import xml.sax.saxutils |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment