def _loadPluginClassesFromPath(scan_path): for loader, name, is_pkg in pkgutil.iter_modules(scan_path): if is_pkg: continue module_loader = loader.find_module(name) # Ignore bytecode only left overs. try: if module_loader.get_filename().endswith(".pyc"): continue except AttributeError: # Not a bytecode loader, but e.g. extension module, which is OK in case # it was compiled with Nuitka. pass try: plugin_module = module_loader.load_module(name) except Exception: if Options.is_nondebug: plugins_logger.warning( "Problem loading plugin %r (%s), ignored. Use --debug to make it visible." % (name, module_loader.get_filename())) continue raise plugin_classes = set(obj for obj in plugin_module.__dict__.values() if isObjectAUserPluginBaseClass(obj)) detectors = [ plugin_class for plugin_class in plugin_classes if hasattr(plugin_class, "detector_for") ] for detector in detectors: plugin_class = detector.detector_for assert detector.plugin_name is None, detector detector.plugin_name = plugin_class.plugin_name if plugin_class not in plugin_classes: plugins_logger.sysexit( "Plugin detector %r references unknown plugin %r" % (detector, plugin_class)) plugin_classes.remove(detector) plugin_classes.remove(plugin_class) plugin_name2plugin_classes[plugin_class.plugin_name] = ( plugin_class, detector, ) for plugin_class in plugin_classes: plugin_name2plugin_classes[ plugin_class.plugin_name] = plugin_class, None
def warnUnusedPlugin(self, message): """An inactive plugin may issue a warning if it believes this may be wrong. Returns: None """ if self.plugin_name not in warned_unused_plugins: warned_unused_plugins.add(self.plugin_name) plugins_logger.warning("Use '--plugin-enable=%s' for: %s" % (self.plugin_name, message))
def decideCompilationMode(is_top, module_name, source_ref): result = Plugins.decideCompilation(module_name, source_ref) if result == "bytecode" and is_top: plugins_logger.warning("""\ Ignoring plugin decision to compile top level package '%s' as bytecode, the extension module entry point is technically required to compiled.""" % module_name) result = "compiled" return result
def decideCompilationMode(is_top, module_name, for_pgo): """Decide the compilation mode for a module. module_name - The module to decide compilation mode for. for_pgo - consider PGO information or not """ result = Plugins.decideCompilation(module_name) # Cannot change mode of __main__ to bytecode, that is not going # to work currently. if result == "bytecode" and is_top: plugins_logger.warning("""\ Ignoring plugin decision to compile top level package '%s' as bytecode, the extension module entry point is technically required to compiled.""" % module_name) result = "compiled" # Include all of standard library as bytecode, for now. We need to identify # which ones really need that. if not is_top: module_filename = Importing.locateModule(module_name=module_name, parent_package=None, level=0)[1] if module_filename is not None and isStandardLibraryPath( module_filename): result = "bytecode" # Plugins need to win over PGO, as they might know it better if result is None and not for_pgo: result = decideCompilationFromPGO(module_name=module_name) # Default if neither plugins nor PGO have expressed an opinion if result is None: result = "compiled" return result
def warning(cls, message): plugins_logger.warning(cls.plugin_name + ": " + message)
def _loadPluginClassesFromPackage(scan_package): scan_path = scan_package.__path__ for item in iter_modules(scan_path): if item.ispkg: continue module_loader = item.module_finder.find_module(item.name) # Ignore bytecode only left overs. try: if module_loader.get_filename().endswith(".pyc"): continue except AttributeError: # Not a bytecode loader, but e.g. extension module, which is OK in case # it was compiled with Nuitka. pass try: plugin_module = module_loader.load_module(item.name) except Exception: if Options.is_nondebug: plugins_logger.warning( "Problem loading plugin %r (%s), ignored. Use --debug to make it visible." % (item.name, module_loader.get_filename())) continue raise # At least for Python2, this is not set properly, but we use it for package # data loading. plugin_module.__package__ = scan_package.__name__ plugin_classes = set(obj for obj in plugin_module.__dict__.values() if isObjectAUserPluginBaseClass(obj)) detectors = [ plugin_class for plugin_class in plugin_classes if hasattr(plugin_class, "detector_for") ] # First the ones with detectors. for detector in detectors: plugin_class = detector.detector_for if detector.__name__.replace("NuitkaPluginDetector", "") != plugin_class.__name__.replace( "NuitkaPlugin", ""): plugins_logger.warning( "Class names %r and %r do not match NuitkaPlugin* and NuitkaPluginDetector* naming convention." % (plugin_class.__name__, detector.__name__)) assert detector.plugin_name is None, detector detector.plugin_name = plugin_class.plugin_name if plugin_class not in plugin_classes: plugins_logger.sysexit( "Plugin detector %r references unknown plugin %r" % (detector, plugin_class)) plugin_classes.remove(detector) plugin_classes.remove(plugin_class) _addPluginClass( plugin_class=plugin_class, detector=detector, ) # Remaining ones have no detector. for plugin_class in plugin_classes: _addPluginClass(plugin_class=plugin_class, detector=None)