def buildClassNode2(provider, node, source_ref): # This function is the Python2 special case with special re-formulation as # according to developer manual, and it's very detailed, pylint: disable=too-many-locals class_statement_nodes, class_doc = extractDocFromBody(node) function_body = ExpressionClassBody(provider=provider, name=node.name, doc=class_doc, source_ref=source_ref) parent_module = provider.getParentModule() code_object = CodeObjectSpec( co_name=node.name, co_kind="Class", co_varnames=(), co_argcount=0, co_posonlyargcount=0, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False, co_filename=parent_module.getRunTimeFilename(), co_lineno=source_ref.getLineNumber(), future_spec=parent_module.getFutureSpec(), ) body = buildFrameNode( provider=function_body, nodes=class_statement_nodes, code_object=code_object, source_ref=source_ref, ) if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref.atInternal() locals_scope = function_body.getLocalsScope() # The class body is basically a function that implicitly, at the end # returns its locals and cannot have other return statements contained, and # starts out with a variables "__module__" and potentially "__doc__" set. statements = [ StatementSetLocalsDictionary(locals_scope=locals_scope, source_ref=source_ref), StatementAssignmentVariableName( provider=function_body, variable_name="__module__", source=ExpressionModuleAttributeNameRef( variable=provider.getParentModule().getVariableForReference( "__name__"), source_ref=source_ref, ), source_ref=source_ref.atInternal(), ), ] if class_doc is not None: statements.append( StatementAssignmentVariableName( provider=function_body, variable_name="__doc__", source=makeConstantRefNode(constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref.atInternal(), )) statements += ( body, StatementReturn( expression=ExpressionBuiltinLocalsRef(locals_scope=locals_scope, source_ref=source_ref), source_ref=source_ref, ), ) body = makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement( provider=function_body, tried=mergeStatements(statements, True), final=StatementReleaseLocals(locals_scope=locals_scope, source_ref=source_ref), source_ref=source_ref, )) # The class body is basically a function that implicitly, at the end # returns its locals and cannot have other return statements contained. function_body.setBody(body) temp_scope = provider.allocateTempScope("class_creation") tmp_bases = provider.allocateTempVariable(temp_scope, "bases") tmp_class_dict = provider.allocateTempVariable(temp_scope, "class_dict") tmp_metaclass = provider.allocateTempVariable(temp_scope, "metaclass") tmp_class = provider.allocateTempVariable(temp_scope, "class") select_metaclass = ExpressionOutlineBody(provider=provider, name="select_metaclass", body=None, source_ref=source_ref) if node.bases: tmp_base = select_metaclass.allocateTempVariable(temp_scope=None, name="base") statements = ( StatementAssignmentVariable( variable=tmp_base, source=ExpressionSubscriptLookup( expression=ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref), subscript=makeConstantRefNode(constant=0, source_ref=source_ref, user_provided=True), source_ref=source_ref, ), source_ref=source_ref, ), makeTryFinallyStatement( provider, tried=StatementTry( tried=makeStatementsSequenceFromStatement( statement=StatementReturn( expression=ExpressionAttributeLookup( expression=ExpressionTempVariableRef( variable=tmp_base, source_ref=source_ref), attribute_name="__class__", source_ref=source_ref, ), source_ref=source_ref, )), except_handler=makeStatementsSequenceFromStatement( statement=StatementReturn( expression=ExpressionBuiltinType1( value=ExpressionTempVariableRef( variable=tmp_base, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, )), break_handler=None, continue_handler=None, return_handler=None, source_ref=source_ref, ), final=StatementReleaseVariable(variable=tmp_base, source_ref=source_ref), source_ref=source_ref, public_exc=False, ), ) else: statements = ( StatementTry( tried=makeStatementsSequenceFromStatement( statement=StatementReturn( # TODO: Should avoid checking __builtins__ for this. expression=ExpressionVariableNameRef( variable_name="__metaclass__", provider=parent_module, source_ref=source_ref, ), source_ref=source_ref, )), except_handler=makeStatementsSequenceFromStatement( statement=StatementReturn( expression=ExpressionBuiltinAnonymousRef( builtin_name="classobj", source_ref=source_ref), source_ref=source_ref, )), break_handler=None, continue_handler=None, return_handler=None, source_ref=source_ref, ), ) select_metaclass.setBody( makeStatementsSequence(statements=statements, allow_none=False, source_ref=source_ref)) statements = [ StatementAssignmentVariable( variable=tmp_bases, source=makeSequenceCreationOrConstant( sequence_kind="tuple", elements=buildNodeList(provider=provider, nodes=node.bases, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariable(variable=tmp_class_dict, source=function_body, source_ref=source_ref), StatementAssignmentVariable( variable=tmp_metaclass, source=ExpressionConditional( condition=ExpressionDictOperationIn( key=makeConstantRefNode( constant="__metaclass__", source_ref=source_ref, user_provided=True, ), dict_arg=ExpressionTempVariableRef(variable=tmp_class_dict, source_ref=source_ref), source_ref=source_ref, ), expression_yes=ExpressionDictOperationGet( dict_arg=ExpressionTempVariableRef(variable=tmp_class_dict, source_ref=source_ref), key=makeConstantRefNode( constant="__metaclass__", source_ref=source_ref, user_provided=True, ), source_ref=source_ref, ), expression_no=select_metaclass, source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariable( variable=tmp_class, source=makeExpressionCall( called=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), args=ExpressionMakeTuple( elements=( makeConstantRefNode( constant=node.name, source_ref=source_ref, user_provided=True, ), ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), ExpressionTempVariableRef(variable=tmp_class_dict, source_ref=source_ref), ), source_ref=source_ref, ), kw=None, source_ref=source_ref, ), source_ref=source_ref, ), ] for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): statements.append( StatementAssignmentVariable( variable=tmp_class, source=makeExpressionCall( called=decorator, args=ExpressionMakeTuple( elements=(ExpressionTempVariableRef( variable=tmp_class, source_ref=source_ref), ), source_ref=source_ref, ), kw=None, source_ref=decorator.getSourceReference(), ), source_ref=decorator.getSourceReference(), )) statements.append( StatementAssignmentVariableName( provider=provider, variable_name=mangleName(node.name, provider), source=ExpressionTempVariableRef(variable=tmp_class, source_ref=source_ref), source_ref=source_ref, )) final = ( StatementReleaseVariable(variable=tmp_class, source_ref=source_ref), StatementReleaseVariable(variable=tmp_bases, source_ref=source_ref), StatementReleaseVariable(variable=tmp_class_dict, source_ref=source_ref), StatementReleaseVariable(variable=tmp_metaclass, source_ref=source_ref), ) return makeTryFinallyStatement(provider=function_body, tried=statements, final=final, source_ref=source_ref)
def _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,R0915 # 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(co_name=node.name, co_kind="Class", co_varnames=(), co_argcount=0, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False) 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 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=makeConstantRefNode( 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=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() qualname_variable = class_creation_function.getVariableForAssignment( "__qualname__") 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( 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] if python_version >= 360 and \ class_creation_function.needsAnnotationsDictionary(): annotations_variable = class_creation_function.getVariableForAssignment( "__annotations__") statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__annotations__", variable=annotations_variable, source_ref=source_ref), source=makeConstantRefNode(constant={}, source_ref=source_ref, user_provided=True), source_ref=source_ref)) statements.append(body) statements += [ StatementAssignmentVariable( variable_ref=class_target_variable_ref, source=ExpressionCall( 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), 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=[ makeConstantRefNode(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=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=ExpressionBuiltinRef(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_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=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=ExpressionCall( 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), 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 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 < 0x340: 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 >= 0x340: qualname_assign = statements[-1] if python_version >= 0x360 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 >= 0x370: 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 >= 0x370 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.setChild("body", 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 < 0x370 else tmp_bases_orig, source=_buildBasesTupleCreationNode(provider=provider, elements=node.bases, source_ref=source_ref), source_ref=source_ref, )) if python_version >= 0x370: 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 >= 0x370: 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 >= 0x364: 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 >= 0x340: 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 >= 0x370: 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 _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(co_name=node.name, co_kind="Class", co_varnames=(), co_argcount=0, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False) 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() # 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=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( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__doc__", source_ref=source_ref), source=makeConstantRefNode(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=makeConstantRefNode(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=makeConstantRefNode(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=(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), 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 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_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 locals_scope = class_creation_function.getFunctionLocalsScope() 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=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 >= 300: 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=makeSequenceCreationOrConstant( sequence_kind="tuple", 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=ExpressionMakeTuple(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=buildTupleCreationNode( 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( 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, ) # 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=makeExpressionBuiltinRef( builtin_name="type", source_ref=source_ref ), source_ref=source_ref, ) else: unspecified_metaclass_expression = makeExpressionBuiltinRef( builtin_name="type", source_ref=source_ref ) call_prepare = StatementAssignmentVariable( variable=tmp_prepared, source=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 ), 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 >= 360: call_prepare = makeStatementsSequenceFromStatements( call_prepare, makeStatementConditional( condition=ExpressionAttributeCheck( object_arg=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( object_arg=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( source=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( object_arg=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 _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( co_name = node.name, co_kind = "Class", co_varnames = (), co_argcount = 0, co_kwonlyargcount = 0, co_has_starlist = False, co_has_stardict = False ) 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 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 = makeConstantRefNode( 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 = 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() qualname_variable = class_creation_function.getVariableForAssignment( "__qualname__" ) 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( 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 = ( makeConstantRefNode( 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 = [ makeConstantRefNode( 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 = 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 = ExpressionBuiltinRef( 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_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 = 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 = ExpressionCall( 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 ), 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 _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( co_name = node.name, co_kind = "Class", co_varnames = (), co_argcount = 0, co_kwonlyargcount = 0, co_has_starlist = False, co_has_stardict = False ) 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() # 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 = 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( StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = "__doc__", source_ref = source_ref ), source = makeConstantRefNode( 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 = makeConstantRefNode( 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 = makeConstantRefNode( 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 = ( 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 ), 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 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 )