Example #1
0
    def onEnterNode(self, node):
        if node.isExpressionVariableNameRef():
            provider = node.provider

            try:
                variable = self._attachVariable(node, provider)
            except MaybeLocalVariableUsage:
                variable_name = node.getVariableName()

                new_node = ExpressionLocalsVariableRefOrFallback(
                    locals_scope=provider.getFunctionLocalsScope(),
                    variable_name=variable_name,
                    fallback=ExpressionVariableRef(
                        variable=node.getParentModule().
                        getVariableForReference(variable_name),
                        source_ref=node.source_ref,
                    ),
                    source_ref=node.source_ref,
                )
            else:
                new_node = ExpressionVariableRef(variable=variable,
                                                 source_ref=node.source_ref)

                variable.addVariableUser(provider)

            parent = node.parent
            node.finalize()

            parent.replaceChild(node, new_node)
    def wrapSuperBuiltin(type_arg, object_arg, source_ref):
        if type_arg is None and python_version >= 300:
            type_arg = ExpressionVariableRef(variable_name="__class__",
                                             source_ref=source_ref)

            # Ought to be already closure taken.
            type_arg.setVariable(
                provider.getVariableForReference(variable_name="__class__"))

            # If we already have this as a local variable, then use that
            # instead.
            type_arg_owner = type_arg.getVariable().getOwner()
            if type_arg_owner is provider or \
            not (type_arg_owner.isExpressionFunctionBody() or \
                 type_arg_owner.isExpressionClassBody()):
                type_arg = None

            if type_arg is None:
                return makeRaiseExceptionReplacementExpression(
                    expression=node,
                    exception_type="SystemError"
                    if python_version < 331 else "RuntimeError",
                    exception_value="super(): __class__ cell not found",
                )

            if object_arg is None:
                if provider.isExpressionGeneratorObjectBody() or \
                   provider.isExpressionCoroutineObjectBody() or \
                   provider.isExpressionAsyncgenObjectBody():
                    parameter_provider = provider.getParentVariableProvider()
                else:
                    parameter_provider = provider

                if parameter_provider.getParameters().getArgumentCount() > 0:
                    par1_name = parameter_provider.getParameters(
                    ).getArgumentNames()[0]

                    object_arg = ExpressionVariableRef(variable_name=par1_name,
                                                       source_ref=source_ref)

                    object_arg.setVariable(
                        provider.getVariableForReference(
                            variable_name=par1_name))

                    if not object_arg.getVariable().isParameterVariable():
                        return makeRaiseExceptionReplacementExpression(
                            expression=node,
                            exception_type="SystemError"
                            if python_version < 330 else "RuntimeError",
                            exception_value="super(): __class__ cell not found",
                        )
                else:
                    return makeRaiseExceptionReplacementExpression(
                        expression=node,
                        exception_type="RuntimeError",
                        exception_value="super(): no arguments")

        return ExpressionBuiltinSuper(super_type=type_arg,
                                      super_object=object_arg,
                                      source_ref=source_ref)
    def wrapSuperBuiltin( type, object, source_ref ):
        if type is None and python_version >= 300:
            provider = node.getParentVariableProvider()

            type = ExpressionVariableRef(
                variable_name = "__class__",
                source_ref    = source_ref
            )

            # Ought to be already closure taken.
            type.setVariable(
                provider.getVariableForReference(
                    variable_name = "__class__"
                )
            )

            from nuitka.nodes.NodeMakingHelpers import makeRaiseExceptionReplacementExpression

            if not type.getVariable().isClosureReference():
                return makeRaiseExceptionReplacementExpression(
                    expression      = node,
                    exception_type  = "SystemError"
                                        if python_version < 331 else
                                      "RuntimeError",
                    exception_value = "super(): __class__ cell not found",
                )

            if object is None and provider.getParameters().getArgumentCount() > 0:
                par1_name = provider.getParameters().getArgumentNames()[0]
                # TODO: Nested first argument would kill us here, need a test
                # for that.

                object = ExpressionVariableRef(
                    variable_name = par1_name,
                    source_ref    = source_ref
                )

                object.setVariable(
                    node.getParentVariableProvider().getVariableForReference(
                        variable_name = par1_name
                    )
                )

                if not object.getVariable().isParameterVariable():
                    return makeRaiseExceptionReplacementExpression(
                        expression      = node,
                        exception_type  = "SystemError"
                                            if python_version < 330 else
                                          "RuntimeError",
                        exception_value = "super(): __class__ cell not found",
                    )


        return ExpressionBuiltinSuper(
            super_type   = type,
            super_object = object,
            source_ref   = source_ref
        )
Example #4
0
def _buildInplaceAssignVariableNode(variable_ref, operator, expression,
                                    source_ref):
    assert variable_ref.isExpressionTargetVariableRef(), variable_ref

    inplace_node = ExpressionOperationBinaryInplace(
        operator   = operator,
        left       = ExpressionVariableRef(
            variable_name = variable_ref.getVariableName(),
            source_ref    = source_ref
        ),
        right      = expression,
        source_ref = source_ref
    )

    inplace_node.markAsInplaceSuspect()

    result = (
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetVariableRef(
                variable_name = variable_ref.getVariableName(),
                source_ref    = source_ref
            ),
            source       = inplace_node,
            source_ref   = source_ref
        ),
    )

    return result
def _buildInplaceAssignVariableNode(variable_ref, tmp_variable1, tmp_variable2,
                                    operator, expression, source_ref):
    assert variable_ref.isExpressionTargetVariableRef(), variable_ref

    # First assign the target value to a temporary variable.
    preserve_to_tmp = StatementAssignmentVariable(
        variable_ref=ExpressionTargetTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
        source=ExpressionVariableRef(
            variable_name=variable_ref.getVariableName(),
            source_ref=source_ref),
        source_ref=source_ref)
    # Second assign the inplace result to a temporary variable
    inplace_to_tmp = StatementAssignmentVariable(
        variable_ref=ExpressionTargetTempVariableRef(variable=tmp_variable2,
                                                     source_ref=source_ref),
        source=ExpressionOperationBinaryInplace(operator=operator,
                                                left=ExpressionTempVariableRef(
                                                    variable=tmp_variable1,
                                                    source_ref=source_ref),
                                                right=expression,
                                                source_ref=source_ref),
        source_ref=source_ref)

    # Third, copy it over, if the reference values change, i.e. IsNot is true.
    copy_back_from_tmp = StatementConditional(
        condition=ExpressionComparisonIsNOT(
            left=ExpressionTempVariableRef(variable=tmp_variable1,
                                           source_ref=source_ref),
            right=ExpressionTempVariableRef(variable=tmp_variable2,
                                            source_ref=source_ref),
            source_ref=source_ref),
        yes_branch=makeStatementsSequenceFromStatement(
            statement=StatementAssignmentVariable(
                variable_ref=variable_ref.makeCloneAt(source_ref),
                source=ExpressionTempVariableRef(variable=tmp_variable2,
                                                 source_ref=source_ref),
                source_ref=source_ref)),
        no_branch=None,
        source_ref=source_ref)

    return (
        preserve_to_tmp,
        # making sure the above temporary variable is deleted in any case.
        makeTryFinallyStatement(
            tried=(inplace_to_tmp, copy_back_from_tmp),
            final=(
                StatementDelVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=tmp_variable1, source_ref=source_ref),
                    tolerant=False,
                    source_ref=source_ref),
                StatementDelVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=tmp_variable2, source_ref=source_ref),
                    tolerant=True,
                    source_ref=source_ref),
            ),
            source_ref=source_ref))
Example #6
0
def buildAnnAssignNode(provider, node, source_ref):
    """ Python3.6 annotation assignment.

    """

    if provider.isCompiledPythonModule() or provider.isExpressionClassBody():
        provider.markAsNeedsAnnotationsDictionary()

    # Evaluate the right hand side first, so it can get names provided
    # before the left hand side exists.
    statements = []

    if node.value is not None:
        source = buildNode(provider, node.value, source_ref)

        statements.append(
            buildAssignmentStatements(provider=provider,
                                      node=node.target,
                                      source=source,
                                      source_ref=source_ref))

        # Only name referencing annotations are effective right now.
        if statements[-1].isStatementAssignmentVariable():
            variable_name = statements[-1].getVariableName()
        else:
            variable_name = None
    else:
        # Only name referencing annotations are effective right now.
        kind, detail = decodeAssignTarget(provider=provider,
                                          node=node.target,
                                          source_ref=source_ref)

        if kind == "Name":
            variable_name = detail
        else:
            variable_name = None

    # Only annotations for modules and classes are really made, for functions
    # they are ignored like comments.
    if variable_name is not None:
        if provider.isExpressionFunctionBody():
            provider.getVariableForAssignment(variable_name)
        else:
            annotation = buildNode(provider, node.annotation, source_ref)

            statements.append(
                StatementAssignmentSubscript(expression=ExpressionVariableRef(
                    variable=provider.getVariableForAssignment(
                        "__annotations__"),
                    source_ref=source_ref),
                                             subscript=makeConstantRefNode(
                                                 constant=variable_name,
                                                 source_ref=source_ref),
                                             source=annotation,
                                             source_ref=source_ref))

    return makeStatementsSequence(statements=statements,
                                  allow_none=True,
                                  source_ref=source_ref)
