def buildExtSliceNode(provider, node, source_ref):
    elements = []

    for dim in node.slice.dims:
        dim_kind = getKind(dim)

        if dim_kind == "Slice":
            lower = buildNode(provider, dim.lower, source_ref, True)
            upper = buildNode(provider, dim.upper, source_ref, True)
            step = buildNode(provider, dim.step, source_ref, True)

            element = ExpressionSliceObject(lower=lower,
                                            upper=upper,
                                            step=step,
                                            source_ref=source_ref)
        elif dim_kind == "Ellipsis":
            element = ExpressionConstantRef(constant=Ellipsis,
                                            source_ref=source_ref,
                                            user_provided=True)
        elif dim_kind == "Index":
            element = buildNode(provider=provider,
                                node=dim.value,
                                source_ref=source_ref)
        else:
            assert False, dim

        elements.append(element)

    return makeSequenceCreationOrConstant(sequence_kind="tuple",
                                          elements=elements,
                                          source_ref=source_ref)
def buildDeleteStatementFromDecoded(kind, detail, source_ref):
    if kind in ("Name", "Name_Exception"):
        # Note: Name_Exception is a "del" for exception handlers that doesn't
        # insist on the variable being defined, user code may do it too, and
        # that will be fine, so make that tolerant.
        variable_ref = detail

        return StatementDelVariable(variable_ref=variable_ref,
                                    tolerant=kind == "Name_Exception",
                                    source_ref=source_ref)
    elif kind == "Attribute":
        lookup_source, attribute_name = detail

        return StatementDelAttribute(expression=lookup_source,
                                     attribute_name=attribute_name,
                                     source_ref=source_ref)
    elif kind == "Subscript":
        subscribed, subscript = detail

        return StatementDelSubscript(expression=subscribed,
                                     subscript=subscript,
                                     source_ref=source_ref)
    elif kind == "Slice":
        lookup_source, lower, upper = detail

        use_sliceobj = Utils.python_version >= 300

        if use_sliceobj:
            return StatementDelSubscript(expression=lookup_source,
                                         subscript=ExpressionSliceObject(
                                             lower=lower,
                                             upper=upper,
                                             step=None,
                                             source_ref=source_ref),
                                         source_ref=source_ref)
        else:
            return StatementDelSlice(expression=lookup_source,
                                     lower=lower,
                                     upper=upper,
                                     source_ref=source_ref)
    elif kind == "Tuple":
        result = []

        for sub_node in detail:
            result.append(
                buildDeleteStatementFromDecoded(kind=sub_node[0],
                                                detail=sub_node[1],
                                                source_ref=source_ref))

        return makeStatementsSequenceOrStatement(statements=result,
                                                 source_ref=source_ref)
    else:
        assert False, (kind, detail, source_ref)
예제 #3
0
def buildSubscriptNode(provider, node, source_ref):
    # Subscript expression nodes.

    assert getKind(node.ctx) == "Load", source_ref

    # The subscribt "[]" operator is one of many different things. This is
    # expressed by this kind, there are "slice" lookups (two values, even if one
    # is using default), and then "index" lookups. The form with three argument
    # is really an "index" lookup, with a slice object. And the "..." lookup is
    # also an index loopup, with it as the argument. So this splits things into
    # two different operations, "subscript" with a single "subscript" object. Or
    # a slice lookup with a lower and higher boundary. These things should
    # behave similar, but they are different slots.
    kind = getKind(node.slice)

    if kind == "Index":
        return ExpressionSubscriptLookup(
            subscribed=buildNode(provider, node.value, source_ref),
            subscript=buildNode(provider, node.slice.value, source_ref),
            source_ref=source_ref)
    elif kind == "Slice":
        lower = buildNode(provider, node.slice.lower, source_ref, True)
        upper = buildNode(provider, node.slice.upper, source_ref, True)

        if node.slice.step is not None:
            step = buildNode(provider, node.slice.step, source_ref)

            return ExpressionSubscriptLookup(
                subscribed=buildNode(provider, node.value, source_ref),
                subscript=ExpressionSliceObject(lower=lower,
                                                upper=upper,
                                                step=step,
                                                source_ref=source_ref),
                source_ref=source_ref)
        else:
            return ExpressionSliceLookup(expression=buildNode(
                provider, node.value, source_ref),
                                         lower=lower,
                                         upper=upper,
                                         source_ref=source_ref)
    elif kind == "ExtSlice":
        return ExpressionSubscriptLookup(
            subscribed=buildNode(provider, node.value, source_ref),
            subscript=buildExtSliceNode(provider, node, source_ref),
            source_ref=source_ref)
    elif kind == "Ellipsis":
        return ExpressionSubscriptLookup(
            subscribed=buildNode(provider, node.value, source_ref),
            subscript=ExpressionConstantRef(constant=Ellipsis,
                                            source_ref=source_ref),
            source_ref=source_ref)
    else:
        assert False, kind
