def considerImplicitImports(self, signal_change): for module_name, module_package in self.getImplicitImports(): _module_package, _module_name, module_filename = \ Importing.findModule( source_ref = self.source_ref, module_name = module_name, parent_package = module_package, level = -1, warn = True ) if module_filename is None: sys.exit( "Error, implicit module '%s' expected by '%s' not found" % ( module_name, self.getFullName() ) ) elif Utils.isDir(module_filename): module_kind = "py" elif module_filename.endswith(".py"): module_kind = "py" elif module_filename.endswith(".so"): module_kind = "shlib" elif module_filename.endswith(".pyd"): module_kind = "shlib" else: assert False, module_filename from nuitka.tree import Recursion decision, reason = Recursion.decideRecursion( module_filename = module_filename, module_name = module_name, module_package = module_package, module_kind = module_kind ) assert decision or reason == "Module is frozen." if decision: module_relpath = Utils.relpath(module_filename) imported_module, added_flag = Recursion.recurseTo( module_package = module_package, module_filename = module_filename, module_relpath = module_relpath, module_kind = module_kind, reason = reason ) from nuitka.ModuleRegistry import addUsedModule addUsedModule(imported_module) if added_flag: signal_change( "new_code", imported_module.getSourceReference(), "Recursed to module." )
def _addParentPackageUsages(using_module, module_name, signal_change, source_ref): for parent_package_name in module_name.getParentPackageNames(): _parent_package_name, parent_package_filename, _finding = locateModule( module_name=parent_package_name, parent_package=None, level=0) assert parent_package_filename is not None, parent_package_name assert _parent_package_name == parent_package_name _parent_package_name, package_module_kind = getModuleNameAndKindFromFilename( parent_package_filename) _decision, reason = decideRecursion( module_filename=parent_package_filename, module_name=parent_package_name, module_kind=package_module_kind, ) used_package_module = recurseTo( signal_change=signal_change, module_name=parent_package_name, module_filename=parent_package_filename, module_kind=package_module_kind, reason=reason, ) addUsedModule( module=used_package_module, using_module=using_module, usage_tag="package", reason=reason, source_ref=source_ref, )
def computeExpression(self, constraint_collection): # Attempt to recurse if not already done. if not self.attempted_recurse: self._attemptRecursion( constraint_collection = constraint_collection ) self.attempted_recurse = True if self.getModule() is not None: from nuitka.ModuleRegistry import addUsedModule addUsedModule(self.getModule()) for found_module in self.found_modules: addUsedModule(found_module) # When a module is recursed to and included, we know it won't raise, # right? But even if you import, that successful import may still raise # and we don't know how to check yet. constraint_collection.onExceptionRaiseExit( BaseException ) return self, None, None
def computeModule(self): CompiledPythonModule.computeModule(self) from nuitka.ModuleRegistry import addUsedModule for early_module in self.early_modules: addUsedModule(early_module)
def _reportImplicitImports(implicit_imports, signal_change): from nuitka.importing import Recursion from nuitka.importing.Importing import getModuleNameAndKindFromFilename for full_name, module_filename in implicit_imports: _module_name2, module_kind = getModuleNameAndKindFromFilename( module_filename) # This will get back to all other plugins allowing them to inhibit it though. decision, reason = Recursion.decideRecursion( module_filename=module_filename, module_name=full_name, module_kind=module_kind, ) if decision: imported_module, added_flag = Recursion.recurseTo( module_package=full_name.getPackageName(), module_filename=module_filename, module_relpath=relpath(module_filename), module_kind=module_kind, reason=reason, ) addUsedModule(imported_module) if added_flag: signal_change( "new_code", imported_module.getSourceReference(), "Recursed to module.", )
def _reportImplicitImports(plugin, module, implicit_imports, signal_change): from nuitka.importing import Recursion from nuitka.importing.Importing import getModuleNameAndKindFromFilename for full_name, module_filename in implicit_imports: _module_name2, module_kind = getModuleNameAndKindFromFilename( module_filename) # This will get back to all other plugins allowing them to inhibit it though. decision, reason = Recursion.decideRecursion( module_filename=module_filename, module_name=full_name, module_kind=module_kind, ) if decision: imported_module = Recursion.recurseTo( signal_change=signal_change, module_name=full_name, module_filename=module_filename, module_kind=module_kind, reason=reason, ) addUsedModule( module=imported_module, using_module=module, usage_tag="plugin:" + plugin.plugin_name, reason=reason, source_ref=module.source_ref, )
def attemptRecursion(self): # Make sure the package is recursed to. # Return the list of newly added modules. result = [] if self.package_name is not None and self.package is None: self.package = getModuleByName(self.package_name) if self.package_name is not None and self.package is None: package_package, package_filename, finding = findModule( importing=self, module_name=self.package_name, parent_package=None, level=1, warn=python_version < 330) # TODO: Temporary, if we can't find the package for Python3.3 that # is semi-OK, maybe. if python_version >= 330 and not package_filename: return [] if self.package_name == "uniconvertor.app.modules": return [] assert package_filename is not None, (self.package_name, finding) _package_name, package_kind = getModuleNameAndKindFromFilename( package_filename) # assert _package_name == self.package_name, (package_filename, _package_name, self.package_name) decision, _reason = decideRecursion( module_filename=package_filename, module_name=self.package_name, module_package=package_package, module_kind=package_kind) if decision is not None: self.package, is_added = recurseTo( module_package=package_package, module_filename=package_filename, module_relpath=relpath(package_filename), module_kind="py", reason="Containing package of recursed module '%s'." % self.getFullName(), ) if is_added: result.append(self.package) if self.package: from nuitka.ModuleRegistry import addUsedModule addUsedModule(self.package) # print "Recursed to package", self.package_name result.extend(self.package.attemptRecursion()) return result
def considerImplicitImports(self, module, signal_change): """ Consider module imports. You will most likely want to look at "module.getFullName()" to get the fully qualified module or package name. You do not want to overload this method, but rather the things it calls, as the "signal_change" part of this API is not to be cared about. Most prominently "getImplicitImports()". """ for full_name in self.getImplicitImports(module.getFullName()): module_name = full_name.split('.')[-1] module_package = '.'.join(full_name.split('.')[:-1]) or None module_filename = self.locateModule( source_ref = module.getSourceReference(), module_name = module_name, module_package = module_package, ) if module_filename is None: sys.exit( "Error, implicit module '%s' expected by '%s' not found" % ( module_name, module.getFullName() ) ) elif Utils.isDir(module_filename): module_kind = "py" elif module_filename.endswith(".py"): module_kind = "py" elif module_filename.endswith(".so") or \ module_filename.endswith(".pyd"): module_kind = "shlib" else: assert False, module_filename # TODO: This should get back to plug-ins, they should be allowed to # preempt or override the decision. decision, reason = self.decideRecursion( module_filename = module_filename, module_name = module_name, module_package = module_package, module_kind = module_kind ) if decision: self.recurseTo( module_package = module_package, module_filename = module_filename, module_kind = module_kind, reason = reason, signal_change = signal_change ) full_name = module.getFullName() if full_name in post_modules: addUsedModule(post_modules[full_name])
def attemptRecursion(self): # Make sure the package is recursed to if any package_name = self.module_name.getPackageName() if package_name is None: return () # Return the list of newly added modules. package = getModuleByName(package_name) if package_name is not None and package is None: _package_name, package_filename, finding = locateModule( module_name=package_name, parent_package=None, level=0, ) # If we can't find the package for Python3.3 that is semi-OK, it might be in a # namespace package, these have no init code. if python_version >= 0x300 and not package_filename: return () if package_name == "uniconvertor.app.modules": return () assert package_filename is not None, (package_name, finding) _package_name, package_kind = getModuleNameAndKindFromFilename( package_filename ) # assert _package_name == self.package_name, (package_filename, _package_name, self.package_name) decision, _reason = decideRecursion( module_filename=package_filename, module_name=package_name, module_kind=package_kind, ) if decision is not None: package = recurseTo( signal_change=self.trace_collection.signalChange if hasattr(self, "trace_collection") else None, module_name=package_name, module_filename=package_filename, module_kind="py", reason="Containing package of '%s'." % self.getFullName(), ) if package: from nuitka.ModuleRegistry import addUsedModule addUsedModule( package, using_module=self, usage_tag="package", reason="Containing package of '%s'." % self.getFullName(), source_ref=self.source_ref, )
def considerUsedModules(module, signal_change): for ( used_module_name, used_module_filename, finding, level, source_ref, ) in module.getUsedModules(): if finding == "not-found": Importing.warnAbout( importing=module, source_ref=source_ref, module_name=used_module_name, level=level, ) try: if used_module_filename is None: continue _module_name, module_kind = getModuleNameAndKindFromFilename( used_module_filename) decision, reason = decideRecursion( module_filename=used_module_filename, module_name=used_module_name, module_kind=module_kind, ) if decision: _addParentPackageUsages( using_module=module, module_name=used_module_name, signal_change=signal_change, source_ref=source_ref, ) used_module = recurseTo( signal_change=signal_change, module_name=used_module_name, module_filename=used_module_filename, module_kind=module_kind, reason=reason, ) addUsedModule( module=used_module, using_module=module, usage_tag="import", reason=reason, source_ref=source_ref, ) except NuitkaForbiddenImportEncounter as e: recursion_logger.sysexit( "Error, forbidden import of '%s' in module '%s' at '%s' encountered." % (e, module.getFullName().asString(), source_ref.getAsString())) Plugins.considerImplicitImports(module=module, signal_change=signal_change)
def onUsedModule(self, module_name): assert type(module_name) is str, module_name self.used_modules.add(module_name) if isImportedModuleByName(module_name): module = getImportedModuleByName(module_name) addUsedModule(module)
def computeExpressionRaw(self, trace_collection): owning_module = self.getParentModule() # Make sure the owning module is added to the used set. This is most # important for helper functions, or modules, which otherwise have # become unused. from nuitka.ModuleRegistry import addUsedModule addUsedModule(owning_module) abort_context = trace_collection.makeAbortStackContext( catch_breaks=False, catch_continues=False, catch_returns=True, catch_exceptions=False, ) with abort_context: body = self.getBody() result = body.computeStatementsSequence( trace_collection=trace_collection) if result is not body: self.setBody(result) body = result return_collections = trace_collection.getFunctionReturnCollections( ) if return_collections: trace_collection.mergeMultipleBranches(return_collections) first_statement = body.getStatements()[0] if first_statement.isStatementReturn(): return ( first_statement.getExpression(), "new_expression", "Outline '%s' is now simple return, use directly." % self.name, ) if first_statement.isStatementRaiseException(): result = ExpressionRaiseException( exception_type=first_statement.getExceptionType(), exception_value=first_statement.getExceptionValue(), source_ref=first_statement.getSourceReference(), ) return ( result, "new_expression", "Outline is now exception raise, use directly.", ) # TODO: Function outline may become too trivial to outline and return # collections may tell us something. return self, None, None
def attemptRecursion(self): # Make sure the package is recursed to. # Return the list of newly added modules. result = [] if self.package_name is not None and self.package is None: package_package, package_filename, _finding = findModule( importing = self, module_name = self.package_name, parent_package = None, level = 1, warn = python_version < 330 ) # TODO: Temporary, if we can't find the package for Python3.3 that # is semi-OK, maybe. if python_version >= 330 and not package_filename: return [] if self.package_name == "uniconvertor.app.modules": return [] assert package_filename is not None, self.package_name _package_name, package_kind = getModuleNameAndKindFromFilename(package_filename) # assert _package_name == self.package_name, (package_filename, _package_name, self.package_name) decision, _reason = decideRecursion( module_filename = package_filename, module_name = self.package_name, module_package = package_package, module_kind = package_kind ) if decision is not None: imported_module, is_added = recurseTo( module_package = package_package, module_filename = package_filename, module_relpath = Utils.relpath(package_filename), module_kind = "py", reason = "Containing package of recursed module '%s'." % self.getFullName(), ) self.package = imported_module if is_added: result.append(imported_module) if self.package: from nuitka.ModuleRegistry import addUsedModule addUsedModule(self.package) # print "Recursed to package", self.package_name result.extend(self.package.attemptRecursion()) return result
def computeExpressionRaw(self, trace_collection): owning_module = self.getParentModule() # Make sure the owning module is added to the used set. This is most # important for helper functions, or modules, which otherwise have # become unused. from nuitka.ModuleRegistry import addUsedModule addUsedModule(owning_module) abort_context = trace_collection.makeAbortStackContext( catch_breaks=False, catch_continues=False, catch_returns=True, catch_exceptions=False, ) with abort_context: body = self.getBody() result = body.computeStatementsSequence(trace_collection=trace_collection) if result is not body: self.setBody(result) body = result return_collections = trace_collection.getFunctionReturnCollections() if return_collections: trace_collection.mergeMultipleBranches(return_collections) first_statement = body.getStatements()[0] if first_statement.isStatementReturn(): return ( first_statement.getExpression(), "new_expression", "Outline '%s' is now simple return, use directly." % self.name, ) if first_statement.isStatementRaiseException(): result = ExpressionRaiseException( exception_type=first_statement.getExceptionType(), exception_value=first_statement.getExceptionValue(), source_ref=first_statement.getSourceReference(), ) return ( result, "new_expression", "Outline is now exception raise, use directly.", ) # TODO: Function outline may become too trivial to outline and return # collections may tell us something. return self, None, None
def onUsedModule(self, module_name, module_relpath): assert type(module_name) is str, module_name # TODO: Make users provide this through a method that has already # done this. module_relpath = relpath(module_relpath) self.used_modules.add((module_name, module_relpath)) module = getImportedModuleByNameAndPath(module_name, module_relpath) addUsedModule(module)
def considerImplicitImports(module, signal_change): for plugin in active_plugin_list: plugin.considerImplicitImports(module, signal_change) # Post load code may have been created, if so indicate it's used. full_name = module.getFullName() if full_name in post_modules: addUsedModule(post_modules[full_name]) if full_name in pre_modules: addUsedModule(pre_modules[full_name])
def onUsedFunction(self, function_body): owning_module = function_body.getParentModule() # Make sure the owning module is added to the used set. This is most # important for helper functions, or modules, which otherwise have # become unused. addUsedModule(owning_module) needs_visit = owning_module.addUsedFunction(function_body) if needs_visit: function_body.computeFunctionRaw(self)
def considerImplicitImports(self, module, signal_change): """ Consider module imports. You will most likely want to look at "module.getFullName()" to get the fully qualified module or package name. You do not want to overload this method, but rather the things it calls, as the "signal_change" part of this API is not to be cared about. Most prominently "getImplicitImports()". """ for full_name in self.getImplicitImports(module.getFullName()): module_name = full_name.split('.')[-1] module_package = '.'.join(full_name.split('.')[:-1]) or None module_filename = self.locateModule( source_ref=module.getSourceReference(), module_name=module_name, module_package=module_package, ) if module_filename is None: sys.exit( "Error, implicit module '%s' expected by '%s' not found" % (module_name, module.getFullName())) elif Utils.isDir(module_filename): module_kind = "py" elif module_filename.endswith(".py"): module_kind = "py" elif module_filename.endswith(".so") or \ module_filename.endswith(".pyd"): module_kind = "shlib" else: assert False, module_filename # TODO: This should get back to plug-ins, they should be allowed to # preempt or override the decision. decision, reason = self.decideRecursion( module_filename=module_filename, module_name=module_name, module_package=module_package, module_kind=module_kind) if decision: self.recurseTo(module_package=module_package, module_filename=module_filename, module_kind=module_kind, reason=reason, signal_change=signal_change) full_name = module.getFullName() if full_name in post_modules: addUsedModule(post_modules[full_name])
def recurseTo(module_package, module_filename, module_kind, reason, signal_change): from nuitka.importing import Recursion imported_module, added_flag = Recursion.recurseTo( module_package=module_package, module_filename=module_filename, module_relpath=Utils.relpath(module_filename), module_kind=module_kind, reason=reason, ) addUsedModule(imported_module) if added_flag: signal_change("new_code", imported_module.getSourceReference(), "Recursed to module.")
def recurseTo(module_package, module_filename, module_kind, reason, signal_change): from nuitka.importing import Recursion imported_module, added_flag = Recursion.recurseTo( module_package=module_package, module_filename=module_filename, module_relpath=relpath(module_filename), module_kind=module_kind, reason=reason) addUsedModule(imported_module) if added_flag: signal_change("new_code", imported_module.getSourceReference(), "Recursed to module.")
def computeExpressionRaw(self, constraint_collection): function_body = self.getFunctionBody() owning_module = function_body.getParentModule() # Make sure the owning module is added to the used set. This is most # important for helper functions, or modules, which otherwise have # become unused. from nuitka.ModuleRegistry import addUsedModule addUsedModule(owning_module) owning_module.addUsedFunction(function_body) from nuitka.optimizations.TraceCollections import \ ConstraintCollectionFunction # TODO: Doesn't this mean, we can do this multiple times by doing it # in the reference. We should do it in the body, and there we should # limit us to only doing it once per module run, e.g. being based on # presence in used functions of the module already. old_collection = function_body.constraint_collection function_body.constraint_collection = ConstraintCollectionFunction( parent = constraint_collection, function_body = function_body ) statements_sequence = function_body.getBody() if statements_sequence is not None and \ not statements_sequence.getStatements(): function_body.setStatements(None) statements_sequence = None if statements_sequence is not None: result = statements_sequence.computeStatementsSequence( constraint_collection = function_body.constraint_collection ) if result is not statements_sequence: function_body.setBody(result) function_body.constraint_collection.updateFromCollection(old_collection) # TODO: Function collection may now know something. return self, None, None
def computeExpression(self, constraint_collection): # Attempt to recurse if not already done. if not self.attempted_recurse: self._attemptRecursion(constraint_collection=constraint_collection) self.attempted_recurse = True if self.getModule() is not None: from nuitka.ModuleRegistry import addUsedModule addUsedModule(self.getModule()) for found_module in self.found_modules: addUsedModule(found_module) # TODO: May return a module reference of some sort in the future with # embedded modules. return self, None, None
def attemptRecursion(self): # Make sure the package is recursed to. from nuitka.tree import Recursion from nuitka import Importing # Return the list of newly added modules. result = [] if self.package_name is not None and self.package is None: package_package, _package_module_name, package_filename = \ Importing.findModule( source_ref = self.getSourceReference(), module_name = self.package_name, parent_package = None, level = 1, warn = Utils.python_version < 330 ) # TODO: Temporary, if we can't find the package for Python3.3 that # is semi-OK, maybe. if Utils.python_version >= 330 and not package_filename: return [] imported_module, is_added = Recursion.recurseTo( module_package=package_package, module_filename=package_filename, module_relpath=Utils.relpath(package_filename), module_kind="py", reason="Containing package of recursed module.", ) self.package = imported_module if is_added: result.append(imported_module) if self.package: from nuitka.ModuleRegistry import addUsedModule addUsedModule(self.package) # print "Recursed to package", self.package_name result.extend(self.package.attemptRecursion()) return result
def attemptRecursion(self): # Make sure the package is recursed to. from nuitka.tree import Recursion from nuitka import Importing # Return the list of newly added modules. result = [] if self.package_name is not None and self.package is None: package_package, _package_module_name, package_filename = \ Importing.findModule( source_ref = self.getSourceReference(), module_name = self.package_name, parent_package = None, level = 1, warn = Utils.python_version < 330 ) # TODO: Temporary, if we can't find the package for Python3.3 that # is semi-OK, maybe. if Utils.python_version >= 330 and not package_filename: return [] imported_module, is_added = Recursion.recurseTo( module_package = package_package, module_filename = package_filename, module_relpath = Utils.relpath(package_filename), module_kind = "py", reason = "Containing package of recursed module.", ) self.package = imported_module if is_added: result.append(imported_module) if self.package: from nuitka.ModuleRegistry import addUsedModule addUsedModule(self.package) # print "Recursed to package", self.package_name result.extend(self.package.attemptRecursion()) return result
def computeExpressionRaw(self, constraint_collection): function_body = self.getFunctionBody() owning_module = function_body.getParentModule() from nuitka.ModuleRegistry import addUsedModule addUsedModule(owning_module) owning_module.addUsedFunction(function_body) from nuitka.optimizations.ConstraintCollections import ConstraintCollectionFunction collection = ConstraintCollectionFunction(parent=constraint_collection, function_body=function_body) function_body.collection = collection # TODO: Function collection may now know something. return self, None, None
def onUsedFunction(self, function_body): owning_module = function_body.getParentModule() # Make sure the owning module is added to the used set. This is most # important for helper functions, or modules, which otherwise have # become unused. addUsedModule( module=owning_module, using_module=None, usage_tag="function", reason="Function %s" % self.name, source_ref=owning_module.source_ref, ) needs_visit = owning_module.addUsedFunction(function_body) if needs_visit: function_body.computeFunctionRaw(self)
def computeExpressionRaw(self, trace_collection): function_body = self.getFunctionBody() owning_module = function_body.getParentModule() # Make sure the owning module is added to the used set. This is most # important for helper functions, or modules, which otherwise have # become unused. from nuitka.ModuleRegistry import addUsedModule addUsedModule(owning_module) needs_visit = owning_module.addUsedFunction(function_body) if needs_visit: function_body.computeFunctionRaw(trace_collection) # TODO: Function collection may now know something. return self, None, None
def computeExpressionRaw(self, constraint_collection): function_body = self.getCoroutineBody() owning_module = function_body.getParentModule() # Make sure the owning module is added to the used set. This is most # important for helper functions, or modules, which otherwise have # become unused. from nuitka.ModuleRegistry import addUsedModule addUsedModule(owning_module) owning_module.addUsedFunction(function_body) from nuitka.optimizations.TraceCollections import \ ConstraintCollectionFunction # TODO: Doesn't this mean, we can do this multiple times by doing it # in the reference. We should do it in the body, and there we should # limit us to only doing it once per module run, e.g. being based on # presence in used functions of the module already. old_collection = function_body.constraint_collection function_body.constraint_collection = ConstraintCollectionFunction( parent=constraint_collection, function_body=function_body) statements_sequence = function_body.getBody() if statements_sequence is not None and \ not statements_sequence.getStatements(): function_body.setStatements(None) statements_sequence = None if statements_sequence is not None: result = statements_sequence.computeStatementsSequence( constraint_collection=function_body.constraint_collection) if result is not statements_sequence: function_body.setBody(result) function_body.constraint_collection.updateFromCollection( old_collection) # TODO: Function collection may now know something. return self, None, None
def computeExpression(self, constraint_collection): # Attempt to recurse if not already done. if not self.attempted_recurse: self._attemptRecursion( constraint_collection = constraint_collection ) self.attempted_recurse = True if self.getModule() is not None: from nuitka.ModuleRegistry import addUsedModule addUsedModule(self.getModule()) for found_module in self.found_modules: addUsedModule(found_module) # TODO: May return a module reference of some sort in the future with # embedded modules. return self, None, None
def computeModule(self): CompiledPythonModule.computeModule(self) from nuitka.ModuleRegistry import addUsedModule for early_module in self.early_modules: if early_module.isTechnical(): usage_tag = "technical" reason = "Module needed for initializing Python" else: usage_tag = "stdlib" reason = "Part of standard library" addUsedModule( module=early_module, using_module=self, usage_tag=usage_tag, reason=reason, source_ref=self.source_ref, )
def computeExpressionRaw(self, constraint_collection): owning_module = self.getParentModule() # Make sure the owning module is added to the used set. This is most # important for helper functions, or modules, which otherwise have # become unused. from nuitka.ModuleRegistry import addUsedModule addUsedModule(owning_module) abort_context = constraint_collection.makeAbortStackContext( catch_breaks = False, catch_continues = False, catch_returns = True, catch_exceptions = False ) with abort_context: body = self.getBody() result = body.computeStatementsSequence( constraint_collection = constraint_collection ) if result is not body: self.setBody(result) body = result return_collections = constraint_collection.getFunctionReturnCollections() constraint_collection.mergeMultipleBranches(return_collections) if body.getStatements()[0].isStatementReturn(): return ( body.getStatements()[0].getExpression(), "new_expression", "Outline is now simple expression, use directly." ) # TODO: Function outline may become too trivial to outline and return # collections may tell us something. return self, None, None
def considerImplicitImports(cls, module, signal_change): for plugin in getActivePlugins(): key = (module.getFullName(), plugin) if key not in cls.implicit_imports_cache: cls.implicit_imports_cache[key] = tuple( cls._considerImplicitImports(plugin=plugin, module=module)) cls._reportImplicitImports( implicit_imports=cls.implicit_imports_cache[key], signal_change=signal_change, ) # Pre and post load code may have been created, if so indicate it's used. full_name = module.getFullName() if full_name in pre_modules: addUsedModule(pre_modules[full_name]) if full_name in post_modules: addUsedModule(post_modules[full_name])
def computeExpressionRaw(self, constraint_collection): owning_module = self.getParentModule() # Make sure the owning module is added to the used set. This is most # important for helper functions, or modules, which otherwise have # become unused. from nuitka.ModuleRegistry import addUsedModule addUsedModule(owning_module) abort_context = constraint_collection.makeAbortStackContext( catch_breaks=False, catch_continues=False, catch_returns=True, catch_exceptions=False) with abort_context: body = self.getBody() result = body.computeStatementsSequence( constraint_collection=constraint_collection) if result is not body: self.setBody(result) body = result return_collections = constraint_collection.getFunctionReturnCollections( ) constraint_collection.mergeMultipleBranches(return_collections) if body.getStatements()[0].isStatementReturn(): return (body.getStatements()[0].getExpression(), "new_expression", "Outline is now simple expression, use directly.") # TODO: Function outline may become too trivial to outline and return # collections may tell us something. return self, None, None
def considerImplicitImports(cls, module, signal_change): for plugin in getActivePlugins(): key = (module.getFullName(), plugin) if key not in cls.implicit_imports_cache: cls.implicit_imports_cache[key] = tuple( cls._considerImplicitImports(plugin=plugin, module=module)) cls._reportImplicitImports( plugin=plugin, module=module, implicit_imports=cls.implicit_imports_cache[key], signal_change=signal_change, ) # Pre and post load code may have been created, if so indicate it's used. full_name = module.getFullName() if full_name in pre_modules: addUsedModule( pre_modules[full_name], using_module=module, usage_tag="plugins", reason="Not yet propagated by plugins.", source_ref=module.source_ref, ) if full_name in post_modules: addUsedModule( module=post_modules[full_name], using_module=module, usage_tag="plugins", reason="Not yet propagated by plugins.", source_ref=module.source_ref, ) if full_name in fake_modules: for fake_module, plugin, reason in fake_modules[full_name]: addUsedModule( module=fake_module, using_module=module, usage_tag="plugins", reason=reason, source_ref=module.source_ref, )
def computeExpressionRaw(self, trace_collection): owning_module = self.getParentModule() # Make sure the owning module is added to the used set. This is most # important for helper functions, or modules, which otherwise have # become unused. from nuitka.ModuleRegistry import addUsedModule addUsedModule( module=owning_module, using_module=None, usage_tag="outline", reason="Owning module", source_ref=self.source_ref, ) abort_context = trace_collection.makeAbortStackContext( catch_breaks=False, catch_continues=False, catch_returns=True, catch_exceptions=False, ) with abort_context: body = self.subnode_body result = body.computeStatementsSequence( trace_collection=trace_collection) if result is not body: self.setChild("body", result) body = result return_collections = trace_collection.getFunctionReturnCollections( ) if return_collections: trace_collection.mergeMultipleBranches(return_collections) first_statement = body.subnode_statements[0] if first_statement.isStatementReturnConstant(): return ( makeConstantRefNode( constant=first_statement.getConstant(), source_ref=first_statement.source_ref, ), "new_expression", "Outline '%s' is now simple return, use directly." % self.name, ) if first_statement.isStatementReturn(): return ( first_statement.subnode_expression, "new_expression", "Outline '%s' is now simple return, use directly." % self.name, ) if first_statement.isStatementRaiseException(): # Exception exit was already annotated, need not repeat it. result = ExpressionRaiseException( exception_type=first_statement.subnode_exception_type, exception_value=first_statement.subnode_exception_value, source_ref=first_statement.getSourceReference(), ) return ( result, "new_expression", "Outline is now exception raise, use directly.", ) # TODO: Function outline may become too trivial to outline and return # collections may tell us something. return self, None, None
def onUsedModule(self, module_name): self.used_modules.add(module_name) if isImportedModuleByName(module_name): module = getImportedModuleByName(module_name) addUsedModule(module)