Example #7
0
def buildVariableReferenceNode(provider, node, source_ref):
    # Python3 is influenced by the mere use of a variable name. So we need to remember it,
    # esp. for cases, where it is optimized away.
    if Utils.python_version >= 300 and node.id == "super" and provider.isExpressionFunctionBody(
    ):
        provider.markAsClassClosureTaker()

    return ExpressionVariableRef(variable_name=node.id, source_ref=source_ref)
    def unpackFrom(source, arg_names):
        accesses = []

        sub_special_index = 0

        iter_var = outer_body.allocateTempVariable(
            None, "arg_iter_%d" % len(iter_vars))
        iter_vars.append(iter_var)

        statements.append(
            StatementAssignmentVariable(variable=iter_var,
                                        source=ExpressionBuiltinIter1(
                                            value=source,
                                            source_ref=source_ref),
                                        source_ref=source_ref))

        for element_index, arg_name in enumerate(arg_names):
            if getKind(arg_name) == "Name":
                arg_var = outer_body.createProvidedVariable(arg_name.id)
                outer_body.registerProvidedVariable(arg_var)

                statements.append(
                    StatementAssignmentVariable(
                        variable=arg_var,
                        source=ExpressionSpecialUnpack(
                            value=ExpressionTempVariableRef(
                                variable=iter_var, source_ref=source_ref),
                            count=element_index + 1,
                            expected=len(arg_names),
                            starred=False,
                            source_ref=source_ref),
                        source_ref=source_ref))

                accesses.append(
                    ExpressionVariableRef(variable=arg_var,
                                          source_ref=source_ref))
            elif getKind(arg_name) == "Tuple":
                accesses.extend(
                    unpackFrom(source=ExpressionSpecialUnpack(
                        value=ExpressionTempVariableRef(variable=iter_var,
                                                        source_ref=source_ref),
                        count=element_index + 1,
                        expected=len(arg_names),
                        starred=False,
                        source_ref=source_ref),
                               arg_names=arg_name.elts))

                sub_special_index += 1
            else:
                assert False, arg_name

        statements.append(
            StatementSpecialUnpackCheck(iterator=ExpressionTempVariableRef(
                variable=iter_var, source_ref=source_ref),
                                        count=len(arg_names),
                                        source_ref=source_ref))

        return accesses
    def wrapSuperBuiltin(type, object, source_ref):
        if type is None and python_version >= 300:
            provider = node.getParentVariableProvider()

            type = ExpressionVariableRef(variable_name="__class__",
                                         source_ref=source_ref)

            # Ought to be already closure taken.
            type.setVariable(
                provider.getVariableForReference(variable_name="__class__"))

            from nuitka.nodes.NodeMakingHelpers import makeRaiseExceptionReplacementExpression

            if not type.getVariable().isClosureReference():
                return makeRaiseExceptionReplacementExpression(
                    expression=node,
                    exception_type="SystemError"
                    if python_version < 331 else "RuntimeError",
                    exception_value="super(): __class__ cell not found",
                )

            if object is None and provider.getParameters().getArgumentCount(
            ) > 0:
                par1_name = provider.getParameters().getArgumentNames()[0]
                # TODO: Nested first argument would kill us here, need a test
                # for that.

                object = ExpressionVariableRef(variable_name=par1_name,
                                               source_ref=source_ref)

                object.setVariable(
                    node.getParentVariableProvider().getVariableForReference(
                        variable_name=par1_name))

                if not object.getVariable().isParameterVariable():
                    return makeRaiseExceptionReplacementExpression(
                        expression=node,
                        exception_type="SystemError"
                        if python_version < 330 else "RuntimeError",
                        exception_value="super(): __class__ cell not found",
                    )

        return ExpressionBuiltinSuper(super_type=type,
                                      super_object=object,
                                      source_ref=source_ref)
Example #10
0
    def onEnterNode(self, node):
        if node.isExpressionVariableNameRef():
            provider = node.provider

            try:
                variable = self._attachVariable(node, provider)
            except MaybeLocalVariableUsage:
                variable_name = node.getVariableName()

                node.replaceWith(
                    ExpressionLocalsVariableRefORFallback(
                        locals_scope=provider.getLocalsScope(),
                        variable_name=variable_name,
                        fallback_node=ExpressionVariableRef(
                            variable=node.getParentModule(
                            ).getVariableForReference(variable_name),
                            source_ref=node.source_ref),
                        source_ref=node.source_ref))
            else:
                node.replaceWith(
                    ExpressionVariableRef(variable=variable,
                                          source_ref=node.source_ref))

                variable.addVariableUser(provider)
Example #11
0
def _buildInplaceAssignVariableNode(provider, variable_ref, tmp_variable1,
                                    tmp_variable2, operator, expression,
                                    source_ref):
    assert variable_ref.isExpressionTargetVariableRef(), variable_ref

    return (
        # First assign the target value to a temporary variable.
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_variable1.makeReference(provider),
                source_ref=source_ref),
            source=ExpressionVariableRef(
                variable_name=variable_ref.getVariableName(),
                source_ref=source_ref),
            source_ref=source_ref),
        # Second assign the inplace result to a temporary variable.
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_variable2.makeReference(provider),
                source_ref=source_ref),
            source=ExpressionOperationBinaryInplace(
                operator=operator,
                left=ExpressionTempVariableRef(
                    variable=tmp_variable1.makeReference(provider),
                    source_ref=source_ref),
                right=expression,
                source_ref=source_ref),
            source_ref=source_ref),
        # Copy it over, if the reference values change, i.e. IsNot is true.
        StatementConditional(
            condition=ExpressionComparisonIsNOT(
                left=ExpressionTempVariableRef(
                    variable=tmp_variable1.makeReference(provider),
                    source_ref=source_ref),
                right=ExpressionTempVariableRef(
                    variable=tmp_variable2.makeReference(provider),
                    source_ref=source_ref),
                source_ref=source_ref),
            yes_branch=makeStatementsSequenceFromStatement(
                statement=StatementAssignmentVariable(
                    variable_ref=variable_ref.makeCloneAt(source_ref),
                    source=ExpressionTempVariableRef(
                        variable=tmp_variable2.makeReference(provider),
                        source_ref=source_ref),
                    source_ref=source_ref)),
            no_branch=None,
            source_ref=source_ref))
Example #12
0
    def onEnterNode(self, node):
        if node.isExpressionVariableNameRef():
            provider = node.getParentVariableProvider()

            try:
                variable = self._attachVariable(node, provider)
            except MaybeLocalVariableUsage:
                variable_name = node.getVariableName()

                node.replaceWith(
                    ExpressionLocalsVariableRef(
                        variable_name=variable_name,
                        fallback_variable=node.getParentModule(
                        ).getVariableForReference(variable_name),
                        source_ref=node.getSourceReference()))
            else:
                node.replaceWith(
                    ExpressionVariableRef(variable=variable,
                                          source_ref=node.source_ref))

                variable.addVariableUser(provider)

        elif node.isExpressionVariableRef():
            provider = node.getParentVariableProvider()

            variable = node.getVariable()

            if variable is None:
                try:
                    variable = self._attachVariable(node, provider)
                except MaybeLocalVariableUsage:
                    variable_name = node.getVariableName()

                    node.replaceWith(
                        ExpressionLocalsVariableRef(
                            variable_name=variable_name,
                            fallback_variable=node.getParentModule(
                            ).getVariableForReference(variable_name),
                            source_ref=node.getSourceReference()))
                else:
                    node.setVariable(variable)

                    variable.addVariableUser(provider)
            else:
                variable.addVariableUser(provider)
Example #13
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=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 wrapSuperBuiltin(type_arg, object_arg, source_ref):
        if type_arg is None and python_version >= 300:
            if provider.isCompiledPythonModule():
                return makeRaiseExceptionReplacementExpression(
                    expression=node,
                    exception_type="RuntimeError",
                    exception_value="super(): no arguments",
                )

            class_variable = provider.getVariableForReference(
                variable_name="__class__")

            provider.trace_collection.getVariableCurrentTrace(
                class_variable).addUsage()

            type_arg = ExpressionVariableRef(
                # Ought to be already closure taken due to "super" flag in
                # tree building.
                variable=class_variable,
                source_ref=source_ref,
            )

            # If we already have this as a local variable, then use that
            # instead.
            type_arg_owner = type_arg.getVariable().getOwner()
            if type_arg_owner is provider or not (
                    type_arg_owner.isExpressionFunctionBody()
                    or type_arg_owner.isExpressionClassBody()):
                type_arg = None

            if type_arg is None:
                return makeRaiseExceptionReplacementExpression(
                    expression=node,
                    exception_type="SystemError"
                    if python_version < 331 else "RuntimeError",
                    exception_value="super(): __class__ cell not found",
                )

            if object_arg is None:
                if (provider.isExpressionGeneratorObjectBody()
                        or provider.isExpressionCoroutineObjectBody()
                        or provider.isExpressionAsyncgenObjectBody()):
                    parameter_provider = provider.getParentVariableProvider()
                else:
                    parameter_provider = provider

                if parameter_provider.getParameters().getArgumentCount() > 0:
                    par1_name = parameter_provider.getParameters(
                    ).getArgumentNames()[0]

                    object_variable = provider.getVariableForReference(
                        variable_name=par1_name)

                    provider.trace_collection.getVariableCurrentTrace(
                        object_variable).addUsage()

                    object_arg = ExpressionVariableRef(
                        variable=object_variable, source_ref=source_ref)

                    if not object_arg.getVariable().isParameterVariable():
                        return makeRaiseExceptionReplacementExpression(
                            expression=node,
                            exception_type="SystemError"
                            if python_version < 300 else "RuntimeError",
                            exception_value="super(): __class__ cell not found",
                        )
                else:
                    return makeRaiseExceptionReplacementExpression(
                        expression=node,
                        exception_type="RuntimeError",
                        exception_value="super(): no arguments",
                    )

        return ExpressionBuiltinSuper(super_type=type_arg,
                                      super_object=object_arg,
                                      source_ref=source_ref)
