def scan_plugins(prefix, path, black_list=None, white_list=None): """ Discover plugins via pkgutil and pyinstaller path """ if black_list is None: black_list = [] if white_list is None: white_list = [] # scan pkgutil.iter_modules module_names = (module_info[1] for module_info in pkgutil.iter_modules() if module_info[2] and module_info[1].startswith(prefix)) import pdb pdb.set_trace() # scan pyinstaller module_names_from_pyinstaller = scan_from_pyinstaller(prefix, path) all_modules = chain(module_names, module_names_from_pyinstaller, white_list) # loop through modules and find our plug ins for module_name in all_modules: log.debug(module_name) if module_name in black_list: log.debug("ignored " + module_name) continue try: do_import(module_name) except ImportError as e: log.debug(module_name) log.debug(e) continue
def handle_plugin_dirs(plugin_dirs): for plugin_dir in plugin_dirs: plugin_path = os.path.dirname(os.path.abspath(plugin_dir)) if plugin_path not in sys.path: sys.path.append(plugin_path) pysearchre = re.compile(".py$", re.IGNORECASE) pluginfiles = filter(pysearchre.search, os.listdir(plugin_dir)) plugins = list(map(lambda fp: os.path.splitext(fp)[0], pluginfiles)) for plugin in plugins: plugin_module = os.path.basename(plugin_dir) + "." + plugin do_import(plugin_module)
def handle_plugin_dirs(plugin_dirs): if plugin_dirs is None: return LOG.info("handling plugin dirs {}".format(",".join(plugin_dirs))) for plugin_dir in plugin_dirs: plugin_path = os.path.normcase( os.path.dirname(os.path.abspath(plugin_dir))) if plugin_path not in sys.path: sys.path.append(plugin_path) pysearchre = re.compile(".py$", re.IGNORECASE) pluginfiles = filter(pysearchre.search, os.listdir(plugin_dir)) plugins = list(map(lambda fp: os.path.splitext(fp)[0], pluginfiles)) for plugin in plugins: plugin_module = os.path.basename(plugin_dir) + "." + plugin do_import(plugin_module)
def scan_plugins_regex( plugin_name_patterns=None, pyinstaller_path=None, black_list=None, white_list=None, ): """ Implicitly discover plugins via pkgutil and pyinstaller path using regular expression Parameters ----------------- plugin_name_patterns: python regular expression it is used to match all your plugins, either it is a prefix, a suffix, some text in the middle or all. pyinstaller_path:string used in pyinstaller only. When your end developer would package your main library and its plugins using pyinstaller, this path helps pyinstaller to find the plugins. black_list:list a list of module names that should be skipped. white_list:list a list of modules that comes with your main module. If you have a built-in module, the module name should be inserted into the list. For example, robot_cuisine is a built-in module inside robotchef. It is listed in white_list. """ log.debug("scanning for plugins...") if black_list is None: black_list = [] if white_list is None: white_list = [] # scan pkgutil.iter_modules module_names = ( module_info[1] for module_info in pkgutil.iter_modules() if module_info[2] and re.match(plugin_name_patterns, module_info[1])) # scan pyinstaller module_names_from_pyinstaller = scan_from_pyinstaller( plugin_name_patterns, pyinstaller_path) all_modules = chain(module_names, module_names_from_pyinstaller, white_list) # loop through modules and find our plug ins for module_name in all_modules: if module_name in black_list: log.debug("ignored " + module_name) continue try: do_import(module_name) except ImportError as e: log.debug(module_name) log.debug(e) continue log.debug("scanning done")
def scan_plugins(prefix, path, black_list=None, white_list=None): """ Implicitly discover plugins via pkgutil and pyinstaller path Parameters ----------------- prefix:string module prefix. This prefix should become the prefix of the module name of all plugins. In the tutorial, robotchef-britishcuisine is a plugin package of robotchef and its module name is 'robotchef_britishcuisine'. When robotchef call scan_plugins to load its cuisine plugins, it specifies its prefix as "robotchef_". All modules that starts with 'robotchef_' will be auto-loaded: robotchef_britishcuisine, robotchef_chinesecuisine, etc. path:string used in pyinstaller only. When your end developer would package your main library and its plugins using pyinstaller, this path helps pyinstaller to find the plugins. black_list:list a list of module names that should be skipped. white_list:list a list of modules that comes with your main module. If you have a built-in module, the module name should be inserted into the list. For example, robot_cuisine is a built-in module inside robotchef. It is listed in white_list. """ log.debug("scanning for plugins...") if black_list is None: black_list = [] if white_list is None: white_list = [] # scan pkgutil.iter_modules module_names = (module_info[1] for module_info in pkgutil.iter_modules() if module_info[2] and module_info[1].startswith(prefix)) # scan pyinstaller module_names_from_pyinstaller = scan_from_pyinstaller(prefix, path) all_modules = chain(module_names, module_names_from_pyinstaller, white_list) # loop through modules and find our plug ins for module_name in all_modules: if module_name in black_list: log.debug("ignored " + module_name) continue try: do_import(module_name) except ImportError as e: log.debug(module_name) log.debug(e) continue log.debug("scanning done")
def test_do_import_error(mock_exception): do_import("non.exist") mock_exception.assert_called_with("No module named 'non'")
def test_do_import_2(): import lml.plugin as plugin themodule = do_import("lml.plugin") eq_(plugin, themodule)
def test_do_import(): import pyexcel_test pyexcel_test_package = do_import("pyexcel_test") eq_(pyexcel_test_package, pyexcel_test)
def test_do_import_error(): do_import("non.exist")
def test_do_import_error(mock_exception): with raises(ImportError): do_import("non.exist") mock_exception.assert_called_with("%s is absent or cannot be imported", "non.exist")
def test_do_import_2(): import lml.plugin as plugin themodule = do_import("lml.plugin") assert plugin == themodule
def test_do_import(): import isort test_package = do_import("isort") assert test_package == isort