예제 #4
0
def _buildInplaceAssignSliceNode(lookup_source, lower, upper, tmp_variable1,
                                 tmp_variable2, tmp_variable3, operator,
                                 expression, source_ref):

    # Due to the 3 inputs, which we need to also put into temporary variables,
    # there are too many variables here, but they are needed.
    # pylint: disable=R0914

    # First assign the target value, lower and upper to temporary variables.
    copy_to_tmp = StatementAssignmentVariable(
        variable_ref = ExpressionTargetTempVariableRef(
            variable   = tmp_variable1,
            source_ref = source_ref
        ),
        source       = lookup_source,
        source_ref   = source_ref
    )

    final_statements = [
        StatementReleaseVariable(
            variable   = tmp_variable1,
            tolerant   = False,
            source_ref = source_ref
        )
    ]
    statements = []

    if lower is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_variable2,
                    source_ref = source_ref
                ),
                source       = lower,
                source_ref   = source_ref
            )
        )
        final_statements.append(
            StatementReleaseVariable(
                variable   = tmp_variable2,
                tolerant   = True,
                source_ref = source_ref
            )
        )

        lower_ref1 = ExpressionTempVariableRef(
            variable   = tmp_variable2,
            source_ref = source_ref
        )
        lower_ref2 = ExpressionTempVariableRef(
            variable   = tmp_variable2,
            source_ref = source_ref
        )
    else:
        assert tmp_variable2 is None

        lower_ref1 = lower_ref2 = None

    if upper is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_variable3,
                    source_ref = source_ref
                ),
                source       = upper,
                source_ref   = source_ref
            )
        )
        final_statements.append(
            StatementReleaseVariable(
                variable   = tmp_variable3,
                tolerant   = True,
                source_ref = source_ref
            )
        )

        upper_ref1 = ExpressionTempVariableRef(
            variable   = tmp_variable3,
            source_ref = source_ref
        )
        upper_ref2 = ExpressionTempVariableRef(
            variable   = tmp_variable3,
            source_ref = source_ref
        )
    else:
        assert tmp_variable3 is None

        upper_ref1 = upper_ref2 = None

    use_sliceobj = Utils.python_version >= 300

        # Second assign the in-place result over the original value.
    if use_sliceobj:
        statements.append(
            StatementAssignmentSubscript(
                expression = ExpressionTempVariableRef(
                    variable   = tmp_variable1,
                    source_ref = source_ref
                ),
                subscript  = ExpressionSliceObject(
                    lower      = lower_ref1,
                    upper      = upper_ref1,
                    step       = None,
                    source_ref = source_ref
                ),
                source     = ExpressionOperationBinaryInplace(
                    operator   = operator,
                    left       = ExpressionSubscriptLookup(
                        subscribed = ExpressionTempVariableRef(
                            variable   = tmp_variable1,
                            source_ref = source_ref
                        ),
                        subscript  = ExpressionSliceObject(
                            lower      = lower_ref2,
                            upper      = upper_ref2,
                            step       = None,
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    right      = expression,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )
        )
    else:
        statements.append(
            StatementAssignmentSlice(
                expression = ExpressionTempVariableRef(
                    variable   = tmp_variable1,
                    source_ref = source_ref
                ),
                lower      = lower_ref1,
                upper      = upper_ref1,
                source     = ExpressionOperationBinaryInplace(
                    operator   = operator,
                    left       = ExpressionSliceLookup(
                        expression = ExpressionTempVariableRef(
                            variable   = tmp_variable1,
                            source_ref = source_ref
                        ),
                        lower      = lower_ref2,
                        upper      = upper_ref2,
                        source_ref = source_ref
                    ),
                    right      = expression,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )
        )

    return (
        copy_to_tmp,
        makeTryFinallyStatement(
            tried      = statements,
            final      = final_statements,
            source_ref = source_ref
        )
    )
예제 #5
0
def decodeAssignTarget(provider, node, source_ref, allow_none = False):
    # Many cases to deal with, because of the different assign targets,
    # pylint: disable=R0911,R0912

    if node is None and allow_none:
        return None

    if hasattr(node, "ctx"):
        assert getKind(node.ctx) in ("Store", "Del")

    kind = getKind(node)

    if type(node) is str:
        return "Name", ExpressionTargetVariableRef(
            variable_name = mangleName(node, provider),
            source_ref    = source_ref
        )
    elif kind == "Name":
        return kind, ExpressionTargetVariableRef(
            variable_name = mangleName(node.id, provider),
            source_ref    = source_ref
        )
    elif kind == "Attribute":
        return kind, (
            buildNode(provider, node.value, source_ref),
            node.attr
        )
    elif kind == "Subscript":
        slice_kind = getKind(node.slice)

        if slice_kind == "Index":
            return "Subscript", (
                buildNode(provider, node.value, source_ref),
                buildNode(provider, node.slice.value, source_ref)
            )
        elif slice_kind == "Slice":
            lower = buildNode(provider, node.slice.lower, source_ref, True)
            upper = buildNode(provider, node.slice.upper, source_ref, True)

            if node.slice.step is not None:
                step = buildNode(provider, node.slice.step, source_ref)

                return "Subscript", (
                    buildNode(provider, node.value, source_ref),
                    ExpressionSliceObject(
                        lower      = lower,
                        upper      = upper,
                        step       = step,
                        source_ref = source_ref
                    )
                )
            else:
                return "Slice", (
                    buildNode(provider, node.value, source_ref),
                    lower,
                    upper
                )
        elif slice_kind == "ExtSlice":
            return "Subscript", (
                buildNode(provider, node.value, source_ref),
                buildExtSliceNode(provider, node, source_ref)
            )
        elif slice_kind == "Ellipsis":
            return "Subscript", (
                buildNode(provider, node.value, source_ref),
                ExpressionConstantRef(
                    constant   = Ellipsis,
                    source_ref = source_ref
                )
            )
        else:
            assert False, slice_kind
    elif kind in ("Tuple", "List"):
        return "Tuple", tuple(
            decodeAssignTarget(
                provider   = provider,
                node       = sub_node,
                source_ref = source_ref,
                allow_none = False
            )
            for sub_node in
            node.elts
        )
    elif kind == "Starred":
        return "Starred", decodeAssignTarget(
            provider   = provider,
            node       = node.value,
            source_ref = source_ref,
            allow_none = False
        )
    else:
        assert False, (source_ref, kind)
예제 #6
0
def buildAssignmentStatementsFromDecoded(provider, kind, detail, source,
                                         source_ref):
    # This is using many variable names on purpose, so as to give names to the
    # unpacked detail values, and has many branches due to the many cases
    # dealt with, pylint: disable=R0912,R0914

    if kind == "Name":
        variable_ref = detail

        return StatementAssignmentVariable(
            variable_ref = variable_ref,
            source       = source,
            source_ref   = source_ref
        )
    elif kind == "Attribute":
        lookup_source, attribute_name = detail

        return StatementAssignmentAttribute(
            expression     = lookup_source,
            attribute_name = attribute_name,
            source         = source,
            source_ref     = source_ref
        )
    elif kind == "Subscript":
        subscribed, subscript = detail

        return StatementAssignmentSubscript(
            expression = subscribed,
            subscript  = subscript,
            source     = source,
            source_ref = source_ref
        )
    elif kind == "Slice":
        lookup_source, lower, upper = detail

        # For Python3 there is no slicing operation, this is always done
        # with subscript using a slice object. For Python2, it is only done
        # if no "step" is provided.
        use_sliceobj = Utils.python_version >= 300

        if use_sliceobj:
            return StatementAssignmentSubscript(
                expression = lookup_source,
                source     = source,
                subscript  = ExpressionSliceObject(
                    lower      = lower,
                    upper      = upper,
                    step       = None,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )

        else:
            return StatementAssignmentSlice(
                expression = lookup_source,
                lower      = lower,
                upper      = upper,
                source     = source,
                source_ref = source_ref
            )
    elif kind == "Tuple":
        temp_scope = provider.allocateTempScope("tuple_unpack")

        source_iter_var = provider.allocateTempVariable(
            temp_scope = temp_scope,
            name       = "source_iter"
        )

        statements = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = source_iter_var,
                    source_ref = source_ref
                ),
                source       = ExpressionBuiltinIter1(
                    value      = source,
                    source_ref = source_ref
                ),
                source_ref   = source_ref
            )
        ]

        element_vars = [
            provider.allocateTempVariable(
                temp_scope = temp_scope,
                name       = "element_%d" % (
                    element_index + 1
                )
            )
            for element_index in
            range(len(detail))
        ]

        starred = False

        for element_index, element in enumerate(detail):
            element_var = element_vars[element_index]

            if element[0] != "Starred":
                statements.append(
                    StatementAssignmentVariable(
                        variable_ref = ExpressionTargetTempVariableRef(
                            variable   = element_var,
                            source_ref = source_ref
                        ),
                        source       = ExpressionSpecialUnpack(
                            value      = ExpressionTempVariableRef(
                                variable   = source_iter_var,
                                source_ref = source_ref
                            ),
                            count      = element_index + 1,
                            source_ref = source_ref
                        ),
                        source_ref   = source_ref
                    )
                )
            else:
                starred = True

                statements.append(
                    StatementAssignmentVariable(
                        variable_ref = ExpressionTargetTempVariableRef(
                            variable   = element_var,
                            source_ref = source_ref
                        ),
                        source       = ExpressionBuiltinList(
                            value      = ExpressionTempVariableRef(
                                variable   = source_iter_var,
                                source_ref = source_ref
                            ),
                            source_ref = source_ref
                        ),
                        source_ref   = source_ref
                    )
                )

        if not starred:
            statements.append(
                StatementSpecialUnpackCheck(
                    iterator   = ExpressionTempVariableRef(
                        variable   = source_iter_var,
                        source_ref = source_ref
                    ),
                    count      = len(detail),
                    source_ref = source_ref
                )
            )

        for element_index, element in enumerate(detail):
            if element[0] == "Starred":
                element = element[1]

            element_var = element_vars[element_index]

            statements.append(
                buildAssignmentStatementsFromDecoded(
                    provider   = provider,
                    kind       = element[0],
                    detail     = element[1],
                    source     = ExpressionTempVariableRef(
                        variable   = element_var,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                )
            )

        final_statements = []

        final_statements.append(
            StatementReleaseVariable(
                variable   = source_iter_var,
                tolerant   = True,
                source_ref = source_ref
            )
        )

        # TODO: In that order, or reversed.
        for element_var in element_vars:
            final_statements.append(
                StatementReleaseVariable(
                    variable   = element_var,
                    tolerant   = True,
                    source_ref = source_ref
                )
            )

        return makeTryFinallyStatement(
            tried      = statements,
            final      = final_statements,
            source_ref = source_ref
        )
    else:
        assert False, (kind, source_ref, detail)