Example #15
0
def buildFunctionWithParsing(provider, function_kind, name, function_doc,
                             flags, node, source_ref):
    # This contains a complex re-formulation for nested parameter functions.
    # pylint: disable=R0914

    kind = getKind(node)

    assert kind in ("FunctionDef", "Lambda",
                    "AsyncFunctionDef"), "unsupported for kind " + kind

    def extractArg(arg):
        if arg is None:
            return None
        elif type(arg) is str:
            return mangleName(arg, provider)
        elif getKind(arg) == "Name":
            return mangleName(arg.id, provider)
        elif getKind(arg) == "arg":
            return mangleName(arg.arg, provider)
        elif getKind(arg) == "Tuple":
            # These are to be re-formulated on the outside.
            assert False
        else:
            assert False, getKind(arg)

    special_args = {}

    def extractNormalArgs(args):
        normal_args = []

        for arg in args:
            if type(arg) is not str and getKind(arg) == "Tuple":
                special_arg_name = ".%d" % (len(special_args) + 1)

                special_args[special_arg_name] = arg.elts
                normal_args.append(special_arg_name)
            else:
                normal_args.append(extractArg(arg))

        return normal_args

    normal_args = extractNormalArgs(node.args.args)

    parameters = ParameterSpec(
        ps_name=name,
        ps_normal_args=normal_args,
        ps_kw_only_args=[extractArg(arg) for arg in node.args.kwonlyargs]
        if python_version >= 300 else [],
        ps_list_star_arg=extractArg(node.args.vararg),
        ps_dict_star_arg=extractArg(node.args.kwarg),
        ps_default_count=len(node.args.defaults))

    message = parameters.checkValid()

    if message is not None:
        SyntaxErrors.raiseSyntaxError(message, source_ref)

    code_object = CodeObjectSpec(
        co_name=name,
        co_kind=function_kind,
        co_varnames=parameters.getParameterNames(),
        co_argcount=parameters.getArgumentCount(),
        co_kwonlyargcount=parameters.getKwOnlyParameterCount(),
        co_has_starlist=parameters.getStarListArgumentName() is not None,
        co_has_stardict=parameters.getStarDictArgumentName() is not None)

    outer_body = ExpressionFunctionBody(provider=provider,
                                        name=name,
                                        flags=flags,
                                        doc=function_doc,
                                        parameters=parameters,
                                        source_ref=source_ref)

    if special_args:
        inner_name = name.strip("<>") + "$inner"
        inner_arg_names = []
        iter_vars = []

        values = []

        statements = []

        def unpackFrom(source, arg_names):
            accesses = []

            sub_special_index = 0

            iter_var = outer_body.allocateTempVariable(
                None, "arg_iter_%d" % len(iter_vars))
            iter_vars.append(iter_var)

            statements.append(
                StatementAssignmentVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=iter_var, source_ref=source_ref),
                    source=ExpressionBuiltinIter1(value=source,
                                                  source_ref=source_ref),
                    source_ref=source_ref))

            for element_index, arg_name in enumerate(arg_names):
                if getKind(arg_name) == "Name":
                    inner_arg_names.append(arg_name.id)

                    arg_var = outer_body.allocateTempVariable(
                        None, "tmp_" + arg_name.id)

                    statements.append(
                        StatementAssignmentVariable(
                            variable_ref=ExpressionTargetTempVariableRef(
                                variable=arg_var, source_ref=source_ref),
                            source=ExpressionSpecialUnpack(
                                value=ExpressionTempVariableRef(
                                    variable=iter_var, source_ref=source_ref),
                                count=element_index + 1,
                                expected=len(arg_names),
                                source_ref=source_ref),
                            source_ref=source_ref))

                    accesses.append(
                        ExpressionTempVariableRef(variable=arg_var,
                                                  source_ref=source_ref))
                elif getKind(arg_name) == "Tuple":
                    accesses.extend(
                        unpackFrom(source=ExpressionSpecialUnpack(
                            value=ExpressionTempVariableRef(
                                variable=iter_var, source_ref=source_ref),
                            count=element_index + 1,
                            expected=len(arg_names),
                            source_ref=source_ref),
                                   arg_names=arg_name.elts))

                    sub_special_index += 1
                else:
                    assert False, arg_name

            statements.append(
                StatementSpecialUnpackCheck(iterator=ExpressionTempVariableRef(
                    variable=iter_var, source_ref=source_ref),
                                            count=len(arg_names),
                                            source_ref=source_ref))

            return accesses

        for arg_name in parameters.getParameterNames():
            if arg_name.startswith('.'):
                source = ExpressionVariableRef(variable_name=arg_name,
                                               source_ref=source_ref)

                values.extend(unpackFrom(source, special_args[arg_name]))
            else:
                values.append(
                    ExpressionVariableRef(variable_name=arg_name,
                                          source_ref=source_ref))

                inner_arg_names.append(arg_name)

        inner_parameters = ParameterSpec(ps_name=inner_name,
                                         ps_normal_args=inner_arg_names,
                                         ps_kw_only_args=(),
                                         ps_list_star_arg=None,
                                         ps_dict_star_arg=None,
                                         ps_default_count=None)

        function_body = ExpressionFunctionBody(provider=outer_body,
                                               name=inner_name,
                                               flags=flags,
                                               doc=function_doc,
                                               parameters=inner_parameters,
                                               source_ref=source_ref)

        statements.append(
            StatementReturn(ExpressionFunctionCall(
                function=ExpressionFunctionCreation(
                    function_ref=ExpressionFunctionRef(
                        function_body=function_body, source_ref=source_ref),
                    code_object=code_object,
                    defaults=(),
                    kw_defaults=None,
                    annotations=None,
                    source_ref=source_ref),
                values=values,
                source_ref=source_ref),
                            source_ref=source_ref))

        outer_body.setBody(
            makeStatementsSequenceFromStatement(
                statement=makeTryFinallyStatement(
                    provider,
                    tried=statements,
                    final=[
                        StatementReleaseVariable(variable=variable,
                                                 source_ref=source_ref)
                        for variable in outer_body.getTempVariables()
                    ],
                    source_ref=source_ref,
                    public_exc=False)))
    else:
        function_body = outer_body

    return outer_body, function_body, code_object
Example #16
0
def getDictUnpackingHelper():
    helper_name = "_unpack_dict"

    result = ExpressionFunctionBody(
        provider   = getInternalModule(),
        name       = helper_name,
        doc        = None,
        parameters = ParameterSpec(
            ps_name          = helper_name,
            ps_normal_args   = (),
            ps_list_star_arg = "args",
            ps_dict_star_arg = None,
            ps_default_count = 0,
            ps_kw_only_args  = ()
        ),
        flags      = set(),
        source_ref = internal_source_ref
    )

    temp_scope = None

    tmp_result_variable = result.allocateTempVariable(temp_scope, "dict")
    tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter")
    tmp_item_variable = result.allocateTempVariable(temp_scope, "keys")

    loop_body = makeStatementsSequenceFromStatements(
        makeTryExceptSingleHandlerNode(
            tried          = StatementAssignmentVariable(
                variable   = tmp_item_variable,
                source     = ExpressionBuiltinNext1(
                    value      = ExpressionTempVariableRef(
                        variable   = tmp_iter_variable,
                        source_ref = internal_source_ref
                    ),
                    source_ref = internal_source_ref
                ),
                source_ref = internal_source_ref
            ),
            exception_name = "StopIteration",
            handler_body   = StatementLoopBreak(
                source_ref = internal_source_ref
            ),
            source_ref     = internal_source_ref
        ),
        makeTryExceptSingleHandlerNode(
            tried          = StatementDictOperationUpdate(
                dict_arg   = ExpressionTempVariableRef(
                    variable   = tmp_result_variable,
                    source_ref = internal_source_ref
                ),
                value      = ExpressionTempVariableRef(
                    variable   = tmp_item_variable,
                    source_ref = internal_source_ref
                ),
                source_ref = internal_source_ref
            ),
            exception_name = "AttributeError",
            handler_body   = StatementRaiseException(
                exception_type  = ExpressionBuiltinMakeException(
                    exception_name = "TypeError",
                    args           = (
                        makeBinaryOperationNode(
                            operator   = "Mod",
                            left       =  makeConstantRefNode(
                                constant      = """\
'%s' object is not a mapping""",
                                source_ref    = internal_source_ref,
                                user_provided = True
                            ),
                            right      = ExpressionMakeTuple(
                                elements   = (
                                    ExpressionAttributeLookup(
                                        source         = ExpressionBuiltinType1(
                                            value      = ExpressionTempVariableRef(
                                                variable   = tmp_item_variable,
                                                source_ref = internal_source_ref
                                            ),
                                            source_ref = internal_source_ref
                                        ),
                                        attribute_name = "__name__",
                                        source_ref     = internal_source_ref
                                    ),
                                ),
                                source_ref = internal_source_ref
                            ),
                            source_ref = internal_source_ref
                        ),
                    ),
                    source_ref     = internal_source_ref
                ),
                exception_value = None,
                exception_trace = None,
                exception_cause = None,
                source_ref      = internal_source_ref
            ),
            source_ref     = internal_source_ref
        )
    )

    args_variable = result.getVariableForAssignment(
        variable_name = "args"
    )

    final = (
        StatementReleaseVariable(
            variable   = tmp_result_variable,
            source_ref = internal_source_ref
        ),
        StatementReleaseVariable(
            variable   = tmp_iter_variable,
            source_ref = internal_source_ref
        ),
        StatementReleaseVariable(
            variable   = tmp_item_variable,
            source_ref = internal_source_ref
        ),
        # We get handed our args responsibility.
        StatementDelVariable(
            variable   = args_variable,
            tolerant   = False,
            source_ref = internal_source_ref
        )
    )

    tried = makeStatementsSequenceFromStatements(
        StatementAssignmentVariable(
            variable   = tmp_iter_variable,
            source     = ExpressionBuiltinIter1(
                value      = ExpressionVariableRef(
                    variable   = args_variable,
                    source_ref = internal_source_ref
                ),
                source_ref = internal_source_ref
            ),
            source_ref = internal_source_ref
        ),
        StatementAssignmentVariable(
            variable   = tmp_result_variable,
            source     = makeConstantRefNode(
                constant   = {},
                source_ref = internal_source_ref
            ),
            source_ref = internal_source_ref
        ),
        StatementLoop(
            body       = loop_body,
            source_ref = internal_source_ref
        ),
        StatementReturn(
            expression = ExpressionTempVariableRef(
                variable   = tmp_result_variable,
                source_ref = internal_source_ref
            ),
            source_ref = internal_source_ref
        )
    )

    result.setBody(
        makeStatementsSequenceFromStatement(
            makeTryFinallyStatement(
                provider   = result,
                tried      = tried,
                final      = final,
                source_ref = internal_source_ref
            )
        )
    )

    return result
