def buildReturnNode(provider, node, source_ref): if provider.isExpressionClassBody() or provider.isCompiledPythonModule(): SyntaxErrors.raiseSyntaxError( "'return' outside function", source_ref.atColumnNumber(node.col_offset) ) expression = buildNode(provider, node.value, source_ref, allow_none = True) if provider.isExpressionGeneratorObjectBody(): if expression is not None and python_version < 300: SyntaxErrors.raiseSyntaxError( "'return' with argument inside generator", source_ref.atColumnNumber(node.col_offset) ) if provider.isExpressionAsyncgenObjectBody(): if expression is not None: SyntaxErrors.raiseSyntaxError( "'return' with value in async generator", source_ref.atColumnNumber(node.col_offset) ) if provider.isExpressionGeneratorObjectBody() or \ provider.isExpressionAsyncgenObjectBody(): if expression is None: expression = ExpressionConstantNoneRef( source_ref = source_ref, user_provided = True ) return StatementGeneratorReturn( expression = expression, source_ref = source_ref ) else: if expression is None: return StatementReturnNone( source_ref = source_ref ) elif expression.isExpressionConstantRef(): return makeStatementReturnConstant( constant = expression.getCompileTimeConstant(), source_ref = source_ref ) else: return StatementReturn( expression = expression, source_ref = source_ref )
def buildReturnNode(provider, node, source_ref): if provider.isExpressionClassBody() or provider.isCompiledPythonModule(): SyntaxErrors.raiseSyntaxError( "'return' outside function", source_ref, None if python_version < 300 else (node.col_offset if provider.isCompiledPythonModule() else node.col_offset + 4)) expression = buildNode(provider, node.value, source_ref, allow_none=True) if provider.isExpressionGeneratorObjectBody(): if expression is not None and python_version < 330: SyntaxErrors.raiseSyntaxError( "'return' with argument inside generator", source_ref=source_ref, ) if expression is None: expression = ExpressionConstantNoneRef(source_ref=source_ref, user_provided=True) if provider.isExpressionGeneratorObjectBody(): return StatementGeneratorReturn(expression=expression, source_ref=source_ref) else: return StatementReturn(expression=expression, source_ref=source_ref)
def buildYieldNode(provider, node, source_ref): _checkInsideGenerator(provider, node, source_ref) if node.value is not None: return ExpressionYield(expression=buildNode(provider, node.value, source_ref), source_ref=source_ref) else: return ExpressionYield(expression=ExpressionConstantNoneRef( source_ref=source_ref, user_provided=True), source_ref=source_ref)
def _insertFinalReturnStatement(function_statements_body, return_class, source_ref): return_statement = return_class( expression=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref) if function_statements_body is None: function_statements_body = makeStatementsSequenceFromStatement( statement=return_statement, ) elif not function_statements_body.isStatementAborting(): function_statements_body.setStatements( function_statements_body.getStatements() + (return_statement, )) return function_statements_body
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(provider=provider, variable_name="__doc__", source=makeConstantRefNode( constant=doc, source_ref=internal_source_ref, user_provided=True), source_ref=internal_source_ref)) statements.append( StatementAssignmentVariableName( provider=provider, variable_name="__file__", source=ExpressionModuleAttributeFileRef( module=provider, 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 >= 300: statements.append( StatementAssignmentVariableName(provider=provider, variable_name="__cached__", source=ExpressionConstantNoneRef( source_ref=internal_source_ref, user_provided=True), source_ref=internal_source_ref)) needs__initializing__ = not provider.isMainModule( ) and 300 <= python_version < 340 if needs__initializing__: # Set "__initializing__" at the beginning to True statements.append( StatementAssignmentVariableName(provider=provider, 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(provider=provider, 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(provider=provider, 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 wrapEvalGlobalsAndLocals(provider, globals_node, locals_node, temp_scope, source_ref): """ Wrap the locals and globals arguments for "eval". This is called from the outside, and when the node tree already exists. """ globals_keeper_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="globals") locals_keeper_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="locals") if locals_node is None: locals_node = ExpressionConstantNoneRef(source_ref=source_ref) if globals_node is None: globals_node = ExpressionConstantNoneRef(source_ref=source_ref) post_statements = [] if provider.isExpressionClassBody(): post_statements.append( StatementLocalsDictSync( locals_arg=ExpressionTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), source_ref=source_ref.atInternal(), )) post_statements += [ StatementReleaseVariable(variable=globals_keeper_variable, source_ref=source_ref), StatementReleaseVariable(variable=locals_keeper_variable, source_ref=source_ref), ] # The locals default is dependent on exec_mode, globals or locals. locals_default = ExpressionConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef(variable=globals_keeper_variable, source_ref=source_ref), right=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref, ), expression_no=ExpressionTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), expression_yes=makeExpressionBuiltinLocals(provider=provider, source_ref=source_ref), source_ref=source_ref, ) pre_statements = [ # First assign globals and locals temporary the values given. StatementAssignmentVariable(variable=globals_keeper_variable, source=globals_node, source_ref=source_ref), StatementAssignmentVariable(variable=locals_keeper_variable, source=locals_node, source_ref=source_ref), makeStatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef(variable=locals_keeper_variable, source_ref=source_ref), right=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref, ), yes_branch=StatementAssignmentVariable( variable=locals_keeper_variable, source=locals_default, source_ref=source_ref, ), no_branch=None, source_ref=source_ref, ), makeStatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), right=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref, ), yes_branch=StatementAssignmentVariable( variable=globals_keeper_variable, source=ExpressionBuiltinGlobals(source_ref=source_ref), source_ref=source_ref, ), no_branch=None, source_ref=source_ref, ), ] return ( ExpressionTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref if globals_node is None else globals_node.getSourceReference(), ), ExpressionTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref if locals_node is None else locals_node.getSourceReference(), ), makeStatementsSequence(pre_statements, False, source_ref), makeStatementsSequence(post_statements, False, source_ref), )
def buildExecNode(provider, node, source_ref): # "exec" statements, should only occur with Python2. # This is using many variables, due to the many details this is # dealing with. The locals and globals need to be dealt with in # temporary variables, and we need handling of indicators, so # that is just the complexity, pylint: disable=too-many-locals exec_globals = node.globals exec_locals = node.locals body = node.body # Handle exec(a,b,c) to be same as exec a, b, c if exec_locals is None and exec_globals is None and getKind( body) == "Tuple": parts = body.elts body = parts[0] if len(parts) > 1: exec_globals = parts[1] if len(parts) > 2: exec_locals = parts[2] else: return StatementRaiseException( exception_type=ExpressionBuiltinExceptionRef( exception_name="TypeError", source_ref=source_ref), exception_value=makeConstantRefNode( constant="""\ exec: arg 1 must be a string, file, or code object""", source_ref=source_ref, ), exception_trace=None, exception_cause=None, source_ref=source_ref, ) temp_scope = provider.allocateTempScope("exec") locals_value = buildNode(provider, exec_locals, source_ref, True) if locals_value is None: locals_value = ExpressionConstantNoneRef(source_ref=source_ref) globals_value = buildNode(provider, exec_globals, source_ref, True) if globals_value is None: globals_value = ExpressionConstantNoneRef(source_ref=source_ref) source_code = buildNode(provider, body, source_ref) source_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="exec_source") globals_keeper_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="globals") locals_keeper_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="locals") plain_indicator_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="plain") tried = ( # First evaluate the source code expressions. StatementAssignmentVariable(variable=source_variable, source=source_code, source_ref=source_ref), # Assign globals and locals temporary the values given, then fix it # up, taking note in the "plain" temporary variable, if it was an # "exec" statement with None arguments, in which case the copy back # will be necessary. StatementAssignmentVariable( variable=globals_keeper_variable, source=globals_value, source_ref=source_ref, ), StatementAssignmentVariable(variable=locals_keeper_variable, source=locals_value, source_ref=source_ref), StatementAssignmentVariable( variable=plain_indicator_variable, source=makeConstantRefNode(constant=False, source_ref=source_ref), source_ref=source_ref, ), makeStatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), right=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref, ), yes_branch=makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable=globals_keeper_variable, source=ExpressionBuiltinGlobals(source_ref=source_ref), source_ref=source_ref, ), makeStatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), right=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref, ), yes_branch=makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable=locals_keeper_variable, source=makeExpressionBuiltinLocals( provider=provider, source_ref=source_ref), source_ref=source_ref, ), StatementAssignmentVariable( variable=plain_indicator_variable, source=makeConstantRefNode(constant=True, source_ref=source_ref), source_ref=source_ref, ), ), no_branch=None, source_ref=source_ref, ), ), no_branch=makeStatementsSequenceFromStatements( makeStatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), right=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref, ), yes_branch=makeStatementsSequenceFromStatement( statement=StatementAssignmentVariable( variable=locals_keeper_variable, source=ExpressionTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), source_ref=source_ref, )), no_branch=None, source_ref=source_ref, )), source_ref=source_ref, ), makeTryFinallyStatement( provider=provider, tried=StatementExec( source_code=ExpressionTempVariableRef(variable=source_variable, source_ref=source_ref), globals_arg=ExpressionTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), locals_arg=ExpressionTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), source_ref=source_ref, ), final=makeStatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=plain_indicator_variable, source_ref=source_ref), right=makeConstantRefNode(constant=True, source_ref=source_ref), source_ref=source_ref, ), yes_branch=StatementLocalsDictSync( locals_arg=ExpressionTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), source_ref=source_ref, ), no_branch=None, source_ref=source_ref, ), source_ref=source_ref, ), ) final = ( StatementReleaseVariable(variable=source_variable, source_ref=source_ref), StatementReleaseVariable(variable=globals_keeper_variable, source_ref=source_ref), StatementReleaseVariable(variable=locals_keeper_variable, source_ref=source_ref), StatementReleaseVariable(variable=plain_indicator_variable, source_ref=source_ref), ) return makeTryFinallyStatement(provider=provider, tried=tried, final=final, source_ref=source_ref)
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=makeExpressionImportModuleNameHard(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 buildLambdaNode(provider, node, source_ref): # Many details to deal with, pylint: disable=too-many-locals assert getKind(node) == "Lambda" function_kind, flags = detectFunctionBodyKind(nodes=(node.body, )) outer_body, function_body, code_object = buildFunctionWithParsing( provider=provider, function_kind=function_kind, name="<lambda>", function_doc=None, flags=flags, node=node, source_ref=source_ref, ) if function_kind == "Function": code_body = function_body else: code_body = ExpressionGeneratorObjectBody( provider=function_body, name="<lambda>", code_object=code_object, flags=set(), source_ref=source_ref, ) code_body.qualname_provider = provider if function_kind == "Generator": function_body.setBody( makeStatementsSequenceFromStatement(statement=StatementReturn( expression=ExpressionMakeGeneratorObject( generator_ref=ExpressionFunctionRef( function_body=code_body, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ))) defaults = buildNodeList(provider, node.args.defaults, source_ref) kw_defaults = buildParameterKwDefaults(provider=provider, node=node, function_body=function_body, source_ref=source_ref) body = buildNode(provider=code_body, node=node.body, source_ref=source_ref) if function_kind == "Generator": if python_version < 270: tmp_return_value = code_body.allocateTempVariable( temp_scope=None, name="yield_return") statements = ( StatementAssignmentVariable(variable=tmp_return_value, source=body, source_ref=source_ref), makeStatementConditional( condition=ExpressionComparisonIsNOT( left=ExpressionTempVariableRef( variable=tmp_return_value, source_ref=source_ref), right=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref, ), yes_branch=StatementExpressionOnly( expression=ExpressionYield( expression=ExpressionTempVariableRef( variable=tmp_return_value, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), no_branch=None, source_ref=source_ref, ), ) body = makeTryFinallyStatement( provider=provider, tried=statements, final=StatementReleaseVariable(variable=tmp_return_value, source_ref=source_ref), source_ref=source_ref, ) else: body = StatementExpressionOnly(expression=body, source_ref=source_ref) else: body = StatementReturn(expression=body, source_ref=source_ref) if function_kind == "Generator": frame_class = StatementsFrameGenerator else: frame_class = StatementsFrameFunction body = frame_class( statements=mergeStatements((body, )), code_object=code_object, source_ref=body.getSourceReference(), ) body = makeStatementsSequenceFromStatement(statement=body) code_body.setBody(body) annotations = buildParameterAnnotations(provider, node, source_ref) return ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=outer_body, source_ref=source_ref), defaults=defaults, kw_defaults=kw_defaults, annotations=annotations, source_ref=source_ref, )
def buildParseTree(provider, ast_tree, 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 # Maybe one day, we do exec inlining again, that is what this is for, # then is_module won't be True, for now it always is. pushFutureSpec() if is_module: provider.setFutureSpec(getFutureSpec()) body, doc = extractDocFromBody(ast_tree) if is_module and is_main and python_version >= 0x360: provider.markAsNeedsAnnotationsDictionary() result = buildStatementsNode(provider=provider, nodes=body, source_ref=source_ref) # After building, we can verify that all future statements were where they # belong, namely at the start of the module. 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 not Options.hasPythonFlagNoSite(): statements.append( StatementExpressionOnly( expression=makeExpressionImportModuleFixed( module_name="site", source_ref=source_ref), source_ref=source_ref, )) for path_imported_name in getPthImportedPackages(): if isHardModuleWithoutSideEffect(path_imported_name): continue statements.append( StatementExpressionOnly( expression=makeExpressionImportModuleFixed( module_name=path_imported_name, source_ref=source_ref), source_ref=source_ref, )) statements.append( StatementAssignmentVariableName( provider=provider, variable_name="__doc__", source=makeConstantRefNode(constant=doc, source_ref=internal_source_ref, user_provided=True), source_ref=internal_source_ref, )) statements.append( StatementAssignmentVariableName( provider=provider, variable_name="__file__", source=ExpressionModuleAttributeFileRef( variable=provider.getVariableForReference("__file__"), source_ref=internal_source_ref, ), source_ref=internal_source_ref, )) if provider.isCompiledPythonPackage(): # This assigns "__path__" value. statements.append( createPathAssignment(provider, internal_source_ref)) statements.append( createImporterCacheAssignment(provider, internal_source_ref)) if python_version >= 0x340 and not is_main: statements += ( StatementAssignmentAttribute( expression=ExpressionModuleAttributeSpecRef( variable=provider.getVariableForReference("__spec__"), source_ref=internal_source_ref, ), attribute_name="origin", source=ExpressionModuleAttributeFileRef( variable=provider.getVariableForReference("__file__"), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), StatementAssignmentAttribute( expression=ExpressionModuleAttributeSpecRef( variable=provider.getVariableForReference("__spec__"), source_ref=internal_source_ref, ), attribute_name="has_location", source=makeConstantRefNode(True, internal_source_ref), source_ref=internal_source_ref, ), ) if provider.isCompiledPythonPackage(): statements.append( StatementAssignmentAttribute( expression=ExpressionModuleAttributeSpecRef( variable=provider.getVariableForReference( "__spec__"), source_ref=internal_source_ref, ), attribute_name="submodule_search_locations", source=ExpressionVariableNameRef( provider=provider, variable_name="__path__", source_ref=internal_source_ref, ), source_ref=internal_source_ref, )) if python_version >= 0x300: statements.append( StatementAssignmentVariableName( provider=provider, variable_name="__cached__", source=ExpressionConstantNoneRef( source_ref=internal_source_ref), source_ref=internal_source_ref, )) needs__initializing__ = (not provider.isMainModule() and 0x300 <= python_version < 0x340) if needs__initializing__: # Set "__initializing__" at the beginning to True statements.append( StatementAssignmentVariableName( provider=provider, 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( provider=provider, 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.subnode_statements) if needs__initializing__: # Set "__initializing__" at the end to False statements.append( StatementAssignmentVariableName( provider=provider, 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 buildExecNode(provider, node, source_ref): # "exec" statements, should only occur with Python2. # This is using many variables, due to the many details this is # dealing with. The locals and globals need to be dealt with in # temporary variables, and we need handling of indicators, so # that is just the complexity, pylint: disable=R0914 exec_globals = node.globals exec_locals = node.locals body = node.body orig_globals = exec_globals # Handle exec(a,b,c) to be same as exec a, b, c if exec_locals is None and exec_globals is None and \ getKind(body) == "Tuple": parts = body.elts body = parts[0] if len(parts) > 1: exec_globals = parts[1] if len(parts) > 2: exec_locals = parts[2] else: return StatementRaiseException( exception_type = ExpressionBuiltinExceptionRef( exception_name = "TypeError", source_ref = source_ref ), exception_value = makeConstantRefNode( constant = """\ exec: arg 1 must be a string, file, or code object""", source_ref = source_ref ), exception_trace = None, exception_cause = None, source_ref = source_ref ) if not provider.isCompiledPythonModule(): provider.markAsExecContaining() if orig_globals is None: provider.markAsUnqualifiedExecContaining(source_ref) temp_scope = provider.allocateTempScope("exec") locals_value = buildNode(provider, exec_locals, source_ref, True) if locals_value is None: locals_value = ExpressionConstantNoneRef( source_ref = source_ref ) globals_value = buildNode(provider, exec_globals, source_ref, True) if globals_value is None: globals_value = ExpressionConstantNoneRef( source_ref = source_ref ) source_code = buildNode(provider, body, source_ref) source_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "exec_source" ) globals_keeper_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "globals" ) locals_keeper_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "locals" ) plain_indicator_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "plain" ) tried = ( # First evaluate the source code expressions. StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = source_variable, source_ref = source_ref ), source = source_code, source_ref = source_ref ), # Assign globals and locals temporary the values given, then fix it # up, taking note in the "plain" temporary variable, if it was an # "exec" statement with None arguments, in which case the copy back # will be necessary. StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), source = globals_value, source_ref = source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref ), source = locals_value, source_ref = source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = plain_indicator_variable, source_ref = source_ref ), source = makeConstantRefNode( constant = False, source_ref = source_ref ), source_ref = source_ref ), StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), right = ExpressionConstantNoneRef( source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), source = ExpressionBuiltinGlobals( source_ref = source_ref ), source_ref = source_ref, ), StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref ), right = ExpressionConstantNoneRef( source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref ), source = _getLocalsClassNode(provider)( source_ref = source_ref ), source_ref = source_ref, ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = plain_indicator_variable, source_ref = source_ref ), source = makeConstantRefNode( constant = True, source_ref = source_ref ), source_ref = source_ref, ) ), no_branch = None, source_ref = source_ref ), ), no_branch = makeStatementsSequenceFromStatements( StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref ), right = ExpressionConstantNoneRef( source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( statement = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref ), source = ExpressionTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), source_ref = source_ref, ) ), no_branch = None, source_ref = source_ref ) ), source_ref = source_ref ), # Source needs some special treatment for not done for "eval", if it's a # file object, then must be read. StatementConditional( condition = ExpressionBuiltinIsinstance( instance = ExpressionTempVariableRef( variable = source_variable, source_ref = source_ref ), classes = ExpressionBuiltinAnonymousRef( builtin_name = "file", source_ref = source_ref, ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( statement = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = source_variable, source_ref = source_ref ), source = ExpressionCallEmpty( called = ExpressionAttributeLookup( source = ExpressionTempVariableRef( variable = source_variable, source_ref = source_ref ), attribute_name = "read", source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ) ), no_branch = None, source_ref = source_ref ), makeTryFinallyStatement( provider = provider, tried = StatementExec( source_code = ExpressionTempVariableRef( variable = source_variable, source_ref = source_ref ), globals_arg = ExpressionTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), locals_arg = ExpressionTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref ), source_ref = source_ref ), final = StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = plain_indicator_variable, source_ref = source_ref ), right = makeConstantRefNode( constant = True, source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( statement = StatementLocalsDictSync( locals_arg = ExpressionTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref, ), source_ref = source_ref.atInternal() ) ), no_branch = None, source_ref = source_ref ), source_ref = source_ref ) ) final = ( StatementReleaseVariable( variable = source_variable, source_ref = source_ref ), StatementReleaseVariable( variable = globals_keeper_variable, source_ref = source_ref ), StatementReleaseVariable( variable = locals_keeper_variable, source_ref = source_ref ), StatementReleaseVariable( variable = plain_indicator_variable, source_ref = source_ref ), ) return makeTryFinallyStatement( provider = provider, tried = tried, final = final, source_ref = source_ref )
def wrapEvalGlobalsAndLocals(provider, globals_node, locals_node, temp_scope, source_ref): """ Wrap the locals and globals arguments for "eval". This is called from the outside, and when the node tree already exists. """ globals_keeper_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "globals" ) locals_keeper_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "locals" ) if locals_node is None: locals_node = ExpressionConstantNoneRef( source_ref = source_ref ) if globals_node is None: globals_node = ExpressionConstantNoneRef( source_ref = source_ref ) post_statements = [] if provider.isExpressionClassBody(): post_statements.append( StatementLocalsDictSync( locals_arg = ExpressionTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref, ), source_ref = source_ref.atInternal() ) ) post_statements += [ StatementReleaseVariable( variable = globals_keeper_variable, source_ref = source_ref ), StatementReleaseVariable( variable = locals_keeper_variable, source_ref = source_ref ) ] # The locals default is dependent on exec_mode, globals or locals. locals_default = ExpressionConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), right = ExpressionConstantNoneRef( source_ref = source_ref ), source_ref = source_ref ), expression_no = ExpressionTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), expression_yes = _getLocalsClassNode(provider)( source_ref = source_ref ), source_ref = source_ref ) pre_statements = [ # First assign globals and locals temporary the values given. StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), source = globals_node, source_ref = source_ref, ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref ), source = locals_node, source_ref = source_ref, ), StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref ), right = ExpressionConstantNoneRef( source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref ), source = locals_default, source_ref = source_ref, ) ), no_branch = None, source_ref = source_ref ), StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), right = ExpressionConstantNoneRef( source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref ), source = ExpressionBuiltinGlobals( source_ref = source_ref ), source_ref = source_ref, ) ), no_branch = None, source_ref = source_ref ) ] return ( ExpressionTempVariableRef( variable = globals_keeper_variable, source_ref = source_ref if globals_node is None else globals_node.getSourceReference() ), ExpressionTempVariableRef( variable = locals_keeper_variable, source_ref = source_ref if locals_node is None else locals_node.getSourceReference() ), makeStatementsSequence(pre_statements, False, source_ref), makeStatementsSequence(post_statements, False, source_ref) )