def buildReturnNode(provider, node, source_ref): if not provider.isExpressionFunctionBody() or \ provider.isClassDictCreation(): SyntaxErrors.raiseSyntaxError( "'return' outside function", source_ref, None if Utils.python_version < 300 else ( node.col_offset if provider.isPythonModule() else node.col_offset+4 ) ) expression = buildNode(provider, node.value, source_ref, allow_none = True) if expression is None: expression = ExpressionConstantRef( constant = None, source_ref = source_ref, user_provided = True ) # Indicate exceptions to potentially try/finally structures. indicator_statements = makeTryFinallyIndicatorStatements( is_loop_exit = False, source_ref = source_ref ) if indicator_statements and expression.mayRaiseException(BaseException): tmp_variable = provider.allocateTempVariable( temp_scope = provider.allocateTempScope("return"), name = "value" ) statements = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable, source_ref = expression.getSourceReference() ), source = expression, source_ref = source_ref ) ] + indicator_statements + [ StatementReturn( expression = ExpressionTempVariableRef( variable = tmp_variable, source_ref = expression.getSourceReference() ), source_ref = source_ref ) ] return makeTryFinallyStatement( tried = statements, final = StatementReleaseVariable( variable = tmp_variable, tolerant = True, source_ref = source_ref ), source_ref = source_ref ) else: return makeStatementsSequenceOrStatement( statements = indicator_statements + [ StatementReturn( expression = expression, source_ref = source_ref ) ], source_ref = source_ref )