def _buildContractionNode(provider, node, name, emit_class, start_value,
                          assign_provider, source_ref):
    # The contraction nodes are reformulated to function bodies, with loops as
    # described in the developer manual. They use a lot of temporary names,
    # nested blocks, etc. and so a lot of variable names. There is no good way
    # around that, and we deal with many cases, due to having generator
    # expressions sharing this code, pylint: disable=R0912,R0914

    # Note: The assign_provider is only to cover Python2 list contractions,
    # assigning one of the loop variables to the outside scope.

    assert provider.isParentVariableProvider(), provider

    function_body = ExpressionFunctionBody(provider=provider,
                                           name=name,
                                           doc=None,
                                           parameters=ParameterSpec(
                                               name="contraction",
                                               normal_args=("__iterator", ),
                                               list_star_arg=None,
                                               dict_star_arg=None,
                                               default_count=0,
                                               kw_only_args=()),
                                           source_ref=source_ref)

    if start_value is not None:
        container_tmp = function_body.allocateTempVariable(
            temp_scope=None, name="contraction_result")
    else:
        container_tmp = None

    outer_iter_ref = ExpressionVariableRef(variable_name="__iterator",
                                           source_ref=source_ref)

    statements, del_statements = _buildContractionBodyNode(
        function_body=function_body,
        assign_provider=assign_provider,
        provider=provider,
        node=node,
        emit_class=emit_class,
        outer_iter_ref=outer_iter_ref,
        temp_scope=None,
        start_value=start_value,
        container_tmp=container_tmp,
        source_ref=source_ref,
    )

    if start_value is not None:
        statements.append(
            StatementReturn(expression=ExpressionTempVariableRef(
                variable=container_tmp.makeReference(function_body),
                source_ref=source_ref),
                            source_ref=source_ref))

    statements = (makeTryFinallyStatement(
        tried=statements,
        final=del_statements,
        source_ref=source_ref.atInternal()), )

    function_body.setBody(
        StatementsFrame(statements=statements,
                        guard_mode="pass_through"
                        if emit_class is not ExpressionYield else "generator",
                        var_names=(),
                        arg_count=0,
                        kw_only_count=0,
                        has_starlist=False,
                        has_stardict=False,
                        code_name="contraction",
                        source_ref=source_ref))

    return ExpressionFunctionCall(function=ExpressionFunctionCreation(
        function_ref=ExpressionFunctionRef(function_body=function_body,
                                           source_ref=source_ref),
        defaults=(),
        kw_defaults=None,
        annotations=None,
        source_ref=source_ref),
                                  values=(ExpressionBuiltinIter1(
                                      value=buildNode(
                                          provider=provider,
                                          node=node.generators[0].iter,
                                          source_ref=source_ref),
                                      source_ref=source_ref), ),
                                  source_ref=source_ref)
