def _injectDecorator(decorators, inject, acceptable, source_ref):
    assert type(inject) is str
    assert type(acceptable) is tuple

    for decorator in decorators:
        if (decorator.isExpressionVariableNameRef()
                and decorator.getVariableName() in acceptable):
            break
    else:
        decorators.append(
            makeExpressionBuiltinRef(builtin_name=inject,
                                     source_ref=source_ref))
    def wrapEvalBuiltin(source, globals_arg, locals_arg, source_ref):
        provider = node.getParentVariableProvider()

        outline_body = ExpressionOutlineBody(
            provider=node.getParentVariableProvider(),
            name="eval_call",
            source_ref=source_ref,
        )

        globals_ref, locals_ref, tried, final = wrapEvalGlobalsAndLocals(
            provider=provider,
            globals_node=globals_arg,
            locals_node=locals_arg,
            temp_scope=outline_body.getOutlineTempScope(),
            source_ref=source_ref,
        )

        # The wrapping should not relocate to the "source_ref".
        assert (globals_arg is None or globals_ref.getSourceReference()
                == globals_arg.getSourceReference())
        assert (locals_arg is None or locals_ref.getSourceReference()
                == locals_arg.getSourceReference())

        source_variable = outline_body.allocateTempVariable(temp_scope=None,
                                                            name="source")

        final.setStatements(final.getStatements() + (StatementDelVariable(
            variable=source_variable, tolerant=True, source_ref=source_ref), ))

        strip_choice = makeConstantRefNode(constant=(" \t", ),
                                           source_ref=source_ref)

        if python_version >= 300:
            strip_choice = ExpressionConditional(
                condition=ExpressionComparisonIs(
                    left=ExpressionBuiltinType1(
                        value=ExpressionTempVariableRef(
                            variable=source_variable, source_ref=source_ref),
                        source_ref=source_ref,
                    ),
                    right=makeExpressionBuiltinRef(builtin_name="bytes",
                                                   source_ref=source_ref),
                    source_ref=source_ref,
                ),
                expression_yes=makeConstantRefNode(constant=(b" \t", ),
                                                   source_ref=source_ref),
                expression_no=strip_choice,
                source_ref=source_ref,
            )

        # Source needs some special treatment for eval, if it's a string, it
        # must be stripped.
        string_fixup = StatementAssignmentVariable(
            variable=source_variable,
            source=makeExpressionCall(
                called=ExpressionAttributeLookup(
                    source=ExpressionTempVariableRef(variable=source_variable,
                                                     source_ref=source_ref),
                    attribute_name="strip",
                    source_ref=source_ref,
                ),
                args=strip_choice,  # This is a tuple
                kw=None,
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        )

        acceptable_builtin_types = [
            ExpressionBuiltinAnonymousRef(builtin_name="code",
                                          source_ref=source_ref)
        ]

        if python_version >= 270:
            acceptable_builtin_types.append(
                makeExpressionBuiltinRef(builtin_name="memoryview",
                                         source_ref=source_ref))

        statements = (
            StatementAssignmentVariable(variable=source_variable,
                                        source=source,
                                        source_ref=source_ref),
            makeStatementConditional(
                condition=ExpressionOperationNOT(
                    operand=ExpressionBuiltinIsinstance(
                        instance=ExpressionTempVariableRef(
                            variable=source_variable, source_ref=source_ref),
                        classes=makeSequenceCreationOrConstant(
                            sequence_kind="tuple",
                            elements=acceptable_builtin_types,
                            source_ref=source_ref,
                        ),
                        source_ref=source_ref,
                    ),
                    source_ref=source_ref,
                ),
                yes_branch=string_fixup,
                no_branch=None,
                source_ref=source_ref,
            ),
            StatementReturn(
                expression=ExpressionBuiltinEval(
                    source_code=ExpressionTempVariableRef(
                        variable=source_variable, source_ref=source_ref),
                    globals_arg=globals_ref,
                    locals_arg=locals_ref,
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
        )

        tried = makeStatementsSequence(statements=(tried, ) + statements,
                                       allow_none=False,
                                       source_ref=source_ref)

        outline_body.setBody(
            makeStatementsSequenceFromStatement(
                statement=makeTryFinallyStatement(
                    provider=outline_body,
                    tried=tried,
                    final=final,
                    source_ref=source_ref,
                )))

        return outline_body
示例#3
0
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_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.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=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 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 >= 364:
        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,
    )
示例#4
0
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,
    )
示例#5
0
    def wrapEvalBuiltin(source, globals_arg, locals_arg, source_ref):
        provider = node.getParentVariableProvider()

        outline_body = ExpressionOutlineBody(
            provider=node.getParentVariableProvider(),
            name="eval_call",
            source_ref=source_ref,
        )

        globals_ref, locals_ref, tried, final = wrapEvalGlobalsAndLocals(
            provider=provider,
            globals_node=globals_arg,
            locals_node=locals_arg,
            temp_scope=outline_body.getOutlineTempScope(),
            source_ref=source_ref,
        )

        # The wrapping should not relocate to the "source_ref".
        assert (
            globals_arg is None
            or globals_ref.getSourceReference() == globals_arg.getSourceReference()
        )
        assert (
            locals_arg is None
            or locals_ref.getSourceReference() == locals_arg.getSourceReference()
        )

        source_variable = outline_body.allocateTempVariable(
            temp_scope=None, name="source"
        )

        final.setStatements(
            final.getStatements()
            + (
                StatementDelVariable(
                    variable=source_variable, tolerant=True, source_ref=source_ref
                ),
            )
        )

        strip_choice = makeConstantRefNode(constant=(" \t",), source_ref=source_ref)

        if python_version >= 300:
            strip_choice = ExpressionConditional(
                condition=ExpressionComparisonIs(
                    left=ExpressionBuiltinType1(
                        value=ExpressionTempVariableRef(
                            variable=source_variable, source_ref=source_ref
                        ),
                        source_ref=source_ref,
                    ),
                    right=makeExpressionBuiltinRef(
                        builtin_name="bytes", source_ref=source_ref
                    ),
                    source_ref=source_ref,
                ),
                expression_yes=makeConstantRefNode(
                    constant=(b" \t",), source_ref=source_ref
                ),
                expression_no=strip_choice,
                source_ref=source_ref,
            )

        # Source needs some special treatment for eval, if it's a string, it
        # must be stripped.
        string_fixup = StatementAssignmentVariable(
            variable=source_variable,
            source=makeExpressionCall(
                called=ExpressionAttributeLookup(
                    source=ExpressionTempVariableRef(
                        variable=source_variable, source_ref=source_ref
                    ),
                    attribute_name="strip",
                    source_ref=source_ref,
                ),
                args=strip_choice,  # This is a tuple
                kw=None,
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        )

        acceptable_builtin_types = [
            ExpressionBuiltinAnonymousRef(builtin_name="code", source_ref=source_ref)
        ]

        if python_version >= 270:
            acceptable_builtin_types.append(
                makeExpressionBuiltinRef(
                    builtin_name="memoryview", source_ref=source_ref
                )
            )

        statements = (
            StatementAssignmentVariable(
                variable=source_variable, source=source, source_ref=source_ref
            ),
            makeStatementConditional(
                condition=ExpressionOperationNOT(
                    operand=ExpressionBuiltinIsinstance(
                        instance=ExpressionTempVariableRef(
                            variable=source_variable, source_ref=source_ref
                        ),
                        classes=makeSequenceCreationOrConstant(
                            sequence_kind="tuple",
                            elements=acceptable_builtin_types,
                            source_ref=source_ref,
                        ),
                        source_ref=source_ref,
                    ),
                    source_ref=source_ref,
                ),
                yes_branch=string_fixup,
                no_branch=None,
                source_ref=source_ref,
            ),
            StatementReturn(
                expression=ExpressionBuiltinEval(
                    source_code=ExpressionTempVariableRef(
                        variable=source_variable, source_ref=source_ref
                    ),
                    globals_arg=globals_ref,
                    locals_arg=locals_ref,
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
        )

        tried = makeStatementsSequence(
            statements=(tried,) + statements, allow_none=False, source_ref=source_ref
        )

        outline_body.setBody(
            makeStatementsSequenceFromStatement(
                statement=makeTryFinallyStatement(
                    provider=outline_body,
                    tried=tried,
                    final=final,
                    source_ref=source_ref,
                )
            )
        )

        return outline_body
def buildFunctionNode(provider, node, source_ref):
    # Functions have way too many details, pylint: disable=too-many-branches,too-many-locals

    assert getKind(node) == "FunctionDef"

    function_statement_nodes, function_doc = extractDocFromBody(node)

    function_kind, flags = detectFunctionBodyKind(
        nodes=function_statement_nodes)

    function_body, code_body, code_object = buildFunctionWithParsing(
        provider=provider,
        function_kind=function_kind,
        name=node.name,
        function_doc=function_doc,
        flags=flags,
        node=node,
        source_ref=source_ref)

    if function_kind == "Generator":
        code_body = ExpressionGeneratorObjectBody(provider=function_body,
                                                  name=node.name,
                                                  flags=flags,
                                                  source_ref=source_ref)
        code_body.qualname_provider = provider

        for variable in function_body.getVariables():
            code_body.getVariableForReference(variable.getName())

        function_body.setBody(
            makeStatementsSequenceFromStatement(statement=StatementReturn(
                expression=ExpressionMakeGeneratorObject(
                    generator_ref=ExpressionFunctionRef(
                        function_body=code_body, source_ref=source_ref),
                    code_object=code_object,
                    source_ref=source_ref),
                source_ref=source_ref)))

    decorators = buildNodeList(provider=provider,
                               nodes=reversed(node.decorator_list),
                               source_ref=source_ref)

    defaults = buildNodeList(provider=provider,
                             nodes=node.args.defaults,
                             source_ref=source_ref)

    kw_defaults = buildParameterKwDefaults(provider=provider,
                                           node=node,
                                           function_body=function_body,
                                           source_ref=source_ref)

    function_statements_body = buildFrameNode(provider=code_body,
                                              nodes=function_statement_nodes,
                                              code_object=code_object,
                                              source_ref=source_ref)

    if function_kind == "Function":
        # TODO: Generators might have to raise GeneratorExit instead.
        function_statements_body = _insertFinalReturnStatement(
            function_statements_body=function_statements_body,
            return_statement=StatementReturnNone(source_ref=source_ref))

    if "has_exec" in flags:
        function_statements_body = _insertInitialSetLocalsDictStatement(
            function_body=code_body,
            function_statements_body=function_statements_body,
        )

    if function_statements_body.isStatementsFrame():
        function_statements_body = makeStatementsSequenceFromStatement(
            statement=function_statements_body)

    code_body.setBody(function_statements_body)

    annotations = buildParameterAnnotations(provider, node, source_ref)

    function_creation = ExpressionFunctionCreation(
        function_ref=ExpressionFunctionRef(function_body=function_body,
                                           source_ref=source_ref),
        code_object=code_object,
        defaults=defaults,
        kw_defaults=kw_defaults,
        annotations=annotations,
        source_ref=source_ref)

    # Add the "staticmethod" decorator to __new__ methods if not provided.

    # CPython made these optional, but secretly applies them when it does
    # "class __new__".  We add them earlier, so our optimization will see it.
    if node.name == "__new__" and \
       provider.isExpressionClassBody():

        for decorator in decorators:
            if decorator.isExpressionVariableNameRef() and \
               decorator.getVariableName() in ("staticmethod", "classmethod"):
                break
        else:
            decorators.append(
                makeExpressionBuiltinRef(builtin_name="staticmethod",
                                         source_ref=source_ref))

    if python_version >= 360 and \
       node.name == "__init_subclass__" and \
       provider.isExpressionClassBody():

        for decorator in decorators:
            if decorator.isExpressionVariableNameRef() and \
               decorator.getVariableName() == "classmethod":
                break
        else:
            decorators.append(
                makeExpressionBuiltinRef(builtin_name="classmethod",
                                         source_ref=source_ref))

    decorated_function = function_creation
    for decorator in decorators:
        decorated_function = makeCallNode(decorator, decorated_function,
                                          decorator.getSourceReference())

    result = StatementAssignmentVariableName(provider=provider,
                                             variable_name=mangleName(
                                                 node.name, provider),
                                             source=decorated_function,
                                             source_ref=source_ref)

    if python_version >= 340:
        function_body.qualname_setup = result.getVariableName()

    return result
示例#7
0
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)