def wrapExpressionBuiltinExecfileCreation(filename, globals_arg, locals_arg, source_ref): outline_body = ExpressionOutlineBody( provider = node.getParentVariableProvider(), name = "execfile_call", source_ref = source_ref ) globals_ref, locals_ref, tried, final = wrapEvalGlobalsAndLocals( provider = node.getParentVariableProvider(), globals_node = globals_arg, locals_node = locals_arg, temp_scope = outline_body.getOutlineTempScope(), source_ref = source_ref ) tried = makeStatementsSequence( statements = ( tried, StatementReturn( expression = ExpressionBuiltinExecfile( source_code = ExpressionCallEmpty( called = ExpressionAttributeLookup( source = ExpressionBuiltinOpen( filename = filename, mode = ExpressionConstantRef( constant = "rU", source_ref = source_ref ), buffering = None, source_ref = source_ref ), attribute_name = "read", source_ref = source_ref ), source_ref = source_ref ), globals_arg = globals_ref, locals_arg = locals_ref, source_ref = source_ref ), source_ref = source_ref ) ), 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 convertFunctionCallToOutline(provider, function_body, values, call_source_ref): # This has got to have pretty man details, pylint: disable=too-many-locals function_source_ref = function_body.getSourceReference() outline_body = ExpressionOutlineBody(provider=provider, name="inline", source_ref=function_source_ref) # Make a clone first, so we do not harm other references. clone = function_body.getBody().makeClone() locals_scope_clone, variable_translation = function_body.locals_scope.makeClone( clone) # TODO: Lets update all at once maybe, it would take less visits. updateLocalsScope( clone, locals_scope=locals_scope_clone, variable_translation=variable_translation, ) argument_names = function_body.getParameters().getParameterNames() assert len(argument_names) == len(values), (argument_names, values) statements = [] for argument_name, value in zip(argument_names, values): statements.append( StatementAssignmentVariable( variable=variable_translation[argument_name], source=value, source_ref=call_source_ref, )) body = makeStatementsSequence(statements=(statements, clone), allow_none=False, source_ref=function_source_ref) auto_releases = function_body.getFunctionVariablesWithAutoReleases() # TODO: Not possible to auto release with outline bodies too? if auto_releases: releases = [ StatementReleaseVariable(variable=variable, source_ref=function_source_ref) for variable in auto_releases ] body = makeTryFinallyStatement( provider=outline_body, tried=body, final=releases, source_ref=function_source_ref, ) outline_body.setBody(body) return outline_body
def buildNamedExprNode(provider, node, source_ref): """ Assignment expressions, Python3.8 or higher only. """ outline_body = ExpressionOutlineBody( provider=provider, name="assignment_expr", source_ref=source_ref ) tmp_value = outline_body.allocateTempVariable(temp_scope=None, name="value") value = buildNode(provider=provider, node=node.value, source_ref=source_ref) locals_owner = provider while locals_owner.isExpressionOutlineFunction(): locals_owner = locals_owner.getParentVariableProvider() variable_name = node.target.id if ( locals_owner.isExpressionGeneratorObjectBody() and locals_owner.name == "<genexpr>" ): locals_owner.addNonlocalsDeclaration( (variable_name,), user_provided=False, source_ref=source_ref ) statements = ( StatementAssignmentVariable( variable=tmp_value, source=value, source_ref=source_ref ), StatementAssignmentVariableName( provider=locals_owner, variable_name=variable_name, source=ExpressionTempVariableRef(variable=tmp_value, source_ref=source_ref), source_ref=source_ref, ), StatementReturn( expression=ExpressionTempVariableRef( variable=tmp_value, source_ref=source_ref ), source_ref=source_ref, ), ) outline_body.setBody( makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement( provider=provider, tried=statements, final=StatementReleaseVariable( variable=tmp_value, source_ref=source_ref ), source_ref=source_ref, ) ) ) return outline_body
def wrapExpressionBuiltinExecCreation(source, globals_arg, locals_arg, source_ref): provider = node.getParentVariableProvider() outline_body = ExpressionOutlineBody( provider = provider, name = "exec_call", body = None, # later source_ref = source_ref ) # TODO: Can't really be true, can it? if provider.isExpressionFunctionBody(): provider.markAsExecContaining() if provider.isExpressionClassBody(): provider.markAsUnqualifiedExecContaining(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 ) tried = makeStatementsSequence( statements = ( tried, StatementReturn( expression = ExpressionBuiltinExec( source_code = source, globals_arg = globals_ref, locals_arg = locals_ref, source_ref = source_ref ), source_ref = source_ref ), ), allow_none = False, source_ref = source_ref ) # Hack: Allow some APIs to work already tried.parent = outline_body outline_body.setBody( makeStatementsSequenceFromStatement( statement = makeTryFinallyStatement( provider = provider, tried = tried, final = final, source_ref = source_ref ) ) ) return outline_body
def convertFunctionCallToOutline(provider, function_ref, values): # This has got to have pretty man details, pylint: disable=R0914 function_body = function_ref.getFunctionBody() # TODO: Use the call location source_ref = function_body.getSourceReference() outline_body = ExpressionOutlineBody(provider=provider, name="inline", body=None, source_ref=source_ref) clone = function_body.getBody().makeClone() temp_scope = outline_body.getOutlineTempScope() translation = {} for variable in function_body.getLocalVariables(): # TODO: Later we should be able to do that too. assert not variable.isSharedTechnically() new_variable = outline_body.allocateTempVariable( temp_scope=temp_scope, name=variable.getName()) # TODO: Lets update all at once maybe, it would take less visits. updateVariableUsage(clone, old_variable=variable, new_variable=new_variable) translation[variable.getName()] = new_variable statements = [] argument_names = function_body.getParameters().getAllNames() assert len(argument_names) == len(values), (argument_names, values) for argument_name, value in zip(argument_names, values): statements.append( StatementAssignmentVariable( variable_ref=makeVariableTargetRefNode( variable=translation[argument_name], source_ref=source_ref), source=value, source_ref=source_ref, )) body = makeStatementsSequence(statements=(statements, clone), allow_none=False, source_ref=source_ref) outline_body.setBody(body) return outline_body
def convertFunctionCallToOutline(provider, function_ref, values): # This has got to have pretty man details, pylint: disable=too-many-locals function_body = function_ref.getFunctionBody() call_source_ref = function_ref.getSourceReference() function_source_ref = function_body.getSourceReference() outline_body = ExpressionOutlineBody( provider=provider, name="inline", source_ref=function_source_ref ) clone = function_body.getBody().makeClone() temp_scope = outline_body.getOutlineTempScope() translation = {} for variable in function_body.getLocalVariables(): # TODO: Later we should be able to do that too. assert variable.isSharedTechnically() is False new_variable = outline_body.allocateTempVariable( temp_scope=temp_scope, name=variable.getName() ) # TODO: Lets update all at once maybe, it would take less visits. updateVariableUsage(clone, old_variable=variable, new_variable=new_variable) translation[variable.getName()] = new_variable statements = [] if function_body.isExpressionClassBody(): argument_names = () else: argument_names = function_body.getParameters().getParameterNames() assert len(argument_names) == len(values), (argument_names, values) for argument_name, value in zip(argument_names, values): statements.append( StatementAssignmentVariable( variable=translation[argument_name], source=value, source_ref=call_source_ref, ) ) body = makeStatementsSequence( statements=(statements, clone), allow_none=False, source_ref=function_source_ref ) outline_body.setBody(body) return outline_body
def _buildPython2ListContraction(provider, node, 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. # Note: The assign_provider is only to cover Python2 list contractions, # assigning one of the loop variables to the outside scope. function_body = ExpressionOutlineBody( provider=provider, name="list_contraction", source_ref=source_ref ) iter_tmp = function_body.allocateTempVariable(temp_scope=None, name=".0") container_tmp = function_body.allocateTempVariable( temp_scope=None, name="contraction_result" ) statements, release_statements = _buildContractionBodyNode( provider=provider, node=node, emit_class=StatementListOperationAppend, iter_tmp=iter_tmp, temp_scope=None, start_value=[], container_tmp=container_tmp, function_body=function_body, assign_provider=True, for_asyncgen=False, source_ref=source_ref, ) statements.append( StatementReturn( expression=ExpressionTempVariableRef( variable=container_tmp, source_ref=source_ref ), source_ref=source_ref, ) ) statement = makeTryFinallyStatement( provider=function_body, tried=statements, final=release_statements, source_ref=source_ref.atInternal(), ) function_body.setBody(makeStatementsSequenceFromStatement(statement=statement)) return function_body
def wrapExpressionBuiltinExecCreation(source, globals_arg, locals_arg, source_ref): provider = node.getParentVariableProvider() outline_body = ExpressionOutlineBody( provider = provider, name = "exec_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 ) tried = makeStatementsSequence( statements = ( tried, StatementReturn( expression = ExpressionBuiltinExec( source_code = source, globals_arg = globals_ref, locals_arg = locals_ref, source_ref = source_ref ), source_ref = source_ref ), ), allow_none = False, source_ref = source_ref ) # Hack: Allow some APIs to work already tried.parent = outline_body outline_body.setBody( makeStatementsSequenceFromStatement( statement = makeTryFinallyStatement( provider = provider, tried = tried, final = final, source_ref = source_ref ) ) ) return outline_body
def _buildPython2ListContraction(provider, node, 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. # Note: The assign_provider is only to cover Python2 list contractions, # assigning one of the loop variables to the outside scope. function_body = ExpressionOutlineBody( provider=provider, name="list_contraction", source_ref=source_ref ) iter_tmp = function_body.allocateTempVariable(temp_scope=None, name=".0") container_tmp = function_body.allocateTempVariable( temp_scope=None, name="contraction_result" ) statements, release_statements = _buildContractionBodyNode( provider=provider, node=node, emit_class=StatementListOperationAppend, iter_tmp=iter_tmp, temp_scope=None, start_value=[], container_tmp=container_tmp, function_body=function_body, assign_provider=True, for_asyncgen=False, source_ref=source_ref, ) statements.append( StatementReturn( expression=ExpressionTempVariableRef( variable=container_tmp, source_ref=source_ref ), source_ref=source_ref, ) ) statement = makeTryFinallyStatement( provider=function_body, tried=statements, final=release_statements, source_ref=source_ref.atInternal(), ) function_body.setBody(makeStatementsSequenceFromStatement(statement=statement)) return function_body
def wrapExpressionBuiltinExecCreation(source, globals_arg, locals_arg, source_ref): provider = node.getParentVariableProvider() outline_body = ExpressionOutlineBody( provider=provider, name="exec_call", body=None, # later source_ref=source_ref) # TODO: Can't really be true, can it? if provider.isExpressionFunctionBody(): provider.markAsExecContaining() if provider.isExpressionClassBody(): provider.markAsUnqualifiedExecContaining(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) tried = makeStatementsSequence(statements=( tried, StatementReturn(expression=ExpressionBuiltinExec( source_code=source, globals_arg=globals_ref, locals_arg=locals_ref, source_ref=source_ref), source_ref=source_ref), ), allow_none=False, source_ref=source_ref) # Hack: Allow some APIs to work already tried.parent = outline_body outline_body.setBody( makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement(provider=provider, tried=tried, final=final, source_ref=source_ref))) return outline_body
def buildGeneratorExpressionNode(provider, node, source_ref): # Generator expressions are dealt with by general code. assert getKind(node) == "GeneratorExp" function_body = ExpressionOutlineBody( provider=provider, name="genexpr", source_ref=source_ref ) iter_tmp = function_body.allocateTempVariable(temp_scope=None, name=".0") parent_module = provider.getParentModule() code_object = CodeObjectSpec( co_name="<genexpr>", co_kind="Generator", co_varnames=(".0",), co_argcount=1, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False, co_filename=parent_module.getRunTimeFilename(), co_lineno=source_ref.getLineNumber(), future_spec=parent_module.getFutureSpec(), ) if python_version < 370: is_async = any(getattr(qual, "is_async", 0) for qual in node.generators) else: is_async = detectFunctionBodyKind(nodes=[node])[0] in ("Asyncgen", "Coroutine") if is_async: code_body = ExpressionAsyncgenObjectBody( provider=provider, name="<genexpr>", code_object=code_object, flags=set(), source_ref=source_ref, ) maker_class = ExpressionMakeAsyncgenObject else: code_body = ExpressionGeneratorObjectBody( provider=provider, name="<genexpr>", code_object=code_object, flags=set(), source_ref=source_ref, ) maker_class = ExpressionMakeGeneratorObject function_body.setBody( makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable=iter_tmp, source=_makeIteratorCreation( provider=provider, qual=node.generators[0], for_asyncgen=is_async, source_ref=source_ref, ), source_ref=source_ref, ), makeTryFinallyStatement( provider=function_body, tried=StatementReturn( expression=maker_class( ExpressionFunctionRef( function_body=code_body, source_ref=source_ref ), source_ref=source_ref, ), source_ref=source_ref, ), final=StatementReleaseVariable( variable=iter_tmp, source_ref=source_ref ), source_ref=source_ref, ), ) ) statements, release_statements = _buildContractionBodyNode( provider=provider, node=node, emit_class=ExpressionYield, iter_tmp=iter_tmp, temp_scope=None, start_value=None, container_tmp=None, function_body=code_body, assign_provider=False, for_asyncgen=is_async, source_ref=source_ref, ) if is_async: statements.append(StatementGeneratorReturnNone(source_ref=source_ref)) statements = ( makeTryFinallyStatement( provider=function_body, tried=statements, final=release_statements, source_ref=source_ref.atInternal(), ), ) code_body.setBody( makeStatementsSequenceFromStatement( statement=StatementsFrameGenerator( statements=mergeStatements(statements, False), code_object=code_object, source_ref=source_ref, ) ) ) return function_body
def buildClassNode2(provider, node, source_ref): # This function is the Python2 special case with special re-formulation as # according to developer manual, and it's very detailed, pylint: disable=too-many-locals class_statement_nodes, class_doc = extractDocFromBody(node) function_body = ExpressionClassBody(provider=provider, name=node.name, doc=class_doc, source_ref=source_ref) parent_module = provider.getParentModule() code_object = CodeObjectSpec( co_name=node.name, co_kind="Class", co_varnames=(), co_argcount=0, co_posonlyargcount=0, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False, co_filename=parent_module.getRunTimeFilename(), co_lineno=source_ref.getLineNumber(), future_spec=parent_module.getFutureSpec(), ) body = buildFrameNode( provider=function_body, nodes=class_statement_nodes, code_object=code_object, 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() locals_scope = function_body.getLocalsScope() # 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 = [ StatementSetLocalsDictionary(locals_scope=locals_scope, source_ref=source_ref), StatementAssignmentVariableName( provider=function_body, variable_name="__module__", source=ExpressionModuleAttributeNameRef( variable=provider.getParentModule().getVariableForReference( "__name__"), source_ref=source_ref, ), source_ref=source_ref.atInternal(), ), ] if class_doc is not None: statements.append( StatementAssignmentVariableName( provider=function_body, variable_name="__doc__", source=makeConstantRefNode(constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref.atInternal(), )) statements += ( body, StatementReturn( expression=ExpressionBuiltinLocalsRef(locals_scope=locals_scope, source_ref=source_ref), source_ref=source_ref, ), ) body = makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement( provider=function_body, tried=mergeStatements(statements, True), final=StatementReleaseLocals(locals_scope=locals_scope, source_ref=source_ref), 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") select_metaclass = ExpressionOutlineBody(provider=provider, name="select_metaclass", body=None, source_ref=source_ref) if node.bases: tmp_base = select_metaclass.allocateTempVariable(temp_scope=None, name="base") statements = ( StatementAssignmentVariable( variable=tmp_base, source=ExpressionSubscriptLookup( expression=ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref), subscript=makeConstantRefNode(constant=0, source_ref=source_ref, user_provided=True), source_ref=source_ref, ), source_ref=source_ref, ), makeTryFinallyStatement( provider, tried=StatementTry( tried=makeStatementsSequenceFromStatement( statement=StatementReturn( expression=ExpressionAttributeLookup( expression=ExpressionTempVariableRef( variable=tmp_base, source_ref=source_ref), attribute_name="__class__", source_ref=source_ref, ), source_ref=source_ref, )), except_handler=makeStatementsSequenceFromStatement( statement=StatementReturn( expression=ExpressionBuiltinType1( value=ExpressionTempVariableRef( variable=tmp_base, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, )), break_handler=None, continue_handler=None, return_handler=None, source_ref=source_ref, ), final=StatementReleaseVariable(variable=tmp_base, source_ref=source_ref), source_ref=source_ref, public_exc=False, ), ) else: statements = ( StatementTry( tried=makeStatementsSequenceFromStatement( statement=StatementReturn( # TODO: Should avoid checking __builtins__ for this. expression=ExpressionVariableNameRef( variable_name="__metaclass__", provider=parent_module, source_ref=source_ref, ), source_ref=source_ref, )), except_handler=makeStatementsSequenceFromStatement( statement=StatementReturn( expression=ExpressionBuiltinAnonymousRef( builtin_name="classobj", source_ref=source_ref), source_ref=source_ref, )), break_handler=None, continue_handler=None, return_handler=None, source_ref=source_ref, ), ) select_metaclass.setBody( makeStatementsSequence(statements=statements, allow_none=False, source_ref=source_ref)) statements = [ StatementAssignmentVariable( variable=tmp_bases, source=makeSequenceCreationOrConstant( sequence_kind="tuple", elements=buildNodeList(provider=provider, nodes=node.bases, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariable(variable=tmp_class_dict, source=function_body, source_ref=source_ref), StatementAssignmentVariable( variable=tmp_metaclass, source=ExpressionConditional( condition=ExpressionDictOperationIn( key=makeConstantRefNode( constant="__metaclass__", source_ref=source_ref, user_provided=True, ), dict_arg=ExpressionTempVariableRef(variable=tmp_class_dict, source_ref=source_ref), source_ref=source_ref, ), expression_yes=ExpressionDictOperationGet( dict_arg=ExpressionTempVariableRef(variable=tmp_class_dict, source_ref=source_ref), key=makeConstantRefNode( constant="__metaclass__", source_ref=source_ref, user_provided=True, ), source_ref=source_ref, ), expression_no=select_metaclass, source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariable( variable=tmp_class, source=makeExpressionCall( called=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), args=ExpressionMakeTuple( elements=( makeConstantRefNode( 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, ), kw=None, source_ref=source_ref, ), source_ref=source_ref, ), ] for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): statements.append( StatementAssignmentVariable( variable=tmp_class, source=makeExpressionCall( called=decorator, args=ExpressionMakeTuple( elements=(ExpressionTempVariableRef( variable=tmp_class, source_ref=source_ref), ), source_ref=source_ref, ), kw=None, source_ref=decorator.getSourceReference(), ), source_ref=decorator.getSourceReference(), )) statements.append( StatementAssignmentVariableName( provider=provider, variable_name=mangleName(node.name, provider), source=ExpressionTempVariableRef(variable=tmp_class, source_ref=source_ref), source_ref=source_ref, )) final = ( StatementReleaseVariable(variable=tmp_class, source_ref=source_ref), StatementReleaseVariable(variable=tmp_bases, source_ref=source_ref), StatementReleaseVariable(variable=tmp_class_dict, source_ref=source_ref), StatementReleaseVariable(variable=tmp_metaclass, source_ref=source_ref), ) return makeTryFinallyStatement(provider=function_body, tried=statements, final=final, source_ref=source_ref)
def buildGeneratorExpressionNode(provider, node, source_ref): # Generator expressions are dealt with by general code. assert getKind(node) == "GeneratorExp" function_body = ExpressionOutlineBody(provider=provider, name="genexpr", source_ref=source_ref) iter_tmp = function_body.allocateTempVariable(temp_scope=None, name=".0") parent_module = provider.getParentModule() code_object = CodeObjectSpec( co_name="<genexpr>", co_kind="Generator", co_varnames=(".0", ), co_freevars=(), co_argcount=1, co_posonlyargcount=0, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False, co_filename=parent_module.getRunTimeFilename(), co_lineno=source_ref.getLineNumber(), future_spec=parent_module.getFutureSpec(), ) is_async = any(getattr(qual, "is_async", 0) for qual in node.generators) # Some of the newly allowed stuff in 3.7 fails to set the async flag. if not is_async and python_version >= 370: is_async = detectFunctionBodyKind(nodes=node.generators)[0] in ( "Asyncgen", "Coroutine", ) if is_async: code_body = ExpressionAsyncgenObjectBody( provider=provider, name="<genexpr>", code_object=code_object, flags=None, auto_release=None, source_ref=source_ref, ) maker_class = ExpressionMakeAsyncgenObject else: code_body = ExpressionGeneratorObjectBody( provider=provider, name="<genexpr>", code_object=code_object, flags=None, auto_release=None, source_ref=source_ref.atColumnNumber(node.col_offset + 1), ) maker_class = ExpressionMakeGeneratorObject function_body.setBody( makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable=iter_tmp, source=_makeIteratorCreation( provider=provider, qual=node.generators[0], for_asyncgen=is_async, source_ref=source_ref, ), source_ref=source_ref, ), makeTryFinallyStatement( provider=function_body, tried=StatementReturn( expression=maker_class( ExpressionFunctionRef(function_body=code_body, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), final=StatementReleaseVariable(variable=iter_tmp, source_ref=source_ref), source_ref=source_ref, ), )) statements, release_statements = _buildContractionBodyNode( provider=provider, node=node, emit_class=ExpressionYield, iter_tmp=iter_tmp, temp_scope=None, start_value=None, container_tmp=None, function_body=code_body, assign_provider=False, for_asyncgen=is_async, source_ref=source_ref, ) if is_async: statements.append(StatementGeneratorReturnNone(source_ref=source_ref)) statements = (makeTryFinallyStatement( provider=function_body, tried=statements, final=release_statements, source_ref=source_ref.atInternal(), ), ) code_body.setBody( makeStatementsSequenceFromStatement(statement=StatementsFrameGenerator( statements=mergeStatements(statements, False), code_object=code_object, source_ref=source_ref, ))) return function_body
def buildGeneratorExpressionNode(provider, node, source_ref): # Generator expressions are dealt with by general code. assert getKind(node) == "GeneratorExp" function_body = ExpressionOutlineBody(provider=provider, name="genexpr", source_ref=source_ref) iter_tmp = function_body.allocateTempVariable(temp_scope=None, name=".0") parent_module = provider.getParentModule() code_object = CodeObjectSpec( co_name="<genexpr>", co_kind="Generator", co_varnames=(".0", ), co_argcount=1, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False, co_filename=parent_module.getRunTimeFilename(), co_lineno=source_ref.getLineNumber(), future_spec=parent_module.getFutureSpec()) code_body = ExpressionGeneratorObjectBody(provider=provider, name="<genexpr>", flags=set(), source_ref=source_ref) function_body.setBody( makeStatementsSequenceFromStatements( StatementAssignmentVariable(variable=iter_tmp, source=ExpressionBuiltinIter1( value=buildNode( provider=provider, node=node.generators[0].iter, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), makeTryFinallyStatement( provider=function_body, tried=StatementReturn(expression=ExpressionMakeGeneratorObject( generator_ref=ExpressionFunctionRef( function_body=code_body, source_ref=source_ref), code_object=code_object, source_ref=source_ref), source_ref=source_ref), final=StatementReleaseVariable(variable=iter_tmp, source_ref=source_ref), source_ref=source_ref))) statements, release_statements = _buildContractionBodyNode( function_body=code_body, provider=provider, node=node, emit_class=ExpressionYield, iter_tmp=iter_tmp, temp_scope=None, start_value=None, container_tmp=None, assign_provider=False, source_ref=source_ref, ) statements = (makeTryFinallyStatement( provider=function_body, tried=statements, final=release_statements, source_ref=source_ref.atInternal()), ) code_body.setBody( makeStatementsSequenceFromStatement(statement=StatementsFrameGenerator( statements=mergeStatements(statements, False), code_object=code_object, source_ref=source_ref))) return function_body
def buildClassNode2(provider, node, source_ref): # This function is the Python2 special case with special re-formulation as # according to developer manual, and it's very detailed, pylint: disable=too-many-locals class_statement_nodes, class_doc = extractDocFromBody(node) function_body = ExpressionClassBody( provider=provider, name=node.name, doc=class_doc, source_ref=source_ref ) parent_module = provider.getParentModule() code_object = CodeObjectSpec( co_name=node.name, co_kind="Class", co_varnames=(), co_argcount=0, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False, co_filename=parent_module.getRunTimeFilename(), co_lineno=source_ref.getLineNumber(), future_spec=parent_module.getFutureSpec(), ) body = buildFrameNode( provider=function_body, nodes=class_statement_nodes, code_object=code_object, 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() locals_scope = function_body.getFunctionLocalsScope() # 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 = [ StatementSetLocalsDictionary(locals_scope=locals_scope, source_ref=source_ref), StatementAssignmentVariableName( provider=function_body, variable_name="__module__", source=makeConstantRefNode( constant=provider.getParentModule().getFullName(), source_ref=source_ref, user_provided=True, ), source_ref=source_ref.atInternal(), ), ] if class_doc is not None: statements.append( StatementAssignmentVariableName( provider=function_body, variable_name="__doc__", source=makeConstantRefNode( constant=class_doc, source_ref=source_ref, user_provided=True ), source_ref=source_ref.atInternal(), ) ) statements += [ body, StatementReturn( expression=ExpressionBuiltinLocalsRef( locals_scope=locals_scope, source_ref=source_ref ), source_ref=source_ref, ), ] body = makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement( provider=function_body, tried=mergeStatements(statements, True), final=StatementReleaseLocals( locals_scope=locals_scope, source_ref=source_ref ), 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") select_metaclass = ExpressionOutlineBody( provider=provider, name="select_metaclass", body=None, source_ref=source_ref ) if node.bases: tmp_base = select_metaclass.allocateTempVariable(temp_scope=None, name="base") statements = ( StatementAssignmentVariable( variable=tmp_base, source=ExpressionSubscriptLookup( subscribed=ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref ), subscript=makeConstantRefNode( constant=0, source_ref=source_ref, user_provided=True ), source_ref=source_ref, ), source_ref=source_ref, ), makeTryFinallyStatement( provider, tried=StatementTry( tried=makeStatementsSequenceFromStatement( statement=StatementReturn( expression=ExpressionAttributeLookup( source=ExpressionTempVariableRef( variable=tmp_base, source_ref=source_ref ), attribute_name="__class__", source_ref=source_ref, ), source_ref=source_ref, ) ), except_handler=makeStatementsSequenceFromStatement( statement=StatementReturn( expression=ExpressionBuiltinType1( value=ExpressionTempVariableRef( variable=tmp_base, source_ref=source_ref ), source_ref=source_ref, ), source_ref=source_ref, ) ), break_handler=None, continue_handler=None, return_handler=None, source_ref=source_ref, ), final=StatementReleaseVariable( variable=tmp_base, source_ref=source_ref ), source_ref=source_ref, public_exc=False, ), ) else: statements = ( StatementTry( tried=makeStatementsSequenceFromStatement( statement=StatementReturn( # TODO: Should avoid checking __builtins__ for this. expression=ExpressionVariableNameRef( variable_name="__metaclass__", provider=parent_module, source_ref=source_ref, ), source_ref=source_ref, ) ), except_handler=makeStatementsSequenceFromStatement( statement=StatementReturn( expression=ExpressionBuiltinAnonymousRef( builtin_name="classobj", source_ref=source_ref ), source_ref=source_ref, ) ), break_handler=None, continue_handler=None, return_handler=None, source_ref=source_ref, ), ) select_metaclass.setBody( makeStatementsSequence( statements=statements, allow_none=False, source_ref=source_ref ) ) statements = [ StatementAssignmentVariable( variable=tmp_bases, source=makeSequenceCreationOrConstant( sequence_kind="tuple", elements=buildNodeList( provider=provider, nodes=node.bases, source_ref=source_ref ), source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariable( variable=tmp_class_dict, source=function_body, source_ref=source_ref ), StatementAssignmentVariable( variable=tmp_metaclass, source=ExpressionConditional( condition=ExpressionDictOperationIn( key=makeConstantRefNode( constant="__metaclass__", source_ref=source_ref, user_provided=True, ), dict_arg=ExpressionTempVariableRef( variable=tmp_class_dict, source_ref=source_ref ), source_ref=source_ref, ), expression_yes=ExpressionDictOperationGet( dict_arg=ExpressionTempVariableRef( variable=tmp_class_dict, source_ref=source_ref ), key=makeConstantRefNode( constant="__metaclass__", source_ref=source_ref, user_provided=True, ), source_ref=source_ref, ), expression_no=select_metaclass, source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariable( variable=tmp_class, source=makeExpressionCall( called=ExpressionTempVariableRef( variable=tmp_metaclass, source_ref=source_ref ), args=ExpressionMakeTuple( elements=( makeConstantRefNode( 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, ), kw=None, source_ref=source_ref, ), source_ref=source_ref, ), ] for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): statements.append( StatementAssignmentVariable( variable=tmp_class, source=makeExpressionCall( called=decorator, args=ExpressionMakeTuple( elements=( ExpressionTempVariableRef( variable=tmp_class, source_ref=source_ref ), ), source_ref=source_ref, ), kw=None, source_ref=decorator.getSourceReference(), ), source_ref=decorator.getSourceReference(), ) ) statements.append( StatementAssignmentVariableName( provider=provider, variable_name=mangleName(node.name, provider), source=ExpressionTempVariableRef(variable=tmp_class, source_ref=source_ref), source_ref=source_ref, ) ) final = ( StatementReleaseVariable(variable=tmp_class, source_ref=source_ref), StatementReleaseVariable(variable=tmp_bases, source_ref=source_ref), StatementReleaseVariable(variable=tmp_class_dict, source_ref=source_ref), StatementReleaseVariable(variable=tmp_metaclass, source_ref=source_ref), ) return makeTryFinallyStatement( provider=function_body, tried=statements, final=final, source_ref=source_ref )
def buildComplexComparisonNode(provider, left, rights, comparators, source_ref): # This is a bit complex, due to the many details, pylint: disable=too-many-locals outline_body = ExpressionOutlineBody( provider=provider, name="comparison_chain", source_ref=source_ref ) variables = [ outline_body.allocateTempVariable(temp_scope=None, name="operand_%d" % count) for count in range(2, len(rights) + 2) ] tmp_variable = outline_body.allocateTempVariable( temp_scope=None, name="comparison_result" ) def makeTempAssignment(count, value): return StatementAssignmentVariable( variable=variables[count], source=value, source_ref=source_ref ) def makeReleaseStatement(count): return StatementReleaseVariable( variable=variables[count], source_ref=source_ref ) def makeValueComparisonReturn(left, right, comparator): yield StatementAssignmentVariable( variable=tmp_variable, source=_makeComparisonNode( left=left, right=right, comparator=comparator, source_ref=source_ref ), source_ref=source_ref, ) yield makeStatementConditional( condition=ExpressionOperationNOT( operand=ExpressionTempVariableRef( variable=tmp_variable, source_ref=source_ref ), source_ref=source_ref, ), yes_branch=StatementReturn( expression=ExpressionTempVariableRef( variable=tmp_variable, source_ref=source_ref ), source_ref=source_ref, ), no_branch=None, source_ref=source_ref, ) statements = [] final = [] for count, value in enumerate(rights): if value is not rights[-1]: statements.append(makeTempAssignment(count, value)) final.append(makeReleaseStatement(count)) right = ExpressionTempVariableRef( variable=variables[count], source_ref=source_ref ) else: right = value if count != 0: left = ExpressionTempVariableRef( variable=variables[count - 1], source_ref=source_ref ) comparator = comparators[count] if value is not rights[-1]: statements.extend(makeValueComparisonReturn(left, right, comparator)) else: statements.append( StatementReturn( expression=_makeComparisonNode( left=left, right=right, comparator=comparator, source_ref=source_ref, ), source_ref=source_ref, ) ) final.append( StatementReleaseVariable(variable=tmp_variable, source_ref=source_ref) ) outline_body.setBody( makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement( provider=outline_body, tried=statements, final=final, source_ref=source_ref, ) ) ) return outline_body
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. # Note: The assign_provider is only to cover Python2 list contractions, # assigning one of the loop variables to the outside scope. if assign_provider: function_body = ExpressionOutlineBody( provider=provider, name=name, body=None, # later source_ref=source_ref) iter_tmp = function_body.allocateTempVariable(temp_scope=None, name=".0") else: function_body = ExpressionFunctionBody(provider=provider, name=name, doc=None, parameters=ParameterSpec( name="contraction", normal_args=(".0", ), list_star_arg=None, dict_star_arg=None, default_count=0, kw_only_args=()), is_class=False, source_ref=source_ref) iter_tmp = function_body.getVariableForAssignment(variable_name=".0") assert iter_tmp.isParameterVariable() if start_value is not None: container_tmp = function_body.allocateTempVariable( temp_scope=None, name="contraction_result") else: container_tmp = None statements, release_statements = _buildContractionBodyNode( function_body=function_body, assign_provider=assign_provider, provider=provider, node=node, emit_class=emit_class, iter_tmp=iter_tmp, temp_scope=None, start_value=start_value, container_tmp=container_tmp, source_ref=source_ref, ) if start_value is not None: statements.append( StatementReturn(expression=ExpressionTempVariableRef( variable=container_tmp, source_ref=source_ref), source_ref=source_ref)) statements = (makeTryFinallyStatement( provider=function_body, tried=statements, final=release_statements, source_ref=source_ref.atInternal()), ) function_body.setBody( makeStatementsSequenceFromStatement(statement=StatementsFrame( statements=mergeStatements(statements, False), 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))) if not assign_provider: 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) else: return function_body
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 buildCallNode(provider, node, source_ref): called = buildNode(provider, node.func, source_ref) if python_version >= 350: list_star_arg = None dict_star_arg = None positional_args = [] # For Python3.5 compatibility, the error handling with star argument last # is the old one, only with a starred argument before that, things use the # new unpacking code. for node_arg in node.args[:-1]: if getKind(node_arg) == "Starred": assert python_version >= 350 list_star_arg = buildListUnpacking(provider, node.args, source_ref) positional_args = [] break else: if node.args and getKind(node.args[-1]) == "Starred": assert python_version >= 350 list_star_arg = buildNode(provider, node.args[-1].value, source_ref) positional_args = buildNodeList(provider, node.args[:-1], source_ref) else: positional_args = buildNodeList(provider, node.args, source_ref) # Only the values of keyword pairs have a real source ref, and those only # really matter, so that makes sense. keys = [] values = [] for keyword in node.keywords[:-1]: if keyword.arg is None: assert python_version >= 350 outline_body = ExpressionOutlineBody(provider=provider, name="dict_unpacking_call", source_ref=source_ref) tmp_called = outline_body.allocateTempVariable(temp_scope=None, name="called") helper_args = [ ExpressionTempVariableRef(variable=tmp_called, source_ref=source_ref), ExpressionMakeTuple( elements=buildDictionaryUnpackingArgs( provider=provider, keys=(keyword.arg for keyword in node.keywords), values=(keyword.value for keyword in node.keywords), source_ref=source_ref, ), source_ref=source_ref, ), ] dict_star_arg = ExpressionFunctionCall( function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef( function_body=getFunctionCallHelperDictionaryUnpacking( ), source_ref=source_ref, ), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref, ), values=helper_args, source_ref=source_ref, ) outline_body.setBody( makeStatementsSequenceFromStatements( StatementAssignmentVariable(variable=tmp_called, source=called, source_ref=source_ref), StatementReturn( expression=_makeCallNode( called=ExpressionTempVariableRef( variable=tmp_called, source_ref=source_ref), positional_args=positional_args, keys=keys, values=values, list_star_arg=list_star_arg, dict_star_arg=dict_star_arg, source_ref=source_ref, ), source_ref=source_ref, ), )) return outline_body # For Python3.5 compatibility, the error handling with star argument last # is the old one, only with a starred argument before that, things use the # new unpacking code. if node.keywords and node.keywords[-1].arg is None: assert python_version >= 350 dict_star_arg = buildNode(provider, node.keywords[-1].value, source_ref) keywords = node.keywords[:-1] else: keywords = node.keywords for keyword in keywords: keys.append( makeConstantRefNode(constant=keyword.arg, source_ref=source_ref, user_provided=True)) values.append(buildNode(provider, keyword.value, source_ref)) if python_version < 350: list_star_arg = buildNode(provider, node.starargs, source_ref, True) dict_star_arg = buildNode(provider, node.kwargs, source_ref, True) return _makeCallNode( called=called, positional_args=positional_args, keys=keys, values=values, list_star_arg=list_star_arg, dict_star_arg=dict_star_arg, 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. # Note: The assign_provider is only to cover Python2 list contractions, # assigning one of the loop variables to the outside scope. if assign_provider: function_body = ExpressionOutlineBody( provider = provider, name = name, body = None, # later source_ref = source_ref ) iter_tmp = function_body.allocateTempVariable( temp_scope = None, name = ".0" ) else: function_body = ExpressionFunctionBody( provider = provider, name = name, doc = None, parameters = ParameterSpec( name = "contraction", normal_args = (".0",), list_star_arg = None, dict_star_arg = None, default_count = 0, kw_only_args = () ), is_class = False, source_ref = source_ref ) iter_tmp = function_body.getVariableForAssignment( variable_name = ".0" ) assert iter_tmp.isParameterVariable() if start_value is not None: container_tmp = function_body.allocateTempVariable( temp_scope = None, name = "contraction_result" ) else: container_tmp = None statements, release_statements = _buildContractionBodyNode( function_body = function_body, assign_provider = assign_provider, provider = provider, node = node, emit_class = emit_class, iter_tmp = iter_tmp, temp_scope = None, start_value = start_value, container_tmp = container_tmp, source_ref = source_ref, ) if start_value is not None: statements.append( StatementReturn( expression = ExpressionTempVariableRef( variable = container_tmp, source_ref = source_ref ), source_ref = source_ref ) ) statements = ( makeTryFinallyStatement( provider = function_body, tried = statements, final = release_statements, source_ref = source_ref.atInternal() ), ) function_body.setBody( makeStatementsSequenceFromStatement( statement = StatementsFrame( statements = mergeStatements(statements, False), 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 ) ) ) if not assign_provider: 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 ) else: return function_body
def wrapEvalBuiltin(source, globals_arg, locals_arg, source_ref): provider = node.getParentVariableProvider() outline_body = ExpressionOutlineBody( provider=node.getParentVariableProvider(), name="eval_call", body=None, source_ref=source_ref # later ) 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_ref=ExpressionTargetTempVariableRef(variable=source_variable, 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, source_ref=source_ref), source_ref=source_ref, ), right=ExpressionBuiltinRef(builtin_name="bytes", source_ref=source_ref), source_ref=source_ref, ), expression_yes=ExpressionConstantRef(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_ref=ExpressionTargetTempVariableRef(variable=source_variable, source_ref=source_ref), source=ExpressionCallNoKeywords( called=ExpressionAttributeLookup( source=ExpressionTempVariableRef(variable=source_variable, 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, source_ref=source_ref), source=source, source_ref=source_ref, ), StatementConditional( condition=ExpressionOperationNOT( operand=ExpressionBuiltinIsinstance( instance=ExpressionTempVariableRef(variable=source_variable, source_ref=source_ref), classes=ExpressionBuiltinAnonymousRef(builtin_name="code", 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, ), 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 convertFunctionCallToOutline(provider, function_ref, values): # This has got to have pretty man details, pylint: disable=too-many-locals function_body = function_ref.getFunctionBody() call_source_ref = function_ref.getSourceReference() function_source_ref = function_body.getSourceReference() outline_body = ExpressionOutlineBody(provider=provider, name="inline", source_ref=function_source_ref) clone = function_body.getBody().makeClone() temp_scope = outline_body.getOutlineTempScope() translation = {} for variable in function_body.getLocalVariables(): # TODO: Later we should be able to do that too. assert variable.isSharedTechnically() is False new_variable = outline_body.allocateTempVariable( temp_scope=temp_scope, name=variable.getName()) # TODO: Lets update all at once maybe, it would take less visits. updateVariableUsage(clone, old_variable=variable, new_variable=new_variable) translation[variable.getName()] = new_variable statements = [] if function_body.isExpressionClassBody(): argument_names = () else: argument_names = function_body.getParameters().getParameterNames() assert len(argument_names) == len(values), (argument_names, values) for argument_name, value in zip(argument_names, values): statements.append( StatementAssignmentVariable( variable=translation[argument_name], source=value, source_ref=call_source_ref, )) body = makeStatementsSequence(statements=(statements, clone), allow_none=False, source_ref=function_source_ref) auto_releases = function_body.getFunctionVariablesWithAutoReleases() if auto_releases: releases = [ StatementReleaseVariable(variable=variable, source_ref=function_source_ref) for variable in auto_releases ] body = makeTryFinallyStatement( provider=outline_body, tried=body, final=releases, source_ref=function_source_ref, ) outline_body.setBody(body) return outline_body
def buildCallNode(provider, node, source_ref): called = buildNode(provider, node.func, source_ref) if python_version >= 350: list_star_arg = None dict_star_arg = None positional_args = [] # For Python3.5 compatibility, the error handling with star argument last # is the old one, only with a starred argument before that, things use the # new unpacking code. for node_arg in node.args[:-1]: if getKind(node_arg) == "Starred": assert python_version >= 350 list_star_arg = buildListUnpacking(provider, node.args, source_ref) positional_args = [] break else: if node.args and getKind(node.args[-1]) == "Starred": assert python_version >= 350 list_star_arg = buildNode(provider, node.args[-1].value, source_ref) positional_args = buildNodeList(provider, node.args[:-1], source_ref) else: positional_args = buildNodeList(provider, node.args, source_ref) # Only the values of keyword pairs have a real source ref, and those only # really matter, so that makes sense. keys = [] values = [] for keyword in node.keywords[:-1]: if keyword.arg is None: assert python_version >= 350 outline_body = ExpressionOutlineBody( provider = provider, name = "dict_unpacking_call", source_ref = source_ref ) tmp_called = outline_body.allocateTempVariable( temp_scope = None, name = "called" ) helper_args = [ ExpressionTempVariableRef( variable = tmp_called, source_ref = source_ref ), ExpressionMakeTuple( elements = buildDictionaryUnpackingArgs( provider = provider, keys = (keyword.arg for keyword in node.keywords), values = (keyword.value for keyword in node.keywords), source_ref = source_ref ), source_ref = source_ref ) ] dict_star_arg = ExpressionFunctionCall( function = ExpressionFunctionCreation( function_ref = ExpressionFunctionRef( function_body = getFunctionCallHelperDictionaryUnpacking(), source_ref = source_ref ), code_object = None, defaults = (), kw_defaults = None, annotations = None, source_ref = source_ref ), values = helper_args, source_ref = source_ref, ) outline_body.setBody( makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_called, source_ref = source_ref ), source = called, source_ref = source_ref ), StatementReturn( expression = _makeCallNode( called = ExpressionTempVariableRef( variable = tmp_called, source_ref = source_ref ), positional_args = positional_args, keys = keys, values = values, list_star_arg = list_star_arg, dict_star_arg = dict_star_arg, source_ref = source_ref, ), source_ref = source_ref ) ) ) return outline_body # For Python3.5 compatibility, the error handling with star argument last # is the old one, only with a starred argument before that, things use the # new unpacking code. if node.keywords and node.keywords[-1].arg is None: assert python_version >= 350 dict_star_arg = buildNode(provider, node.keywords[-1].value, source_ref) keywords = node.keywords[:-1] else: keywords = node.keywords for keyword in keywords: keys.append( ExpressionConstantRef( constant = keyword.arg, source_ref = source_ref, user_provided = True ) ) values.append( buildNode(provider, keyword.value, source_ref) ) if python_version < 350: list_star_arg = buildNode(provider, node.starargs, source_ref, True) dict_star_arg = buildNode(provider, node.kwargs, source_ref, True) return _makeCallNode( called = called, positional_args = positional_args, keys = keys, values = values, list_star_arg = list_star_arg, dict_star_arg = dict_star_arg, source_ref = source_ref, )
def buildComplexComparisonNode(provider, left, rights, comparators, source_ref): # This is a bit complex, due to the many details, pylint: disable=too-many-locals outline_body = ExpressionOutlineBody(provider=provider, name="comparison_chain", source_ref=source_ref) variables = [ outline_body.allocateTempVariable(temp_scope=None, name="operand_%d" % count) for count in range(2, len(rights) + 2) ] tmp_variable = outline_body.allocateTempVariable(temp_scope=None, name="comparison_result") def makeTempAssignment(count, value): return StatementAssignmentVariable( variable=variables[count], source=value, source_ref=source_ref, ) def makeReleaseStatement(count): return StatementReleaseVariable(variable=variables[count], source_ref=source_ref) def makeValueComparisonReturn(left, right, comparator): yield StatementAssignmentVariable( variable=tmp_variable, source=makeComparisonNode(left=left, right=right, comparator=comparator, source_ref=source_ref), source_ref=source_ref, ) yield StatementConditional( condition=ExpressionOperationNOT(operand=ExpressionTempVariableRef( variable=tmp_variable, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=StatementReturn(expression=ExpressionTempVariableRef( variable=tmp_variable, source_ref=source_ref), source_ref=source_ref)), no_branch=None, source_ref=source_ref) statements = [] final = [] for count, value in enumerate(rights): if value is not rights[-1]: statements.append(makeTempAssignment(count, value)) final.append(makeReleaseStatement(count)) right = ExpressionTempVariableRef(variable=variables[count], source_ref=source_ref) else: right = value if count != 0: left = ExpressionTempVariableRef(variable=variables[count - 1], source_ref=source_ref) comparator = comparators[count] if value is not rights[-1]: statements.extend( makeValueComparisonReturn(left, right, comparator)) else: statements.append( StatementReturn(expression=makeComparisonNode( left=left, right=right, comparator=comparator, source_ref=source_ref), source_ref=source_ref)) final.append( StatementReleaseVariable(variable=tmp_variable, source_ref=source_ref)) outline_body.setBody( makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement(provider=outline_body, tried=statements, final=final, source_ref=source_ref))) return outline_body