Example #18
0
def getClassBasesMroConversionHelper():
    helper_name = "_mro_entries_conversion"

    result = makeInternalHelperFunctionBody(
        name=helper_name,
        parameters=ParameterSpec(
            ps_name=helper_name,
            ps_normal_args=("bases", ),
            ps_pos_only_args=(),
            ps_list_star_arg=None,
            ps_dict_star_arg=None,
            ps_default_count=0,
            ps_kw_only_args=(),
        ),
        inline_const_args=False,  # TODO: Allow this.
    )

    temp_scope = None

    tmp_result_variable = result.allocateTempVariable(temp_scope, "list")
    tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter")
    tmp_item_variable = result.allocateTempVariable(temp_scope, "base")

    args_variable = result.getVariableForAssignment(variable_name="bases")

    non_type_case = makeStatementConditional(
        condition=ExpressionAttributeCheck(
            expression=ExpressionTempVariableRef(
                variable=tmp_item_variable, source_ref=internal_source_ref),
            attribute_name="__mro_entries__",
            source_ref=internal_source_ref,
        ),
        yes_branch=StatementExpressionOnly(
            expression=ExpressionListOperationExtend(
                list_arg=ExpressionTempVariableRef(
                    variable=tmp_result_variable,
                    source_ref=internal_source_ref),
                value=makeExpressionCall(
                    called=ExpressionAttributeLookup(
                        expression=ExpressionTempVariableRef(
                            variable=tmp_item_variable,
                            source_ref=internal_source_ref),
                        attribute_name="__mro_entries__",
                        source_ref=internal_source_ref,
                    ),
                    args=makeExpressionMakeTuple(
                        elements=(ExpressionVariableRef(
                            variable=args_variable,
                            source_ref=internal_source_ref), ),
                        source_ref=internal_source_ref,
                    ),
                    kw=None,
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
        no_branch=StatementListOperationAppend(
            list_arg=ExpressionTempVariableRef(variable=tmp_result_variable,
                                               source_ref=internal_source_ref),
            value=ExpressionTempVariableRef(variable=tmp_item_variable,
                                            source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
        source_ref=internal_source_ref,
    )

    type_case = StatementListOperationAppend(
        list_arg=ExpressionTempVariableRef(variable=tmp_result_variable,
                                           source_ref=internal_source_ref),
        value=ExpressionTempVariableRef(variable=tmp_item_variable,
                                        source_ref=internal_source_ref),
        source_ref=internal_source_ref,
    )

    loop_body = makeStatementsSequenceFromStatements(
        makeTryExceptSingleHandlerNode(
            tried=StatementAssignmentVariable(
                variable=tmp_item_variable,
                source=ExpressionBuiltinNext1(
                    value=ExpressionTempVariableRef(
                        variable=tmp_iter_variable,
                        source_ref=internal_source_ref),
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref,
            ),
            exception_name="StopIteration",
            handler_body=StatementLoopBreak(source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
        makeStatementConditional(
            condition=ExpressionConditionalAnd(
                left=ExpressionBuiltinIsinstance(
                    instance=ExpressionTempVariableRef(
                        variable=tmp_item_variable,
                        source_ref=internal_source_ref),
                    classes=makeConstantRefNode(
                        constant=type, source_ref=internal_source_ref),
                    source_ref=internal_source_ref,
                ),
                right=ExpressionBuiltinIssubclass(
                    cls=ExpressionTempVariableRef(
                        variable=tmp_item_variable,
                        source_ref=internal_source_ref),
                    classes=makeConstantRefNode(
                        constant=type, source_ref=internal_source_ref),
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref,
            ),
            yes_branch=type_case,
            no_branch=non_type_case,
            source_ref=internal_source_ref,
        ),
    )

    final = (
        StatementReleaseVariable(variable=args_variable,
                                 source_ref=internal_source_ref),
        StatementReleaseVariable(variable=tmp_result_variable,
                                 source_ref=internal_source_ref),
        StatementReleaseVariable(variable=tmp_iter_variable,
                                 source_ref=internal_source_ref),
        StatementReleaseVariable(variable=tmp_item_variable,
                                 source_ref=internal_source_ref),
    )

    tried = makeStatementsSequenceFromStatements(
        StatementAssignmentVariable(
            variable=tmp_iter_variable,
            source=ExpressionBuiltinIter1(
                value=ExpressionVariableRef(variable=args_variable,
                                            source_ref=internal_source_ref),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
        StatementAssignmentVariable(
            variable=tmp_result_variable,
            source=makeConstantRefNode(constant=[],
                                       source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
        StatementLoop(loop_body=loop_body, source_ref=internal_source_ref),
        StatementReturn(
            expression=ExpressionBuiltinTuple(
                value=ExpressionTempVariableRef(
                    variable=tmp_result_variable,
                    source_ref=internal_source_ref),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
    )

    result.setChild(
        "body",
        makeStatementsSequenceFromStatement(
            makeTryFinallyStatement(
                provider=result,
                tried=tried,
                final=final,
                source_ref=internal_source_ref,
            )),
    )

    return result
def getListUnpackingHelper():
    helper_name = "_unpack_list"

    result = ExpressionFunctionBody(
        provider   = getInternalModule(),
        name       = helper_name,
        doc        = None,
        parameters = ParameterSpec(
            name          = helper_name,
            normal_args   = (),
            list_star_arg = "args",
            dict_star_arg = None,
            default_count = 0,
            kw_only_args  = ()
        ),
        flags      = set(),
        source_ref = internal_source_ref
    )

    temp_scope = None

    tmp_result_variable = result.allocateTempVariable(temp_scope, "list")
    tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter")
    tmp_item_variable = result.allocateTempVariable(temp_scope, "keys")

    loop_body = makeStatementsSequenceFromStatements(
        makeTryExceptSingleHandlerNode(
            tried          = StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_item_variable,
                    source_ref = internal_source_ref
                ),
                source       = ExpressionBuiltinNext1(
                    value      = ExpressionTempVariableRef(
                        variable   = tmp_iter_variable,
                        source_ref = internal_source_ref
                    ),
                    source_ref = internal_source_ref
                ),
                source_ref   = internal_source_ref
            ),
            exception_name = "StopIteration",
            handler_body   = StatementLoopBreak(
                source_ref = internal_source_ref
            ),
            source_ref     = internal_source_ref
        ),
        StatementExpressionOnly(
            expression = ExpressionListOperationExtend(
                list_arg   = ExpressionTempVariableRef(
                    variable   = tmp_result_variable,
                    source_ref = internal_source_ref
                ),
                value      = ExpressionTempVariableRef(
                    variable   = tmp_item_variable,
                    source_ref = internal_source_ref
                ),
                source_ref = internal_source_ref
            ),
            source_ref = internal_source_ref
        )
    )

    args_variable = result.getVariableForAssignment(
        variable_name = "args"
    )

    final = (
        StatementReleaseVariable(
            variable   = tmp_result_variable,
            source_ref = internal_source_ref
        ),
        StatementReleaseVariable(
            variable   = tmp_iter_variable,
            source_ref = internal_source_ref
        ),
        StatementReleaseVariable(
            variable   = tmp_item_variable,
            source_ref = internal_source_ref
        ),
    )

    tried = makeStatementsSequenceFromStatements(
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_iter_variable,
                source_ref = internal_source_ref
            ),
            source       = ExpressionBuiltinIter1(
                value      = ExpressionVariableRef(
                    variable_name = "args",
                    variable      = args_variable,
                    source_ref    = internal_source_ref
                ),
                source_ref = internal_source_ref
            ),
            source_ref   = internal_source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_result_variable,
                source_ref = internal_source_ref
            ),
            source       = ExpressionConstantRef(
                constant   = [],
                source_ref = internal_source_ref
            ),
            source_ref   = internal_source_ref
        ),
        StatementLoop(
            body       = loop_body,
            source_ref = internal_source_ref
        ),
        StatementReturn(
            expression = ExpressionTempVariableRef(
                variable   = tmp_result_variable,
                source_ref = internal_source_ref
            ),
            source_ref = internal_source_ref
        )
    )

    result.setBody(
        makeStatementsSequenceFromStatement(
            makeTryFinallyStatement(
                provider   = result,
                tried      = tried,
                final      = final,
                source_ref = internal_source_ref
            )
        )
    )

    return result
Example #20
0
    def wrapSuperBuiltin(type, object, source_ref):
        if type is None and python_version >= 300:
            provider = node.getParentVariableProvider()

            if python_version < 340 or True: # TODO: Temporarily reverted:
                type = ExpressionVariableRef(
                    variable_name = "__class__",
                    source_ref    = source_ref
                )

                # Ought to be already closure taken.
                type.setVariable(
                    provider.getVariableForClosure(
                        variable_name = "__class__"
                    )
                )

                # If we already have this as a local variable, then use that
                # instead.
                if not type.getVariable().isClosureReference():
                    type = None
                else:
                    from nuitka.VariableRegistry import addVariableUsage
                    addVariableUsage(type.getVariable(), provider)
            else:
                parent_provider = provider.getParentVariableProvider()

                class_var = parent_provider.getTempVariable(
                    temp_scope = None,
                    name       = "__class__"
                )

                type = ExpressionTempVariableRef(
                    variable      = class_var.makeReference(parent_provider).makeReference(provider),
                    source_ref    = source_ref
                )

                from nuitka.VariableRegistry import addVariableUsage
                addVariableUsage(type.getVariable(), provider)

            from nuitka.nodes.NodeMakingHelpers import \
                makeRaiseExceptionReplacementExpression

            if type is None:
                return makeRaiseExceptionReplacementExpression(
                    expression      = node,
                    exception_type  = "SystemError"
                                        if python_version < 331 else
                                      "RuntimeError",
                    exception_value = "super(): __class__ cell not found",
                )

            if object is None:
                if provider.getParameters().getArgumentCount() > 0:
                    par1_name = provider.getParameters().getArgumentNames()[0]
                    # TODO: Nested first argument would kill us here, need a
                    # test for that.

                    object = ExpressionVariableRef(
                        variable_name = par1_name,
                        source_ref    = source_ref
                    )

                    object.setVariable(
                        provider.getVariableForReference(
                            variable_name = par1_name
                        )
                    )

                    if not object.getVariable().isParameterVariable():
                        return makeRaiseExceptionReplacementExpression(
                            expression      = node,
                            exception_type  = "SystemError"
                                                if python_version < 330 else
                                              "RuntimeError",
                            exception_value = "super(): __class__ cell not found",
                        )
                else:
                    return makeRaiseExceptionReplacementExpression(
                        expression      = node,
                        exception_type  = "RuntimeError",
                        exception_value = "super(): no arguments"
                    )

        return ExpressionBuiltinSuper(
            super_type   = type,
            super_object = object,
            source_ref   = source_ref
        )
Example #21
0
def buildVariableReferenceNode(provider, node, source_ref):
    return ExpressionVariableRef(
        variable_name = mangleName(node.id, provider),
        source_ref    = source_ref
    )
Example #22
0
    def onEnterNode(self, node):
        # Mighty complex code with lots of branches and statements, but it
        # couldn't be less without making it more difficult.
        # pylint: disable=too-many-branches,too-many-statements

        if node.isExpressionVariableNameRef():
            provider = node.provider

            if provider.isExpressionClassBody():
                if node.needsFallback():
                    variable = provider.getVariableForReference(
                        variable_name=node.getVariableName())

                    new_node = ExpressionLocalsVariableRefOrFallback(
                        locals_scope=provider.getFunctionLocalsScope(),
                        variable_name=node.getVariableName(),
                        fallback=ExpressionVariableRef(
                            variable=variable, source_ref=node.source_ref),
                        source_ref=node.source_ref,
                    )

                    variable.addVariableUser(provider)
                else:
                    new_node = ExpressionLocalsVariableRef(
                        locals_scope=provider.getFunctionLocalsScope(),
                        variable_name=node.getVariableName(),
                        source_ref=node.source_ref,
                    )

                parent = node.parent
                node.finalize()

                parent.replaceChild(node, new_node)
        elif node.isExpressionTempVariableRef():
            if node.getVariable().getOwner() != node.getParentVariableProvider(
            ):
                node.getParentVariableProvider().addClosureVariable(
                    node.getVariable())
        elif node.isExpressionGeneratorObjectBody():
            if python_version >= 300:
                self._handleNonLocal(node)

            # Only Python3.4 or later allows for generators to have qualname.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        elif node.isExpressionCoroutineObjectBody():
            self._handleNonLocal(node)

            self._handleQualnameSetup(node)
        elif node.isExpressionAsyncgenObjectBody():
            self._handleNonLocal(node)

            self._handleQualnameSetup(node)
        elif node.isExpressionClassBody():
            if python_version >= 300:
                self._handleNonLocal(node)

            # Python3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        elif node.isExpressionFunctionBody():
            if python_version >= 300:
                self._handleNonLocal(node)

            # Python 3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        # Attribute access of names of class functions should be mangled, if
        # they start with "__", but do not end in "__" as well.
        elif (node.isExpressionAttributeLookup()
              or node.isStatementAssignmentAttribute()
              or node.isStatementDelAttribute()):
            attribute_name = node.getAttributeName()

            if attribute_name.startswith(
                    "__") and not attribute_name.endswith("__"):
                seen_function = False

                current = node

                while True:
                    current = current.getParentVariableProvider()

                    if current.isCompiledPythonModule():
                        break

                    if current.isExpressionClassBody():
                        if seen_function:
                            node.setAttributeName(
                                "_%s%s" % (current.getName().lstrip("_"),
                                           attribute_name))

                        break

                    seen_function = True
        # Check if continue and break are properly in loops. If not, raise a
        # syntax error.
        elif node.isStatementLoopBreak() or node.isStatementLoopContinue():
            current = node

            while True:
                current = current.getParent()

                if current.isStatementLoop():
                    break

                if current.isParentVariableProvider():
                    if node.isStatementLoopContinue():
                        message = "'continue' not properly in loop"
                    else:
                        message = "'break' outside loop"

                    raiseSyntaxError(message, node.getSourceReference())
def _buildContractionNode(provider, node, name, emit_class, start_value,
                          assign_provider, source_ref):
    # The contraction nodes are reformulated to function bodies, with loops as
    # described in the developer manual. They use a lot of temporary names,
    # nested blocks, etc. and so a lot of variable names. There is no good way
    # around that, and we deal with many cases, due to having generator
    # expressions sharing this code, pylint: disable=R0912,R0914

    # Note: The assign_provider is only to cover Python2 list contractions,
    # assigning one of the loop variables to the outside scope.

    assert provider.isParentVariableProvider(), provider

    function_body = ExpressionFunctionBody(
        provider=provider,
        name=name,
        doc=None,
        parameters=make_contraction_parameters,
        source_ref=source_ref)

    if start_value is not None:
        container_tmp = function_body.allocateTempVariable(None, "result")

        statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=container_tmp.makeReference(function_body),
                    source_ref=source_ref),
                source=start_value,
                source_ref=source_ref.atInternal())
        ]
    else:
        statements = []

    if hasattr(node, "elt"):
        if start_value is not None:
            current_body = emit_class(ExpressionTempVariableRef(
                variable=container_tmp.makeReference(function_body),
                source_ref=source_ref),
                                      buildNode(provider=function_body,
                                                node=node.elt,
                                                source_ref=source_ref),
                                      source_ref=source_ref)
        else:
            assert emit_class is ExpressionYield

            function_body.markAsGenerator()

            current_body = emit_class(buildNode(provider=function_body,
                                                node=node.elt,
                                                source_ref=source_ref),
                                      source_ref=source_ref)
    else:
        assert emit_class is ExpressionDictOperationSet

        current_body = emit_class(ExpressionTempVariableRef(
            variable=container_tmp.makeReference(function_body),
            source_ref=source_ref),
                                  key=buildNode(
                                      provider=function_body,
                                      node=node.key,
                                      source_ref=source_ref,
                                  ),
                                  value=buildNode(
                                      provider=function_body,
                                      node=node.value,
                                      source_ref=source_ref,
                                  ),
                                  source_ref=source_ref)

    current_body = StatementExpressionOnly(expression=current_body,
                                           source_ref=source_ref)

    for count, qual in enumerate(reversed(node.generators)):
        tmp_iter_variable = function_body.allocateTempVariable(
            temp_scope=None, name="contraction_iter_%d" % count)

        tmp_value_variable = function_body.allocateTempVariable(
            temp_scope=None, name="iter_value_%d" % count)

        # The first iterated value is to be calculated outside of the function
        # and will be given as a parameter "_iterated", the others are built
        # inside the function.
        if qual is node.generators[0]:
            value_iterator = ExpressionVariableRef(variable_name="__iterator",
                                                   source_ref=source_ref)
        else:
            value_iterator = ExpressionBuiltinIter1(value=buildNode(
                provider=function_body, node=qual.iter, source_ref=source_ref),
                                                    source_ref=source_ref)

        # First create the iterator and store it, next should be loop body
        nested_statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_iter_variable.makeReference(function_body),
                    source_ref=source_ref),
                source=value_iterator,
                source_ref=source_ref)
        ]

        loop_statements = [
            makeTryExceptSingleHandlerNode(
                tried=makeStatementsSequenceFromStatement(
                    statement=StatementAssignmentVariable(
                        variable_ref=ExpressionTargetTempVariableRef(
                            variable=tmp_value_variable.makeReference(
                                function_body),
                            source_ref=source_ref),
                        source=ExpressionBuiltinNext1(
                            value=ExpressionTempVariableRef(
                                variable=tmp_iter_variable.makeReference(
                                    function_body),
                                source_ref=source_ref),
                            source_ref=source_ref),
                        source_ref=source_ref)),
                exception_name="StopIteration",
                handler_body=makeStatementsSequenceFromStatement(
                    statement=StatementBreakLoop(
                        source_ref=source_ref.atInternal())),
                source_ref=source_ref),
            buildAssignmentStatements(
                provider=provider if assign_provider else function_body,
                temp_provider=function_body,
                node=qual.target,
                source=ExpressionTempVariableRef(
                    variable=tmp_value_variable.makeReference(function_body),
                    source_ref=source_ref),
                source_ref=source_ref)
        ]

        conditions = buildNodeList(provider=function_body,
                                   nodes=qual.ifs,
                                   source_ref=source_ref)

        if len(conditions) == 1:
            loop_statements.append(
                StatementConditional(
                    condition=conditions[0],
                    yes_branch=makeStatementsSequenceFromStatement(
                        statement=current_body),
                    no_branch=None,
                    source_ref=source_ref))
        elif len(conditions) > 1:
            loop_statements.append(
                StatementConditional(
                    condition=buildAndNode(provider=function_body,
                                           values=conditions,
                                           source_ref=source_ref),
                    yes_branch=makeStatementsSequenceFromStatement(
                        statement=current_body),
                    no_branch=None,
                    source_ref=source_ref))
        else:
            loop_statements.append(current_body)

        nested_statements.append(
            StatementLoop(body=StatementsSequence(
                statements=mergeStatements(loop_statements),
                source_ref=source_ref),
                          source_ref=source_ref))

        nested_statements.append(
            StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_iter_variable.makeReference(function_body),
                source_ref=source_ref),
                                 tolerant=False,
                                 source_ref=source_ref))

        current_body = StatementsSequence(statements=nested_statements,
                                          source_ref=source_ref)

    statements.append(current_body)

    if start_value is not None:
        statements.append(
            StatementReturn(expression=ExpressionTempVariableRef(
                variable=container_tmp.makeReference(function_body),
                source_ref=source_ref),
                            source_ref=source_ref))

    function_body.setBody(
        StatementsFrame(statements=mergeStatements(statements),
                        guard_mode="pass_through"
                        if emit_class is not ExpressionYield else "generator",
                        var_names=(),
                        arg_count=0,
                        kw_only_count=0,
                        has_starlist=False,
                        has_stardict=False,
                        code_name="contraction",
                        source_ref=source_ref))

    return ExpressionFunctionCall(function=ExpressionFunctionCreation(
        function_ref=ExpressionFunctionRef(function_body=function_body,
                                           source_ref=source_ref),
        defaults=(),
        kw_defaults=None,
        annotations=None,
        source_ref=source_ref),
                                  values=(ExpressionBuiltinIter1(
                                      value=buildNode(
                                          provider=provider,
                                          node=node.generators[0].iter,
                                          source_ref=source_ref),
                                      source_ref=source_ref), ),
                                  source_ref=source_ref)
Example #24
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=R0914

    # This function is the Python3 special case with special re-formulation as according
    # to developer manual.
    class_statements, class_doc = extractDocFromBody(node)

    # The result will be a temp block that holds the temporary variables.
    result = StatementTempBlock(source_ref=source_ref)

    tmp_bases = result.getTempVariable("bases")
    tmp_class_decl_dict = result.getTempVariable("class_decl_dict")
    tmp_metaclass = result.getTempVariable("metaclass")
    tmp_prepared = result.getTempVariable("prepared")

    class_creation_function = ExpressionFunctionBody(
        provider=provider,
        is_class=True,
        parameters=make_class_parameters,
        name=node.name,
        doc=class_doc,
        source_ref=source_ref)

    # Hack:
    class_creation_function.parent = provider

    body = buildStatementsNode(provider=class_creation_function,
                               nodes=class_statements,
                               frame=True,
                               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()

    statements = [
        StatementSetLocals(new_locals=ExpressionTempVariableRef(
            variable=tmp_prepared.makeReference(result),
            source_ref=source_ref),
                           source_ref=source_ref.atInternal()),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetVariableRef(
                variable_name="__module__", source_ref=source_ref),
            source=ExpressionConstantRef(
                constant=provider.getParentModule().getName(),
                source_ref=source_ref),
            source_ref=source_ref.atInternal())
    ]

    if class_doc is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetVariableRef(
                    variable_name="__doc__", source_ref=source_ref),
                source=ExpressionConstantRef(constant=class_doc,
                                             source_ref=source_ref),
                source_ref=source_ref.atInternal()))

    if Utils.python_version >= 330:
        if provider.isExpressionFunctionBody():
            qualname = provider.getName() + ".<locals>." + node.name
        else:
            qualname = node.name

        statements.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetVariableRef(
                    variable_name="__qualname__", source_ref=source_ref),
                source=ExpressionConstantRef(constant=qualname,
                                             source_ref=source_ref),
                source_ref=source_ref.atInternal()))

    statements += [
        body,
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetVariableRef(variable_name="__class__",
                                                     source_ref=source_ref),
            source=ExpressionCall(
                called=ExpressionTempVariableRef(
                    variable=tmp_metaclass.makeReference(result),
                    source_ref=source_ref),
                args=ExpressionMakeTuple(
                    elements=(ExpressionConstantRef(constant=node.name,
                                                    source_ref=source_ref),
                              ExpressionTempVariableRef(
                                  variable=tmp_bases.makeReference(result),
                                  source_ref=source_ref),
                              ExpressionBuiltinLocals(source_ref=source_ref)),
                    source_ref=source_ref),
                kw=ExpressionTempVariableRef(
                    variable=tmp_class_decl_dict.makeReference(result),
                    source_ref=source_ref),
                source_ref=source_ref),
            source_ref=source_ref.atInternal()),
        StatementReturn(expression=ExpressionVariableRef(
            variable_name="__class__", 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 implicitely, 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 implicitely, 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),
                                            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.makeReference(result),
                source_ref=source_ref),
            source=ExpressionMakeTuple(elements=buildNodeList(
                provider, node.bases, source_ref),
                                       source_ref=source_ref),
            source_ref=source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_class_decl_dict.makeReference(result),
                source_ref=source_ref),
            source=ExpressionMakeDict(pairs=[
                ExpressionKeyValuePair(
                    key=ExpressionConstantRef(constant=keyword.arg,
                                              source_ref=source_ref),
                    value=buildNode(provider, keyword.value, source_ref),
                    source_ref=source_ref) for keyword in node.keywords
            ],
                                      source_ref=source_ref),
            source_ref=source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_metaclass.makeReference(result),
                source_ref=source_ref),
            source=ExpressionSelectMetaclass(
                metaclass=ExpressionConditional(
                    condition=ExpressionComparison(
                        comparator="In",
                        left=ExpressionConstantRef(constant="metaclass",
                                                   source_ref=source_ref),
                        right=ExpressionTempVariableRef(
                            variable=tmp_class_decl_dict.makeReference(result),
                            source_ref=source_ref),
                        source_ref=source_ref),
                    yes_expression=ExpressionDictOperationGet(
                        dicte=ExpressionTempVariableRef(
                            variable=tmp_class_decl_dict.makeReference(result),
                            source_ref=source_ref),
                        key=ExpressionConstantRef(constant="metaclass",
                                                  source_ref=source_ref),
                        source_ref=source_ref),
                    no_expression=ExpressionConditional(
                        condition=ExpressionTempVariableRef(
                            variable=tmp_bases.makeReference(result),
                            source_ref=source_ref),
                        no_expression=ExpressionBuiltinRef(
                            builtin_name="type", source_ref=source_ref),
                        yes_expression=ExpressionBuiltinType1(
                            value=ExpressionSubscriptLookup(
                                expression=ExpressionTempVariableRef(
                                    variable=tmp_bases.makeReference(result),
                                    source_ref=source_ref),
                                subscript=ExpressionConstantRef(
                                    constant=0, source_ref=source_ref),
                                source_ref=source_ref),
                            source_ref=source_ref),
                        source_ref=source_ref),
                    source_ref=source_ref),
                bases=ExpressionTempVariableRef(
                    variable=tmp_bases.makeReference(result),
                    source_ref=source_ref),
                source_ref=source_ref),
            source_ref=source_ref),
        StatementConditional(
            condition=ExpressionComparison(
                comparator="In",
                left=ExpressionConstantRef(constant="metaclass",
                                           source_ref=source_ref),
                right=ExpressionTempVariableRef(
                    variable=tmp_class_decl_dict.makeReference(result),
                    source_ref=source_ref),
                source_ref=source_ref),
            no_branch=None,
            yes_branch=makeStatementsSequenceFromStatement(
                statement=StatementDictOperationRemove(
                    dicte=ExpressionTempVariableRef(
                        variable=tmp_class_decl_dict.makeReference(result),
                        source_ref=source_ref),
                    key=ExpressionConstantRef(constant="metaclass",
                                              source_ref=source_ref),
                    source_ref=source_ref)),
            source_ref=source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_prepared.makeReference(result),
                source_ref=source_ref),
            source=ExpressionConditional(
                condition=ExpressionBuiltinHasattr(
                    object=ExpressionTempVariableRef(
                        variable=tmp_metaclass.makeReference(result),
                        source_ref=source_ref),
                    name=ExpressionConstantRef(constant="__prepare__",
                                               source_ref=source_ref),
                    source_ref=source_ref),
                no_expression=ExpressionConstantRef(constant={},
                                                    source_ref=source_ref),
                yes_expression=ExpressionCall(
                    called=ExpressionAttributeLookup(
                        expression=ExpressionTempVariableRef(
                            variable=tmp_metaclass.makeReference(result),
                            source_ref=source_ref),
                        attribute_name="__prepare__",
                        source_ref=source_ref),
                    args=ExpressionMakeTuple(
                        elements=(ExpressionConstantRef(constant=node.name,
                                                        source_ref=source_ref),
                                  ExpressionTempVariableRef(
                                      variable=tmp_bases.makeReference(result),
                                      source_ref=source_ref)),
                        source_ref=source_ref),
                    kw=ExpressionTempVariableRef(
                        variable=tmp_class_decl_dict.makeReference(result),
                        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)
    ]

    result.setBody(
        StatementsSequence(statements=statements, source_ref=source_ref))

    return result
Example #25
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=R0914

    # This function is the Python3 special case with special re-formulation as
    # according to developer manual.
    class_statements, 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 = ExpressionFunctionBody(
        provider=provider,
        is_class=True,
        parameters=make_class_parameters,
        name=node.name,
        doc=class_doc,
        source_ref=source_ref)

    # Hack: This allows some APIs to work although this is not yet officially a
    # child yet.
    class_creation_function.parent = provider

    body = buildStatementsNode(provider=class_creation_function,
                               nodes=class_statements,
                               frame=True,
                               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.makeReference(provider),
            source_ref=source_ref),
                           source_ref=source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetVariableRef(
                variable_name="__module__",
                variable=module_variable,
                source_ref=source_ref),
            source=ExpressionConstantRef(
                constant=provider.getParentModule().getFullName(),
                source_ref=source_ref,
                user_provided=True),
            source_ref=source_ref)
    ]

    if class_doc is not None:
        doc_variable = class_creation_function.getVariableForAssignment(
            "__doc__")

        statements.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetVariableRef(
                    variable_name="__doc__",
                    variable=doc_variable,
                    source_ref=source_ref),
                source=ExpressionConstantRef(constant=class_doc,
                                             source_ref=source_ref,
                                             user_provided=True),
                source_ref=source_ref))

    # The "__qualname__" attribute is new in Python 3.3.
    if Utils.python_version >= 330:
        qualname = class_creation_function.getFunctionQualname()
        qualname_variable = class_creation_function.getVariableForAssignment(
            "__qualname__")

        statements.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetVariableRef(
                    variable_name="__qualname__",
                    variable=qualname_variable,
                    source_ref=source_ref),
                source=ExpressionConstantRef(constant=qualname,
                                             source_ref=source_ref,
                                             user_provided=True),
                source_ref=source_ref))

    if Utils.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.makeReference(class_creation_function),
            source_ref=source_ref)
        class_variable_ref = ExpressionTempVariableRef(
            variable=tmp_class.makeReference(class_creation_function),
            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)

    statements += [
        body,
        StatementAssignmentVariable(
            variable_ref=class_target_variable_ref,
            source=ExpressionCall(
                called=ExpressionTempVariableRef(
                    variable=tmp_metaclass.makeReference(provider),
                    source_ref=source_ref),
                args=makeSequenceCreationOrConstant(
                    sequence_kind="tuple",
                    elements=(ExpressionConstantRef(constant=node.name,
                                                    source_ref=source_ref,
                                                    user_provided=True),
                              ExpressionTempVariableRef(
                                  variable=tmp_bases.makeReference(provider),
                                  source_ref=source_ref),
                              ExpressionBuiltinLocals(source_ref=source_ref)),
                    source_ref=source_ref),
                kw=ExpressionTempVariableRef(
                    variable=tmp_class_decl_dict.makeReference(provider),
                    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 implicitely, 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 implicitely, 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),
                                            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.makeReference(provider),
                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.makeReference(provider),
                source_ref=source_ref),
            source=makeDictCreationOrConstant(keys=[
                ExpressionConstantRef(constant=keyword.arg,
                                      source_ref=source_ref,
                                      user_provided=True)
                for keyword in node.keywords
            ],
                                              values=[
                                                  buildNode(
                                                      provider, keyword.value,
                                                      source_ref)
                                                  for keyword in node.keywords
                                              ],
                                              lazy_order=False,
                                              source_ref=source_ref),
            source_ref=source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_metaclass.makeReference(provider),
                source_ref=source_ref),
            source=ExpressionSelectMetaclass(metaclass=ExpressionConditional(
                condition=ExpressionComparison(
                    comparator="In",
                    left=ExpressionConstantRef(constant="metaclass",
                                               source_ref=source_ref,
                                               user_provided=True),
                    right=ExpressionTempVariableRef(
                        variable=tmp_class_decl_dict.makeReference(provider),
                        source_ref=source_ref),
                    source_ref=source_ref),
                yes_expression=ExpressionDictOperationGet(
                    dicte=ExpressionTempVariableRef(
                        variable=tmp_class_decl_dict.makeReference(provider),
                        source_ref=source_ref),
                    key=ExpressionConstantRef(constant="metaclass",
                                              source_ref=source_ref,
                                              user_provided=True),
                    source_ref=source_ref),
                no_expression=ExpressionConditional(
                    condition=ExpressionTempVariableRef(
                        variable=tmp_bases.makeReference(provider),
                        source_ref=source_ref),
                    no_expression=ExpressionBuiltinRef(builtin_name="type",
                                                       source_ref=source_ref),
                    yes_expression=ExpressionBuiltinType1(
                        value=ExpressionSubscriptLookup(
                            expression=ExpressionTempVariableRef(
                                variable=tmp_bases.makeReference(provider),
                                source_ref=source_ref),
                            subscript=ExpressionConstantRef(
                                constant=0,
                                source_ref=source_ref,
                                user_provided=True),
                            source_ref=source_ref),
                        source_ref=source_ref),
                    source_ref=source_ref),
                source_ref=source_ref),
                                             bases=ExpressionTempVariableRef(
                                                 variable=tmp_bases.
                                                 makeReference(provider),
                                                 source_ref=source_ref),
                                             source_ref=source_ref),
            source_ref=source_ref_orig),
        StatementConditional(
            condition=ExpressionComparison(
                comparator="In",
                left=ExpressionConstantRef(constant="metaclass",
                                           source_ref=source_ref,
                                           user_provided=True),
                right=ExpressionTempVariableRef(
                    variable=tmp_class_decl_dict.makeReference(provider),
                    source_ref=source_ref),
                source_ref=source_ref),
            no_branch=None,
            yes_branch=makeStatementsSequenceFromStatement(
                statement=StatementDictOperationRemove(
                    dicte=ExpressionTempVariableRef(
                        variable=tmp_class_decl_dict.makeReference(provider),
                        source_ref=source_ref),
                    key=ExpressionConstantRef(constant="metaclass",
                                              source_ref=source_ref,
                                              user_provided=True),
                    source_ref=source_ref)),
            source_ref=source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_prepared.makeReference(provider),
                source_ref=source_ref),
            source=ExpressionConditional(
                condition=ExpressionBuiltinHasattr(
                    object=ExpressionTempVariableRef(
                        variable=tmp_metaclass.makeReference(provider),
                        source_ref=source_ref),
                    name=ExpressionConstantRef(constant="__prepare__",
                                               source_ref=source_ref,
                                               user_provided=True),
                    source_ref=source_ref),
                no_expression=ExpressionConstantRef(constant={},
                                                    source_ref=source_ref,
                                                    user_provided=True),
                yes_expression=ExpressionCall(
                    called=ExpressionAttributeLookup(
                        expression=ExpressionTempVariableRef(
                            variable=tmp_metaclass.makeReference(provider),
                            source_ref=source_ref),
                        attribute_name="__prepare__",
                        source_ref=source_ref),
                    args=ExpressionMakeTuple(elements=(
                        ExpressionConstantRef(constant=node.name,
                                              source_ref=source_ref,
                                              user_provided=True),
                        ExpressionTempVariableRef(
                            variable=tmp_bases.makeReference(provider),
                            source_ref=source_ref)),
                                             source_ref=source_ref),
                    kw=ExpressionTempVariableRef(
                        variable=tmp_class_decl_dict.makeReference(provider),
                        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),
    )

    final = (StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
        variable=tmp_bases.makeReference(provider), source_ref=source_ref),
                                  tolerant=True,
                                  source_ref=source_ref),
             StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
                 variable=tmp_class_decl_dict.makeReference(provider),
                 source_ref=source_ref),
                                  tolerant=True,
                                  source_ref=source_ref),
             StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
                 variable=tmp_metaclass.makeReference(provider),
                 source_ref=source_ref),
                                  tolerant=True,
                                  source_ref=source_ref),
             StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
                 variable=tmp_prepared.makeReference(provider),
                 source_ref=source_ref),
                                  tolerant=True,
                                  source_ref=source_ref))

    return makeTryFinallyStatement(tried=statements,
                                   final=final,
                                   source_ref=source_ref)
