def createPathAssignment(package, source_ref): if Options.getFileReferenceMode() == "original": path_value = makeConstantRefNode( constant=[os.path.dirname(source_ref.getFilename())], source_ref=source_ref, user_provided=True) else: elements = [ ExpressionCallNoKeywords( called=ExpressionAttributeLookup( source=ExpressionImportModuleNameHard( module_name="os", import_name="path", source_ref=source_ref), attribute_name="dirname", source_ref=source_ref), args=ExpressionMakeTuple( elements=(ExpressionModuleAttributeFileRef( variable=package.getVariableForReference("__file__"), source_ref=source_ref, ), ), source_ref=source_ref, ), source_ref=source_ref, ) ] if package.canHaveExternalImports(): parts = package.getFullName().split('.') for count in range(len(parts)): path_part = _makeCall( "os", "environ", "get", source_ref, makeConstantRefNode( constant="NUITKA_PACKAGE_%s" % '_'.join(parts[:count + 1]), source_ref=source_ref, ), makeConstantRefNode( constant="/notexist", source_ref=source_ref, )) if parts[count + 1:]: path_part = _makeCall( "os", "path", "join", source_ref, path_part, makeConstantRefNode( constant=os.path.join(*parts[count + 1:]), source_ref=source_ref, )) elements.append(path_part) path_value = ExpressionMakeList(elements=elements, source_ref=source_ref) return StatementAssignmentVariableName(provider=package, variable_name="__path__", source=path_value, source_ref=source_ref)
def _makeCall(module_name, import_name, attribute_name, source_ref, *args): return ExpressionCallNoKeywords(called=ExpressionAttributeLookup( source=ExpressionImportModuleNameHard(module_name=module_name, import_name=import_name, source_ref=source_ref), attribute_name=attribute_name, source_ref=source_ref), args=ExpressionMakeTuple( elements=args, source_ref=source_ref), source_ref=source_ref)
def _makeCall(module_name, import_name, attribute_name, source_ref, *args): return ExpressionCallNoKeywords( called=makeExpressionAttributeLookup( expression=ExpressionImportModuleNameHard(module_name=module_name, import_name=import_name, source_ref=source_ref), attribute_name=attribute_name, source_ref=source_ref, ), args=makeExpressionMakeTupleOrConstant(elements=args, user_provided=True, source_ref=source_ref), source_ref=source_ref, )
def createImporterCacheAssignment(package, source_ref): return StatementDictOperationSet( dict_arg=ExpressionImportModuleNameHard( module_name="sys", import_name="path_importer_cache", source_ref=source_ref ), key=ExpressionSubscriptLookup( expression=ExpressionVariableNameRef( provider=package, variable_name="__path__", source_ref=source_ref ), subscript=makeConstantRefNode(constant=0, source_ref=source_ref), source_ref=source_ref, ), value=ExpressionNuitkaLoaderCreation(provider=package, source_ref=source_ref), source_ref=source_ref, )
def buildParseTree(provider, source_code, source_ref, is_module, is_main): # There are a bunch of branches here, mostly to deal with version # differences for module default variables. pylint: disable=too-many-branches pushFutureSpec() if is_module: provider.future_spec = getFutureSpec() body = parseSourceCodeToAst(source_code=source_code, filename=source_ref.getFilename(), line_offset=source_ref.getLineNumber() - 1) body, doc = extractDocFromBody(body) if is_module and is_main and python_version >= 360: provider.markAsNeedsAnnotationsDictionary() result = buildStatementsNode(provider=provider, nodes=body, source_ref=source_ref) checkFutureImportsOnlyAtStart(body) internal_source_ref = source_ref.atInternal() statements = [] if is_module: # Add import of "site" module of main programs visibly in the node tree, # so recursion and optimization can pick it up, checking its effects. if is_main and "no_site" not in Options.getPythonFlags(): for path_imported_name in getPthImportedPackages(): statements.append( StatementExpressionOnly(expression=makeAbsoluteImportNode( module_name=path_imported_name, source_ref=source_ref, ), source_ref=source_ref)) statements.append( StatementExpressionOnly(expression=makeAbsoluteImportNode( module_name="site", source_ref=source_ref, ), source_ref=source_ref)) statements.append( StatementAssignmentVariableName(variable_name="__doc__", source=makeConstantRefNode( constant=doc, source_ref=internal_source_ref, user_provided=True), source_ref=internal_source_ref)) statements.append( StatementAssignmentVariableName( variable_name="__file__", source=ExpressionModuleFileAttributeRef( source_ref=internal_source_ref, ), source_ref=internal_source_ref)) if provider.isCompiledPythonPackage(): # This assigns "__path__" value. statements.append( createPathAssignment(provider, internal_source_ref)) if python_version >= 330: statements.append( StatementAssignmentVariableName( variable_name="__loader__", source=ExpressionModuleLoaderRef( source_ref=internal_source_ref, ), source_ref=internal_source_ref)) if python_version >= 340: if provider.isMainModule(): spec_value = makeConstantRefNode(constant=None, source_ref=internal_source_ref) else: spec_value = makeCallNode( ExpressionImportModuleNameHard( module_name="importlib._bootstrap", import_name="ModuleSpec", source_ref=internal_source_ref, ), makeConstantRefNode(constant=provider.getFullName(), source_ref=internal_source_ref, user_provided=True), ExpressionModuleLoaderRef(source_ref=internal_source_ref, ), internal_source_ref) statements.append( StatementAssignmentVariableName(variable_name="__spec__", source=spec_value, source_ref=internal_source_ref)) if python_version >= 300: statements.append( StatementAssignmentVariableName(variable_name="__cached__", source=ExpressionConstantNoneRef( source_ref=internal_source_ref, user_provided=True), source_ref=internal_source_ref)) # The "__package__" attribute is set to proper value for 3.3 or higher even # for normal modules, previously for packages only. statements.append( StatementAssignmentVariableName( variable_name="__package__", source=makeConstantRefNode( constant=((None if '.' not in provider.getFullName() or python_version >= 320 else provider.getFullName()) if python_version < 330 else provider.getFullName()) if provider.isCompiledPythonPackage() else (provider.getPackage() if python_version >= 330 else None), source_ref=internal_source_ref, user_provided=True), source_ref=internal_source_ref)) needs__initializing__ = not provider.isMainModule() and \ (python_version >= 330 and python_version < 340) if needs__initializing__: # Set "__initializing__" at the beginning to True statements.append( StatementAssignmentVariableName(variable_name="__initializing__", source=makeConstantRefNode( constant=True, source_ref=internal_source_ref, user_provided=True), source_ref=internal_source_ref)) if provider.needsAnnotationsDictionary(): # Set "__annotations__" on module level to {} statements.append( StatementAssignmentVariableName(variable_name="__annotations__", source=makeConstantRefNode( constant={}, source_ref=internal_source_ref, user_provided=True), source_ref=internal_source_ref)) # Now the module body if there is any at all. if result is not None: statements.extend(result.getStatements()) if needs__initializing__: # Set "__initializing__" at the end to False statements.append( StatementAssignmentVariableName(variable_name="__initializing__", source=makeConstantRefNode( constant=False, source_ref=internal_source_ref, user_provided=True), source_ref=internal_source_ref)) if is_module: result = makeModuleFrame(module=provider, statements=statements, source_ref=source_ref) popFutureSpec() return result else: assert False
def buildPrintNode(provider, node, source_ref): # "print" statements, should only occur with Python2. if node.dest is not None: temp_scope = provider.allocateTempScope("print") tmp_target_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="target") target_default_statement = StatementAssignmentVariable( variable=tmp_target_variable, source=ExpressionImportModuleNameHard(module_name="sys", import_name="stdout", source_ref=source_ref), source_ref=source_ref, ) statements = [ StatementAssignmentVariable( variable=tmp_target_variable, source=buildNode(provider=provider, node=node.dest, source_ref=source_ref), source_ref=source_ref, ), makeStatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_target_variable, source_ref=source_ref), right=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref, ), yes_branch=target_default_statement, no_branch=None, source_ref=source_ref, ), ] values = buildNodeList(provider=provider, nodes=node.values, source_ref=source_ref) if node.dest is not None: print_statements = [ StatementPrintValue( dest=ExpressionTempVariableRef(variable=tmp_target_variable, source_ref=source_ref), value=value, source_ref=source_ref, ) for value in values ] if node.nl: print_statements.append( StatementPrintNewline( dest=ExpressionTempVariableRef( variable=tmp_target_variable, source_ref=source_ref), source_ref=source_ref, )) statements.append( makeTryFinallyStatement( provider=provider, tried=print_statements, final=StatementReleaseVariable(variable=tmp_target_variable, source_ref=source_ref), source_ref=source_ref, )) else: statements = [ StatementPrintValue(dest=None, value=value, source_ref=source_ref) for value in values ] if node.nl: statements.append( StatementPrintNewline(dest=None, source_ref=source_ref)) return makeStatementsSequenceFromStatements(*statements)
def getNameSpacePathExpression(package, source_ref): """Create the __path__ expression for a package.""" reference_mode = Options.getFileReferenceMode() if reference_mode == "original": return makeConstantRefNode( constant=[package.getCompileTimeDirectory()], source_ref=source_ref, ) elif reference_mode == "frozen": return makeConstantRefNode( constant=[], source_ref=source_ref, ) else: elements = [ ExpressionCallNoKeywords( called=makeExpressionAttributeLookup( expression=ExpressionImportModuleNameHard( module_name="os", import_name="path", source_ref=source_ref), attribute_name="dirname", source_ref=source_ref, ), args=makeExpressionMakeTuple( elements=(ExpressionModuleAttributeFileRef( variable=package.getVariableForReference("__file__"), source_ref=source_ref, ), ), source_ref=source_ref, ), source_ref=source_ref, ) ] if package.canHaveExternalImports(): parts = package.getFullName().asString().split(".") for count in range(len(parts)): path_part = _makeCall( "os", "environ", "get", source_ref, makeConstantRefNode( constant="NUITKA_PACKAGE_%s" % "_".join(parts[:count + 1]), source_ref=source_ref, ), makeConstantRefNode(constant="/notexist", source_ref=source_ref), ) if parts[count + 1:]: path_part = _makeCall( "os", "path", "join", source_ref, path_part, makeConstantRefNode( constant=os.path.join(*parts[count + 1:]), source_ref=source_ref, ), ) elements.append(path_part) return makeExpressionMakeList(elements=elements, source_ref=source_ref)