def buildBoolOpNode(provider, node, source_ref): bool_op = getKind(node.op) if bool_op == "Or": # The "or" may be short circuit and is therefore not a plain operation. values = buildNodeList(provider, node.values, source_ref) for value in values[:-1]: value.setCompatibleSourceReference(values[-1].getSourceReference()) source_ref = values[-1].getSourceReference() return buildOrNode(values=values, source_ref=source_ref) elif bool_op == "And": # The "and" may be short circuit and is therefore not a plain operation. values = buildNodeList(provider, node.values, source_ref) for value in values[:-1]: value.setCompatibleSourceReference(values[-1].getSourceReference()) source_ref = values[-1].getSourceReference() return buildAndNode(values=values, source_ref=source_ref) elif bool_op == "Not": # The "not" is really only a unary operation and no special. return ExpressionOperationNOT(operand=buildNode( provider, node.operand, source_ref), source_ref=source_ref) else: assert False, bool_op
def makeConditionalStatement(condition, yes_branch, no_branch, source_ref): """ Create conditional statement, with yes_branch not being empty. May have to invert condition to achieve that. """ if yes_branch is None: condition = ExpressionOperationNOT( operand = condition, source_ref = condition.getSourceReference() ) yes_branch, no_branch = no_branch, yes_branch if not yes_branch.isStatementsSequence(): yes_branch = makeStatementsSequenceFromStatement(yes_branch) if no_branch is not None and not no_branch.isStatementsSequence(): no_branch = makeStatementsSequenceFromStatement(no_branch) return StatementConditional( condition = condition, yes_branch = yes_branch, no_branch = no_branch, source_ref = source_ref )
def makeValueComparisonReturn(left, right, comparator): yield StatementAssignmentVariable( variable=tmp_variable, source=_makeComparisonNode( left=left, right=right, comparator=comparator, source_ref=source_ref ), source_ref=source_ref, ) yield makeStatementConditional( condition=ExpressionOperationNOT( operand=ExpressionTempVariableRef( variable=tmp_variable, source_ref=source_ref ), source_ref=source_ref, ), yes_branch=StatementReturn( expression=ExpressionTempVariableRef( variable=tmp_variable, source_ref=source_ref ), source_ref=source_ref, ), no_branch=None, source_ref=source_ref, )
def buildAssertNode(provider, node, source_ref): # Build assert statements. These are re-formulated as described in the # developer manual too. They end up as conditional statement with raises of # AssertionError exceptions. # Underlying assumption: # # Assert x, y is the same as: # if not x: # raise AssertionError, y # Therefore assert statements are really just conditional statements with a # static raise contained. # # Starting with CPython2.7, it is, which means the creation of the exception # object is no more delayed: # if not x: # raise AssertionError( y ) if Utils.python_version < 270 or node.msg is None: raise_statement = StatementRaiseException( exception_type = ExpressionBuiltinExceptionRef( exception_name = "AssertionError", source_ref = source_ref ), exception_value = buildNode( provider, node.msg, source_ref, True ), exception_trace = None, exception_cause = None, source_ref = source_ref ) else: raise_statement = StatementRaiseException( exception_type = ExpressionBuiltinMakeException( exception_name = "AssertionError", args = ( buildNode( provider, node.msg, source_ref, True ), ), source_ref = source_ref ), exception_value = None, exception_trace = None, exception_cause = None, source_ref = source_ref ) return StatementConditional( condition = ExpressionOperationNOT( operand = buildNode( provider, node.test, source_ref ), source_ref = source_ref ), yes_branch = StatementsSequence( statements = ( raise_statement, ), source_ref = source_ref ), no_branch = None, source_ref = source_ref )
def buildAssertNode(provider, node, source_ref): # Build assert statements. These are re-formulated as described in the # developer manual too. They end up as conditional statement with raises of # AssertionError exceptions. # Underlying assumption: # # Assert x, y is the same as: # if not x: # raise AssertionError, y # Therefore assert statements are really just conditional statements with a # static raise contained. # exception_value = buildNode(provider, node.msg, source_ref, True) if "no_asserts" in getPythonFlags(): return None if exception_value is not None and python_version > 272: exception_value = ExpressionMakeTuple( elements = (exception_value,), source_ref = source_ref ) raise_statement = StatementRaiseException( exception_type = ExpressionBuiltinExceptionRef( exception_name = "AssertionError", source_ref = source_ref ), exception_value = exception_value, exception_trace = None, exception_cause = None, source_ref = source_ref ) return StatementConditional( condition = ExpressionOperationNOT( operand = buildNode(provider, node.test, source_ref), source_ref = source_ref ), yes_branch = StatementsSequence( statements = ( raise_statement, ), source_ref = source_ref ), no_branch = None, source_ref = source_ref )
def buildBoolOpNode(provider, node, source_ref): bool_op = getKind(node.op) if bool_op == "Or": # The "or" may be short circuit and is therefore not a plain operation return buildOrNode(provider=provider, values=buildNodeList(provider, node.values, source_ref), source_ref=source_ref) elif bool_op == "And": # The "and" may be short circuit and is therefore not a plain operation return buildAndNode(provider=provider, values=buildNodeList(provider, node.values, source_ref), source_ref=source_ref) elif bool_op == "Not": # The "not" is really only a unary operation and no special. return ExpressionOperationNOT(operand=buildNode( provider, node.operand, source_ref), source_ref=source_ref) else: assert False, bool_op
def wrapEvalBuiltin(source, globals_arg, locals_arg, source_ref): provider = node.getParentVariableProvider() outline_body = ExpressionOutlineBody( provider=node.getParentVariableProvider(), name="eval_call", source_ref=source_ref, ) globals_ref, locals_ref, tried, final = wrapEvalGlobalsAndLocals( provider=provider, globals_node=globals_arg, locals_node=locals_arg, temp_scope=outline_body.getOutlineTempScope(), source_ref=source_ref, ) # The wrapping should not relocate to the "source_ref". assert (globals_arg is None or globals_ref.getSourceReference() == globals_arg.getSourceReference()) assert (locals_arg is None or locals_ref.getSourceReference() == locals_arg.getSourceReference()) source_variable = outline_body.allocateTempVariable(temp_scope=None, name="source") final.setStatements(final.getStatements() + (StatementDelVariable( variable=source_variable, tolerant=True, source_ref=source_ref), )) strip_choice = makeConstantRefNode(constant=(" \t", ), source_ref=source_ref) if python_version >= 300: strip_choice = ExpressionConditional( condition=ExpressionComparisonIs( left=ExpressionBuiltinType1( value=ExpressionTempVariableRef( variable=source_variable, source_ref=source_ref), source_ref=source_ref, ), right=makeExpressionBuiltinRef(builtin_name="bytes", source_ref=source_ref), source_ref=source_ref, ), expression_yes=makeConstantRefNode(constant=(b" \t", ), source_ref=source_ref), expression_no=strip_choice, source_ref=source_ref, ) # Source needs some special treatment for eval, if it's a string, it # must be stripped. string_fixup = StatementAssignmentVariable( variable=source_variable, source=makeExpressionCall( called=ExpressionAttributeLookup( source=ExpressionTempVariableRef(variable=source_variable, source_ref=source_ref), attribute_name="strip", source_ref=source_ref, ), args=strip_choice, # This is a tuple kw=None, source_ref=source_ref, ), source_ref=source_ref, ) acceptable_builtin_types = [ ExpressionBuiltinAnonymousRef(builtin_name="code", source_ref=source_ref) ] if python_version >= 270: acceptable_builtin_types.append( makeExpressionBuiltinRef(builtin_name="memoryview", source_ref=source_ref)) statements = ( StatementAssignmentVariable(variable=source_variable, source=source, source_ref=source_ref), makeStatementConditional( condition=ExpressionOperationNOT( operand=ExpressionBuiltinIsinstance( instance=ExpressionTempVariableRef( variable=source_variable, source_ref=source_ref), classes=makeSequenceCreationOrConstant( sequence_kind="tuple", elements=acceptable_builtin_types, source_ref=source_ref, ), source_ref=source_ref, ), source_ref=source_ref, ), yes_branch=string_fixup, no_branch=None, source_ref=source_ref, ), StatementReturn( expression=ExpressionBuiltinEval( source_code=ExpressionTempVariableRef( variable=source_variable, source_ref=source_ref), globals_arg=globals_ref, locals_arg=locals_ref, source_ref=source_ref, ), source_ref=source_ref, ), ) tried = makeStatementsSequence(statements=(tried, ) + statements, allow_none=False, source_ref=source_ref) outline_body.setBody( makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement( provider=outline_body, tried=tried, final=final, source_ref=source_ref, ))) return outline_body
def buildWhileLoopNode(provider, node, source_ref): # The while loop is re-formulated according to developer manual. The # condition becomes an early condition to break the loop. The else block is # taken if a while loop exits normally, i.e. because of condition not being # true. We do this by introducing an indicator variable. else_block = buildStatementsNode( provider=provider, nodes=node.orelse if node.orelse else None, source_ref=source_ref, ) if else_block is not None: temp_scope = provider.allocateTempScope("while_loop") tmp_break_indicator = provider.allocateTempVariable( temp_scope=temp_scope, name="break_indicator" ) statements = ( StatementAssignmentVariable( variable=tmp_break_indicator, source=makeConstantRefNode(constant=True, source_ref=source_ref), source_ref=source_ref, ), StatementLoopBreak(source_ref=source_ref), ) else: statements = (StatementLoopBreak(source_ref=source_ref),) pushBuildContext("loop_body") loop_statements = buildStatementsNode( provider=provider, nodes=node.body, source_ref=source_ref ) popBuildContext() # The loop body contains a conditional statement at the start that breaks # the loop if it fails. loop_body = makeStatementsSequence( statements=( makeStatementConditional( condition=ExpressionOperationNOT( operand=buildNode(provider, node.test, source_ref), source_ref=source_ref, ), yes_branch=StatementsSequence( statements=statements, source_ref=source_ref ), no_branch=None, source_ref=source_ref, ), loop_statements, ), allow_none=True, source_ref=source_ref, ) loop_statement = StatementLoop(body=loop_body, source_ref=source_ref) if else_block is None: return loop_statement else: statements = ( StatementAssignmentVariable( variable=tmp_break_indicator, source=makeConstantRefNode(constant=False, source_ref=source_ref), source_ref=source_ref, ), loop_statement, makeStatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_break_indicator, source_ref=source_ref ), right=makeConstantRefNode(constant=True, source_ref=source_ref), source_ref=source_ref, ), yes_branch=else_block, no_branch=None, source_ref=source_ref, ), ) statements = ( makeTryFinallyStatement( provider=provider, tried=statements, final=StatementReleaseVariable( variable=tmp_break_indicator, source_ref=source_ref ), source_ref=source_ref, ), ) return StatementsSequence( statements=mergeStatements(statements, False), source_ref=source_ref )
def wrapEvalBuiltin(source, globals, locals, source_ref): provider = node.getParentVariableProvider() temp_scope = provider.allocateTempScope("eval") globals_ref, locals_ref, tried, final = wrapEvalGlobalsAndLocals( provider = provider, globals_node = globals, locals_node = locals, temp_scope = temp_scope, source_ref = source_ref ) # The wrapping should not relocate to the "source_ref". assert globals is None or \ globals_ref.getSourceReference() == globals.getSourceReference() assert locals is None or \ locals_ref.getSourceReference() == locals.getSourceReference() source_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "source" ) final.setStatements( final.getStatements() + ( StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = source_variable.makeReference( provider ), source_ref = source_ref ), tolerant = True, source_ref = source_ref ), ) ) strip_choice = ExpressionConstantRef( constant = (" \t",), source_ref = source_ref ) if python_version >= 300: strip_choice = ExpressionConditional( condition = ExpressionComparisonIs( left = ExpressionBuiltinType1( value = ExpressionTempVariableRef( variable = source_variable.makeReference( provider ), source_ref = source_ref ), source_ref = source_ref ), right = ExpressionBuiltinRef( builtin_name = "bytes", source_ref = source_ref ), source_ref = source_ref ), yes_expression = ExpressionConstantRef( constant = (b" \t",), source_ref = source_ref ), no_expression = strip_choice, source_ref = source_ref ) # Source needs some special treatment for eval, if it's a string, it # must be stripped. string_fixup = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = source_variable.makeReference( provider ), source_ref = source_ref ), source = ExpressionCallNoKeywords( called = ExpressionAttributeLookup( expression = ExpressionTempVariableRef( variable = source_variable.makeReference( provider ), source_ref = source_ref ), attribute_name = "strip", source_ref = source_ref ), args = strip_choice, source_ref = source_ref ), source_ref = source_ref ) ] statements = ( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = source_variable.makeReference( provider ), source_ref = source_ref ), source = source, source_ref = source_ref, ), StatementConditional( condition = ExpressionOperationNOT( operand = ExpressionBuiltinIsinstance( cls = ExpressionBuiltinAnonymousRef( builtin_name = "code", source_ref = source_ref, ), instance = ExpressionTempVariableRef( variable = source_variable.makeReference( provider ), source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ), yes_branch = StatementsSequence( statements = string_fixup, source_ref = source_ref ), no_branch = None, source_ref = source_ref ) ) tried.setStatements( tried.getStatements() + statements ) return ExpressionTryFinally( tried = tried, expression = ExpressionBuiltinEval( source_code = ExpressionTempVariableRef( variable = source_variable.makeReference( provider ), source_ref = source_ref ), globals_arg = globals_ref, locals_arg = locals_ref, source_ref = source_ref ), final = final, source_ref = source_ref )