Example #26
0
    def wrapSuperBuiltin(type_arg, object_arg, source_ref):
        if type_arg is None and python_version >= 300:
            provider = node.getParentVariableProvider()

            if python_version < 340 or True:  # TODO: Temporarily reverted:
                type_arg = ExpressionVariableRef(variable_name="__class__", source_ref=source_ref)

                # Ought to be already closure taken.
                type_arg.setVariable(provider.getVariableForClosure(variable_name="__class__"))

                # If we already have this as a local variable, then use that
                # instead.
                if type_arg.getVariable().getOwner() is provider:
                    type_arg = None
                else:
                    addVariableUsage(type_arg.getVariable(), provider)
            else:
                parent_provider = provider.getParentVariableProvider()

                class_var = parent_provider.getTempVariable(temp_scope=None, name="__class__")

                type_arg = ExpressionTempVariableRef(variable=class_var, source_ref=source_ref)
                addVariableUsage(type_arg.getVariable(), provider)

            if type_arg is None:
                return makeRaiseExceptionReplacementExpression(
                    expression=node,
                    exception_type="SystemError" if python_version < 331 else "RuntimeError",
                    exception_value="super(): __class__ cell not found",
                )

            if object_arg is None:
                if provider.getParameters().getArgumentCount() > 0:
                    par1_name = provider.getParameters().getArgumentNames()[0]
                    # TODO: Nested first argument would kill us here, need a
                    # test for that.

                    object_arg = ExpressionVariableRef(variable_name=par1_name, source_ref=source_ref)

                    object_arg.setVariable(provider.getVariableForReference(variable_name=par1_name))

                    if not object_arg.getVariable().isParameterVariable():
                        return makeRaiseExceptionReplacementExpression(
                            expression=node,
                            exception_type="SystemError" if python_version < 330 else "RuntimeError",
                            exception_value="super(): __class__ cell not found",
                        )
                else:
                    return makeRaiseExceptionReplacementExpression(
                        expression=node, exception_type="RuntimeError", exception_value="super(): no arguments"
                    )

        return ExpressionBuiltinSuper(super_type=type_arg, super_object=object_arg, source_ref=source_ref)
