def buildFrameNode(provider, nodes, code_object, source_ref): # We are not creating empty statement sequences. if nodes is None: return None # Build as list of statements, throw away empty ones, and remove useless # nesting. statements = buildNodeList(provider, nodes, source_ref, allow_none = True) statements = mergeStatements(statements) # We are not creating empty statement sequences. Might be empty, because # e.g. a global node generates not really a statement, or pass statements. if not statements: return None if provider.isExpressionOutlineFunction(): provider = provider.getParentVariableProvider() if provider.isExpressionFunctionBody() or \ provider.isExpressionClassBody(): result = StatementsFrameFunction( statements = statements, code_object = code_object, source_ref = source_ref ) elif provider.isExpressionGeneratorObjectBody(): result = StatementsFrameGenerator( statements = statements, code_object = code_object, source_ref = source_ref ) elif provider.isExpressionCoroutineObjectBody(): result = StatementsFrameCoroutine( statements = statements, code_object = code_object, source_ref = source_ref ) elif provider.isExpressionAsyncgenObjectBody(): result = StatementsFrameAsyncgen( statements = statements, code_object = code_object, source_ref = source_ref ) else: assert False, provider 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_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