def makeTryExceptNoRaise(provider, temp_scope, tried, handling, no_raise, source_ref): # This helper executes the core re-formulation of "no_raise" blocks, which # are the "else" blocks of "try"/"except" statements. In order to limit the # execution, we use an indicator variable instead, which will signal that # the tried block executed up to the end. And then we make the else block be # a conditional statement checking that. tmp_handler_indicator_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "unhandled_indicator" ) statements = mergeStatements( ( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_handler_indicator_variable, source_ref = source_ref.atInternal() ), source = makeConstantRefNode( constant = False, source_ref = source_ref ), source_ref = no_raise.getSourceReference().atInternal() ), handling ), allow_none = True ) handling = StatementsSequence( statements = statements, source_ref = source_ref ) tried = ( StatementTry( tried = tried, except_handler = handling, break_handler = None, continue_handler = None, return_handler = None, source_ref = source_ref ), StatementConditional( condition = ExpressionComparisonIs( left = ExpressionTempVariableRef( variable = tmp_handler_indicator_variable, source_ref = source_ref ), right = makeConstantRefNode( constant = True, source_ref = source_ref ), source_ref = source_ref ), yes_branch = no_raise, no_branch = None, source_ref = source_ref ) ) final = StatementReleaseVariable( variable = tmp_handler_indicator_variable, source_ref = source_ref.atInternal() ) return makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_handler_indicator_variable, source_ref = source_ref.atInternal() ), source = makeConstantRefNode( constant = True, source_ref = source_ref ), source_ref = source_ref.atInternal() ), makeTryFinallyStatement( provider = provider, tried = tried, final = final, source_ref = source_ref ) )
def buildClassNode3(provider, node, source_ref): # Many variables, due to the huge re-formulation that is going on here, # which just has the complexity and optimization checks: # pylint: disable=I0021,too-many-branches,too-many-locals,too-many-statements # This function is the Python3 special case with special re-formulation as # according to developer manual. class_statement_nodes, class_doc = extractDocFromBody(node) # We need a scope for the temporary variables, and they might be closured. temp_scope = provider.allocateTempScope(name="class_creation") tmp_class_decl_dict = provider.allocateTempVariable(temp_scope=temp_scope, name="class_decl_dict") tmp_metaclass = provider.allocateTempVariable(temp_scope=temp_scope, name="metaclass") tmp_prepared = provider.allocateTempVariable(temp_scope=temp_scope, name="prepared") class_creation_function = ExpressionClassBody(provider=provider, name=node.name, doc=class_doc, source_ref=source_ref) class_locals_scope = class_creation_function.getLocalsScope() # Only local variable, for provision to methods. class_variable = class_locals_scope.getLocalVariable( owner=class_creation_function, variable_name="__class__") class_locals_scope.registerProvidedVariable(class_variable) class_variable_ref = ExpressionVariableRef(variable=class_variable, source_ref=source_ref) parent_module = provider.getParentModule() code_object = CodeObjectSpec( co_name=node.name, co_kind="Class", co_varnames=(), co_freevars=(), 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=class_creation_function, nodes=class_statement_nodes, code_object=code_object, source_ref=source_ref, ) source_ref_orig = source_ref if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref locals_scope = class_creation_function.getLocalsScope() statements = [ StatementSetLocals( locals_scope=locals_scope, new_locals=ExpressionTempVariableRef(variable=tmp_prepared, source_ref=source_ref), source_ref=source_ref, ), StatementAssignmentVariableName( provider=class_creation_function, variable_name="__module__", source=ExpressionModuleAttributeNameRef( variable=provider.getParentModule().getVariableForReference( "__name__"), source_ref=source_ref, ), source_ref=source_ref, ), ] if class_doc is not None: statements.append( StatementAssignmentVariableName( provider=class_creation_function, variable_name="__doc__", source=makeConstantRefNode(constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref, )) # The "__qualname__" attribute is new in Python3. qualname = class_creation_function.getFunctionQualname() if python_version < 340: qualname_ref = makeConstantRefNode(constant=qualname, source_ref=source_ref, user_provided=True) else: qualname_ref = ExpressionFunctionQualnameRef( function_body=class_creation_function, source_ref=source_ref) statements.append( StatementLocalsDictOperationSet( locals_scope=locals_scope, variable_name="__qualname__", value=qualname_ref, source_ref=source_ref, )) if python_version >= 340: qualname_assign = statements[-1] if python_version >= 360 and class_creation_function.needsAnnotationsDictionary( ): statements.append( StatementLocalsDictOperationSet( locals_scope=locals_scope, variable_name="__annotations__", value=makeConstantRefNode(constant={}, source_ref=source_ref, user_provided=True), source_ref=source_ref, )) statements.append(body) if node.bases: tmp_bases = provider.allocateTempVariable(temp_scope=temp_scope, name="bases") if python_version >= 370: tmp_bases_orig = provider.allocateTempVariable( temp_scope=temp_scope, name="bases_orig") def makeBasesRef(): return ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref) else: def makeBasesRef(): return makeConstantRefNode(constant=(), source_ref=source_ref) if python_version >= 370 and node.bases: statements.append( makeStatementConditional( condition=makeComparisonExpression( comparator="NotEq", left=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), right=ExpressionTempVariableRef(variable=tmp_bases_orig, source_ref=source_ref), source_ref=source_ref, ), yes_branch=StatementLocalsDictOperationSet( locals_scope=locals_scope, variable_name="__orig_bases__", value=ExpressionTempVariableRef(variable=tmp_bases_orig, source_ref=source_ref), source_ref=source_ref, ), no_branch=None, source_ref=source_ref, )) statements += ( StatementAssignmentVariable( variable=class_variable, source=makeExpressionCall( called=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), args=makeExpressionMakeTuple( elements=( makeConstantRefNode( constant=node.name, source_ref=source_ref, user_provided=True, ), makeBasesRef(), ExpressionBuiltinLocalsRef(locals_scope=locals_scope, source_ref=source_ref), ), source_ref=source_ref, ), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), StatementReturn(expression=class_variable_ref, source_ref=source_ref), ) body = makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement( provider=class_creation_function, 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. class_creation_function.setBody(body) # The class body is basically a function that implicitly, at the end # returns its created class and cannot have other return statements # contained. decorated_body = class_creation_function for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): decorated_body = makeExpressionCall( called=decorator, args=makeExpressionMakeTuple(elements=(decorated_body, ), source_ref=source_ref), kw=None, source_ref=decorator.getSourceReference(), ) if node.keywords and node.keywords[-1].arg is None: keywords = node.keywords[:-1] else: keywords = node.keywords statements = [] if node.bases: statements.append( StatementAssignmentVariable( variable=tmp_bases if python_version < 370 else tmp_bases_orig, source=_buildBasesTupleCreationNode(provider=provider, elements=node.bases, source_ref=source_ref), source_ref=source_ref, )) if python_version >= 370: bases_conversion = ExpressionFunctionCall( function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef( function_body=getClassBasesMroConversionHelper(), source_ref=source_ref, ), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref, ), values=(ExpressionTempVariableRef(variable=tmp_bases_orig, source_ref=source_ref), ), source_ref=source_ref, ) statements.append( StatementAssignmentVariable(variable=tmp_bases, source=bases_conversion, source_ref=source_ref)) statements.append( StatementAssignmentVariable( variable=tmp_class_decl_dict, source=makeDictCreationOrConstant2( keys=[keyword.arg for keyword in keywords], values=[ buildNode(provider, keyword.value, source_ref) for keyword in keywords ], source_ref=source_ref, ), source_ref=source_ref, )) if node.keywords and node.keywords[-1].arg is None: statements.append( StatementDictOperationUpdate( dict_arg=ExpressionVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), value=buildNode(provider, node.keywords[-1].value, source_ref), source_ref=source_ref, )) # Check if there are bases, and if there are, go with the type of the # first base class as a metaclass unless it was specified in the class # decl dict of course. if node.bases: unspecified_metaclass_expression = ExpressionBuiltinType1( value=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, ) # Might become empty behind our back during conversion, therefore make the # check at run time for 3.7 or higher. if python_version >= 370: unspecified_metaclass_expression = ExpressionConditional( condition=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), expression_yes=unspecified_metaclass_expression, expression_no=makeExpressionBuiltinTypeRef( builtin_name="type", source_ref=source_ref), source_ref=source_ref, ) else: unspecified_metaclass_expression = makeExpressionBuiltinTypeRef( builtin_name="type", source_ref=source_ref) call_prepare = StatementAssignmentVariable( variable=tmp_prepared, source=makeExpressionCall( called=ExpressionAttributeLookup( expression=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), attribute_name="__prepare__", source_ref=source_ref, ), args=makeExpressionMakeTuple( elements=( makeConstantRefNode(constant=node.name, source_ref=source_ref, user_provided=True), makeBasesRef(), ), source_ref=source_ref, ), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ) if python_version >= 364: call_prepare = makeStatementsSequenceFromStatements( call_prepare, makeStatementConditional( condition=ExpressionAttributeCheck( expression=ExpressionTempVariableRef( variable=tmp_prepared, source_ref=source_ref), attribute_name="__getitem__", source_ref=source_ref, ), yes_branch=None, no_branch=makeRaiseExceptionExpressionFromTemplate( exception_type="TypeError", template="%s.__prepare__() must return a mapping, not %s", template_args=( ExpressionBuiltinGetattr( expression=ExpressionTempVariableRef( variable=tmp_metaclass, source_ref=source_ref), name=makeConstantRefNode(constant="__name__", source_ref=source_ref), default=makeConstantRefNode(constant="<metaclass>", source_ref=source_ref), source_ref=source_ref, ), ExpressionAttributeLookup( expression=ExpressionBuiltinType1( value=ExpressionTempVariableRef( variable=tmp_prepared, source_ref=source_ref), source_ref=source_ref, ), attribute_name="__name__", source_ref=source_ref, ), ), source_ref=source_ref, ).asStatement(), source_ref=source_ref, ), ) statements += ( StatementAssignmentVariable( variable=tmp_metaclass, source=ExpressionSelectMetaclass( metaclass=ExpressionConditional( condition=ExpressionDictOperationIn( key=makeConstantRefNode( constant="metaclass", source_ref=source_ref, user_provided=True, ), dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref, ), expression_yes=ExpressionDictOperationGet( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=makeConstantRefNode( constant="metaclass", source_ref=source_ref, user_provided=True, ), source_ref=source_ref, ), expression_no=unspecified_metaclass_expression, source_ref=source_ref, ), bases=makeBasesRef(), source_ref=source_ref, ), source_ref=source_ref_orig, ), makeStatementConditional( condition=ExpressionDictOperationIn( key=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref, ), no_branch=None, yes_branch=StatementDictOperationRemove( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref, ), source_ref=source_ref, ), makeStatementConditional( condition=ExpressionAttributeCheck( expression=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), attribute_name="__prepare__", source_ref=source_ref, ), yes_branch=call_prepare, no_branch=StatementAssignmentVariable( variable=tmp_prepared, source=makeConstantRefNode(constant={}, source_ref=source_ref, user_provided=True), source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariableName( provider=provider, variable_name=mangleName(node.name, provider), source=decorated_body, source_ref=source_ref, ), ) if python_version >= 340: class_creation_function.qualname_setup = node.name, qualname_assign final = [tmp_class_decl_dict, tmp_metaclass, tmp_prepared] if node.bases: final.insert(0, tmp_bases) if python_version >= 370: final.insert(0, tmp_bases_orig) return makeTryFinallyStatement( provider=provider, tried=statements, final=tuple( StatementReleaseVariable(variable=variable, source_ref=source_ref) for variable in final), source_ref=source_ref, )
def _buildWithNode(provider, context_expr, assign_target, body, sync, source_ref): # Many details, pylint: disable=too-many-locals with_source = buildNode(provider, context_expr, source_ref) if python_version < 380 and Options.is_fullcompat: source_ref = with_source.getCompatibleSourceReference() temp_scope = provider.allocateTempScope("with") tmp_source_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="source") tmp_exit_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="exit") tmp_enter_variable = provider.allocateTempVariable(temp_scope=temp_scope, name="enter") # Indicator variable, will end up with C bool type, and need not be released. tmp_indicator_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="indicator", temp_type="bool") statements = ( buildAssignmentStatements( provider=provider, node=assign_target, allow_none=True, source=ExpressionTempVariableRef(variable=tmp_enter_variable, source_ref=source_ref), source_ref=source_ref, ), body, ) with_body = makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref) if body: deepest = body while deepest.getVisitableNodes(): deepest = deepest.getVisitableNodes()[-1] if python_version < 370: body_lineno = deepest.getCompatibleSourceReference().getLineNumber( ) else: body_lineno = deepest.getSourceReference().getLineNumber() with_exit_source_ref = source_ref.atLineNumber(body_lineno) else: with_exit_source_ref = source_ref # The "__enter__" and "__exit__" were normal attribute lookups under # CPython2.6, but that changed with CPython2.7. if python_version < 270: attribute_lookup_class = ExpressionAttributeLookup else: attribute_lookup_class = ExpressionAttributeLookupSpecial enter_value = ExpressionCallEmpty( called=attribute_lookup_class( expression=ExpressionTempVariableRef(variable=tmp_source_variable, source_ref=source_ref), attribute_name="__enter__" if sync else "__aenter__", source_ref=source_ref, ), source_ref=source_ref, ) exit_value_exception = ExpressionCallNoKeywords( called=ExpressionTempVariableRef(variable=tmp_exit_variable, source_ref=with_exit_source_ref), args=makeExpressionMakeTuple( elements=( ExpressionCaughtExceptionTypeRef( source_ref=with_exit_source_ref), ExpressionCaughtExceptionValueRef( source_ref=with_exit_source_ref), ExpressionCaughtExceptionTracebackRef(source_ref=source_ref), ), source_ref=source_ref, ), source_ref=with_exit_source_ref, ) exit_value_no_exception = ExpressionCallNoKeywords( called=ExpressionTempVariableRef(variable=tmp_exit_variable, source_ref=source_ref), args=makeConstantRefNode(constant=(None, None, None), source_ref=source_ref), source_ref=with_exit_source_ref, ) # For "async with", await the entered value and exit value must be awaited. if not sync: enter_value = ExpressionYieldFromWaitable( expression=ExpressionAsyncWaitEnter(expression=enter_value, source_ref=source_ref), source_ref=source_ref, ) exit_value_exception = ExpressionYieldFromWaitable( expression=ExpressionAsyncWaitExit(expression=exit_value_exception, source_ref=source_ref), source_ref=source_ref, ) exit_value_no_exception = ExpressionYieldFromWaitable( ExpressionAsyncWaitExit(expression=exit_value_no_exception, source_ref=source_ref), source_ref=source_ref, ) statements = [ # First assign the with context to a temporary variable. StatementAssignmentVariable(variable=tmp_source_variable, source=with_source, source_ref=source_ref) ] attribute_assignments = [ # Next, assign "__enter__" and "__exit__" attributes to temporary # variables. StatementAssignmentVariable( variable=tmp_exit_variable, source=attribute_lookup_class( expression=ExpressionTempVariableRef( variable=tmp_source_variable, source_ref=source_ref), attribute_name="__exit__" if sync else "__aexit__", source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariable(variable=tmp_enter_variable, source=enter_value, source_ref=source_ref), ] if python_version >= 360 and sync: attribute_assignments.reverse() statements += attribute_assignments statements.append( StatementAssignmentVariable( variable=tmp_indicator_variable, source=makeConstantRefNode(constant=True, source_ref=source_ref), source_ref=source_ref, )) statements += ( makeTryFinallyStatement( provider=provider, tried=makeTryExceptSingleHandlerNodeWithPublish( provider=provider, tried=with_body, exception_name="BaseException", handler_body=StatementsSequence( statements=( # Prevents final block from calling __exit__ as # well. StatementAssignmentVariable( variable=tmp_indicator_variable, source=makeConstantRefNode(constant=False, source_ref=source_ref), source_ref=source_ref, ), makeStatementConditional( condition=exit_value_exception, no_branch=makeReraiseExceptionStatement( source_ref=with_exit_source_ref), yes_branch=None, source_ref=with_exit_source_ref, ), ), source_ref=source_ref, ), public_exc=python_version >= 270, source_ref=source_ref, ), final=makeStatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_indicator_variable, source_ref=source_ref), right=makeConstantRefNode(constant=True, source_ref=source_ref), source_ref=source_ref, ), yes_branch=StatementExpressionOnly( expression=exit_value_no_exception, source_ref=source_ref), no_branch=None, source_ref=source_ref, ), source_ref=source_ref, ), ) return makeTryFinallyStatement( provider=provider, tried=statements, final=( StatementReleaseVariable(variable=tmp_source_variable, source_ref=with_exit_source_ref), StatementReleaseVariable(variable=tmp_enter_variable, source_ref=with_exit_source_ref), StatementReleaseVariable(variable=tmp_exit_variable, source_ref=with_exit_source_ref), ), source_ref=source_ref, )
def _buildInplaceAssignSliceNode(provider, lookup_source, lower, upper, tmp_variable1, tmp_variable2, tmp_variable3, operator, expression, source_ref): # Due to the 3 inputs, which we need to also put into temporary variables, # there are too many variables here, but they are needed. # pylint: disable=too-many-locals # First assign the target value, lower and upper to temporary variables. copy_to_tmp = StatementAssignmentVariable(variable=tmp_variable1, source=lookup_source, source_ref=source_ref) final_statements = [ StatementReleaseVariable(variable=tmp_variable1, source_ref=source_ref) ] statements = [] if lower is not None: statements.append( StatementAssignmentVariable(variable=tmp_variable2, source=lower, source_ref=source_ref)) final_statements.append( StatementReleaseVariable(variable=tmp_variable2, source_ref=source_ref)) lower_ref1 = ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref) lower_ref2 = ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref) else: assert tmp_variable2 is None lower_ref1 = lower_ref2 = None if upper is not None: statements.append( StatementAssignmentVariable(variable=tmp_variable3, source=upper, source_ref=source_ref)) final_statements.append( StatementReleaseVariable(variable=tmp_variable3, source_ref=source_ref)) upper_ref1 = ExpressionTempVariableRef(variable=tmp_variable3, source_ref=source_ref) upper_ref2 = ExpressionTempVariableRef(variable=tmp_variable3, source_ref=source_ref) else: assert tmp_variable3 is None upper_ref1 = upper_ref2 = None use_sliceobj = python_version >= 300 # Second assign the in-place result over the original value. if use_sliceobj: statements.append( StatementAssignmentSubscript( expression=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), subscript=ExpressionBuiltinSlice(start=lower_ref1, stop=upper_ref1, step=None, source_ref=source_ref), source=makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionSubscriptLookup( subscribed=ExpressionTempVariableRef( variable=tmp_variable1, source_ref=source_ref), subscript=ExpressionBuiltinSlice( start=lower_ref2, stop=upper_ref2, step=None, source_ref=source_ref), source_ref=source_ref), right=expression, source_ref=source_ref), source_ref=source_ref)) else: statements.append( StatementAssignmentSlice( expression=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), lower=lower_ref1, upper=upper_ref1, source=makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionSliceLookup( expression=ExpressionTempVariableRef( variable=tmp_variable1, source_ref=source_ref), lower=lower_ref2, upper=upper_ref2, source_ref=source_ref), right=expression, source_ref=source_ref), source_ref=source_ref)) return (copy_to_tmp, makeTryFinallyStatement(provider=provider, tried=statements, final=final_statements, source_ref=source_ref))
def makeReleaseStatement(count): return StatementReleaseVariable(variable=variables[count], source_ref=source_ref)
def buildAssignNode(provider, node, source_ref): assert len(node.targets) >= 1, source_ref # Evaluate the right hand side first, so it can get names provided # before the left hand side exists. source = buildNode(provider, node.value, source_ref) if len(node.targets) == 1: # Simple assignment case, one source, one target. return buildAssignmentStatements( provider = provider, node = node.targets[0], source = source, source_ref = source_ref ) else: # Complex assignment case, one source, but multiple targets. We keep the # source in a temporary variable, and then assign from it multiple # times. temp_scope = provider.allocateTempScope("assign_unpack") tmp_source = provider.allocateTempVariable( temp_scope = temp_scope, name = "assign_source" ) statements = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_source, source_ref = source_ref ), source = source, source_ref = source_ref ) ] for target in node.targets: statements.append( buildAssignmentStatements( provider = provider, node = target, source = ExpressionTempVariableRef( variable = tmp_source, source_ref = source_ref ), source_ref = source_ref ) ) return makeTryFinallyStatement( provider = provider, tried = statements, final = StatementReleaseVariable( variable = tmp_source, source_ref = source_ref ), source_ref = source_ref )
def _buildInplaceAssignSubscriptNode(provider, subscribed, subscript, tmp_variable1, tmp_variable2, operator, expression, source_ref): # First assign the subscribed value to a temporary variable. preserve_to_tmp1 = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable1, source_ref = source_ref ), source = subscribed, source_ref = source_ref ) # Second assign the subscript value to a temporary variable preserve_to_tmp2 = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable2, source_ref = source_ref ), source = subscript, source_ref = source_ref ) execute_in_place = StatementAssignmentSubscript( expression = ExpressionTempVariableRef( variable = tmp_variable1, source_ref = source_ref ), subscript = ExpressionTempVariableRef( variable = tmp_variable2, source_ref = source_ref ), source = makeExpressionOperationBinaryInplace( operator = operator, left = ExpressionSubscriptLookup( subscribed = ExpressionTempVariableRef( variable = tmp_variable1, source_ref = source_ref ), subscript = ExpressionTempVariableRef( variable = tmp_variable2, source_ref = source_ref ), source_ref = source_ref ), right = expression, source_ref = source_ref ), source_ref = source_ref ) # Note: No copy back is happening, for subscripts that is implied. return ( preserve_to_tmp1, makeTryFinallyStatement( provider = provider, tried = ( preserve_to_tmp2, execute_in_place, ), final = ( StatementReleaseVariable( variable = tmp_variable1, source_ref = source_ref ), StatementReleaseVariable( variable = tmp_variable2, source_ref = source_ref ) ), source_ref = source_ref ) )
def buildPrintNode(provider, node, source_ref): # "print" statements, should only occur with Python2. if node.dest is not None: temp_scope = provider.allocateTempScope("print") tmp_target_variable = provider.allocateTempVariable( temp_scope=temp_scope, name="target") target_default_statement = StatementAssignmentVariable( variable=tmp_target_variable, source=ExpressionImportModuleNameHard(module_name="sys", import_name="stdout", source_ref=source_ref), source_ref=source_ref, ) statements = [ StatementAssignmentVariable( variable=tmp_target_variable, source=buildNode(provider=provider, node=node.dest, source_ref=source_ref), source_ref=source_ref, ), makeStatementConditional( condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_target_variable, source_ref=source_ref), right=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref, ), yes_branch=target_default_statement, no_branch=None, source_ref=source_ref, ), ] values = buildNodeList(provider=provider, nodes=node.values, source_ref=source_ref) if node.dest is not None: print_statements = [ StatementPrintValue( dest=ExpressionTempVariableRef(variable=tmp_target_variable, source_ref=source_ref), value=value, source_ref=source_ref, ) for value in values ] if node.nl: print_statements.append( StatementPrintNewline( dest=ExpressionTempVariableRef( variable=tmp_target_variable, source_ref=source_ref), source_ref=source_ref, )) statements.append( makeTryFinallyStatement( provider=provider, tried=print_statements, final=StatementReleaseVariable(variable=tmp_target_variable, source_ref=source_ref), source_ref=source_ref, )) else: statements = [ StatementPrintValue(dest=None, value=value, source_ref=source_ref) for value in values ] if node.nl: statements.append( StatementPrintNewline(dest=None, source_ref=source_ref)) return makeStatementsSequenceFromStatements(*statements)
def getDictUnpackingHelper(): helper_name = "_unpack_dict" result = ExpressionFunctionBody( provider = getInternalModule(), name = helper_name, doc = None, parameters = ParameterSpec( ps_name = helper_name, ps_normal_args = (), ps_list_star_arg = "args", ps_dict_star_arg = None, ps_default_count = 0, ps_kw_only_args = () ), flags = set(), source_ref = internal_source_ref ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "dict") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "keys") loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried = StatementAssignmentVariable( variable = tmp_item_variable, source = ExpressionBuiltinNext1( value = ExpressionTempVariableRef( variable = tmp_iter_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), exception_name = "StopIteration", handler_body = StatementLoopBreak( source_ref = internal_source_ref ), source_ref = internal_source_ref ), makeTryExceptSingleHandlerNode( tried = StatementDictOperationUpdate( dict_arg = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), value = ExpressionTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), exception_name = "AttributeError", handler_body = StatementRaiseException( exception_type = ExpressionBuiltinMakeException( exception_name = "TypeError", args = ( makeBinaryOperationNode( operator = "Mod", left = makeConstantRefNode( constant = """\ '%s' object is not a mapping""", source_ref = internal_source_ref, user_provided = True ), right = ExpressionMakeTuple( elements = ( ExpressionAttributeLookup( source = ExpressionBuiltinType1( value = ExpressionTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), attribute_name = "__name__", source_ref = internal_source_ref ), ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), ), source_ref = internal_source_ref ), exception_value = None, exception_trace = None, exception_cause = None, source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) args_variable = result.getVariableForAssignment( variable_name = "args" ) final = ( StatementReleaseVariable( variable = tmp_result_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_iter_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_item_variable, source_ref = internal_source_ref ), ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable = tmp_iter_variable, source = ExpressionBuiltinIter1( value = ExpressionVariableRef( variable = args_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementAssignmentVariable( variable = tmp_result_variable, source = makeConstantRefNode( constant = {}, source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementLoop( body = loop_body, source_ref = internal_source_ref ), StatementReturn( expression = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) result.setBody( makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider = result, tried = tried, final = final, source_ref = internal_source_ref ) ) ) return result
def buildImportFromNode(provider, node, source_ref): # "from .. import .." statements. This may trigger a star import, or # multiple names being looked up from the given module variable name. # This is pretty complex, pylint: disable=R0912,R0914 module_name = node.module if node.module is not None else "" level = node.level # Importing from "__future__" module may enable flags to the parser, # that we need to know about, handle that. if module_name == "__future__": _handleFutureImport(provider, node, source_ref) target_names = [] import_names = [] # Mapping imported "fromlist" to assigned "fromlist" if any, handling the # star case as well. for import_desc in node.names: object_name, local_name = import_desc.name, import_desc.asname if object_name == '*': target_names.append(None) assert local_name is None else: target_names.append( local_name if local_name is not None else object_name ) import_names.append(object_name) # Star imports get special treatment. if None in target_names: # More than "*" is a syntax error in Python, need not care about this at # all, it's only allowed value for import list in this case. assert target_names == [None] # Python3 made it so that these can only occur on the module level, # so this a syntax error if not there. For Python2 it is OK to # occur everywhere though. if not provider.isCompiledPythonModule() and python_version >= 300: SyntaxErrors.raiseSyntaxError( "import * only allowed at module level", source_ref.atColumnNumber(node.col_offset) ) # Functions with star imports get a marker. if provider.isExpressionFunctionBody(): provider.markAsStarImportContaining() return StatementImportStar( module_import = ExpressionImportModule( module_name = module_name, import_list = ('*',), level = level, source_ref = source_ref ), source_ref = source_ref ) else: def makeImportName(import_name): if module_name == "__future__": # Make "__future__" imports tie hard immediately, they cannot be # any other way. return ExpressionImportModuleHard( module_name = "__future__", import_name = import_name, source_ref = source_ref ) else: # Refer to be module, or a clone of the reference if need be. return ExpressionImportName( module = imported_from_module, import_name = import_name, source_ref = source_ref ) imported_from_module = ExpressionImportModule( module_name = module_name, import_list = tuple(import_names), level = level, source_ref = source_ref ) # If we have multiple names to import, consider each. multi_names = len(target_names) > 1 statements = [] if multi_names: tmp_import_from = provider.allocateTempVariable( temp_scope = provider.allocateTempScope("import_from"), name = "module" ) statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_import_from, source_ref = source_ref ), source = imported_from_module, source_ref = source_ref ) ) imported_from_module = ExpressionTempVariableRef( variable = tmp_import_from, source_ref = source_ref ) import_statements = [] first = True for target_name, import_name in zip(target_names, import_names): # Make a clone of the variable reference, if we are going to use # another one. if not first: imported_from_module = imported_from_module.makeClone() first = False import_statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = mangleName(target_name, provider), source_ref = source_ref ), source = makeImportName( import_name = import_name, ), source_ref = source_ref ) ) # Release the temporary module value as well. if multi_names: statements.append( makeTryFinallyStatement( provider = provider, tried = import_statements, final = ( StatementReleaseVariable( variable = tmp_import_from, source_ref = source_ref ), ), source_ref = source_ref ) ) else: statements.extend(import_statements) # Note: Each import is sequential. It can succeed, and the failure of a # later one is not undoing previous ones. We can therefore have a # sequence of imports that each only import one thing therefore. return StatementsSequence( statements = mergeStatements(statements), source_ref = source_ref )
def _buildClassNode3(provider, node, source_ref): # Many variables, due to the huge re-formulation that is going on here, # which just has the complexity, pylint: disable=too-many-locals # This function is the Python3 special case with special re-formulation as # according to developer manual. class_statement_nodes, class_doc = extractDocFromBody(node) # We need a scope for the temporary variables, and they might be closured. temp_scope = provider.allocateTempScope(name="class_creation") tmp_bases = provider.allocateTempVariable(temp_scope=temp_scope, name="bases") tmp_class_decl_dict = provider.allocateTempVariable(temp_scope=temp_scope, name="class_decl_dict") tmp_metaclass = provider.allocateTempVariable(temp_scope=temp_scope, name="metaclass") tmp_prepared = provider.allocateTempVariable(temp_scope=temp_scope, name="prepared") class_creation_function = ExpressionClassBody(provider=provider, name=node.name, doc=class_doc, source_ref=source_ref) class_variable = class_creation_function.getVariableForAssignment( "__class__") class_variable_ref = ExpressionVariableRef(variable=class_variable, 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=class_creation_function, nodes=class_statement_nodes, code_object=code_object, source_ref=source_ref) source_ref_orig = source_ref if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref statements = [ StatementSetLocals( locals_scope=class_creation_function.getLocalsScope(), new_locals=ExpressionTempVariableRef(variable=tmp_prepared, source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariableName( provider=class_creation_function, variable_name="__module__", source=makeConstantRefNode( constant=provider.getParentModule().getFullName(), source_ref=source_ref, user_provided=True), source_ref=source_ref) ] if class_doc is not None: statements.append( StatementAssignmentVariableName(provider=class_creation_function, variable_name="__doc__", source=makeConstantRefNode( constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref)) # The "__qualname__" attribute is new in Python 3.3. if python_version >= 330: qualname = class_creation_function.getFunctionQualname() if python_version < 340: qualname_ref = makeConstantRefNode(constant=qualname, source_ref=source_ref, user_provided=True) else: qualname_ref = ExpressionFunctionQualnameRef( function_body=class_creation_function, source_ref=source_ref, ) statements.append( StatementLocalsDictOperationSet( locals_scope=class_creation_function.getLocalsScope(), variable_name="__qualname__", value=qualname_ref, source_ref=source_ref)) if python_version >= 340: qualname_assign = statements[-1] if python_version >= 360 and \ class_creation_function.needsAnnotationsDictionary(): statements.append( StatementAssignmentVariableName(provider=class_creation_function, variable_name="__annotations__", source=makeConstantRefNode( constant={}, source_ref=source_ref, user_provided=True), source_ref=source_ref)) statements.append(body) statements += [ StatementAssignmentVariable( variable=class_variable, source=makeExpressionCall( called=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), args=makeSequenceCreationOrConstant( sequence_kind="tuple", elements=(makeConstantRefNode(constant=node.name, source_ref=source_ref, user_provided=True), ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), ExpressionBuiltinLocalsRef( locals_scope=class_creation_function. getLocalsScope(), source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementReturn(expression=class_variable_ref, source_ref=source_ref) ] body = makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement( provider=class_creation_function, tried=mergeStatements(statements, True), final=StatementReleaseLocals( locals_scope=class_creation_function.getLocalsScope(), 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. class_creation_function.setBody(body) # The class body is basically a function that implicitly, at the end # returns its created class and cannot have other return statements # contained. decorated_body = class_creation_function for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): decorated_body = makeExpressionCall( called=decorator, args=ExpressionMakeTuple(elements=(decorated_body, ), source_ref=source_ref), kw=None, source_ref=decorator.getSourceReference()) statements = ( StatementAssignmentVariable(variable=tmp_bases, source=buildTupleCreationNode( provider=provider, elements=node.bases, source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable=tmp_class_decl_dict, source=makeDictCreationOrConstant2( keys=[keyword.arg for keyword in node.keywords], values=[ buildNode(provider, keyword.value, source_ref) for keyword in node.keywords ], source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable=tmp_metaclass, source=ExpressionSelectMetaclass(metaclass=ExpressionConditional( condition=ExpressionComparisonIn( left=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), right=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), expression_yes=ExpressionDictOperationGet( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref), expression_no=ExpressionConditional( condition=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), expression_no=makeExpressionBuiltinRef( builtin_name="type", source_ref=source_ref), expression_yes=ExpressionBuiltinType1( value=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), source_ref=source_ref), source_ref=source_ref), bases=ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref_orig), StatementConditional( condition=ExpressionComparisonIn( left=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), right=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), no_branch=None, yes_branch=makeStatementsSequenceFromStatement( statement=StatementDictOperationRemove( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref)), source_ref=source_ref), StatementAssignmentVariable( variable=tmp_prepared, source=ExpressionConditional( condition=ExpressionBuiltinHasattr( object_arg=ExpressionTempVariableRef( variable=tmp_metaclass, source_ref=source_ref), name=makeConstantRefNode(constant="__prepare__", source_ref=source_ref, user_provided=True), source_ref=source_ref), expression_no=makeConstantRefNode(constant={}, source_ref=source_ref, user_provided=True), expression_yes=makeExpressionCall( called=ExpressionAttributeLookup( source=ExpressionTempVariableRef( variable=tmp_metaclass, source_ref=source_ref), attribute_name="__prepare__", 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)), source_ref=source_ref), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariableName(provider=provider, variable_name=mangleName( node.name, provider), source=decorated_body, source_ref=source_ref)) if python_version >= 340: class_creation_function.qualname_setup = node.name, qualname_assign final = (StatementReleaseVariable(variable=tmp_bases, source_ref=source_ref), StatementReleaseVariable(variable=tmp_class_decl_dict, source_ref=source_ref), StatementReleaseVariable(variable=tmp_metaclass, source_ref=source_ref), StatementReleaseVariable(variable=tmp_prepared, source_ref=source_ref)) return makeTryFinallyStatement(provider=provider, tried=statements, final=final, source_ref=source_ref)
def _buildInplaceAssignSubscriptNode( provider, subscribed, subscript, tmp_variable1, tmp_variable2, tmp_variable3, operator, expression, source_ref, ): # First assign the subscribed value to a temporary variable. preserve_to_tmp1 = StatementAssignmentVariable(variable=tmp_variable1, source=subscribed, source_ref=source_ref) # Second assign the subscript value to a temporary variable statements = ( StatementAssignmentVariable(variable=tmp_variable2, source=subscript, source_ref=source_ref), StatementAssignmentVariable( variable=tmp_variable3, source=ExpressionSubscriptLookup( expression=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), subscript=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariable( variable=tmp_variable3, source=makeExpressionOperationBinaryInplace( operator=operator, left=ExpressionTempVariableRef(variable=tmp_variable3, source_ref=source_ref), right=expression, source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentSubscript( subscribed=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), subscript=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source=ExpressionTempVariableRef(variable=tmp_variable3, source_ref=source_ref), source_ref=source_ref, ), ) return ( preserve_to_tmp1, makeTryFinallyStatement( provider=provider, tried=statements, final=( StatementReleaseVariable(variable=tmp_variable1, source_ref=source_ref), StatementReleaseVariable(variable=tmp_variable2, source_ref=source_ref), StatementReleaseVariable(variable=tmp_variable3, source_ref=source_ref), ), source_ref=source_ref, ), )
def buildAssignmentStatementsFromDecoded(provider, kind, detail, source, source_ref): # This is using many variable names on purpose, so as to give names to the # unpacked detail values, and has many branches due to the many cases # dealt with and it is return driven. # pylint: disable=too-many-branches,too-many-locals,too-many-return-statements,too-many-statements if kind == "Name": if detail in ("_inject_c_code", "_inject_c_decl") and isExperimental("c-code-injection"): if not source.isExpressionConstantStrRef(): general.sysexit( "Error, value assigned to '%s' not be constant str" % detail) if detail == "_inject_c_code": return StatementInjectCCode( c_code=source.getCompileTimeConstant(), source_ref=source_ref) else: return StatementInjectCDecl( c_code=source.getCompileTimeConstant(), source_ref=source_ref) return StatementAssignmentVariableName( provider=provider, variable_name=detail, source=source, source_ref=source_ref, ) elif kind == "Attribute": lookup_source, attribute_name = detail return StatementAssignmentAttribute( expression=lookup_source, attribute_name=mangleName(attribute_name, provider), source=source, source_ref=source_ref, ) elif kind == "Subscript": subscribed, subscript = detail return StatementAssignmentSubscript( subscribed=subscribed, subscript=subscript, source=source, source_ref=source_ref, ) elif kind == "Slice": lookup_source, lower, upper = detail # For Python3 there is no slicing operation, this is always done # with subscript using a slice object. For Python2, it is only done # if no "step" is provided. use_sliceobj = python_version >= 0x300 if use_sliceobj: return StatementAssignmentSubscript( subscribed=lookup_source, source=source, subscript=makeExpressionBuiltinSlice(start=lower, stop=upper, step=None, source_ref=source_ref), source_ref=source_ref, ) else: return StatementAssignmentSlice( expression=lookup_source, lower=lower, upper=upper, source=source, source_ref=source_ref, ) elif kind == "Tuple": temp_scope = provider.allocateTempScope("tuple_unpack") source_iter_var = provider.allocateTempVariable(temp_scope=temp_scope, name="source_iter") element_vars = [ provider.allocateTempVariable(temp_scope=temp_scope, name="element_%d" % (element_index + 1)) for element_index in range(len(detail)) ] starred_list_var = None starred_index = None statements = [] for element_index, element in enumerate(detail): if element[0] == "Starred": if starred_index is not None: raiseSyntaxError( "two starred expressions in assignment" if python_version < 0x390 else "multiple starred expressions in assignment", source_ref.atColumnNumber(0), ) starred_index = element_index for element_index, element in enumerate(detail): element_var = element_vars[element_index] if starred_list_var is not None: statements.insert( starred_index + 1, StatementAssignmentVariable( variable=element_var, source=ExpressionListOperationPop( list_arg=ExpressionTempVariableRef( variable=starred_list_var, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), ) elif element[0] != "Starred": statements.append( StatementAssignmentVariable( variable=element_var, source=ExpressionSpecialUnpack( value=ExpressionTempVariableRef( variable=source_iter_var, source_ref=source_ref), count=element_index + 1, expected=starred_index or len(detail), starred=starred_index is not None, source_ref=source_ref, ), source_ref=source_ref, )) else: assert starred_index == element_index starred_list_var = element_var statements.append( StatementAssignmentVariable( variable=element_var, source=ExpressionBuiltinList( value=ExpressionTempVariableRef( variable=source_iter_var, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, )) if starred_list_var is None: statements.append( StatementSpecialUnpackCheck( iterator=ExpressionTempVariableRef( variable=source_iter_var, source_ref=source_ref), count=len(detail), source_ref=source_ref, )) else: statements.insert( starred_index + 1, makeStatementConditional( condition=makeComparisonExpression( comparator="Lt", left=ExpressionBuiltinLen( value=ExpressionTempVariableRef( variable=starred_list_var, source_ref=source_ref), source_ref=source_ref, ), right=makeConstantRefNode( constant=len(statements) - starred_index - 1, source_ref=source_ref, ), source_ref=source_ref, ), yes_branch=makeRaiseExceptionExpressionFromTemplate( exception_type="ValueError", template="""\ not enough values to unpack (expected at least %d, got %%d)""" % (len(statements) - 1), template_args=makeBinaryOperationNode( operator="Add", left=ExpressionBuiltinLen( value=ExpressionTempVariableRef( variable=starred_list_var, source_ref=source_ref), source_ref=source_ref, ), right=makeConstantRefNode(constant=starred_index, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ).asStatement(), no_branch=None, source_ref=source_ref, ), ) if python_version >= 0x370: iter_creation_class = ExpressionBuiltinIterForUnpack else: iter_creation_class = ExpressionBuiltinIter1 statements = [ StatementAssignmentVariable( variable=source_iter_var, source=iter_creation_class(value=source, source_ref=source_ref), source_ref=source_ref, ), makeTryFinallyStatement( provider=provider, tried=statements, final=(StatementReleaseVariable(variable=source_iter_var, source_ref=source_ref), ), source_ref=source_ref, ), ] # When all is done, copy over to the actual assignment targets, starred # or not makes no difference here anymore. for element_index, element in enumerate(detail): if element[0] == "Starred": element = element[1] element_var = element_vars[element_index] statements.append( buildAssignmentStatementsFromDecoded( provider=provider, kind=element[0], detail=element[1], source=ExpressionTempVariableRef(variable=element_var, source_ref=source_ref), source_ref=source_ref, )) # Need to release temporary variables right after successful # usage. statements.append( StatementDelVariable(variable=element_var, tolerant=True, source_ref=source_ref)) final_statements = [] for element_var in element_vars: final_statements.append( StatementReleaseVariable(variable=element_var, source_ref=source_ref)) return makeTryFinallyStatement( provider=provider, tried=statements, final=final_statements, source_ref=source_ref, ) elif kind == "Starred": raiseSyntaxError( "starred assignment target must be in a list or tuple", source_ref.atColumnNumber(0), ) else: assert False, (kind, source_ref, detail)
def buildImportFromNode(provider, node, source_ref): # "from .. import .." statements. This may trigger a star import, or # multiple names being looked up from the given module variable name. # This is pretty complex. # pylint: disable=too-many-branches,too-many-locals,too-many-statements module_name = node.module if node.module is not None else "" level = node.level # Use default level under some circumstances. if level == -1: level = None elif level == 0 and not _future_specs[-1].isAbsoluteImport(): level = None if level is not None: level_obj = makeConstantRefNode(level, source_ref, True) else: level_obj = None # Importing from "__future__" module may enable flags to the parser, # that we need to know about, handle that. if module_name == "__future__": _handleFutureImport(provider, node, source_ref) target_names = [] import_names = [] # Mapping imported "fromlist" to assigned "fromlist" if any, handling the # star case as well. for import_desc in node.names: object_name, local_name = import_desc.name, import_desc.asname if object_name == "*": target_names.append(None) assert local_name is None else: target_names.append( local_name if local_name is not None else object_name) import_names.append(object_name) # Star imports get special treatment. if None in target_names: # More than "*" is a syntax error in Python, need not care about this at # all, it's only allowed value for import list in this case. assert target_names == [None] # Python3 made it so that these can only occur on the module level, # so this a syntax error if not there. For Python2 it is OK to # occur everywhere though. if not provider.isCompiledPythonModule() and python_version >= 300: raiseSyntaxError( "import * only allowed at module level", source_ref.atColumnNumber(node.col_offset), ) if provider.isCompiledPythonModule(): import_globals = ExpressionBuiltinGlobals(source_ref) import_locals = ExpressionBuiltinGlobals(source_ref) else: import_globals = ExpressionBuiltinGlobals(source_ref) import_locals = makeConstantRefNode({}, source_ref, True) return StatementImportStar( target_scope=provider.getModuleDictScope() if provider.isCompiledPythonModule() else provider.getFunctionLocalsScope(), module_import=ExpressionBuiltinImport( name=makeConstantRefNode(module_name, source_ref, True), globals_arg=import_globals, locals_arg=import_locals, fromlist=makeConstantRefNode(("*", ), source_ref, True), level=level_obj, source_ref=source_ref, ), source_ref=source_ref, ) else: if module_name == "__future__": imported_from_module = ExpressionImportModuleHard( module_name="__future__", source_ref=source_ref) else: imported_from_module = ExpressionBuiltinImport( name=makeConstantRefNode(module_name, source_ref, True), globals_arg=ExpressionBuiltinGlobals(source_ref), locals_arg=makeConstantRefNode(None, source_ref, True), fromlist=makeConstantRefNode(tuple(import_names), source_ref, True), level=level_obj, source_ref=source_ref, ) # If we have multiple names to import, consider each. multi_names = len(target_names) > 1 statements = [] if multi_names: tmp_import_from = provider.allocateTempVariable( temp_scope=provider.allocateTempScope("import_from"), name="module") statements.append( StatementAssignmentVariable( variable=tmp_import_from, source=imported_from_module, source_ref=source_ref, )) imported_from_module = ExpressionTempVariableRef( variable=tmp_import_from, source_ref=source_ref) import_statements = [] first = True for target_name, import_name in zip(target_names, import_names): # Make a clone of the variable reference, if we are going to use # another one. if not first: imported_from_module = imported_from_module.makeClone() first = False import_statements.append( StatementAssignmentVariableName( provider=provider, variable_name=mangleName(target_name, provider), source=ExpressionImportName( module=imported_from_module, import_name=import_name, level=level, source_ref=source_ref, ), source_ref=source_ref, )) # Release the temporary module value as well. if multi_names: statements.append( makeTryFinallyStatement( provider=provider, tried=import_statements, final=(StatementReleaseVariable(variable=tmp_import_from, source_ref=source_ref), ), source_ref=source_ref, )) else: statements.extend(import_statements) # Note: Each import is sequential. It can succeed, and the failure of a # later one is not undoing previous ones. We can therefore have a # sequence of imports that each only import one thing therefore. return StatementsSequence(statements=mergeStatements(statements), 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_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>", 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
def buildListContractionNode(provider, node, source_ref): # List contractions are dealt with by general code. if Utils.python_version < 300: temp_scope = provider.allocateTempScope("listcontr") outer_iter_var = provider.allocateTempVariable(temp_scope=temp_scope, name="listcontr_iter") outer_iter_ref = ExpressionTempVariableRef(variable=outer_iter_var, source_ref=source_ref) container_tmp = provider.allocateTempVariable(temp_scope=temp_scope, name="listcontr_result") statements, release_statements = _buildContractionBodyNode( provider=provider, node=node, emit_class=ExpressionListOperationAppend, start_value=ExpressionConstantRef(constant=[], source_ref=source_ref), outer_iter_ref=outer_iter_ref, container_tmp=container_tmp, temp_scope=temp_scope, assign_provider=True, source_ref=source_ref, function_body=provider) statements.insert( 0, StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=outer_iter_var, source_ref=source_ref), source=ExpressionBuiltinIter1(value=buildNode( provider=provider, node=node.generators[0].iter, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref)) result = makeTryFinallyExpression(expression=ExpressionTempVariableRef( variable=container_tmp, source_ref=source_ref), tried=statements, final=release_statements, source_ref=source_ref) final = StatementsSequence(statements=( StatementReleaseVariable(variable=container_tmp, tolerant=True, source_ref=source_ref), StatementReleaseVariable(variable=outer_iter_var, tolerant=True, source_ref=source_ref), ), source_ref=source_ref) wrapTryFinallyLater(node=result, final=final) return result return _buildContractionNode( provider=provider, node=node, name="<listcontraction>", emit_class=ExpressionListOperationAppend, start_value=ExpressionConstantRef(constant=[], source_ref=source_ref), # Note: For Python3, the list contractions no longer assign to the outer # scope. assign_provider=Utils.python_version < 300, source_ref=source_ref)
def _buildContractionBodyNode(provider, node, emit_class, start_value, container_tmp, iter_tmp, temp_scope, assign_provider, source_ref, function_body): # This uses lots of variables and branches. There is no good way # around that, and we deal with many cases, due to having generator # expressions sharing this code, pylint: disable=R0912,R0914 tmp_variables = [] if assign_provider: tmp_variables.append(iter_tmp) if container_tmp is not None: tmp_variables.append(container_tmp) # First assign the iterator if we are an outline. if assign_provider: statements = [ StatementAssignmentVariable( variable_ref=makeVariableTargetRefNode(variable=iter_tmp, source_ref=source_ref), source=ExpressionBuiltinIter1(value=buildNode( provider=provider, node=node.generators[0].iter, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref.atInternal()) ] else: statements = [] if start_value is not None: statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=container_tmp, source_ref=source_ref), source=start_value, source_ref=source_ref.atInternal())) if hasattr(node, "elt"): if start_value is not None: current_body = emit_class(ExpressionTempVariableRef( variable=container_tmp, source_ref=source_ref), buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionYield function_body.markAsGenerator() current_body = emit_class(buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionDictOperationSet current_body = ExpressionDictOperationSet( dict_arg=ExpressionTempVariableRef(variable=container_tmp, source_ref=source_ref), key=buildNode( provider=function_body, node=node.key, source_ref=source_ref, ), value=buildNode( provider=function_body, node=node.value, source_ref=source_ref, ), source_ref=source_ref) current_body = StatementExpressionOnly(expression=current_body, source_ref=source_ref) for count, qual in enumerate(reversed(node.generators)): tmp_value_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="iter_value_%d" % count) tmp_variables.append(tmp_value_variable) # The first iterated value is to be calculated outside of the function # and will be given as a parameter "_iterated", the others are built # inside the function. if qual is node.generators[0]: iterator_ref = makeVariableRefNode(variable=iter_tmp, source_ref=source_ref) tmp_iter_variable = None nested_statements = [] else: # First create the iterator and store it, next should be loop body value_iterator = ExpressionBuiltinIter1(value=buildNode( provider=function_body, node=qual.iter, source_ref=source_ref), source_ref=source_ref) tmp_iter_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="contraction_iter_%d" % count) tmp_variables.append(tmp_iter_variable) nested_statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable, source_ref=source_ref), source=value_iterator, source_ref=source_ref) ] iterator_ref = ExpressionTempVariableRef( variable=tmp_iter_variable, source_ref=source_ref) loop_statements = [ makeTryExceptSingleHandlerNode( tried=StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_value_variable, source_ref=source_ref), source=ExpressionBuiltinNext1(value=iterator_ref, source_ref=source_ref), source_ref=source_ref), exception_name="StopIteration", handler_body=StatementBreakLoop( source_ref=source_ref.atInternal()), source_ref=source_ref), buildAssignmentStatements( provider=provider if assign_provider else function_body, temp_provider=function_body, node=qual.target, source=ExpressionTempVariableRef(variable=tmp_value_variable, source_ref=source_ref), source_ref=source_ref) ] conditions = buildNodeList(provider=function_body, nodes=qual.ifs, source_ref=source_ref) if len(conditions) >= 1: loop_statements.append( StatementConditional( condition=buildAndNode(values=conditions, source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=current_body), no_branch=None, source_ref=source_ref)) else: loop_statements.append(current_body) nested_statements.append( StatementLoop(body=StatementsSequence( statements=mergeStatements(loop_statements), source_ref=source_ref), source_ref=source_ref)) if tmp_iter_variable is not None: nested_statements.append( StatementReleaseVariable(variable=tmp_iter_variable, source_ref=source_ref)) current_body = StatementsSequence(statements=mergeStatements( nested_statements, False), source_ref=source_ref) statements.append(current_body) statements = mergeStatements(statements) if emit_class is ExpressionYield: statements.insert(0, StatementGeneratorEntry(source_ref=source_ref)) release_statements = [ StatementReleaseVariable(variable=tmp_variable, source_ref=source_ref) for tmp_variable in tmp_variables ] return statements, release_statements
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=R0914 class_statement_nodes, class_doc = extractDocFromBody(node) function_body = ExpressionClassBody(provider=provider, name=node.name, doc=class_doc, flags=set(), source_ref=source_ref) code_object = CodeObjectSpec(code_name=node.name, code_kind="Class", arg_names=(), kw_only_count=0, has_starlist=False, has_stardict=False) body = buildStatementsNode(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() # 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 = [ StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__module__", source_ref=source_ref), source=ExpressionConstantRef( constant=provider.getParentModule().getFullName(), source_ref=source_ref, user_provided=True), source_ref=source_ref.atInternal()) ] if class_doc is not None: statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__doc__", source_ref=source_ref), source=ExpressionConstantRef(constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref.atInternal())) statements += [ body, StatementReturn( expression=ExpressionBuiltinLocals(source_ref=source_ref), source_ref=source_ref.atInternal()) ] body = makeStatementsSequence(statements=statements, allow_none=True, 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") statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_bases, source_ref=source_ref), source=makeSequenceCreationOrConstant(sequence_kind="tuple", elements=buildNodeList( provider, node.bases, source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class_dict, source_ref=source_ref), source=ExpressionFunctionCall(function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=function_body, source_ref=source_ref), code_object=None, defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_metaclass, source_ref=source_ref), source=ExpressionConditional( condition=ExpressionComparisonIn( left=ExpressionConstantRef(constant="__metaclass__", source_ref=source_ref, user_provided=True), right=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=ExpressionConstantRef(constant="__metaclass__", source_ref=source_ref, user_provided=True), source_ref=source_ref), expression_no=ExpressionSelectMetaclass( metaclass=None, bases=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class, source_ref=source_ref), source=ExpressionCallNoKeywords( called=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), args=ExpressionMakeTuple( elements=(ExpressionConstantRef(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), source_ref=source_ref), source_ref=source_ref), ] for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class, source_ref=source_ref), source=ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple( elements=(ExpressionTempVariableRef( variable=tmp_class, source_ref=source_ref), ), source_ref=source_ref), source_ref=decorator.getSourceReference()), source_ref=decorator.getSourceReference())) statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef(variable_name=node.name, source_ref=source_ref), 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 _buildInplaceAssignAttributeNode(provider, lookup_source, attribute_name, tmp_variable1, tmp_variable2, operator, expression, source_ref): # First assign the target value to a temporary variable. preserve_to_tmp = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable1, source_ref = source_ref ), source = ExpressionAttributeLookup( source = lookup_source.makeClone(), attribute_name = attribute_name, source_ref = source_ref ), source_ref = source_ref ) # Second assign the in-place result to a temporary variable inplace_to_tmp = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable2, source_ref = source_ref ), source = makeExpressionOperationBinaryInplace( operator = operator, left = ExpressionTempVariableRef( variable = tmp_variable1, source_ref = source_ref ), right = expression, source_ref = source_ref ), source_ref = source_ref ) # Third, copy it over, if the reference values change, i.e. IsNot is true. copy_back_from_tmp = StatementConditional( condition = ExpressionComparisonIsNOT( left = ExpressionTempVariableRef( variable = tmp_variable1, source_ref = source_ref ), right = ExpressionTempVariableRef( variable = tmp_variable2, source_ref = source_ref ), source_ref = source_ref ), yes_branch = makeStatementsSequenceFromStatement( statement = StatementAssignmentAttribute( expression = lookup_source.makeClone(), attribute_name = attribute_name, source = ExpressionTempVariableRef( variable = tmp_variable2, source_ref = source_ref ), source_ref = source_ref ) ), no_branch = None, source_ref = source_ref ) copy_back_from_tmp = makeTryFinallyStatement( provider = provider, tried = copy_back_from_tmp, final = StatementReleaseVariable( variable = tmp_variable2, source_ref = source_ref ), source_ref = source_ref ) return ( preserve_to_tmp, # making sure the above temporary variable is deleted in any case. makeTryFinallyStatement( provider = provider, tried = ( inplace_to_tmp, copy_back_from_tmp, ), final = StatementReleaseVariable( variable = tmp_variable1, source_ref = source_ref ), source_ref = source_ref ) )
def _buildClassNode3(provider, node, source_ref): # Many variables, due to the huge re-formulation that is going on here, # which just has the complexity, pylint: disable=R0914 # This function is the Python3 special case with special re-formulation as # according to developer manual. class_statement_nodes, class_doc = extractDocFromBody(node) # We need a scope for the temporary variables, and they might be closured. temp_scope = provider.allocateTempScope(name="class_creation", allow_closure=True) tmp_bases = provider.allocateTempVariable(temp_scope=temp_scope, name="bases") tmp_class_decl_dict = provider.allocateTempVariable(temp_scope=temp_scope, name="class_decl_dict") tmp_metaclass = provider.allocateTempVariable(temp_scope=temp_scope, name="metaclass") tmp_prepared = provider.allocateTempVariable(temp_scope=temp_scope, name="prepared") class_creation_function = ExpressionClassBody(provider=provider, name=node.name, doc=class_doc, flags=set(), source_ref=source_ref) if python_version >= 340 and False: # TODO: Temporarily reverted: tmp_class = class_creation_function.allocateTempVariable( temp_scope=None, name="__class__") class_target_variable_ref = ExpressionTargetTempVariableRef( variable=tmp_class, source_ref=source_ref) class_variable_ref = ExpressionTempVariableRef(variable=tmp_class, source_ref=source_ref) else: class_variable = class_creation_function.getVariableForAssignment( "__class__") class_target_variable_ref = ExpressionTargetVariableRef( variable_name="__class__", variable=class_variable, source_ref=source_ref) class_variable_ref = ExpressionVariableRef(variable_name="__class__", variable=class_variable, source_ref=source_ref) code_object = CodeObjectSpec(code_name=node.name, code_kind="Class", arg_names=(), kw_only_count=0, has_starlist=False, has_stardict=False) body = buildStatementsNode(provider=class_creation_function, nodes=class_statement_nodes, code_object=code_object, source_ref=source_ref) source_ref_orig = source_ref if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref module_variable = class_creation_function.getVariableForAssignment( "__module__") statements = [ StatementSetLocals(new_locals=ExpressionTempVariableRef( variable=tmp_prepared, source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__module__", variable=module_variable, source_ref=source_ref), source=ExpressionConstantRef( constant=provider.getParentModule().getFullName(), source_ref=source_ref, user_provided=True), source_ref=source_ref) ] if class_doc is not None: doc_variable = class_creation_function.getVariableForAssignment( "__doc__") statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__doc__", variable=doc_variable, source_ref=source_ref), source=ExpressionConstantRef(constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref)) # The "__qualname__" attribute is new in Python 3.3. if python_version >= 330: qualname = class_creation_function.getFunctionQualname() qualname_variable = class_creation_function.getVariableForAssignment( "__qualname__") if python_version < 340: qualname_ref = ExpressionConstantRef(constant=qualname, source_ref=source_ref, user_provided=True) else: qualname_ref = ExpressionFunctionQualnameRef( function_body=class_creation_function, source_ref=source_ref, ) statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__qualname__", variable=qualname_variable, source_ref=source_ref), source=qualname_ref, source_ref=source_ref)) if python_version >= 340: qualname_assign = statements[-1] statements += [ body, StatementAssignmentVariable( variable_ref=class_target_variable_ref, source=ExpressionCall( called=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), args=makeSequenceCreationOrConstant( sequence_kind="tuple", elements=(ExpressionConstantRef(constant=node.name, source_ref=source_ref, user_provided=True), ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), ExpressionBuiltinLocals(source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementReturn(expression=class_variable_ref, source_ref=source_ref) ] body = makeStatementsSequence(statements=statements, allow_none=True, 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. class_creation_function.setBody(body) class_creation_function.registerProvidedVariable(tmp_bases) class_creation_function.registerProvidedVariable(tmp_class_decl_dict) class_creation_function.registerProvidedVariable(tmp_metaclass) class_creation_function.registerProvidedVariable(tmp_prepared) # The class body is basically a function that implicitly, at the end # returns its created class and cannot have other return statements # contained. decorated_body = ExpressionFunctionCall( function=ExpressionFunctionCreation(function_ref=ExpressionFunctionRef( function_body=class_creation_function, source_ref=source_ref), code_object=code_object, defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(), source_ref=source_ref) for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): decorated_body = ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple(elements=(decorated_body, ), source_ref=source_ref), source_ref=decorator.getSourceReference()) statements = ( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_bases, source_ref=source_ref), source=makeSequenceCreationOrConstant(sequence_kind="tuple", elements=buildNodeList( provider, node.bases, source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), source=makeDictCreationOrConstant(keys=[ ExpressionConstantRef(constant=keyword.arg, source_ref=source_ref, user_provided=True) for keyword in node.keywords ], values=[ buildNode( provider, keyword.value, source_ref) for keyword in node.keywords ], source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_metaclass, source_ref=source_ref), source=ExpressionSelectMetaclass(metaclass=ExpressionConditional( condition=ExpressionComparisonIn( left=ExpressionConstantRef(constant="metaclass", source_ref=source_ref, user_provided=True), right=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), expression_yes=ExpressionDictOperationGet( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=ExpressionConstantRef(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref), expression_no=ExpressionConditional( condition=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), expression_no=ExpressionBuiltinRef(builtin_name="type", source_ref=source_ref), expression_yes=ExpressionBuiltinType1( value=ExpressionSubscriptLookup( subscribed=ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref), subscript=ExpressionConstantRef( constant=0, source_ref=source_ref, user_provided=True), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), bases=ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref_orig), StatementConditional( condition=ExpressionComparisonIn( left=ExpressionConstantRef(constant="metaclass", source_ref=source_ref, user_provided=True), right=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), no_branch=None, yes_branch=makeStatementsSequenceFromStatement( statement=StatementDictOperationRemove( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=ExpressionConstantRef(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref)), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_prepared, source_ref=source_ref), source=ExpressionConditional( condition=ExpressionBuiltinHasattr( # pylint: disable=E1120,E1123 object=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), name=ExpressionConstantRef(constant="__prepare__", source_ref=source_ref, user_provided=True), source_ref=source_ref), expression_no=ExpressionConstantRef(constant={}, source_ref=source_ref, user_provided=True), expression_yes=ExpressionCall( called=ExpressionAttributeLookup( source=ExpressionTempVariableRef( variable=tmp_metaclass, source_ref=source_ref), attribute_name="__prepare__", source_ref=source_ref), args=ExpressionMakeTuple( elements=(ExpressionConstantRef(constant=node.name, source_ref=source_ref, user_provided=True), ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable(variable_ref=ExpressionTargetVariableRef( variable_name=node.name, source_ref=source_ref), source=decorated_body, source_ref=source_ref), ) if python_version >= 340: class_assign = statements[-1] class_creation_function.qualname_setup = class_assign, qualname_assign final = (StatementReleaseVariable(variable=tmp_bases, source_ref=source_ref), StatementReleaseVariable(variable=tmp_class_decl_dict, source_ref=source_ref), StatementReleaseVariable(variable=tmp_metaclass, source_ref=source_ref), StatementReleaseVariable(variable=tmp_prepared, source_ref=source_ref)) return makeTryFinallyStatement(provider=provider, tried=statements, final=final, source_ref=source_ref)
def buildWhileLoopNode(provider, node, source_ref): # The while loop is re-formulated according to developer manual. The # condition becomes an early condition to break the loop. The else block is # taken if a while loop exits normally, i.e. because of condition not being # true. We do this by introducing an indicator variable. else_block = buildStatementsNode( provider=provider, nodes=node.orelse if node.orelse else None, source_ref=source_ref) if else_block is not None: temp_scope = provider.allocateTempScope("while_loop") tmp_break_indicator = provider.allocateTempVariable( temp_scope=temp_scope, name="break_indicator") statements = (StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_break_indicator, source_ref=source_ref), source=makeConstantRefNode(constant=True, source_ref=source_ref), source_ref=source_ref), StatementLoopBreak(source_ref=source_ref)) else: statements = (StatementLoopBreak(source_ref=source_ref), ) pushBuildContext("loop_body") loop_statements = buildStatementsNode(provider=provider, nodes=node.body, source_ref=source_ref) popBuildContext() # The loop body contains a conditional statement at the start that breaks # the loop if it fails. loop_body = makeStatementsSequence(statements=(StatementConditional( condition=ExpressionOperationNOT( operand=buildNode(provider, node.test, source_ref), source_ref=source_ref, ), yes_branch=StatementsSequence(statements=statements, source_ref=source_ref), no_branch=None, source_ref=source_ref), loop_statements), allow_none=True, source_ref=source_ref) loop_statement = StatementLoop(body=loop_body, source_ref=source_ref) if else_block is None: return loop_statement else: statements = (StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_break_indicator, source_ref=source_ref), source=makeConstantRefNode(constant=False, source_ref=source_ref), source_ref=source_ref), loop_statement, StatementConditional(condition=ExpressionComparisonIs( left=ExpressionTempVariableRef( variable=tmp_break_indicator, source_ref=source_ref), right=makeConstantRefNode(constant=True, source_ref=source_ref), source_ref=source_ref), yes_branch=else_block, no_branch=None, source_ref=source_ref)) statements = (makeTryFinallyStatement(provider=provider, tried=statements, final=StatementReleaseVariable( variable=tmp_break_indicator, source_ref=source_ref), source_ref=source_ref), ) return StatementsSequence(statements=mergeStatements( statements, False), source_ref=source_ref)
def getListUnpackingHelper(): helper_name = "_unpack_list" result = ExpressionFunctionBody( provider = getInternalModule(), name = helper_name, doc = None, parameters = ParameterSpec( name = helper_name, normal_args = (), list_star_arg = "args", dict_star_arg = None, default_count = 0, kw_only_args = () ), flags = set(), source_ref = internal_source_ref ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "list") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "keys") loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source = ExpressionBuiltinNext1( value = ExpressionTempVariableRef( variable = tmp_iter_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), exception_name = "StopIteration", handler_body = StatementLoopBreak( source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementExpressionOnly( expression = ExpressionListOperationExtend( list_arg = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), value = ExpressionTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) args_variable = result.getVariableForAssignment( variable_name = "args" ) final = ( StatementReleaseVariable( variable = tmp_result_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_iter_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_item_variable, source_ref = internal_source_ref ), ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_iter_variable, source_ref = internal_source_ref ), source = ExpressionBuiltinIter1( value = ExpressionVariableRef( variable_name = "args", variable = args_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), source = ExpressionConstantRef( constant = [], source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementLoop( body = loop_body, source_ref = internal_source_ref ), StatementReturn( expression = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) result.setBody( makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider = result, tried = tried, final = final, source_ref = internal_source_ref ) ) ) return result
def buildAssignmentStatementsFromDecoded(provider, kind, detail, source, source_ref): # This is using many variable names on purpose, so as to give names to the # unpacked detail values, and has many branches due to the many cases # dealt with, pylint: disable=too-many-branches,too-many-locals if kind == "Name": return StatementAssignmentVariableName(variable_name=detail, source=source, source_ref=source_ref) elif kind == "Attribute": lookup_source, attribute_name = detail return StatementAssignmentAttribute(expression=lookup_source, attribute_name=attribute_name, source=source, source_ref=source_ref) elif kind == "Subscript": subscribed, subscript = detail return StatementAssignmentSubscript(expression=subscribed, subscript=subscript, source=source, source_ref=source_ref) elif kind == "Slice": lookup_source, lower, upper = detail # For Python3 there is no slicing operation, this is always done # with subscript using a slice object. For Python2, it is only done # if no "step" is provided. use_sliceobj = python_version >= 300 if use_sliceobj: return StatementAssignmentSubscript( expression=lookup_source, source=source, subscript=ExpressionBuiltinSlice(start=lower, stop=upper, step=None, source_ref=source_ref), source_ref=source_ref) else: return StatementAssignmentSlice(expression=lookup_source, lower=lower, upper=upper, source=source, source_ref=source_ref) elif kind == "Tuple": temp_scope = provider.allocateTempScope("tuple_unpack") source_iter_var = provider.allocateTempVariable(temp_scope=temp_scope, name="source_iter") element_vars = [ provider.allocateTempVariable(temp_scope=temp_scope, name="element_%d" % (element_index + 1)) for element_index in range(len(detail)) ] starred_list_var = None starred_index = None statements = [] for element_index, element in enumerate(detail): element_var = element_vars[element_index] if starred_list_var is not None: if element[0] == "Starred": raiseSyntaxError("two starred expressions in assignment", source_ref.atColumnNumber(0)) statements.insert( starred_index + 1, StatementAssignmentVariable( variable=element_var, source=ExpressionListOperationPop( list_arg=ExpressionTempVariableRef( variable=starred_list_var, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref)) elif element[0] != "Starred": statements.append( StatementAssignmentVariable( variable=element_var, source=ExpressionSpecialUnpack( value=ExpressionTempVariableRef( variable=source_iter_var, source_ref=source_ref), count=element_index + 1, expected=len(detail), source_ref=source_ref), source_ref=source_ref)) else: starred_index = element_index starred_list_var = element_var statements.append( StatementAssignmentVariable( variable=element_var, source=ExpressionBuiltinList( value=ExpressionTempVariableRef( variable=source_iter_var, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref)) if starred_list_var is None: statements.append( StatementSpecialUnpackCheck(iterator=ExpressionTempVariableRef( variable=source_iter_var, source_ref=source_ref), count=len(detail), source_ref=source_ref)) statements = [ StatementAssignmentVariable(variable=source_iter_var, source=ExpressionBuiltinIter1( value=source, source_ref=source_ref), source_ref=source_ref), makeTryFinallyStatement(provider=provider, tried=statements, final=(StatementReleaseVariable( variable=source_iter_var, source_ref=source_ref), ), source_ref=source_ref) ] # When all is done, copy over to the actual assignment targets, starred # or not makes no difference here anymore. for element_index, element in enumerate(detail): if element[0] == "Starred": element = element[1] element_var = element_vars[element_index] statements.append( buildAssignmentStatementsFromDecoded( provider=provider, kind=element[0], detail=element[1], source=ExpressionTempVariableRef(variable=element_var, source_ref=source_ref), source_ref=source_ref)) # Need to release temporary variables right after successful # usage. statements.append( StatementDelVariable( variable=element_var, tolerant=True, source_ref=source_ref, )) final_statements = [] for element_var in element_vars: final_statements.append( StatementReleaseVariable( variable=element_var, source_ref=source_ref, )) return makeTryFinallyStatement(provider=provider, tried=statements, final=final_statements, source_ref=source_ref) elif kind == "Starred": raiseSyntaxError( "starred assignment target must be in a list or tuple", source_ref.atColumnNumber(0)) else: assert False, (kind, source_ref, detail)
def buildComparisonNode(provider, node, source_ref): from nuitka.nodes.NodeMakingHelpers import makeComparisonNode assert len(node.comparators) == len(node.ops) # Comparisons are re-formulated as described in the developer manual. When # having multiple compators, things require assignment expressions and # references of them to work properly. Then they can become normal "and" # code. # The operands are split out left = buildNode(provider, node.left, source_ref) rights = [ buildNode(provider, comparator, source_ref) for comparator in node.comparators ] # Only the first comparison has as left operands as the real thing, the # others must reference the previous comparison right one temp variable ref. values = [] # For PyLint to like it, this will hold the previous one, normally. keeper_variable = None temp_scope = None final = [] for comparator, right in zip(node.ops, rights): if values: # Now we know it's not the only one, so we change the "left" to be a # reference to the previously saved right side. left = ExpressionTempVariableRef( variable = keeper_variable, source_ref = source_ref ) keeper_variable = None if right is not rights[-1]: # Now we know it's not the last one, so we ought to preseve the # "right" so it can be referenced by the next part that will # come. We do it by assining it to a temp variable to be shared with # the next part. if temp_scope is None: temp_scope = provider.allocateTempScope( name = "comparison" ) keeper_variable = provider.allocateTempVariable( temp_scope = temp_scope, name = "value_%d" % (rights.index(right)+2), ) tried = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = keeper_variable, source_ref = source_ref ), source = right, source_ref = source_ref, ) # TODO: The release ought to be placed later. final.append( StatementReleaseVariable( variable = keeper_variable, tolerant = True, source_ref = source_ref, ) ) right = makeTryFinallyExpression( tried = tried, final = None, expression = ExpressionTempVariableRef( variable = keeper_variable, source_ref = source_ref ), source_ref = source_ref ) comparator = getKind(comparator) values.append( makeComparisonNode( left = left, right = right, comparator = comparator, source_ref = source_ref ) ) assert keeper_variable is None result = buildAndNode( provider = provider, values = values, source_ref = source_ref ) if final: return makeTryFinallyExpression( tried = None, expression = result, final = final, source_ref = source_ref ) else: return result
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 buildLambdaNode(provider, node, source_ref): # Many details to deal with, pylint: disable=too-many-locals assert getKind(node) == "Lambda" function_kind, flags = detectFunctionBodyKind(nodes=(node.body, )) outer_body, function_body, code_object = buildFunctionWithParsing( provider=provider, function_kind=function_kind, name="<lambda>", function_doc=None, flags=flags, node=node, source_ref=source_ref, ) if function_kind == "Function": code_body = function_body else: code_body = ExpressionGeneratorObjectBody( provider=function_body, name="<lambda>", code_object=code_object, flags=None, auto_release=None, source_ref=source_ref, ) code_body.qualname_provider = provider if function_kind == "Generator": function_body.setBody( makeStatementsSequenceFromStatement(statement=StatementReturn( expression=ExpressionMakeGeneratorObject( generator_ref=ExpressionFunctionRef( function_body=code_body, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ))) defaults = buildNodeList(provider, node.args.defaults, source_ref) kw_defaults = buildParameterKwDefaults(provider=provider, node=node, function_body=function_body, source_ref=source_ref) body = buildNode(provider=code_body, node=node.body, source_ref=source_ref) if function_kind == "Generator": if python_version < 270: tmp_return_value = code_body.allocateTempVariable( temp_scope=None, name="yield_return") statements = ( StatementAssignmentVariable(variable=tmp_return_value, source=body, source_ref=source_ref), makeStatementConditional( condition=ExpressionComparisonIsNot( left=ExpressionTempVariableRef( variable=tmp_return_value, source_ref=source_ref), right=ExpressionConstantNoneRef(source_ref=source_ref), source_ref=source_ref, ), yes_branch=StatementExpressionOnly( expression=ExpressionYield( expression=ExpressionTempVariableRef( variable=tmp_return_value, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), no_branch=None, source_ref=source_ref, ), ) body = makeTryFinallyStatement( provider=provider, tried=statements, final=StatementReleaseVariable(variable=tmp_return_value, source_ref=source_ref), source_ref=source_ref, ) else: body = StatementExpressionOnly(expression=body, source_ref=source_ref) else: body = StatementReturn(expression=body, source_ref=source_ref) if function_kind == "Generator": frame_class = StatementsFrameGenerator else: frame_class = StatementsFrameFunction body = frame_class( statements=mergeStatements((body, )), code_object=code_object, source_ref=body.getSourceReference(), ) body = makeStatementsSequenceFromStatement(statement=body) code_body.setBody(body) annotations = buildParameterAnnotations(provider, node, source_ref) return ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=outer_body, source_ref=source_ref), defaults=defaults, kw_defaults=kw_defaults, annotations=annotations, source_ref=source_ref, )
def getClassBasesMroConversionHelper(): helper_name = "_mro_entries_conversion" result = makeInternalHelperFunctionBody( name=helper_name, parameters=ParameterSpec( ps_name=helper_name, ps_normal_args=("bases", ), ps_pos_only_args=(), ps_list_star_arg=None, ps_dict_star_arg=None, ps_default_count=0, ps_kw_only_args=(), ), inline_const_args=False, # TODO: Allow this. ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "list") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "base") args_variable = result.getVariableForAssignment(variable_name="bases") non_type_case = makeStatementConditional( condition=ExpressionAttributeCheck( expression=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), attribute_name="__mro_entries__", source_ref=internal_source_ref, ), yes_branch=StatementExpressionOnly( expression=ExpressionListOperationExtend( list_arg=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), value=makeExpressionCall( called=ExpressionAttributeLookup( expression=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), attribute_name="__mro_entries__", source_ref=internal_source_ref, ), args=makeExpressionMakeTuple( elements=(ExpressionVariableRef( variable=args_variable, source_ref=internal_source_ref), ), source_ref=internal_source_ref, ), kw=None, source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), no_branch=StatementListOperationAppend( list_arg=ExpressionTempVariableRef(variable=tmp_result_variable, source_ref=internal_source_ref), value=ExpressionTempVariableRef(variable=tmp_item_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ) type_case = StatementListOperationAppend( list_arg=ExpressionTempVariableRef(variable=tmp_result_variable, source_ref=internal_source_ref), value=ExpressionTempVariableRef(variable=tmp_item_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ) loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried=StatementAssignmentVariable( variable=tmp_item_variable, source=ExpressionBuiltinNext1( value=ExpressionTempVariableRef( variable=tmp_iter_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), exception_name="StopIteration", handler_body=StatementLoopBreak(source_ref=internal_source_ref), source_ref=internal_source_ref, ), makeStatementConditional( condition=ExpressionBuiltinIsinstance( instance=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), classes=makeConstantRefNode(constant=type, source_ref=internal_source_ref), source_ref=internal_source_ref, ), yes_branch=type_case, no_branch=non_type_case, source_ref=internal_source_ref, ), ) final = ( StatementReleaseVariable(variable=args_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_result_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_iter_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_item_variable, source_ref=internal_source_ref), ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable=tmp_iter_variable, source=ExpressionBuiltinIter1( value=ExpressionVariableRef(variable=args_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), StatementAssignmentVariable( variable=tmp_result_variable, source=makeConstantRefNode(constant=[], source_ref=internal_source_ref), source_ref=internal_source_ref, ), StatementLoop(body=loop_body, source_ref=internal_source_ref), StatementReturn( expression=ExpressionBuiltinTuple( value=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), ) result.setBody( makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider=result, tried=tried, final=final, source_ref=internal_source_ref, ))) return result
def getSetUnpackingHelper(): helper_name = "_unpack_set" result = makeInternalHelperFunctionBody( name=helper_name, parameters=ParameterSpec( ps_name=helper_name, ps_normal_args=(), ps_list_star_arg="args", ps_dict_star_arg=None, ps_default_count=0, ps_kw_only_args=(), ps_pos_only_args=(), ), ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "set") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "keys") loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried=StatementAssignmentVariable( variable=tmp_item_variable, source=ExpressionBuiltinNext1( value=ExpressionTempVariableRef( variable=tmp_iter_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), exception_name="StopIteration", handler_body=StatementLoopBreak(source_ref=internal_source_ref), source_ref=internal_source_ref, ), StatementExpressionOnly( expression=ExpressionSetOperationUpdate( set_arg=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), value=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), ) args_variable = result.getVariableForAssignment(variable_name="args") final = ( StatementReleaseVariable(variable=tmp_result_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_iter_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_item_variable, source_ref=internal_source_ref), ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable=tmp_iter_variable, source=ExpressionBuiltinIter1( value=ExpressionVariableRef(variable=args_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), StatementAssignmentVariable( variable=tmp_result_variable, source=makeConstantRefNode(constant=set(), source_ref=internal_source_ref), source_ref=internal_source_ref, ), StatementLoop(loop_body=loop_body, source_ref=internal_source_ref), StatementReturn( expression=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), ) result.setChild( "body", makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider=result, tried=tried, final=final, source_ref=internal_source_ref, )), ) return result
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 _buildContractionBodyNode( provider, node, emit_class, start_value, container_tmp, iter_tmp, temp_scope, assign_provider, function_body, for_asyncgen, source_ref, ): # This uses lots of variables and branches. There is no good way # around that, and we deal with many cases, due to having generator # expressions sharing this code, pylint: disable=too-many-branches,too-many-locals # Note: The assign_provider is only to cover Python2 list contractions, # assigning one of the loop variables to the outside scope. tmp_variables = [] if emit_class is not ExpressionYield: tmp_variables.append(iter_tmp) if container_tmp is not None: tmp_variables.append(container_tmp) statements = [] # First assign the iterator if we are an outline. if assign_provider: statements.append( StatementAssignmentVariable( variable=iter_tmp, source=_makeIteratorCreation( provider=provider, qual=node.generators[0], for_asyncgen=False, source_ref=source_ref, ), source_ref=source_ref.atInternal(), ) ) if for_asyncgen and python_version >= 0x370 and node.generators[0].is_async: statements.append( StatementAssignmentVariable( variable=iter_tmp, source=ExpressionTempVariableRef( variable=iter_tmp, source_ref=source_ref ), source_ref=source_ref, ) ) if start_value is not None: statements.append( StatementAssignmentVariable( variable=container_tmp, source=makeConstantRefNode(constant=start_value, source_ref=source_ref), source_ref=source_ref.atInternal(), ) ) if hasattr(node, "elt"): if start_value is not None: current_body = emit_class( ExpressionTempVariableRef( variable=container_tmp, source_ref=source_ref ), buildNode( provider=function_body if not assign_provider else provider, node=node.elt, source_ref=source_ref, ), source_ref=source_ref, ) else: assert emit_class is ExpressionYield current_body = emit_class( buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref, ) else: current_body = emit_class( dict_arg=ExpressionTempVariableRef( variable=container_tmp, source_ref=source_ref ), key=buildNode( provider=function_body if not assign_provider else provider, node=node.key, source_ref=source_ref, ), value=buildNode( provider=function_body if not assign_provider else provider, node=node.value, source_ref=source_ref, ), source_ref=source_ref, ) if current_body.isExpression(): current_body = StatementExpressionOnly( expression=current_body, source_ref=source_ref ) for count, qual in enumerate(reversed(node.generators)): tmp_value_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="iter_value_%d" % count ) tmp_variables.append(tmp_value_variable) # The first iterated value is to be calculated outside of the function # and will be given as a parameter "_iterated", the others are built # inside the function. if qual is node.generators[0]: iterator_ref = makeVariableRefNode(variable=iter_tmp, source_ref=source_ref) if for_asyncgen and python_version >= 0x370: iterator_ref = ExpressionYieldFromWaitable( expression=iterator_ref, source_ref=source_ref ) tmp_iter_variable = None nested_statements = [] else: # First create the iterator and store it, next should be loop body value_iterator = _makeIteratorCreation( provider=provider if assign_provider else function_body, qual=qual, for_asyncgen=False, source_ref=source_ref, ) tmp_iter_variable = function_body.allocateTempVariable( temp_scope=temp_scope, name="contraction_iter_%d" % count ) tmp_variables.append(tmp_iter_variable) nested_statements = [ StatementAssignmentVariable( variable=tmp_iter_variable, source=value_iterator, source_ref=source_ref, ) ] iterator_ref = ExpressionTempVariableRef( variable=tmp_iter_variable, source_ref=source_ref ) loop_statements = [ makeTryExceptSingleHandlerNode( tried=StatementAssignmentVariable( variable=tmp_value_variable, source=_makeIteratorNext( iterator_ref=iterator_ref, qual=qual, source_ref=source_ref ), source_ref=source_ref, ), exception_name=_getStopIterationName(qual), handler_body=StatementLoopBreak(source_ref=source_ref), source_ref=source_ref, ), buildAssignmentStatements( provider=provider if assign_provider else function_body, temp_provider=function_body, node=qual.target, source=ExpressionTempVariableRef( variable=tmp_value_variable, source_ref=source_ref ), source_ref=source_ref, ), ] conditions = buildNodeList( provider=provider if assign_provider else function_body, nodes=qual.ifs, source_ref=source_ref, ) if len(conditions) >= 1: loop_statements.append( makeStatementConditional( condition=buildAndNode(values=conditions, source_ref=source_ref), yes_branch=current_body, no_branch=None, source_ref=source_ref, ) ) else: loop_statements.append(current_body) nested_statements.append( StatementLoop( loop_body=StatementsSequence( statements=mergeStatements(loop_statements), source_ref=source_ref ), source_ref=source_ref, ) ) if tmp_iter_variable is not None: nested_statements.append( StatementReleaseVariable( variable=tmp_iter_variable, source_ref=source_ref ) ) current_body = StatementsSequence( statements=mergeStatements(nested_statements, False), source_ref=source_ref ) statements.append(current_body) statements = mergeStatements(statements) release_statements = [ StatementReleaseVariable(variable=tmp_variable, source_ref=source_ref) for tmp_variable in tmp_variables ] return statements, release_statements