Example #27
0
    def wrapSuperBuiltin(type_arg, object_arg, source_ref):
        if type_arg is None and python_version >= 300:
            if provider.isCompiledPythonModule():
                return makeRaiseExceptionReplacementExpression(
                    expression=node,
                    exception_type="RuntimeError",
                    exception_value="super(): no arguments",
                )

            class_variable = provider.getVariableForReference(variable_name="__class__")

            provider.trace_collection.getVariableCurrentTrace(class_variable).addUsage()

            type_arg = ExpressionVariableRef(
                # Ought to be already closure taken due to "super" flag in
                # tree building.
                variable=class_variable,
                source_ref=source_ref,
            )

            # If we already have this as a local variable, then use that
            # instead.
            type_arg_owner = type_arg.getVariable().getOwner()
            if type_arg_owner is provider or not (
                type_arg_owner.isExpressionFunctionBody()
                or type_arg_owner.isExpressionClassBody()
            ):
                type_arg = None

            if type_arg is None:
                return makeRaiseExceptionReplacementExpression(
                    expression=node,
                    exception_type="SystemError"
                    if python_version < 331
                    else "RuntimeError",
                    exception_value="super(): __class__ cell not found",
                )

            if object_arg is None:
                if (
                    provider.isExpressionGeneratorObjectBody()
                    or provider.isExpressionCoroutineObjectBody()
                    or provider.isExpressionAsyncgenObjectBody()
                ):
                    parameter_provider = provider.getParentVariableProvider()
                else:
                    parameter_provider = provider

                if parameter_provider.getParameters().getArgumentCount() > 0:
                    par1_name = parameter_provider.getParameters().getArgumentNames()[0]

                    object_variable = provider.getVariableForReference(
                        variable_name=par1_name
                    )

                    provider.trace_collection.getVariableCurrentTrace(
                        object_variable
                    ).addUsage()

                    object_arg = ExpressionVariableRef(
                        variable=object_variable, source_ref=source_ref
                    )

                    if not object_arg.getVariable().isParameterVariable():
                        return makeRaiseExceptionReplacementExpression(
                            expression=node,
                            exception_type="SystemError"
                            if python_version < 300
                            else "RuntimeError",
                            exception_value="super(): __class__ cell not found",
                        )
                else:
                    return makeRaiseExceptionReplacementExpression(
                        expression=node,
                        exception_type="RuntimeError",
                        exception_value="super(): no arguments",
                    )

        return ExpressionBuiltinSuper(
            super_type=type_arg, super_object=object_arg, source_ref=source_ref
        )
