fdi.utils.moduleloader 源代码

# -*- coding: utf-8 -*-
""" https://stackoverflow.com/a/43573798/13472124 """
from .common import lls, trbk

import sys
import os.path

from importlib.abc import Loader, MetaPathFinder
from importlib.util import spec_from_file_location


import logging
# create logger
logger = logging.getLogger(__name__)
# logger.debug('level %d' %  (logger.getEffectiveLevel()))


[文档]class MyMetaFinder(MetaPathFinder):
[文档] def find_spec(self, fullname, path, target=None): print('===', fullname, path, type(path)) if path is None or path == "": path = [os.getcwd()] # top level import -- if "." in fullname: *parents, name = fullname.split(".") else: name = fullname print('***', name, path, type(path)) for entry in path: if os.path.isdir(os.path.join(entry, name)): # this module has child modules filename = os.path.join(entry, name, "__init__.py") submodule_locations = [os.path.join(entry, name)] else: filename = os.path.join(entry, name + ".py") submodule_locations = None if not os.path.exists(filename): continue loader = MyLoader(filename) print('###', fullname, filename, submodule_locations, loader) ret = spec_from_file_location(fullname, filename, loader=loader, submodule_search_locations=submodule_locations) print('%%%', ret) return ret print('!!!', 'no loader', filename) return None # we don't know how to import this
[文档]class SelectiveMetaFinder(MetaPathFinder): """ Raise ExcludedModule exception if loading modules whose names have any of cls.exclude. """
[文档] class ExcludedModule(Exception): pass
exclude = []
[文档] def find_spec(self, fullname, path, target=None): # print('===', fullname, path, type(path)) if path is None or path == "": path = [os.getcwd()] # top level import -- if "." in fullname: *parents, name = fullname.split(".") else: name = fullname #print('***', fullname, name, path, type(path), SelectiveMetaFinder.exclude) for entry in path: if os.path.isdir(os.path.join(entry, name)): # this module has child modules filename = os.path.join(entry, name, "__init__.py") submodule_locations = [os.path.join(entry, name)] else: # this is a module and if the name matches ... if name in SelectiveMetaFinder.exclude: # print('!!!!!!!!!!!!!!!!!!!!!!!') raise(SelectiveMetaFinder.ExcludedModule( name + ' is excluded from loading.')) filename = os.path.join(entry, name + ".py") submodule_locations = None if not os.path.exists(filename): logger.debug('Module file not exists. ' + filename) continue logger.debug('Module file found: ' + filename) loader = MyLoader(filename) # print('###', fullname, filename, submodule_locations, loader) ret = spec_from_file_location(fullname, filename, loader=loader, submodule_search_locations=submodule_locations) #print('%%%', ret) return ret #print('!!!', 'no loader', filename) return None # we don't know how to import this
[文档]class MyLoader(Loader): def __init__(self, filename): self.filename = filename logger.debug('Created MyLoader for ' + filename)
[文档] def create_module(self, spec): return None # use default module creation semantics
[文档] def exec_module(self, module): with open(self.filename, encoding='utf-8') as f: data = f.read() # manipulate data some way... #data += '\nb=42\n' logger.debug('exec ' + self.filename) exec(data, vars(module))
[文档]def install(): """Inserts the finder into the import machinery""" sys.meta_path.insert(0, MyMetaFinder())
[文档]def installSelectiveMetaFinder(): """Inserts the finder into the import machinery""" sys.meta_path.insert(0, SelectiveMetaFinder())
[文档]def main(ipath='.'): if 0: install() import bar print(dir(bar)) else: installSelectiveMetaFinder() SelectiveMetaFinder.exclude = ['notthis'] # this is allowed from fdi.dataset.metadata import Parameter p = Parameter(0.99) assert p.value == 0.99 # this is stopped. try: from fdi.dataset.notthis import BaseProduct except SelectiveMetaFinder.ExcludedModule as e: assert True else: assert False sys.path.insert(0, ipath) import bar assert hasattr(bar, 'k')
if __name__ == '__main__': main('tests') print('passed')