def _considerImplicitImports(plugin, module): from nuitka.importing import Importing result = [] def iterateModuleNames(value): for v in value: if type(v) in (tuple, list): plugin.sysexit( "Plugin %r needs to be change to only return modules names, not %r (for %s)" % (plugin.plugin_name, v, module.getFullName().asString())) if inspect.isgenerator(v): for w in iterateModuleNames(v): yield w return if not checkModuleName(v): plugin.sysexit( "Plugin %r returned an invalid module name, not %r (for %s)" % (plugin, v, module.getFullName().asString())) yield ModuleName(v) for full_name in iterateModuleNames(plugin.getImplicitImports(module)): try: _module_name, module_filename, _finding = Importing.locateModule( module_name=full_name, parent_package=None, level=0, ) except Exception: plugin.warning( "Problem locating '%s' for implicit imports of '%s'." % (module.getFullName(), full_name)) raise if module_filename is None: if Options.isShowInclusion(): plugin.info( "Implicit module '%s' suggested for '%s' not found." % (full_name, module.getFullName())) continue result.append((full_name, module_filename)) if result: plugin.info("Implicit dependencies of module '%s' added '%s'." % (module.getFullName(), ",".join(r[0] for r in result))) return result
def _loadUncompiledModuleFromCache(module_name, is_package, source_code, source_ref): result = makeUncompiledPythonModule( module_name=module_name, filename=source_ref.getFilename(), bytecode=demoteSourceCodeToBytecode( module_name=module_name, source_code=source_code, filename=source_ref.getFilename(), ), user_provided=False, technical=False, is_package=is_package, ) used_modules = OrderedSet() for used_module_name, line_number in getCachedImportedModulesNames( module_name=module_name, source_code=source_code): _module_name, module_filename, finding = Importing.locateModule( module_name=used_module_name, parent_package=None, level=0, ) assert _module_name == used_module_name used_modules.add(( used_module_name, module_filename, finding, 0, source_ref.atLineNumber(line_number), )) # assert not is_package, (module_name, used_modules, result, result.getCompileTimeFilename()) result.setUsedModules(used_modules) 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 _createNodeTree(filename): """Create a node tree. Turn that source code into a node tree structure. If recursion into imported modules is available, more trees will be available during optimization, or immediately through recursed directory paths. """ # Many cases to deal with, pylint: disable=too-many-branches # First, build the raw node tree from the source code. main_module = Building.buildMainModuleTree( filename=filename, is_main=not Options.shallMakeModule(), ) # First remove old object files and old generated files, old binary or # module, and standalone mode program directory if any, they can only do # harm. source_dir = OutputDirectories.getSourceDirectoryPath() if not Options.shallOnlyExecCCompilerCall(): SconsInterface.cleanSconsDirectory(source_dir) # Prepare the ".dist" directory, throwing away what was there before. if Options.isStandaloneMode(): standalone_dir = OutputDirectories.getStandaloneDirectoryPath(bundle=False) removeDirectory(path=standalone_dir, ignore_errors=True) if Options.shallCreateAppBundle(): removeDirectory( path=changeFilenameExtension(standalone_dir, ".app"), ignore_errors=True ) # Delete result file, to avoid confusion with previous build and to # avoid locking issues after the build. deleteFile( path=OutputDirectories.getResultFullpath(onefile=False), must_exist=False ) if Options.isOnefileMode(): deleteFile( path=OutputDirectories.getResultFullpath(onefile=True), must_exist=False ) # Second, do it for the directories given. for plugin_filename in Options.getShallFollowExtra(): Recursion.checkPluginPath(plugin_filename=plugin_filename, module_package=None) for pattern in Options.getShallFollowExtraFilePatterns(): Recursion.checkPluginFilenamePattern(pattern=pattern) for package_name in Options.getMustIncludePackages(): package_name, package_directory, kind = Importing.locateModule( module_name=ModuleName(package_name), parent_package=None, level=0, ) if kind != "absolute": inclusion_logger.sysexit( "Error, failed to locate package %r you asked to include." % package_name.asString() ) Recursion.checkPluginPath( plugin_filename=package_directory, module_package=package_name.getPackageName(), ) for module_name in Options.getMustIncludeModules(): module_name, module_filename, kind = Importing.locateModule( module_name=ModuleName(module_name), parent_package=None, level=0, ) if kind != "absolute": inclusion_logger.sysexit( "Error, failed to locate module '%s' you asked to include." % module_name.asString() ) Recursion.checkPluginSinglePath( plugin_filename=module_filename, module_package=module_name.getPackageName() ) # Allow plugins to add more modules based on the initial set being complete. Plugins.onModuleInitialSet() # Then optimize the tree and potentially recursed modules. optimizeModules(main_module.getOutputFilename()) # Allow plugins to comment on final module set. Plugins.onModuleCompleteSet() if Options.isExperimental("check_xml_persistence"): for module in ModuleRegistry.getRootModules(): if module.isMainModule(): return module assert False else: # Main module might change behind our back, look it up again. return main_module