Example #28
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_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,
    )
Example #29
0
    def wrapSuperBuiltin(type_arg, object_arg, source_ref):
        if type_arg is None and python_version >= 300:

            provider = node.getParentVariableProvider()

            type_arg = ExpressionVariableRef(
                variable_name = "__class__",
                source_ref    = source_ref
            )

            # Ought to be already closure taken.
            type_arg.setVariable(
                provider.getVariableForReference(
                    variable_name = "__class__"
                )
            )

            # If we already have this as a local variable, then use that
            # instead.
            type_arg_owner = type_arg.getVariable().getOwner()
            if type_arg_owner is provider or \
            not (type_arg_owner.isExpressionFunctionBody() or \
                 type_arg_owner.isExpressionClassBody()):
                type_arg = None
            else:
                addVariableUsage(type_arg.getVariable(), provider)

            if type_arg is None:
                return makeRaiseExceptionReplacementExpression(
                    expression      = node,
                    exception_type  = "SystemError"
                                        if python_version < 331 else
                                      "RuntimeError",
                    exception_value = "super(): __class__ cell not found",
                )

            if object_arg is None:
                if provider.isExpressionGeneratorObjectBody():
                    parameter_provider = provider.getParentVariableProvider()
                else:
                    parameter_provider = provider

                if parameter_provider.getParameters().getArgumentCount() > 0:
                    par1_name = parameter_provider.getParameters().getArgumentNames()[0]

                    object_arg = ExpressionVariableRef(
                        variable_name = par1_name,
                        source_ref    = source_ref
                    )

                    object_arg.setVariable(
                        provider.getVariableForReference(
                            variable_name = par1_name
                        )
                    )

                    if not object_arg.getVariable().isParameterVariable():
                        return makeRaiseExceptionReplacementExpression(
                            expression      = node,
                            exception_type  = "SystemError"
                                                if python_version < 330 else
                                              "RuntimeError",
                            exception_value = "super(): __class__ cell not found",
                        )
                else:
                    return makeRaiseExceptionReplacementExpression(
                        expression      = node,
                        exception_type  = "RuntimeError",
                        exception_value = "super(): no arguments"
                    )

        return ExpressionBuiltinSuper(
            super_type   = type_arg,
            super_object = object_arg,
            source_ref   = source_ref
        )
Example #30
0
def getSetUnpackingHelper():
    helper_name = "_unpack_set"

    result = makeInternalHelperFunctionBody(
        name=helper_name,
        parameters=ParameterSpec(
            ps_name=helper_name,
            ps_normal_args=(),
            ps_list_star_arg="args",
            ps_dict_star_arg=None,
            ps_default_count=0,
            ps_kw_only_args=(),
            ps_pos_only_args=(),
        ),
    )

    temp_scope = None

    tmp_result_variable = result.allocateTempVariable(temp_scope, "set")
    tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter")
    tmp_item_variable = result.allocateTempVariable(temp_scope, "keys")

    loop_body = makeStatementsSequenceFromStatements(
        makeTryExceptSingleHandlerNode(
            tried=StatementAssignmentVariable(
                variable=tmp_item_variable,
                source=ExpressionBuiltinNext1(
                    value=ExpressionTempVariableRef(
                        variable=tmp_iter_variable,
                        source_ref=internal_source_ref),
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref,
            ),
            exception_name="StopIteration",
            handler_body=StatementLoopBreak(source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
        StatementExpressionOnly(
            expression=ExpressionSetOperationUpdate(
                set_arg=ExpressionTempVariableRef(
                    variable=tmp_result_variable,
                    source_ref=internal_source_ref),
                value=ExpressionTempVariableRef(
                    variable=tmp_item_variable,
                    source_ref=internal_source_ref),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
    )

    args_variable = result.getVariableForAssignment(variable_name="args")

    final = (
        StatementReleaseVariable(variable=tmp_result_variable,
                                 source_ref=internal_source_ref),
        StatementReleaseVariable(variable=tmp_iter_variable,
                                 source_ref=internal_source_ref),
        StatementReleaseVariable(variable=tmp_item_variable,
                                 source_ref=internal_source_ref),
    )

    tried = makeStatementsSequenceFromStatements(
        StatementAssignmentVariable(
            variable=tmp_iter_variable,
            source=ExpressionBuiltinIter1(
                value=ExpressionVariableRef(variable=args_variable,
                                            source_ref=internal_source_ref),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
        StatementAssignmentVariable(
            variable=tmp_result_variable,
            source=makeConstantRefNode(constant=set(),
                                       source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
        StatementLoop(body=loop_body, source_ref=internal_source_ref),
        StatementReturn(
            expression=ExpressionTempVariableRef(
                variable=tmp_result_variable, source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
    )

    result.setBody(
        makeStatementsSequenceFromStatement(
            makeTryFinallyStatement(
                provider=result,
                tried=tried,
                final=final,
                source_ref=internal_source_ref,
            )))

    return result
Example #31
0
    def onEnterNode(self, node):
        # Mighty complex code with lots of branches and statements, but it
        # couldn't be less without making it more difficult.
        # pylint: disable=too-many-branches,too-many-statements

        if node.isExpressionVariableNameRef():
            provider = node.getParentVariableProvider()

            if provider.isEarlyClosure():
                variable = provider.getVariableForReference(
                    variable_name=node.getVariableName())

                # Python3.4 version respects closure variables taken can be
                # overridden by writes to locals. It should be done for
                # globals too, on all versions, but for Python2 the locals
                # dictionary is avoided unless "exec" appears, so it's not
                # done.
                owner = variable.getOwner()
                user = provider

                while user is not owner:
                    if user.isExpressionFunctionBody() or \
                       user.isExpressionClassBody():
                        break

                    user = user.getParentVariableProvider()

                if owner is not user:
                    if python_version >= 340 or \
                       (python_version >= 300 and \
                        variable.isModuleVariable()):

                        node.replaceWith(
                            ExpressionLocalsVariableRef(
                                variable_name=node.getVariableName(),
                                fallback_variable=variable,
                                source_ref=node.getSourceReference()))

                    else:
                        node.replaceWith(
                            ExpressionVariableRef(variable=variable,
                                                  source_ref=node.source_ref))
                else:
                    node.replaceWith(
                        ExpressionVariableRef(variable=variable,
                                              source_ref=node.source_ref))

                variable.addVariableUser(provider)
        elif node.isExpressionTempVariableRef():
            if node.getVariable().getOwner() != node.getParentVariableProvider(
            ):
                node.getParentVariableProvider().addClosureVariable(
                    node.getVariable())
        elif node.isExpressionGeneratorObjectBody():
            self._handleNonLocal(node)

            # Only Python3.4 or later allows for generators to have qualname.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        elif node.isExpressionCoroutineObjectBody():
            self._handleNonLocal(node)

            self._handleQualnameSetup(node)
        elif node.isExpressionAsyncgenObjectBody():
            self._handleNonLocal(node)

            self._handleQualnameSetup(node)
        elif node.isExpressionClassBody():
            self._handleNonLocal(node)

            # Python3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        elif node.isExpressionFunctionBody():
            self._handleNonLocal(node)

            # Python 3.4 allows for class declarations to be made global, even
            # after they were declared, so we need to fix this up.
            if python_version >= 340:
                self._handleQualnameSetup(node)
        # Attribute access of names of class functions should be mangled, if
        # they start with "__", but do not end in "__" as well.
        elif node.isExpressionAttributeLookup() or \
             node.isStatementAssignmentAttribute() or \
             node.isStatementDelAttribute():
            attribute_name = node.getAttributeName()

            if attribute_name.startswith("__") and \
               not attribute_name.endswith("__"):
                seen_function = False

                current = node

                while True:
                    current = current.getParentVariableProvider()

                    if current.isCompiledPythonModule():
                        break

                    if current.isExpressionClassBody():
                        if seen_function:
                            node.setAttributeName(
                                "_%s%s" % (current.getName().lstrip('_'),
                                           attribute_name))

                        break
                    else:
                        seen_function = True
        # Check if continue and break are properly in loops. If not, raise a
        # syntax error.
        elif node.isStatementLoopBreak() or node.isStatementLoopContinue():
            current = node

            while True:
                current = current.getParent()

                if current.isStatementLoop():
                    break

                if current.isParentVariableProvider():
                    if node.isStatementLoopContinue():
                        message = "'continue' not properly in loop"
                    else:
                        message = "'break' outside loop"

                    raiseSyntaxError(
                        message,
                        node.getSourceReference(),
                    )