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 buildAsyncFunctionNode(provider, node, source_ref): # We are creating a function here that creates coroutine objects, with # many details each, pylint: disable=too-many-locals assert getKind(node) == "AsyncFunctionDef" function_statement_nodes, function_doc = extractDocFromBody(node) function_kind, flags = detectFunctionBodyKind( nodes=function_statement_nodes, start_value="Coroutine" ) creator_function_body, _, code_object = buildFunctionWithParsing( provider=provider, function_kind=function_kind, name=node.name, function_doc=function_doc, flags=(), node=node, source_ref=source_ref, ) if function_kind == "Coroutine": function_body = ExpressionCoroutineObjectBody( provider=creator_function_body, name=node.name, code_object=code_object, flags=flags, auto_release=None, source_ref=source_ref, ) else: function_body = ExpressionAsyncgenObjectBody( provider=creator_function_body, name=node.name, code_object=code_object, flags=flags, auto_release=None, source_ref=source_ref, ) function_body.qualname_provider = provider for variable in creator_function_body.getProvidedVariables(): function_body.getVariableForReference(variable.getName()) decorators = buildNodeList( provider=provider, nodes=reversed(node.decorator_list), source_ref=source_ref ) defaults = buildNodeList( provider=provider, nodes=node.args.defaults, source_ref=source_ref ) function_statements_body = buildFrameNode( provider=function_body, nodes=function_statement_nodes, code_object=code_object, source_ref=source_ref, ) function_statements_body = _insertFinalReturnStatement( function_statements_body=function_statements_body, return_statement=StatementGeneratorReturnNone(source_ref=source_ref), ) if function_statements_body.isStatementsFrame(): function_statements_body = makeStatementsSequenceFromStatement( statement=function_statements_body ) function_body.setChild("body", function_statements_body) annotations = buildParameterAnnotations(provider, node, source_ref) kw_defaults = buildParameterKwDefaults( provider=provider, node=node, function_body=creator_function_body, source_ref=source_ref, ) if function_kind == "Coroutine": creation_node = ExpressionMakeCoroutineObject( coroutine_ref=ExpressionFunctionRef( function_body=function_body, source_ref=source_ref ), source_ref=source_ref, ) else: creation_node = ExpressionMakeAsyncgenObject( asyncgen_ref=ExpressionFunctionRef( function_body=function_body, source_ref=source_ref ), source_ref=source_ref, ) creator_function_body.setChild( "body", makeStatementsSequenceFromStatement( statement=StatementReturn(expression=creation_node, source_ref=source_ref) ), ) function_creation = ExpressionFunctionCreation( function_ref=ExpressionFunctionRef( function_body=creator_function_body, source_ref=source_ref ), defaults=defaults, kw_defaults=kw_defaults, annotations=annotations, source_ref=source_ref, ) decorated_function = function_creation for decorator in decorators: decorated_function = makeCallNode( decorator, decorated_function, decorator.getSourceReference() ) result = StatementAssignmentVariableName( provider=provider, variable_name=mangleName(node.name, provider), source=decorated_function, source_ref=source_ref, ) function_body.qualname_setup = result.getVariableName() # Share the non-local declarations. TODO: This may also apply to generators # and async generators. creator_function_body.non_local_declarations = function_body.non_local_declarations return result
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()) is_async = sum(getattr(qual, "is_async", 0) for qual in node.generators) if is_async: code_body = ExpressionAsyncgenObjectBody(provider=provider, name="<genexpr>", flags=set(), source_ref=source_ref) maker_class = ExpressionMakeAsyncgenObject else: code_body = ExpressionGeneratorObjectBody(provider=provider, name="<genexpr>", flags=set(), source_ref=source_ref) maker_class = ExpressionMakeGeneratorObject function_body.setBody( makeStatementsSequenceFromStatements( StatementAssignmentVariable(variable=iter_tmp, source=_makeIteratorCreation( provider, node.generators[0], source_ref), source_ref=source_ref), makeTryFinallyStatement( provider=function_body, tried=StatementReturn(expression=maker_class( 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, ) 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