def _buildInplaceAssignVariableNode(variable_ref, tmp_variable1, tmp_variable2, operator, expression, source_ref): assert variable_ref.isExpressionTargetVariableRef(), variable_ref # First assign the target value to a temporary variable. preserve_to_tmp = StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef(variable=tmp_variable1, source_ref=source_ref), source=ExpressionVariableRef( variable_name=variable_ref.getVariableName(), source_ref=source_ref), source_ref=source_ref) # Second assign the inplace result to a temporary variable inplace_to_tmp = StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source=ExpressionOperationBinaryInplace(operator=operator, left=ExpressionTempVariableRef( variable=tmp_variable1, source_ref=source_ref), right=expression, source_ref=source_ref), source_ref=source_ref) # Third, copy it over, if the reference values change, i.e. IsNot is true. copy_back_from_tmp = StatementConditional( condition=ExpressionComparisonIsNOT( left=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), right=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=StatementAssignmentVariable( variable_ref=variable_ref.makeCloneAt(source_ref), source=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref)), no_branch=None, source_ref=source_ref) return ( preserve_to_tmp, # making sure the above temporary variable is deleted in any case. makeTryFinallyStatement( tried=(inplace_to_tmp, copy_back_from_tmp), final=( StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_variable1, source_ref=source_ref), tolerant=False, source_ref=source_ref), StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_variable2, source_ref=source_ref), tolerant=True, source_ref=source_ref), ), source_ref=source_ref))
def buildOrNode(provider, values, source_ref): values = list(values) result = values[-1] del values[-1] temp_scope = None count = 1 while values: if temp_scope is None: temp_scope = provider.allocateTempScope(name="or") keeper_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="value_%d" % count) count += 1 tried = StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=keeper_variable, source_ref=source_ref), source=values[-1], source_ref=source_ref, ) result = makeTryFinallyExpression( tried=tried, final=None, expression=ExpressionConditional( condition=ExpressionTempVariableRef(variable=keeper_variable, source_ref=source_ref), yes_expression=ExpressionTempVariableRef( variable=keeper_variable, source_ref=source_ref), no_expression=makeTryFinallyExpression( expression=result, final=None, tried=StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=keeper_variable, source_ref=source_ref), tolerant=False, source_ref=source_ref, ), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref) wrapTryFinallyLater( result, StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=keeper_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref, )) del values[-1] return result
def _buildInplaceAssignSubscriptNode(subscribed, subscript, tmp_variable1, tmp_variable2, operator, expression, source_ref): # First assign the subscribed value to a temporary variable. preserve_to_tmp1 = StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef(variable=tmp_variable1, source_ref=source_ref), source=subscribed, source_ref=source_ref) # Second assign the subscript value to a temporary variable preserve_to_tmp2 = StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source=subscript, source_ref=source_ref) execute_in_place = StatementAssignmentSubscript( expression=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), subscript=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source=ExpressionOperationBinaryInplace( operator=operator, left=ExpressionSubscriptLookup( subscribed=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), subscript=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref), right=expression, source_ref=source_ref), source_ref=source_ref) # Note: No copy back is happening, for subscripts that is implied. return (preserve_to_tmp1, makeTryFinallyStatement( tried=( preserve_to_tmp2, execute_in_place, ), final=(StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_variable1, source_ref=source_ref), tolerant=False, source_ref=source_ref), StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_variable2, source_ref=source_ref), tolerant=True, source_ref=source_ref)), source_ref=source_ref))
def onLeaveNode(self, node): if node.isStatementAssignmentVariableName(): provider = node.getParentVariableProvider() variable = provider.getVariableForAssignment( variable_name=node.getVariableName()) node.replaceWith( StatementAssignmentVariable(variable=variable, source=node.subnode_source, source_ref=node.source_ref)) variable.addVariableUser(provider) elif node.isStatementDelVariableName(): provider = node.getParentVariableProvider() variable = provider.getVariableForAssignment( variable_name=node.getVariableName()) node.replaceWith( StatementDelVariable(variable=variable, tolerant=node.tolerant, source_ref=node.source_ref)) variable.addVariableUser(provider)
def onLeaveNode(self, node): if node.isStatementAssignmentVariableName(): variable_name = node.getVariableName() provider = node.provider # Classes always assign to locals dictionary except for closure # variables taken. if self._shouldUseLocalsDict(provider, variable_name): new_node = StatementLocalsDictOperationSet( locals_scope=provider.getFunctionLocalsScope(), variable_name=variable_name, value=node.subnode_source, source_ref=node.source_ref, ) else: variable = provider.getVariableForAssignment( variable_name=variable_name) new_node = StatementAssignmentVariable( variable=variable, source=node.subnode_source, source_ref=node.source_ref, ) variable.addVariableUser(provider) node.parent.replaceChild(node, new_node) del node.parent del node.provider elif node.isStatementDelVariableName(): variable_name = node.getVariableName() provider = node.provider if self._shouldUseLocalsDict(provider, variable_name): # Classes always assign to locals dictionary except for closure # variables taken. new_node = StatementLocalsDictOperationDel( locals_scope=provider.getFunctionLocalsScope(), variable_name=variable_name, tolerant=node.tolerant, source_ref=node.source_ref, ) else: variable = provider.getVariableForAssignment( variable_name=variable_name) new_node = StatementDelVariable( variable=variable, tolerant=node.tolerant, source_ref=node.source_ref, ) variable.addVariableUser(provider) parent = node.parent node.finalize() parent.replaceChild(node, new_node)
def makeTryExceptNoRaise(provider, temp_scope, tried, handling, no_raise, public_exc, source_ref): # This helper executes the core re-formulation of "no_raise" blocks, which # are the "else" blocks of "try"/"except" statements. In order to limit the # execution, we use an indicator variable instead, which will signal that # the tried block executed up to the end. And then we make the else block be # a conditional statement checking that. assert no_raise is not None tmp_handler_indicator_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="unhandled_indicator") statements = mergeStatements((StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_handler_indicator_variable.makeReference(provider), source_ref=source_ref.atInternal()), source=ExpressionConstantRef(constant=False, source_ref=source_ref), source_ref=no_raise.getSourceReference().atInternal()), handling), allow_none=True) handling = StatementsSequence(statements=statements, source_ref=source_ref) tried = (StatementTryExcept(tried=tried, handling=handling, public_exc=public_exc, source_ref=source_ref), StatementConditional(condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_handler_indicator_variable.makeReference( provider), source_ref=source_ref), right=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref), yes_branch=no_raise, no_branch=None, source_ref=source_ref)) final = StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_handler_indicator_variable.makeReference(provider), source_ref=source_ref.atInternal()), tolerant=False, source_ref=source_ref.atInternal()), return StatementsSequence(statements=(StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_handler_indicator_variable.makeReference(provider), source_ref=source_ref.atInternal()), source=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref.atInternal()), makeTryFinallyStatement( tried=tried, final=final, source_ref=source_ref)), source_ref=source_ref)
def buildDeleteStatementFromDecoded(kind, detail, source_ref): if kind in ("Name", "Name_Exception"): # Note: Name_Exception is a "del" for exception handlers that doesn't # insist on the variable being defined, user code may do it too, and # that will be fine, so make that tolerant. variable_ref = detail return StatementDelVariable( variable_ref = variable_ref, tolerant = kind == "Name_Exception", source_ref = source_ref ) elif kind == "Attribute": lookup_source, attribute_name = detail return StatementDelAttribute( expression = lookup_source, attribute_name = attribute_name, source_ref = source_ref ) elif kind == "Subscript": subscribed, subscript = detail return StatementDelSubscript( expression = subscribed, subscript = subscript, source_ref = source_ref ) elif kind == "Slice": lookup_source, lower, upper = detail return StatementDelSlice( expression = lookup_source, lower = lower, upper = upper, source_ref = source_ref ) elif kind == "Tuple": result = [] for sub_node in detail: result.append( buildDeleteStatementFromDecoded( kind = sub_node[0], detail = sub_node[1], source_ref = source_ref ) ) return makeStatementsSequenceOrStatement( statements = result, source_ref = source_ref ) else: assert False, ( kind, detail, source_ref )
def buildAssignNode(provider, node, source_ref): assert len(node.targets) >= 1, source_ref # Evaluate the right hand side first, so it can get names provided # before the left hand side exists. source = buildNode(provider, node.value, source_ref) if len(node.targets) == 1: # Simple assignment case, one source, one target. return buildAssignmentStatements(provider=provider, node=node.targets[0], source=source, source_ref=source_ref) else: # Complex assignment case, one source, but multiple targets. We keep the # source in a temporary variable, and then assign from it multiple # times. temp_scope = provider.allocateTempScope("assign_unpack") tmp_source = provider.allocateTempVariable(temp_scope=temp_scope, name="assign_source") statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_source.makeReference(provider), source_ref=source_ref), source=source, source_ref=source_ref) ] for target in node.targets: statements.append( buildAssignmentStatements( provider=provider, node=target, source=ExpressionTempVariableRef( variable=tmp_source.makeReference(provider), source_ref=source_ref), source_ref=source_ref)) statements.append( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_source.makeReference(provider), source_ref=source_ref), tolerant=False, source_ref=source_ref)) return StatementsSequence(statements=statements, source_ref=source_ref)
def onLeaveNode(self, node): if node.isStatementAssignmentVariableName(): variable_name = node.getVariableName() provider = node.provider # Classes always assign to locals dictionary except for closure # variables taken. if self._shouldUseLocalsDict(provider, variable_name): node.replaceWith( StatementLocalsDictOperationSet( locals_scope=provider.getLocalsScope(), variable_name=variable_name, value=node.subnode_source, source_ref=node.source_ref)) else: variable = provider.getVariableForAssignment( variable_name=variable_name) node.replaceWith( StatementAssignmentVariable(variable=variable, source=node.subnode_source, source_ref=node.source_ref)) variable.addVariableUser(provider) elif node.isStatementDelVariableName(): variable_name = node.getVariableName() provider = node.provider if self._shouldUseLocalsDict(provider, variable_name): # Classes always assign to locals dictionary node.replaceWith( StatementLocalsDictOperationDel( locals_scope=provider.getLocalsScope(), variable_name=variable_name, source_ref=node.source_ref)) else: variable = provider.getVariableForAssignment( variable_name=variable_name) node.replaceWith( StatementDelVariable(variable=variable, tolerant=node.tolerant, source_ref=node.source_ref)) variable.addVariableUser(provider)
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 )
def wrapEvalGlobalsAndLocals(provider, globals_node, locals_node, temp_scope, source_ref): """ Wrap the locals and globals arguments for eval and exec. 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 = ExpressionConstantRef(constant=None, source_ref=source_ref) if globals_node is None: globals_node = ExpressionConstantRef(constant=None, source_ref=source_ref) post_statements = [ StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=globals_keeper_variable.makeReference(provider), source_ref=globals_node.getSourceReference()), tolerant=False, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=locals_keeper_variable.makeReference(provider), source_ref=locals_node.getSourceReference()), tolerant=False, source_ref=source_ref) ] # The locals default is dependant on exec_mode, globals or locals. locals_default = ExpressionConditional( condition=ExpressionComparisonIs(left=ExpressionTempVariableRef( variable=globals_keeper_variable.makeReference(provider), source_ref=source_ref), right=ExpressionConstantRef( constant=None, source_ref=source_ref), source_ref=source_ref), no_expression=ExpressionTempVariableRef( variable=globals_keeper_variable.makeReference(provider), source_ref=source_ref), yes_expression=ExpressionBuiltinLocals(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.makeReference(provider), source_ref=source_ref), source=globals_node, source_ref=source_ref, ), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=locals_keeper_variable.makeReference(provider), source_ref=source_ref), source=locals_node, source_ref=source_ref, ), StatementConditional( condition=ExpressionComparisonIs(left=ExpressionTempVariableRef( variable=locals_keeper_variable.makeReference(provider), source_ref=source_ref), right=ExpressionConstantRef( constant=None, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=locals_keeper_variable.makeReference( provider), 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.makeReference(provider), source_ref=source_ref), right=ExpressionConstantRef( constant=None, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=globals_keeper_variable.makeReference( provider), 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.makeReference(provider), source_ref=source_ref if globals_node is None else globals_node.getSourceReference()), ExpressionTempVariableRef( variable=locals_keeper_variable.makeReference(provider), 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. 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=ExpressionConstantRef(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 provider.isExpressionFunctionBody(): provider.markAsExecContaining() if orig_globals is None: provider.markAsUnqualifiedExecContaining(source_ref) temp_scope = provider.allocateTempScope("exec") globals_ref, locals_ref, tried, final = wrapEvalGlobalsAndLocals( provider=provider, globals_node=buildNode(provider, exec_globals, source_ref, True), locals_node=buildNode(provider, exec_locals, source_ref, True), temp_scope=temp_scope, source_ref=source_ref) source_code = buildNode(provider, body, source_ref) source_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="source") # Source needs some special treatment for eval, if it's a string, it # must be stripped. file_fixup = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=source_variable.makeReference(provider), source_ref=source_ref), source=ExpressionCallEmpty(called=ExpressionAttributeLookup( expression=ExpressionTempVariableRef( variable=source_variable.makeReference(provider), source_ref=source_ref), attribute_name="read", source_ref=source_ref), source_ref=source_ref), source_ref=source_ref) ] statements = (StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=source_variable.makeReference(provider), source_ref=source_ref), source=source_code, source_ref=source_ref, ), StatementConditional(condition=ExpressionBuiltinIsinstance( cls=ExpressionBuiltinAnonymousRef( builtin_name="file", source_ref=source_ref, ), instance=ExpressionTempVariableRef( variable=source_variable.makeReference(provider), source_ref=source_ref), source_ref=source_ref), yes_branch=StatementsSequence( statements=file_fixup, source_ref=source_ref), no_branch=None, source_ref=source_ref), StatementExec(source_code=ExpressionTempVariableRef( variable=source_variable.makeReference(provider), source_ref=source_ref), globals_arg=globals_ref, locals_arg=locals_ref, source_ref=source_ref)) tried.setChild("statements", tried.getStatements() + statements) final.setStatements(final.getStatements() + ( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=source_variable.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref), )) return StatementTryFinally(tried=tried, final=final, public_exc=False, source_ref=source_ref)
def buildAssignmentStatementsFromDecoded(provider, kind, detail, source, source_ref): # This is using many variable names on purpose, so as to give names to the # unpacked detail values, and has many branches due to the many cases # dealt with, pylint: disable=too-many-branches,too-many-locals,too-many-statements if kind == "Name": return StatementAssignmentVariableName( provider=provider, variable_name=detail, source=source, source_ref=source_ref, ) elif kind == "Attribute": lookup_source, attribute_name = detail return StatementAssignmentAttribute( expression=lookup_source, attribute_name=mangleName(attribute_name, provider), source=source, source_ref=source_ref, ) elif kind == "Subscript": subscribed, subscript = detail return StatementAssignmentSubscript( expression=subscribed, subscript=subscript, source=source, source_ref=source_ref, ) elif kind == "Slice": lookup_source, lower, upper = detail # For Python3 there is no slicing operation, this is always done # with subscript using a slice object. For Python2, it is only done # if no "step" is provided. use_sliceobj = python_version >= 300 if use_sliceobj: return StatementAssignmentSubscript( expression=lookup_source, source=source, subscript=makeExpressionBuiltinSlice(start=lower, stop=upper, step=None, source_ref=source_ref), source_ref=source_ref, ) else: return StatementAssignmentSlice( expression=lookup_source, lower=lower, upper=upper, source=source, source_ref=source_ref, ) elif kind == "Tuple": temp_scope = provider.allocateTempScope("tuple_unpack") source_iter_var = provider.allocateTempVariable(temp_scope=temp_scope, name="source_iter") element_vars = [ provider.allocateTempVariable(temp_scope=temp_scope, name="element_%d" % (element_index + 1)) for element_index in range(len(detail)) ] starred_list_var = None starred_index = None statements = [] for element_index, element in enumerate(detail): if element[0] == "Starred": if starred_index is not None: raiseSyntaxError( "two starred expressions in assignment" if python_version < 390 else "multiple starred expressions in assignment", source_ref.atColumnNumber(0), ) starred_index = element_index for element_index, element in enumerate(detail): element_var = element_vars[element_index] if starred_list_var is not None: statements.insert( starred_index + 1, StatementAssignmentVariable( variable=element_var, source=ExpressionListOperationPop( list_arg=ExpressionTempVariableRef( variable=starred_list_var, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), ) elif element[0] != "Starred": statements.append( StatementAssignmentVariable( variable=element_var, source=ExpressionSpecialUnpack( value=ExpressionTempVariableRef( variable=source_iter_var, source_ref=source_ref), count=element_index + 1, expected=starred_index or len(detail), starred=starred_index is not None, source_ref=source_ref, ), source_ref=source_ref, )) else: assert starred_index == element_index starred_list_var = element_var statements.append( StatementAssignmentVariable( variable=element_var, source=ExpressionBuiltinList( value=ExpressionTempVariableRef( variable=source_iter_var, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, )) if starred_list_var is None: statements.append( StatementSpecialUnpackCheck( iterator=ExpressionTempVariableRef( variable=source_iter_var, source_ref=source_ref), count=len(detail), source_ref=source_ref, )) else: statements.insert( starred_index + 1, makeStatementConditional( condition=makeComparisonExpression( comparator="Lt", left=ExpressionBuiltinLen( value=ExpressionTempVariableRef( variable=starred_list_var, source_ref=source_ref), source_ref=source_ref, ), right=makeConstantRefNode( constant=len(statements) - starred_index - 1, source_ref=source_ref, ), source_ref=source_ref, ), yes_branch=makeRaiseExceptionExpressionFromTemplate( exception_type="ValueError", template="""\ not enough values to unpack (expected at least %d, got %%d)""" % (len(statements) - 1), template_args=makeBinaryOperationNode( operator="Add", left=ExpressionBuiltinLen( value=ExpressionTempVariableRef( variable=starred_list_var, source_ref=source_ref), source_ref=source_ref, ), right=makeConstantRefNode(constant=starred_index, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ).asStatement(), no_branch=None, source_ref=source_ref, ), ) if python_version >= 370: iter_creation_class = ExpressionBuiltinIterForUnpack else: iter_creation_class = ExpressionBuiltinIter1 statements = [ StatementAssignmentVariable( variable=source_iter_var, source=iter_creation_class(value=source, source_ref=source_ref), source_ref=source_ref, ), makeTryFinallyStatement( provider=provider, tried=statements, final=(StatementReleaseVariable(variable=source_iter_var, source_ref=source_ref), ), source_ref=source_ref, ), ] # When all is done, copy over to the actual assignment targets, starred # or not makes no difference here anymore. for element_index, element in enumerate(detail): if element[0] == "Starred": element = element[1] element_var = element_vars[element_index] statements.append( buildAssignmentStatementsFromDecoded( provider=provider, kind=element[0], detail=element[1], source=ExpressionTempVariableRef(variable=element_var, source_ref=source_ref), source_ref=source_ref, )) # Need to release temporary variables right after successful # usage. statements.append( StatementDelVariable(variable=element_var, tolerant=True, source_ref=source_ref)) final_statements = [] for element_var in element_vars: final_statements.append( StatementReleaseVariable(variable=element_var, source_ref=source_ref)) return makeTryFinallyStatement( provider=provider, tried=statements, final=final_statements, source_ref=source_ref, ) elif kind == "Starred": raiseSyntaxError( "starred assignment target must be in a list or tuple", source_ref.atColumnNumber(0), ) else: assert False, (kind, source_ref, detail)
def getDictUnpackingHelper(): helper_name = "_unpack_dict" result = ExpressionFunctionBody( provider = getInternalModule(), name = helper_name, doc = None, parameters = ParameterSpec( ps_name = helper_name, ps_normal_args = (), ps_list_star_arg = "args", ps_dict_star_arg = None, ps_default_count = 0, ps_kw_only_args = () ), flags = set(), source_ref = internal_source_ref ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "dict") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "keys") loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried = StatementAssignmentVariable( variable = tmp_item_variable, source = ExpressionBuiltinNext1( value = ExpressionTempVariableRef( variable = tmp_iter_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), exception_name = "StopIteration", handler_body = StatementLoopBreak( source_ref = internal_source_ref ), source_ref = internal_source_ref ), makeTryExceptSingleHandlerNode( tried = StatementDictOperationUpdate( dict_arg = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), value = ExpressionTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), exception_name = "AttributeError", handler_body = StatementRaiseException( exception_type = ExpressionBuiltinMakeException( exception_name = "TypeError", args = ( makeBinaryOperationNode( operator = "Mod", left = makeConstantRefNode( constant = """\ '%s' object is not a mapping""", source_ref = internal_source_ref, user_provided = True ), right = ExpressionMakeTuple( elements = ( ExpressionAttributeLookup( source = ExpressionBuiltinType1( value = ExpressionTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), attribute_name = "__name__", source_ref = internal_source_ref ), ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), ), source_ref = internal_source_ref ), exception_value = None, exception_trace = None, exception_cause = None, source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) args_variable = result.getVariableForAssignment( variable_name = "args" ) final = ( StatementReleaseVariable( variable = tmp_result_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_iter_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_item_variable, source_ref = internal_source_ref ), # We get handed our args responsibility. StatementDelVariable( variable = args_variable, tolerant = False, source_ref = internal_source_ref ) ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable = tmp_iter_variable, source = ExpressionBuiltinIter1( value = ExpressionVariableRef( variable = args_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementAssignmentVariable( variable = tmp_result_variable, source = makeConstantRefNode( constant = {}, source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementLoop( body = loop_body, source_ref = internal_source_ref ), StatementReturn( expression = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) result.setBody( makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider = result, tried = tried, final = final, source_ref = internal_source_ref ) ) ) return result
def buildListContractionNode(provider, node, source_ref): # List contractions are dealt with by general code. if Utils.python_version < 300: temp_scope = provider.allocateTempScope("listcontr") outer_iter_var = provider.allocateTempVariable(temp_scope=temp_scope, name="listcontr_iter") outer_iter_ref = ExpressionTempVariableRef( variable=outer_iter_var.makeReference(provider), source_ref=source_ref) container_tmp = provider.allocateTempVariable(temp_scope=temp_scope, name="listcontr_result") statements, del_statements = _buildContractionBodyNode( provider=provider, node=node, emit_class=ExpressionListOperationAppend, start_value=ExpressionConstantRef(constant=[], source_ref=source_ref), outer_iter_ref=outer_iter_ref, container_tmp=container_tmp, temp_scope=temp_scope, assign_provider=True, source_ref=source_ref, function_body=provider) statements.insert( 0, StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=outer_iter_var.makeReference(provider), source_ref=source_ref), source=ExpressionBuiltinIter1(value=buildNode( provider=provider, node=node.generators[0].iter, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref)) result = makeTryFinallyExpression(expression=ExpressionTempVariableRef( variable=container_tmp.makeReference(provider), source_ref=source_ref), tried=statements, final=del_statements, source_ref=source_ref) final = StatementsSequence(statements=( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=container_tmp.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=outer_iter_var.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref), ), source_ref=source_ref) wrapTryFinallyLater(node=result, final=final) return result return _buildContractionNode( provider=provider, node=node, name="<listcontraction>", emit_class=ExpressionListOperationAppend, start_value=ExpressionConstantRef(constant=[], source_ref=source_ref), # Note: For Python3, the list contractions no longer assign to the outer # scope. assign_provider=Utils.python_version < 300, source_ref=source_ref)
def onLeaveNode(self, node): if node.isStatementAssignmentVariableName(): variable_name = node.getVariableName() provider = node.provider # Classes always assign to locals dictionary except for closure # variables taken. if self._shouldUseLocalsDict(provider, variable_name): if node.subnode_source.isExpressionOperationInplace(): temp_scope = provider.allocateTempScope("class_inplace") tmp_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="value" ) statements = mergeStatements( statements=( StatementAssignmentVariable( variable=tmp_variable, source=node.subnode_source.getLeft(), source_ref=node.source_ref, ), makeTryFinallyStatement( provider=provider, tried=( StatementAssignmentVariable( variable=tmp_variable, source=makeExpressionOperationBinaryInplace( left=ExpressionTempVariableRef( variable=tmp_variable, source_ref=node.source_ref, ), right=node.subnode_source.getRight(), operator=node.subnode_source.getOperator(), source_ref=node.source_ref, ), source_ref=node.source_ref, ), StatementLocalsDictOperationSet( locals_scope=provider.getLocalsScope(), variable_name=variable_name, value=ExpressionTempVariableRef( variable=tmp_variable, source_ref=node.source_ref, ), source_ref=node.source_ref, ), ), final=StatementReleaseVariable( variable=tmp_variable, source_ref=node.source_ref ), source_ref=node.source_ref, ), ) ) node.parent.replaceStatement(node, statements) else: new_node = StatementLocalsDictOperationSet( locals_scope=provider.getLocalsScope(), variable_name=variable_name, value=node.subnode_source, source_ref=node.source_ref, ) node.parent.replaceChild(node, new_node) else: variable = provider.getVariableForAssignment( variable_name=variable_name ) new_node = StatementAssignmentVariable( variable=variable, source=node.subnode_source, source_ref=node.source_ref, ) variable.addVariableUser(provider) node.parent.replaceChild(node, new_node) del node.parent del node.provider elif node.isStatementDelVariableName(): variable_name = node.getVariableName() provider = node.provider if self._shouldUseLocalsDict(provider, variable_name): # Classes always assign to locals dictionary except for closure # variables taken. new_node = StatementLocalsDictOperationDel( locals_scope=provider.getLocalsScope(), variable_name=variable_name, tolerant=node.tolerant, source_ref=node.source_ref, ) else: variable = provider.getVariableForAssignment( variable_name=variable_name ) new_node = StatementDelVariable( variable=variable, tolerant=node.tolerant, source_ref=node.source_ref, ) variable.addVariableUser(provider) parent = node.parent node.finalize() parent.replaceChild(node, new_node)
def _buildClassNode2(provider, node, source_ref): class_statements, class_doc = extractDocFromBody(node) # This function is the Python2 special case with special re-formulation as # according to developer manual. function_body = ExpressionFunctionBody( provider = provider, is_class = True, parameters = make_class_parameters, name = node.name, doc = class_doc, source_ref = source_ref ) body = buildStatementsNode( provider = function_body, nodes = class_statements, frame = True, source_ref = source_ref ) if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref.atInternal() # The class body is basically a function that implicitly, at the end # returns its locals and cannot have other return statements contained, and # starts out with a variables "__module__" and potentially "__doc__" set. statements = [ StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = "__module__", source_ref = source_ref ), source = ExpressionConstantRef( constant = provider.getParentModule().getFullName(), source_ref = source_ref, user_provided = True ), source_ref = source_ref.atInternal() ) ] if class_doc is not None: statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = "__doc__", source_ref = source_ref ), source = ExpressionConstantRef( constant = class_doc, source_ref = source_ref, user_provided = True ), source_ref = source_ref.atInternal() ) ) statements += [ body, StatementReturn( expression = ExpressionBuiltinLocals( source_ref = source_ref ), source_ref = source_ref.atInternal() ) ] body = makeStatementsSequence( statements = statements, allow_none = True, source_ref = source_ref ) # The class body is basically a function that implicitly, at the end # returns its locals and cannot have other return statements contained. function_body.setBody(body) temp_scope = provider.allocateTempScope("class_creation") tmp_bases = provider.allocateTempVariable(temp_scope, "bases") tmp_class_dict = provider.allocateTempVariable(temp_scope, "class_dict") tmp_metaclass = provider.allocateTempVariable(temp_scope, "metaclass") tmp_class = provider.allocateTempVariable(temp_scope, "class") statements = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_bases, source_ref = source_ref ), source = makeSequenceCreationOrConstant( sequence_kind = "tuple", elements = buildNodeList( provider, node.bases, source_ref ), source_ref = source_ref ), source_ref = source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_class_dict, source_ref = source_ref ), source = ExpressionFunctionCall( function = ExpressionFunctionCreation( function_ref = ExpressionFunctionRef( function_body = function_body, source_ref = source_ref ), defaults = (), kw_defaults = None, annotations = None, source_ref = source_ref ), values = (), source_ref = source_ref ), source_ref = source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_metaclass, source_ref = source_ref ), source = ExpressionConditional( condition = ExpressionComparison( comparator = "In", left = ExpressionConstantRef( constant = "__metaclass__", source_ref = source_ref, user_provided = True ), right = ExpressionTempVariableRef( variable = tmp_class_dict, source_ref = source_ref ), source_ref = source_ref ), yes_expression = ExpressionDictOperationGet( dicte = ExpressionTempVariableRef( variable = tmp_class_dict, source_ref = source_ref ), key = ExpressionConstantRef( constant = "__metaclass__", source_ref = source_ref, user_provided = True ), source_ref = source_ref ), no_expression = ExpressionSelectMetaclass( metaclass = None, bases = ExpressionTempVariableRef( variable = tmp_bases, source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_class, source_ref = source_ref ), source = ExpressionCallNoKeywords( called = ExpressionTempVariableRef( variable = tmp_metaclass, source_ref = source_ref ), args = ExpressionMakeTuple( elements = ( ExpressionConstantRef( constant = node.name, source_ref = source_ref, user_provided = True ), ExpressionTempVariableRef( variable = tmp_bases, source_ref = source_ref ), ExpressionTempVariableRef( variable = tmp_class_dict, source_ref = source_ref ) ), source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ), ] for decorator in buildNodeList( provider, reversed(node.decorator_list), source_ref ): statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_class, source_ref = source_ref ), source = ExpressionCallNoKeywords( called = decorator, args = ExpressionMakeTuple( elements = ( ExpressionTempVariableRef( variable = tmp_class, source_ref = source_ref ), ), source_ref = source_ref ), source_ref = decorator.getSourceReference() ), source_ref = decorator.getSourceReference() ) ) statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = node.name, source_ref = source_ref ), source = ExpressionTempVariableRef( variable = tmp_class, source_ref = source_ref ), source_ref = source_ref ) ) final = ( StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_class, source_ref = source_ref ), tolerant = True, source_ref = source_ref ), StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_bases, source_ref = source_ref ), tolerant = True, source_ref = source_ref ), StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_class_dict, source_ref = source_ref ), tolerant = True, source_ref = source_ref ), StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_metaclass, source_ref = source_ref ), tolerant = True, source_ref = source_ref ) ) return makeTryFinallyStatement( tried = statements, final = final, source_ref = source_ref )
def _buildContractionNode(provider, node, name, emit_class, start_value, assign_provider, source_ref): # The contraction nodes are reformulated to function bodies, with loops as # described in the developer manual. They use a lot of temporary names, # nested blocks, etc. and so a lot of variable names. There is no good way # around that, and we deal with many cases, due to having generator # expressions sharing this code, pylint: disable=R0912,R0914 # Note: The assign_provider is only to cover Python2 list contractions, # assigning one of the loop variables to the outside scope. assert provider.isParentVariableProvider(), provider function_body = ExpressionFunctionBody( provider=provider, name=name, doc=None, parameters=make_contraction_parameters, source_ref=source_ref) if start_value is not None: container_tmp = function_body.allocateTempVariable(None, "result") statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), source=start_value, source_ref=source_ref.atInternal()) ] else: statements = [] if hasattr(node, "elt"): if start_value is not None: current_body = emit_class(ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionYield function_body.markAsGenerator() current_body = emit_class(buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionDictOperationSet current_body = emit_class(ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), key=buildNode( provider=function_body, node=node.key, source_ref=source_ref, ), value=buildNode( provider=function_body, node=node.value, source_ref=source_ref, ), source_ref=source_ref) current_body = StatementExpressionOnly(expression=current_body, source_ref=source_ref) for count, qual in enumerate(reversed(node.generators)): tmp_iter_variable = function_body.allocateTempVariable( temp_scope=None, name="contraction_iter_%d" % count) tmp_value_variable = function_body.allocateTempVariable( temp_scope=None, name="iter_value_%d" % count) # The first iterated value is to be calculated outside of the function # and will be given as a parameter "_iterated", the others are built # inside the function. if qual is node.generators[0]: value_iterator = ExpressionVariableRef(variable_name="__iterator", source_ref=source_ref) else: value_iterator = ExpressionBuiltinIter1(value=buildNode( provider=function_body, node=qual.iter, source_ref=source_ref), source_ref=source_ref) # First create the iterator and store it, next should be loop body nested_statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable.makeReference(function_body), source_ref=source_ref), source=value_iterator, source_ref=source_ref) ] loop_statements = [ makeTryExceptSingleHandlerNode( tried=makeStatementsSequenceFromStatement( statement=StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_value_variable.makeReference( function_body), source_ref=source_ref), source=ExpressionBuiltinNext1( value=ExpressionTempVariableRef( variable=tmp_iter_variable.makeReference( function_body), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref)), exception_name="StopIteration", handler_body=makeStatementsSequenceFromStatement( statement=StatementBreakLoop( source_ref=source_ref.atInternal())), source_ref=source_ref), buildAssignmentStatements( provider=provider if assign_provider else function_body, temp_provider=function_body, node=qual.target, source=ExpressionTempVariableRef( variable=tmp_value_variable.makeReference(function_body), source_ref=source_ref), source_ref=source_ref) ] conditions = buildNodeList(provider=function_body, nodes=qual.ifs, source_ref=source_ref) if len(conditions) == 1: loop_statements.append( StatementConditional( condition=conditions[0], yes_branch=makeStatementsSequenceFromStatement( statement=current_body), no_branch=None, source_ref=source_ref)) elif len(conditions) > 1: loop_statements.append( StatementConditional( condition=buildAndNode(provider=function_body, values=conditions, source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=current_body), no_branch=None, source_ref=source_ref)) else: loop_statements.append(current_body) nested_statements.append( StatementLoop(body=StatementsSequence( statements=mergeStatements(loop_statements), source_ref=source_ref), source_ref=source_ref)) nested_statements.append( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable.makeReference(function_body), source_ref=source_ref), tolerant=False, source_ref=source_ref)) current_body = StatementsSequence(statements=nested_statements, source_ref=source_ref) statements.append(current_body) if start_value is not None: statements.append( StatementReturn(expression=ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), source_ref=source_ref)) function_body.setBody( StatementsFrame(statements=mergeStatements(statements), guard_mode="pass_through" if emit_class is not ExpressionYield else "generator", var_names=(), arg_count=0, kw_only_count=0, has_starlist=False, has_stardict=False, code_name="contraction", source_ref=source_ref)) return ExpressionFunctionCall(function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=function_body, source_ref=source_ref), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(ExpressionBuiltinIter1( value=buildNode( provider=provider, node=node.generators[0].iter, source_ref=source_ref), source_ref=source_ref), ), source_ref=source_ref)
def __init__(self, parent, function_body): assert function_body.isExpressionFunctionBody(), function_body CollectionStartpointMixin.__init__(self) ConstraintCollectionBase.__init__(self, parent=parent) VariableUsageTrackingMixin.__init__(self) self.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 self.setupVariableTraces(function_body) if statements_sequence is not None: result = statements_sequence.computeStatementsSequence( constraint_collection=self) if result is not statements_sequence: function_body.setBody(result) # TODO: Should become trace based as well. self.setIndications() self.makeVariableTraceOptimizations(function_body) if not Options.isExperimental() or self.removes_knowledge: return # self.dumpTrace() # Cannot mess with locals yet. if self.unclear_locals: return # Trace based optimization goes here: for variable_trace in self.variable_traces.values(): variable = variable_trace.getVariable() # print variable if variable.isLocalVariable() and not variable.isShared(): if variable_trace.isAssignTrace(): assign_node = variable_trace.getAssignNode() if not assign_node.getAssignSource().mayHaveSideEffects(): if not variable_trace.getPotentialUsages() and \ not variable_trace.isEscaped(): assign_node.parent.replaceWith( StatementDelVariable(variable_ref=assign_node, tolerant=True, source_ref=assign_node. getSourceReference())) for release in variable_trace.releases: if release.isStatementDelVariable(): release.replaceWith(None) self.signalChange( "new_statements", assign_node.parent.getSourceReference(), "Removed assignment without effect.") elif variable_trace.isMergeTrace(): # print variable_trace if not variable_trace.getDefiniteUsages() and \ not variable_trace.isEscaped() and \ not variable_trace.releases: pass
def _buildInplaceAssignSliceNode(provider, lookup_source, lower, upper, tmp_variable1, tmp_variable2, tmp_variable3, operator, expression, source_ref): # First assign the target value, lower and upper to temporary variables. copy_to_tmp = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable1.makeReference(provider), source_ref = source_ref ), source = lookup_source, source_ref = source_ref ) final_statements = [ StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable1.makeReference(provider), source_ref = source_ref ), tolerant = False, source_ref = source_ref ) ] statements = [] if lower is not None: statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable2.makeReference(provider), source_ref = source_ref ), source = lower, source_ref = source_ref ) ) final_statements.append( StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable2.makeReference(provider), source_ref = source_ref ), tolerant = True, source_ref = source_ref ) ) lower_ref1 = ExpressionTempVariableRef( variable = tmp_variable2.makeReference(provider), source_ref = source_ref ) lower_ref2 = ExpressionTempVariableRef( variable = tmp_variable2.makeReference(provider), source_ref = source_ref ) else: assert tmp_variable2 is None lower_ref1 = lower_ref2 = None if upper is not None: statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable3.makeReference( provider ), source_ref = source_ref ), source = upper, source_ref = source_ref ) ) final_statements.append( StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable3.makeReference(provider), source_ref = source_ref ), tolerant = True, source_ref = source_ref ) ) upper_ref1 = ExpressionTempVariableRef( variable = tmp_variable3.makeReference( provider ), source_ref = source_ref ) upper_ref2 = ExpressionTempVariableRef( variable = tmp_variable3.makeReference(provider), source_ref = source_ref ) else: assert tmp_variable3 is None upper_ref1 = upper_ref2 = None # Second assign the inplace result over the original value. statements.append( StatementAssignmentSlice( expression = ExpressionTempVariableRef( variable = tmp_variable1.makeReference(provider), source_ref = source_ref ), lower = lower_ref1, upper = upper_ref1, source = ExpressionOperationBinaryInplace( operator = operator, left = ExpressionSliceLookup( expression = ExpressionTempVariableRef( variable = tmp_variable1.makeReference(provider), source_ref = source_ref ), lower = lower_ref2, upper = upper_ref2, source_ref = source_ref ), right = expression, source_ref = source_ref ), source_ref = source_ref ) ) return ( copy_to_tmp, makeTryFinallyStatement( tried = statements, final = final_statements, source_ref = source_ref ) )
def _buildClassNode3(provider, node, source_ref): # Many variables, due to the huge re-formulation that is going on here, # which just has the complexity, pylint: disable=R0914 # This function is the Python3 special case with special re-formulation as # according to developer manual. class_statements, class_doc = extractDocFromBody(node) # We need a scope for the temporary variables, and they might be closured. temp_scope = provider.allocateTempScope( name = "class_creation", allow_closure = True ) tmp_bases = provider.allocateTempVariable( temp_scope = temp_scope, name = "bases" ) tmp_class_decl_dict = provider.allocateTempVariable( temp_scope = temp_scope, name = "class_decl_dict" ) tmp_metaclass = provider.allocateTempVariable( temp_scope = temp_scope, name = "metaclass" ) tmp_prepared = provider.allocateTempVariable( temp_scope = temp_scope, name = "prepared" ) class_creation_function = ExpressionFunctionBody( provider = provider, is_class = True, parameters = make_class_parameters, name = node.name, doc = class_doc, source_ref = source_ref ) # Hack: This allows some APIs to work although this is not yet officially a # child yet. class_creation_function.parent = provider body = buildStatementsNode( provider = class_creation_function, nodes = class_statements, frame = True, source_ref = source_ref ) source_ref_orig = source_ref if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref module_variable = class_creation_function.getVariableForAssignment( "__module__" ) statements = [ StatementSetLocals( new_locals = ExpressionTempVariableRef( variable = tmp_prepared, source_ref = source_ref ), source_ref = source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = "__module__", variable = module_variable, source_ref = source_ref ), source = ExpressionConstantRef( constant = provider.getParentModule().getFullName(), source_ref = source_ref, user_provided = True ), source_ref = source_ref ) ] if class_doc is not None: doc_variable = class_creation_function.getVariableForAssignment( "__doc__" ) statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = "__doc__", variable = doc_variable, source_ref = source_ref ), source = ExpressionConstantRef( constant = class_doc, source_ref = source_ref, user_provided = True ), source_ref = source_ref ) ) # The "__qualname__" attribute is new in Python 3.3. if Utils.python_version >= 330: qualname = class_creation_function.getFunctionQualname() qualname_variable = class_creation_function.getVariableForAssignment( "__qualname__" ) if Utils.python_version < 340: qualname_ref = ExpressionConstantRef( constant = qualname, source_ref = source_ref, user_provided = True ) else: qualname_ref = ExpressionFunctionQualnameRef( function_body = class_creation_function, source_ref = source_ref, ) statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = "__qualname__", variable = qualname_variable, source_ref = source_ref ), source = qualname_ref, source_ref = source_ref ) ) if Utils.python_version >= 340: qualname_assign = statements[-1] if Utils.python_version >= 340 and False: # TODO: Temporarily reverted: tmp_class = class_creation_function.allocateTempVariable( temp_scope = None, name = "__class__" ) class_target_variable_ref = ExpressionTargetTempVariableRef( variable = tmp_class, source_ref = source_ref ) class_variable_ref = ExpressionTempVariableRef( variable = tmp_class, source_ref = source_ref ) else: class_variable = class_creation_function.getVariableForAssignment( "__class__" ) class_target_variable_ref = ExpressionTargetVariableRef( variable_name = "__class__", variable = class_variable, source_ref = source_ref ) class_variable_ref = ExpressionVariableRef( variable_name = "__class__", variable = class_variable, source_ref = source_ref ) statements += [ body, StatementAssignmentVariable( variable_ref = class_target_variable_ref, source = ExpressionCall( called = ExpressionTempVariableRef( variable = tmp_metaclass, source_ref = source_ref ), args = makeSequenceCreationOrConstant( sequence_kind = "tuple", elements = ( ExpressionConstantRef( constant = node.name, source_ref = source_ref, user_provided = True ), ExpressionTempVariableRef( variable = tmp_bases, source_ref = source_ref ), ExpressionBuiltinLocals( source_ref = source_ref ) ), source_ref = source_ref ), kw = ExpressionTempVariableRef( variable = tmp_class_decl_dict, source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ), StatementReturn( expression = class_variable_ref, source_ref = source_ref ) ] body = makeStatementsSequence( statements = statements, allow_none = True, source_ref = source_ref ) # The class body is basically a function that implicitly, at the end # returns its locals and cannot have other return statements contained. class_creation_function.setBody(body) # The class body is basically a function that implicitly, at the end # returns its created class and cannot have other return statements # contained. decorated_body = ExpressionFunctionCall( function = ExpressionFunctionCreation( function_ref = ExpressionFunctionRef( function_body = class_creation_function, source_ref = source_ref ), defaults = (), kw_defaults = None, annotations = None, source_ref = source_ref ), values = (), source_ref = source_ref ) for decorator in buildNodeList( provider, reversed(node.decorator_list), source_ref ): decorated_body = ExpressionCallNoKeywords( called = decorator, args = ExpressionMakeTuple( elements = ( decorated_body, ), source_ref = source_ref ), source_ref = decorator.getSourceReference() ) statements = ( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_bases, source_ref = source_ref ), source = makeSequenceCreationOrConstant( sequence_kind = "tuple", elements = buildNodeList( provider, node.bases, source_ref ), source_ref = source_ref ), source_ref = source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_class_decl_dict, source_ref = source_ref ), source = makeDictCreationOrConstant( keys = [ ExpressionConstantRef( constant = keyword.arg, source_ref = source_ref, user_provided = True ) for keyword in node.keywords ], values = [ buildNode(provider, keyword.value, source_ref) for keyword in node.keywords ], lazy_order = False, source_ref = source_ref ), source_ref = source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_metaclass, source_ref = source_ref ), source = ExpressionSelectMetaclass( metaclass = ExpressionConditional( condition = ExpressionComparison( comparator = "In", left = ExpressionConstantRef( constant = "metaclass", source_ref = source_ref, user_provided = True ), right = ExpressionTempVariableRef( variable = tmp_class_decl_dict, source_ref = source_ref ), source_ref = source_ref ), yes_expression = ExpressionDictOperationGet( dicte = ExpressionTempVariableRef( variable = tmp_class_decl_dict, source_ref = source_ref ), key = ExpressionConstantRef( constant = "metaclass", source_ref = source_ref, user_provided = True ), source_ref = source_ref ), no_expression = ExpressionConditional( condition = ExpressionTempVariableRef( variable = tmp_bases, source_ref = source_ref ), no_expression = ExpressionBuiltinRef( builtin_name = "type", source_ref = source_ref ), yes_expression = ExpressionBuiltinType1( value = ExpressionSubscriptLookup( subscribed = ExpressionTempVariableRef( variable = tmp_bases, source_ref = source_ref ), subscript = ExpressionConstantRef( constant = 0, source_ref = source_ref, user_provided = True ), source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ), bases = ExpressionTempVariableRef( variable = tmp_bases, source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref_orig ), StatementConditional( condition = ExpressionComparison( comparator = "In", left = ExpressionConstantRef( constant = "metaclass", source_ref = source_ref, user_provided = True ), right = ExpressionTempVariableRef( variable = tmp_class_decl_dict, source_ref = source_ref ), source_ref = source_ref ), no_branch = None, yes_branch = makeStatementsSequenceFromStatement( statement = StatementDictOperationRemove( dicte = ExpressionTempVariableRef( variable = tmp_class_decl_dict, source_ref = source_ref ), key = ExpressionConstantRef( constant = "metaclass", source_ref = source_ref, user_provided = True ), source_ref = source_ref ) ), source_ref = source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_prepared, source_ref = source_ref ), source = ExpressionConditional( condition = ExpressionBuiltinHasattr( object = ExpressionTempVariableRef( variable = tmp_metaclass, source_ref = source_ref ), name = ExpressionConstantRef( constant = "__prepare__", source_ref = source_ref, user_provided = True ), source_ref = source_ref ), no_expression = ExpressionConstantRef( constant = {}, source_ref = source_ref, user_provided = True ), yes_expression = ExpressionCall( called = ExpressionAttributeLookup( source = ExpressionTempVariableRef( variable = tmp_metaclass, source_ref = source_ref ), attribute_name = "__prepare__", source_ref = source_ref ), args = ExpressionMakeTuple( elements = ( ExpressionConstantRef( constant = node.name, source_ref = source_ref, user_provided = True ), ExpressionTempVariableRef( variable = tmp_bases, source_ref = source_ref ) ), source_ref = source_ref ), kw = ExpressionTempVariableRef( variable = tmp_class_decl_dict, source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = node.name, source_ref = source_ref ), source = decorated_body, source_ref = source_ref ), ) if Utils.python_version >= 340: class_assign = statements[-1] # assert False, class_creation_function class_creation_function.qualname_setup = class_assign, qualname_assign final = ( StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_bases, source_ref = source_ref ), tolerant = True, source_ref = source_ref ), StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_class_decl_dict, source_ref = source_ref ), tolerant = True, source_ref = source_ref ), StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_metaclass, source_ref = source_ref ), tolerant = True, source_ref = source_ref ), StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_prepared, source_ref = source_ref ), tolerant = True, source_ref = source_ref ) ) return makeTryFinallyStatement( tried = statements, final = final, source_ref = source_ref )
def buildComparisonNode(provider, node, source_ref): from nuitka.nodes.NodeMakingHelpers import makeComparisonNode assert len(node.comparators) == len(node.ops) # Comparisons are re-formulated as described in the developer manual. When # having multiple compators, things require assignment expressions and # references of them to work properly. Then they can become normal "and" # code. # The operands are split out left = buildNode(provider, node.left, source_ref) rights = [ buildNode(provider, comparator, source_ref) for comparator in node.comparators ] # Only the first comparison has as left operands as the real thing, the # others must reference the previous comparison right one temp variable ref. values = [] # For PyLint to like it, this will hold the previous one, normally. keeper_variable = None temp_scope = None final = [] for comparator, right in zip(node.ops, rights): if values: # Now we know it's not the only one, so we change the "left" to be a # reference to the previously saved right side. left = ExpressionTempVariableRef( variable=keeper_variable.makeReference(provider), source_ref=source_ref) keeper_variable = None if right is not rights[-1]: # Now we know it's not the last one, so we ought to preseve the # "right" so it can be referenced by the next part that will # come. We do it by assining it to a temp variable to be shared with # the next part. if temp_scope is None: temp_scope = provider.allocateTempScope(name="comparison") keeper_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="value_%d" % (rights.index(right) + 2), ) tried = StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=keeper_variable.makeReference(provider), source_ref=source_ref), source=right, source_ref=source_ref, ) # TODO: The delete must be placed later. final.append( StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=keeper_variable.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref, )) right = makeTryFinallyExpression( tried=tried, final=None, expression=ExpressionTempVariableRef( variable=keeper_variable.makeReference(provider), source_ref=source_ref), source_ref=source_ref) comparator = getKind(comparator) values.append( makeComparisonNode(left=left, right=right, comparator=comparator, source_ref=source_ref)) assert keeper_variable is None result = buildAndNode(provider=provider, values=values, source_ref=source_ref) if final: return makeTryFinallyExpression(tried=None, expression=result, final=final, source_ref=source_ref) else: return result
def _buildContractionBodyNode(provider, node, emit_class, start_value, container_tmp, outer_iter_ref, temp_scope, assign_provider, source_ref, function_body): if start_value is not None: statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), source=start_value, source_ref=source_ref.atInternal()) ] if assign_provider: tmp_variables = [] else: tmp_variables = [container_tmp] else: statements = [] tmp_variables = [] if hasattr(node, "elt"): if start_value is not None: current_body = emit_class(ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionYield function_body.markAsGenerator() current_body = emit_class(buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionDictOperationSet current_body = emit_class(ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), key=buildNode( provider=function_body, node=node.key, source_ref=source_ref, ), value=buildNode( provider=function_body, node=node.value, source_ref=source_ref, ), source_ref=source_ref) current_body = StatementExpressionOnly(expression=current_body, source_ref=source_ref) for count, qual in enumerate(reversed(node.generators)): tmp_value_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="iter_value_%d" % count) tmp_variables.append(tmp_value_variable) # The first iterated value is to be calculated outside of the function # and will be given as a parameter "_iterated", the others are built # inside the function. if qual is node.generators[0]: def makeIteratorRef(): return outer_iter_ref.makeCloneAt(source_ref) tmp_iter_variable = None nested_statements = [] else: # First create the iterator and store it, next should be loop body value_iterator = ExpressionBuiltinIter1(value=buildNode( provider=function_body, node=qual.iter, source_ref=source_ref), source_ref=source_ref) tmp_iter_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="contraction_iter_%d" % count) tmp_variables.append(tmp_iter_variable) nested_statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable.makeReference( function_body), source_ref=source_ref), source=value_iterator, source_ref=source_ref) ] def makeIteratorRef(): return ExpressionTempVariableRef( variable=tmp_iter_variable.makeReference(function_body), source_ref=source_ref) loop_statements = [ makeTryExceptSingleHandlerNode( tried=makeStatementsSequenceFromStatement( statement=StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_value_variable.makeReference( function_body), source_ref=source_ref), source=ExpressionBuiltinNext1(value=makeIteratorRef(), source_ref=source_ref), source_ref=source_ref)), exception_name="StopIteration", handler_body=makeStatementsSequenceFromStatement( statement=StatementBreakLoop( source_ref=source_ref.atInternal())), public_exc=False, source_ref=source_ref), buildAssignmentStatements( provider=provider if assign_provider else function_body, temp_provider=function_body, node=qual.target, source=ExpressionTempVariableRef( variable=tmp_value_variable.makeReference(function_body), source_ref=source_ref), source_ref=source_ref) ] conditions = buildNodeList(provider=function_body, nodes=qual.ifs, source_ref=source_ref) if len(conditions) == 1: loop_statements.append( StatementConditional( condition=conditions[0], yes_branch=makeStatementsSequenceFromStatement( statement=current_body), no_branch=None, source_ref=source_ref)) elif len(conditions) > 1: loop_statements.append( StatementConditional( condition=buildAndNode(provider=function_body, values=conditions, source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=current_body), no_branch=None, source_ref=source_ref)) else: loop_statements.append(current_body) nested_statements.append( StatementLoop(body=StatementsSequence( statements=mergeStatements(loop_statements), source_ref=source_ref), source_ref=source_ref)) if tmp_iter_variable is not None: nested_statements.append( StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable.makeReference( function_body), source_ref=source_ref), tolerant=False, source_ref=source_ref)) current_body = StatementsSequence(statements=nested_statements, source_ref=source_ref) statements.append(current_body) statements = mergeStatements(statements) if emit_class is ExpressionYield: statements.insert(0, StatementGeneratorEntry(source_ref=source_ref)) del_statements = [] for tmp_variable in tmp_variables: del_statements.append( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_variable.makeReference(function_body), source_ref=source_ref), tolerant=True, source_ref=source_ref.atInternal())) return statements, del_statements
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_ref = ExpressionTargetTempVariableRef( variable = tmp_break_indicator, source_ref = source_ref ), source = ExpressionConstantRef( constant = True, source_ref = source_ref ), source_ref = source_ref ), StatementBreakLoop( source_ref = source_ref ) ) else: statements = ( StatementBreakLoop( source_ref = source_ref ), ) pushBuildContext("loop_body") pushIndicatorVariable(None) loop_statements = buildStatementsNode( provider = provider, nodes = node.body, source_ref = source_ref ) popIndicatorVariable() popBuildContext() # The loop body contains a conditional statement at the start that breaks # the loop if it fails. loop_body = makeStatementsSequence( statements = ( StatementConditional( condition = buildNode(provider, node.test, source_ref), no_branch = StatementsSequence( statements = statements, source_ref = source_ref ), yes_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_ref = ExpressionTargetTempVariableRef( variable = tmp_break_indicator, source_ref = source_ref ), source = ExpressionConstantRef( constant = False, source_ref = source_ref ), source_ref = source_ref ), loop_statement, StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = tmp_break_indicator, source_ref = source_ref ), right = ExpressionConstantRef( constant = True, source_ref = source_ref ), source_ref = source_ref ), yes_branch = else_block, no_branch = None, source_ref = source_ref ) ) statements = ( makeTryFinallyStatement( tried = statements, final = StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_break_indicator, source_ref = source_ref ), tolerant = False, source_ref = source_ref ), source_ref = source_ref ), ) return StatementsSequence( statements = statements, source_ref = source_ref )
def _buildWithNode(provider, context_expr, assign_target, body, source_ref): with_source = buildNode(provider, context_expr, source_ref) temp_scope = provider.allocateTempScope("with") tmp_source_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="source") tmp_exit_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="exit") tmp_enter_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="enter") tmp_indicator_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="indicator") statements = (buildAssignmentStatements(provider=provider, node=assign_target, allow_none=True, source=ExpressionTempVariableRef( variable=tmp_enter_variable, source_ref=source_ref), source_ref=source_ref), body) with_body = makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref) if Options.isFullCompat() and with_body is not None: with_exit_source_ref = with_body.getStatements()[-1].\ getSourceReference() else: with_exit_source_ref = source_ref # The "__enter__" and "__exit__" were normal attribute lookups under # CPython2.6, but that changed with CPython2.7. if Utils.python_version < 270: attribute_lookup_class = ExpressionAttributeLookup else: attribute_lookup_class = ExpressionSpecialAttributeLookup statements = [ # First assign the with context to a temporary variable. StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_source_variable, source_ref=source_ref), source=with_source, source_ref=source_ref), # Next, assign "__enter__" and "__exit__" attributes to temporary # variables. StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_exit_variable, source_ref=source_ref), source=attribute_lookup_class(source=ExpressionTempVariableRef( variable=tmp_source_variable, source_ref=source_ref), attribute_name="__exit__", source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_enter_variable, source_ref=source_ref), source=ExpressionCallEmpty(called=attribute_lookup_class( source=ExpressionTempVariableRef(variable=tmp_source_variable, source_ref=source_ref), attribute_name="__enter__", source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_indicator_variable, source_ref=source_ref), source=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref), ] source_ref = source_ref.atInternal() statements += [ makeTryFinallyStatement( tried=makeTryExceptSingleHandlerNode( tried=with_body, exception_name="BaseException", handler_body=StatementsSequence( statements=( # Prevents final block from calling __exit__ as # well. StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_indicator_variable, source_ref=source_ref), source=ExpressionConstantRef( constant=False, source_ref=source_ref), source_ref=source_ref), StatementConditional( condition=ExpressionCallNoKeywords( called=ExpressionTempVariableRef( variable=tmp_exit_variable, source_ref=source_ref), args=ExpressionMakeTuple( elements=( ExpressionCaughtExceptionTypeRef( source_ref=source_ref), ExpressionCaughtExceptionValueRef( source_ref=source_ref), ExpressionCaughtExceptionTracebackRef( source_ref=source_ref), ), source_ref=source_ref), source_ref=source_ref), no_branch=makeStatementsSequenceFromStatement( statement=StatementRaiseException( exception_type=None, exception_value=None, exception_trace=None, exception_cause=None, source_ref=source_ref)), yes_branch=None, source_ref=source_ref), ), source_ref=source_ref), public_exc=Utils.python_version >= 270, source_ref=source_ref), final=StatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_indicator_variable, source_ref=source_ref), right=ExpressionConstantRef(constant=True, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=StatementExpressionOnly( expression=ExpressionCallNoKeywords( called=ExpressionTempVariableRef( variable=tmp_exit_variable, source_ref=source_ref), args=ExpressionConstantRef(constant=(None, None, None), source_ref=source_ref), source_ref=with_exit_source_ref), source_ref=source_ref)), no_branch=None, source_ref=source_ref), source_ref=source_ref) ] return makeTryFinallyStatement( tried=statements, final=( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_source_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_enter_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_exit_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_indicator_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), ), source_ref=source_ref)
def buildForLoopNode(provider, node, source_ref): # The for loop is re-formulated according to developer manual. An iterator # is created, and looped until it gives StopIteration. The else block is # taken if a for loop exits normally, i.e. because of iterator # exhaustion. We do this by introducing an indicator variable. source = buildNode(provider, node.iter, source_ref) temp_scope = provider.allocateTempScope("for_loop") tmp_iter_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "for_iterator" ) tmp_value_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "iter_value" ) else_block = buildStatementsNode( provider = provider, nodes = node.orelse if node.orelse else None, source_ref = source_ref ) if else_block is not None: tmp_break_indicator = provider.allocateTempVariable( temp_scope = temp_scope, name = "break_indicator" ) statements = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_break_indicator, source_ref = source_ref ), source = ExpressionConstantRef( constant = True, source_ref = source_ref ), source_ref = source_ref ) ] else: statements = [] statements.append( StatementBreakLoop( source_ref = source_ref ) ) handler_body = makeStatementsSequence( statements = statements, allow_none = False, source_ref = source_ref ) statements = ( makeTryExceptSingleHandlerNode( tried = makeStatementsSequenceFromStatement( statement = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_value_variable, source_ref = source_ref ), source = ExpressionBuiltinNext1( value = ExpressionTempVariableRef( variable = tmp_iter_variable, source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ) ), exception_name = "StopIteration", handler_body = handler_body, public_exc = False, source_ref = source_ref ), buildAssignmentStatements( provider = provider, node = node.target, source = ExpressionTempVariableRef( variable = tmp_value_variable, source_ref = source_ref ), source_ref = source_ref ) ) pushBuildContext("loop_body") pushIndicatorVariable(None) statements += ( buildStatementsNode( provider = provider, nodes = node.body, source_ref = source_ref ), ) popIndicatorVariable() popBuildContext() loop_body = makeStatementsSequence( statements = statements, allow_none = True, source_ref = source_ref ) cleanup_statements = [ StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_value_variable, source_ref = source_ref ), tolerant = True, source_ref = source_ref ), StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_iter_variable, source_ref = source_ref ), tolerant = True, source_ref = source_ref ) ] if else_block is not None: statements = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_break_indicator, source_ref = source_ref ), source = ExpressionConstantRef( constant = False, source_ref = source_ref ), source_ref = source_ref ) ] else: statements = [] statements += [ # First create the iterator and store it. StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_iter_variable, source_ref = source_ref ), source = ExpressionBuiltinIter1( value = source, source_ref = source.getSourceReference() ), source_ref = source_ref ), makeTryFinallyStatement( tried = StatementLoop( body = loop_body, source_ref = source_ref ), final = StatementsSequence( statements = cleanup_statements, source_ref = source_ref ), source_ref = source_ref ) ] if else_block is not None: statements += [ StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = tmp_break_indicator, source_ref = source_ref ), right = ExpressionConstantRef( constant = True, source_ref = source_ref ), source_ref = source_ref ), yes_branch = else_block, no_branch = None, source_ref = source_ref ) ] statements = ( makeTryFinallyStatement( tried = statements, final = StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_break_indicator, source_ref = source_ref ), tolerant = False, source_ref = source_ref ), source_ref = source_ref ), ) return StatementsSequence( statements = statements, source_ref = source_ref )
def buildPrintNode(provider, node, source_ref): # "print" statements, should only occur with Python2. def wrapValue(value): if value.isExpressionConstantRef(): str_value = value.getStrValue() if str_value is not None: return str_value return ExpressionBuiltinStr(value=value, source_ref=value.getSourceReference()) 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_ref=ExpressionTargetTempVariableRef( variable=tmp_target_variable, source_ref=source_ref), source=ExpressionImportModuleHard(module_name="sys", import_name="stdout", source_ref=source_ref), source_ref=source_ref) statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_target_variable, source_ref=source_ref), source=buildNode(provider=provider, node=node.dest, source_ref=source_ref), source_ref=source_ref), StatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_target_variable, source_ref=source_ref), right=ExpressionConstantRef(constant=None, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=target_default_statement), no_branch=None, source_ref=source_ref) ] values = buildNodeList(provider=provider, nodes=node.values, source_ref=source_ref) values = [wrapValue(value) for value in values] 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( tried=print_statements, final=StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_target_variable, source_ref=source_ref), tolerant=False, 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 StatementsSequence(statements=statements, source_ref=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=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=ExpressionConstantRef(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 provider.isExpressionFunctionBody(): 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 = ExpressionConstantRef(constant=None, source_ref=source_ref) globals_value = buildNode(provider, exec_globals, source_ref, True) if globals_value is None: globals_value = ExpressionConstantRef(constant=None, 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 = makeStatementsSequenceFromStatements( # 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=ExpressionConstantRef(constant=False, source_ref=source_ref), source_ref=source_ref), StatementConditional( condition=ExpressionComparisonIs(left=ExpressionTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), right=ExpressionConstantRef( constant=None, 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=ExpressionConstantRef(constant=None, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), source=ExpressionBuiltinLocals( source_ref=source_ref), source_ref=source_ref, ), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=plain_indicator_variable, source_ref=source_ref), source=ExpressionConstantRef( 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=ExpressionConstantRef(constant=None, 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), StatementTryFinally( tried=makeStatementsSequenceFromStatement(statement=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=makeStatementsSequenceFromStatements( StatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=plain_indicator_variable, source_ref=source_ref), right=ExpressionConstantRef(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), ), public_exc=False, source_ref=source_ref)) final = makeStatementsSequenceFromStatements( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=source_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=plain_indicator_variable, source_ref=source_ref), tolerant=True, source_ref=source_ref), ) return StatementTryFinally(tried=tried, final=final, public_exc=False, source_ref=source_ref)
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 buildTryFinallyNode(provider, build_tried, node, source_ref): if Utils.python_version < 300: # Prevent "continue" statements in the final blocks pushBuildContext("finally") final = buildStatementsNode( provider = provider, nodes = node.finalbody, source_ref = source_ref ) popBuildContext() return StatementTryFinally( tried = build_tried(), final = final, public_exc = Utils.python_version >= 300, # TODO: Use below code source_ref = source_ref ) else: temp_scope = provider.allocateTempScope("try_finally") tmp_indicator_var = provider.allocateTempVariable( temp_scope = temp_scope, name = "unhandled_indicator" ) pushIndicatorVariable(tmp_indicator_var) statements = ( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_indicator_var.makeReference( provider ), source_ref = source_ref.atInternal() ), source = ExpressionConstantRef( constant = False, source_ref = source_ref ), source_ref = source_ref.atInternal() ), build_tried(), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_indicator_var.makeReference( provider ), source_ref = source_ref.atInternal() ), source = ExpressionConstantRef( constant = True, source_ref = source_ref ), source_ref = source_ref.atInternal() ) ) # Prevent "continue" statements in the final blocks pushBuildContext("finally") final = buildStatementsNode( provider = provider, nodes = node.finalbody, source_ref = source_ref ) popBuildContext() popIndicatorVariable() tried = StatementsSequence( statements = mergeStatements(statements, allow_none = True), source_ref = source_ref ) prelude = StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = tmp_indicator_var.makeReference( provider ), source_ref = source_ref.atInternal() ), right = ExpressionConstantRef( constant = False, source_ref = source_ref ), source_ref = source_ref ), yes_branch = StatementsSequence( statements = ( StatementPreserveFrameException( source_ref = source_ref.atInternal() ), StatementPublishException( source_ref = source_ref.atInternal() ) ), source_ref = source_ref.atInternal() ), no_branch = None, source_ref = source_ref.atInternal() ) postlude = ( StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = tmp_indicator_var.makeReference( provider ), source_ref = source_ref.atInternal() ), right = ExpressionConstantRef( constant = False, source_ref = source_ref ), source_ref = source_ref ), yes_branch = StatementsSequence( statements = ( StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_indicator_var.makeReference( provider ), source_ref = source_ref.atInternal() ), tolerant = False, source_ref = source_ref.atInternal() ), StatementReraiseFrameException( source_ref = source_ref.atInternal() ), ), source_ref = source_ref.atInternal() ), no_branch = StatementsSequence( statements = ( StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_indicator_var.makeReference( provider ), source_ref = source_ref.atInternal() ), tolerant = False, source_ref = source_ref.atInternal() ), ), source_ref = source_ref.atInternal() ), source_ref = source_ref.atInternal() ), ) final = StatementsSequence( statements = mergeStatements( ( prelude, makeTryFinallyStatement( tried = final, final = postlude, source_ref = source_ref.atInternal() ), ) ), source_ref = source_ref.atInternal() ) return StatementTryFinally( tried = tried, final = final, public_exc = True, source_ref = source_ref )