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 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 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 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 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=too-many-locals 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=makeConstantRefNode(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 not provider.isCompiledPythonModule(): 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 = ExpressionConstantNoneRef(source_ref=source_ref) globals_value = buildNode(provider, exec_globals, source_ref, True) if globals_value is None: globals_value = ExpressionConstantNoneRef(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 = ( # First evaluate the source code expressions. StatementAssignmentVariable(variable=source_variable, 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=globals_keeper_variable, source=globals_value, source_ref=source_ref), StatementAssignmentVariable(variable=locals_keeper_variable, source=locals_value, source_ref=source_ref), StatementAssignmentVariable(variable=plain_indicator_variable, source=makeConstantRefNode( constant=False, source_ref=source_ref), source_ref=source_ref), StatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=globals_keeper_variable, source_ref=source_ref), right=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable=globals_keeper_variable, source=ExpressionBuiltinGlobals(source_ref=source_ref), source_ref=source_ref, ), StatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=locals_keeper_variable, source_ref=source_ref), right=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable=locals_keeper_variable, source=makeExpressionBuiltinLocals( provider=provider, source_ref=source_ref), source_ref=source_ref, ), StatementAssignmentVariable( variable=plain_indicator_variable, source=makeConstantRefNode(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=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=StatementAssignmentVariable( variable=locals_keeper_variable, 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=source_variable, 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), makeTryFinallyStatement( provider=provider, tried=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=StatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=plain_indicator_variable, source_ref=source_ref), right=makeConstantRefNode(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), source_ref=source_ref)) final = ( StatementReleaseVariable(variable=source_variable, source_ref=source_ref), StatementReleaseVariable(variable=globals_keeper_variable, source_ref=source_ref), StatementReleaseVariable(variable=locals_keeper_variable, source_ref=source_ref), StatementReleaseVariable(variable=plain_indicator_variable, source_ref=source_ref), ) return makeTryFinallyStatement(provider=provider, tried=tried, final=final, source_ref=source_ref)