def _buildInplaceAssignVariableNode(variable_ref, operator, expression,
                                    source_ref):
    assert variable_ref.isExpressionTargetVariableRef(), variable_ref

    inplace_node = makeExpressionOperationBinaryInplace(
        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
コード例 #2
0
def _buildInplaceAssignAttributeNode(
    provider,
    lookup_source,
    attribute_name,
    tmp_variable1,
    tmp_variable2,
    operator,
    expression,
    source_ref,
):
    # First assign the target value to a temporary variable.
    preserve_to_tmp = StatementAssignmentVariable(
        variable=tmp_variable1,
        source=ExpressionAttributeLookup(
            source=lookup_source.makeClone(),
            attribute_name=attribute_name,
            source_ref=source_ref,
        ),
        source_ref=source_ref,
    )

    # Second assign the in-place result to a temporary variable
    inplace_to_tmp = StatementAssignmentVariable(
        variable=tmp_variable2,
        source=makeExpressionOperationBinaryInplace(
            operator=operator,
            left=ExpressionTempVariableRef(variable=tmp_variable1,
                                           source_ref=source_ref),
            right=expression,
            source_ref=source_ref,
        ),
        source_ref=source_ref,
    )

    # Third, copy it back.
    copy_back_from_tmp = makeTryFinallyStatement(
        provider=provider,
        tried=StatementAssignmentAttribute(
            expression=lookup_source.makeClone(),
            attribute_name=attribute_name,
            source=ExpressionTempVariableRef(variable=tmp_variable2,
                                             source_ref=source_ref),
            source_ref=source_ref,
        ),
        final=StatementReleaseVariable(variable=tmp_variable2,
                                       source_ref=source_ref),
        source_ref=source_ref,
    )

    return (
        preserve_to_tmp,
        # making sure the above temporary variable is deleted in any case.
        makeTryFinallyStatement(
            provider=provider,
            tried=(inplace_to_tmp, copy_back_from_tmp),
            final=StatementReleaseVariable(variable=tmp_variable1,
                                           source_ref=source_ref),
            source_ref=source_ref,
        ),
    )
コード例 #3
0
def _buildInplaceAssignAttributeNode(provider, lookup_source, attribute_name,
                                     tmp_variable1, tmp_variable2, operator,
                                     expression, source_ref):
    # First assign the target value to a temporary variable.
    preserve_to_tmp = StatementAssignmentVariable(
        variable=tmp_variable1,
        source=ExpressionAttributeLookup(source=lookup_source.makeClone(),
                                         attribute_name=attribute_name,
                                         source_ref=source_ref),
        source_ref=source_ref)

    # Second assign the in-place result to a temporary variable
    inplace_to_tmp = StatementAssignmentVariable(
        variable=tmp_variable2,
        source=makeExpressionOperationBinaryInplace(
            operator=operator,
            left=ExpressionTempVariableRef(variable=tmp_variable1,
                                           source_ref=source_ref),
            right=expression,
            source_ref=source_ref),
        source_ref=source_ref)

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

    copy_back_from_tmp = makeTryFinallyStatement(
        provider=provider,
        tried=copy_back_from_tmp,
        final=StatementReleaseVariable(variable=tmp_variable2,
                                       source_ref=source_ref),
        source_ref=source_ref)

    return (
        preserve_to_tmp,
        # making sure the above temporary variable is deleted in any case.
        makeTryFinallyStatement(provider=provider,
                                tried=(
                                    inplace_to_tmp,
                                    copy_back_from_tmp,
                                ),
                                final=StatementReleaseVariable(
                                    variable=tmp_variable1,
                                    source_ref=source_ref),
                                source_ref=source_ref))
コード例 #4
0
def _buildInplaceAssignSubscriptNode(
    provider,
    subscribed,
    subscript,
    tmp_variable1,
    tmp_variable2,
    operator,
    expression,
    source_ref,
):
    # First assign the subscribed value to a temporary variable.
    preserve_to_tmp1 = StatementAssignmentVariable(
        variable=tmp_variable1, source=subscribed, source_ref=source_ref
    )
    # Second assign the subscript value to a temporary variable
    preserve_to_tmp2 = StatementAssignmentVariable(
        variable=tmp_variable2, source=subscript, source_ref=source_ref
    )

    execute_in_place = StatementAssignmentSubscript(
        expression=ExpressionTempVariableRef(
            variable=tmp_variable1, source_ref=source_ref
        ),
        subscript=ExpressionTempVariableRef(
            variable=tmp_variable2, source_ref=source_ref
        ),
        source=makeExpressionOperationBinaryInplace(
            operator=operator,
            left=ExpressionSubscriptLookup(
                subscribed=ExpressionTempVariableRef(
                    variable=tmp_variable1, source_ref=source_ref
                ),
                subscript=ExpressionTempVariableRef(
                    variable=tmp_variable2, source_ref=source_ref
                ),
                source_ref=source_ref,
            ),
            right=expression,
            source_ref=source_ref,
        ),
        source_ref=source_ref,
    )

    # Note: No copy back is happening, for subscripts that is implied.

    return (
        preserve_to_tmp1,
        makeTryFinallyStatement(
            provider=provider,
            tried=(preserve_to_tmp2, execute_in_place),
            final=(
                StatementReleaseVariable(variable=tmp_variable1, source_ref=source_ref),
                StatementReleaseVariable(variable=tmp_variable2, source_ref=source_ref),
            ),
            source_ref=source_ref,
        ),
    )
コード例 #5
0
def _buildInplaceAssignSubscriptNode(
    provider,
    subscribed,
    subscript,
    tmp_variable1,
    tmp_variable2,
    operator,
    expression,
    source_ref,
):
    # First assign the subscribed value to a temporary variable.
    preserve_to_tmp1 = StatementAssignmentVariable(variable=tmp_variable1,
                                                   source=subscribed,
                                                   source_ref=source_ref)
    # Second assign the subscript value to a temporary variable
    preserve_to_tmp2 = StatementAssignmentVariable(variable=tmp_variable2,
                                                   source=subscript,
                                                   source_ref=source_ref)

    execute_in_place = StatementAssignmentSubscript(
        expression=ExpressionTempVariableRef(variable=tmp_variable1,
                                             source_ref=source_ref),
        subscript=ExpressionTempVariableRef(variable=tmp_variable2,
                                            source_ref=source_ref),
        source=makeExpressionOperationBinaryInplace(
            operator=operator,
            left=ExpressionSubscriptLookup(
                subscribed=ExpressionTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
                subscript=ExpressionTempVariableRef(variable=tmp_variable2,
                                                    source_ref=source_ref),
                source_ref=source_ref,
            ),
            right=expression,
            source_ref=source_ref,
        ),
        source_ref=source_ref,
    )

    # Note: No copy back is happening, for subscripts that is implied.

    return (
        preserve_to_tmp1,
        makeTryFinallyStatement(
            provider=provider,
            tried=(preserve_to_tmp2, execute_in_place),
            final=(
                StatementReleaseVariable(variable=tmp_variable1,
                                         source_ref=source_ref),
                StatementReleaseVariable(variable=tmp_variable2,
                                         source_ref=source_ref),
            ),
            source_ref=source_ref,
        ),
    )
コード例 #6
0
def _buildInplaceAssignVariableNode(variable_name, operator, expression,
                                    source_ref):
    inplace_node = makeExpressionOperationBinaryInplace(
        operator=operator,
        left=ExpressionVariableNameRef(variable_name=variable_name,
                                       source_ref=source_ref),
        right=expression,
        source_ref=source_ref)

    inplace_node.markAsInplaceSuspect()

    return (StatementAssignmentVariableName(variable_name=variable_name,
                                            source=inplace_node,
                                            source_ref=source_ref), )
コード例 #7
0
def _buildInplaceAssignVariableNode(
    provider, variable_name, operator, expression, source_ref
):
    inplace_node = makeExpressionOperationBinaryInplace(
        operator=operator,
        left=ExpressionVariableNameRef(
            provider=provider, variable_name=variable_name, source_ref=source_ref
        ),
        right=expression,
        source_ref=source_ref,
    )

    inplace_node.markAsInplaceSuspect()

    return (
        StatementAssignmentVariableName(
            provider=provider,
            variable_name=variable_name,
            source=inplace_node,
            source_ref=source_ref,
        ),
    )
コード例 #8
0
def _buildInplaceAssignSliceNode(
    provider,
    lookup_source,
    lower,
    upper,
    tmp_variable1,
    tmp_variable2,
    tmp_variable3,
    tmp_variable4,
    operator,
    expression,
    source_ref,
):

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

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

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

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

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

        lower_ref1 = lower_ref2 = None

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

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

        upper_ref1 = upper_ref2 = None

    use_sliceobj = python_version >= 300

    # Second assign the in-place result over the original value.
    if use_sliceobj:
        statements += (
            StatementAssignmentVariable(
                variable=tmp_variable4,
                source=ExpressionSubscriptLookup(
                    expression=ExpressionTempVariableRef(
                        variable=tmp_variable1, source_ref=source_ref),
                    subscript=makeExpressionBuiltinSlice(
                        start=lower_ref2,
                        stop=upper_ref2,
                        step=None,
                        source_ref=source_ref,
                    ),
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
            StatementAssignmentVariable(
                variable=tmp_variable4,
                source=makeExpressionOperationBinaryInplace(
                    operator=operator,
                    left=ExpressionTempVariableRef(variable=tmp_variable4,
                                                   source_ref=source_ref),
                    right=expression,
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
            StatementAssignmentSubscript(
                expression=ExpressionTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
                subscript=makeExpressionBuiltinSlice(start=lower_ref1,
                                                     stop=upper_ref1,
                                                     step=None,
                                                     source_ref=source_ref),
                source=ExpressionTempVariableRef(variable=tmp_variable4,
                                                 source_ref=source_ref),
                source_ref=source_ref,
            ),
        )
    else:
        statements += (
            StatementAssignmentVariable(
                variable=tmp_variable4,
                source=ExpressionSliceLookup(
                    expression=ExpressionTempVariableRef(
                        variable=tmp_variable1, source_ref=source_ref),
                    lower=lower_ref2,
                    upper=upper_ref2,
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
            StatementAssignmentVariable(
                variable=tmp_variable4,
                source=makeExpressionOperationBinaryInplace(
                    operator=operator,
                    left=ExpressionTempVariableRef(variable=tmp_variable4,
                                                   source_ref=source_ref),
                    right=expression,
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
            StatementAssignmentSlice(
                expression=ExpressionTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
                lower=lower_ref1,
                upper=upper_ref1,
                source=ExpressionTempVariableRef(variable=tmp_variable4,
                                                 source_ref=source_ref),
                source_ref=source_ref,
            ),
        )

    final_statements.append(
        StatementReleaseVariable(variable=tmp_variable4,
                                 source_ref=source_ref))

    return (
        copy_to_tmp,
        makeTryFinallyStatement(
            provider=provider,
            tried=statements,
            final=final_statements,
            source_ref=source_ref,
        ),
    )
コード例 #9
0
def _buildInplaceAssignSubscriptNode(
    provider,
    subscribed,
    subscript,
    tmp_variable1,
    tmp_variable2,
    tmp_variable3,
    operator,
    expression,
    source_ref,
):
    # First assign the subscribed value to a temporary variable.
    preserve_to_tmp1 = StatementAssignmentVariable(variable=tmp_variable1,
                                                   source=subscribed,
                                                   source_ref=source_ref)
    # Second assign the subscript value to a temporary variable
    statements = (
        StatementAssignmentVariable(variable=tmp_variable2,
                                    source=subscript,
                                    source_ref=source_ref),
        StatementAssignmentVariable(
            variable=tmp_variable3,
            source=ExpressionSubscriptLookup(
                expression=ExpressionTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
                subscript=ExpressionTempVariableRef(variable=tmp_variable2,
                                                    source_ref=source_ref),
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        ),
        StatementAssignmentVariable(
            variable=tmp_variable3,
            source=makeExpressionOperationBinaryInplace(
                operator=operator,
                left=ExpressionTempVariableRef(variable=tmp_variable3,
                                               source_ref=source_ref),
                right=expression,
                source_ref=source_ref,
            ),
            source_ref=source_ref,
        ),
        StatementAssignmentSubscript(
            expression=ExpressionTempVariableRef(variable=tmp_variable1,
                                                 source_ref=source_ref),
            subscript=ExpressionTempVariableRef(variable=tmp_variable2,
                                                source_ref=source_ref),
            source=ExpressionTempVariableRef(variable=tmp_variable3,
                                             source_ref=source_ref),
            source_ref=source_ref,
        ),
    )

    return (
        preserve_to_tmp1,
        makeTryFinallyStatement(
            provider=provider,
            tried=statements,
            final=(
                StatementReleaseVariable(variable=tmp_variable1,
                                         source_ref=source_ref),
                StatementReleaseVariable(variable=tmp_variable2,
                                         source_ref=source_ref),
                StatementReleaseVariable(variable=tmp_variable3,
                                         source_ref=source_ref),
            ),
            source_ref=source_ref,
        ),
    )
コード例 #10
0
    def onLeaveNode(self, node):
        if node.isStatementAssignmentVariableName():
            variable_name = node.getVariableName()
            provider = node.provider

            # Classes always assign to locals dictionary except for closure
            # variables taken.
            if self._shouldUseLocalsDict(provider, variable_name):
                if node.subnode_source.isExpressionOperationInplace():
                    temp_scope = provider.allocateTempScope("class_inplace")

                    tmp_variable = provider.allocateTempVariable(
                        temp_scope=temp_scope, name="value"
                    )

                    statements = mergeStatements(
                        statements=(
                            StatementAssignmentVariable(
                                variable=tmp_variable,
                                source=node.subnode_source.getLeft(),
                                source_ref=node.source_ref,
                            ),
                            makeTryFinallyStatement(
                                provider=provider,
                                tried=(
                                    StatementAssignmentVariable(
                                        variable=tmp_variable,
                                        source=makeExpressionOperationBinaryInplace(
                                            left=ExpressionTempVariableRef(
                                                variable=tmp_variable,
                                                source_ref=node.source_ref,
                                            ),
                                            right=node.subnode_source.getRight(),
                                            operator=node.subnode_source.getOperator(),
                                            source_ref=node.source_ref,
                                        ),
                                        source_ref=node.source_ref,
                                    ),
                                    StatementLocalsDictOperationSet(
                                        locals_scope=provider.getLocalsScope(),
                                        variable_name=variable_name,
                                        value=ExpressionTempVariableRef(
                                            variable=tmp_variable,
                                            source_ref=node.source_ref,
                                        ),
                                        source_ref=node.source_ref,
                                    ),
                                ),
                                final=StatementReleaseVariable(
                                    variable=tmp_variable, source_ref=node.source_ref
                                ),
                                source_ref=node.source_ref,
                            ),
                        )
                    )

                    node.parent.replaceStatement(node, statements)

                else:
                    new_node = StatementLocalsDictOperationSet(
                        locals_scope=provider.getLocalsScope(),
                        variable_name=variable_name,
                        value=node.subnode_source,
                        source_ref=node.source_ref,
                    )

                    node.parent.replaceChild(node, new_node)
            else:
                variable = provider.getVariableForAssignment(
                    variable_name=variable_name
                )

                new_node = StatementAssignmentVariable(
                    variable=variable,
                    source=node.subnode_source,
                    source_ref=node.source_ref,
                )

                variable.addVariableUser(provider)

                node.parent.replaceChild(node, new_node)

            del node.parent
            del node.provider
        elif node.isStatementDelVariableName():
            variable_name = node.getVariableName()

            provider = node.provider

            if self._shouldUseLocalsDict(provider, variable_name):
                # Classes always assign to locals dictionary except for closure
                # variables taken.
                new_node = StatementLocalsDictOperationDel(
                    locals_scope=provider.getLocalsScope(),
                    variable_name=variable_name,
                    tolerant=node.tolerant,
                    source_ref=node.source_ref,
                )
            else:
                variable = provider.getVariableForAssignment(
                    variable_name=variable_name
                )

                new_node = StatementDelVariable(
                    variable=variable,
                    tolerant=node.tolerant,
                    source_ref=node.source_ref,
                )

                variable.addVariableUser(provider)

            parent = node.parent
            node.finalize()

            parent.replaceChild(node, new_node)
コード例 #11
0
def _buildInplaceAssignSliceNode(
    provider,
    lookup_source,
    lower,
    upper,
    tmp_variable1,
    tmp_variable2,
    tmp_variable3,
    operator,
    expression,
    source_ref,
):

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

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

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

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

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

        lower_ref1 = lower_ref2 = None

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

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

        upper_ref1 = upper_ref2 = None

    use_sliceobj = python_version >= 300

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

    return (
        copy_to_tmp,
        makeTryFinallyStatement(
            provider=provider,
            tried=statements,
            final=final_statements,
            source_ref=source_ref,
        ),
    )
コード例 #12
0
def _buildInplaceAssignAttributeNode(
    provider,
    lookup_source,
    attribute_name,
    tmp_variable1,
    tmp_variable2,
    operator,
    expression,
    source_ref,
):
    # First assign the target value to a temporary variable.
    preserve_to_tmp = StatementAssignmentVariable(
        variable=tmp_variable1,
        source=ExpressionAttributeLookup(
            source=lookup_source.makeClone(),
            attribute_name=attribute_name,
            source_ref=source_ref,
        ),
        source_ref=source_ref,
    )

    # Second assign the in-place result to a temporary variable
    inplace_to_tmp = StatementAssignmentVariable(
        variable=tmp_variable2,
        source=makeExpressionOperationBinaryInplace(
            operator=operator,
            left=ExpressionTempVariableRef(
                variable=tmp_variable1, source_ref=source_ref
            ),
            right=expression,
            source_ref=source_ref,
        ),
        source_ref=source_ref,
    )

    # Third, copy it back.
    copy_back_from_tmp = makeTryFinallyStatement(
        provider=provider,
        tried=StatementAssignmentAttribute(
            expression=lookup_source.makeClone(),
            attribute_name=attribute_name,
            source=ExpressionTempVariableRef(
                variable=tmp_variable2, source_ref=source_ref
            ),
            source_ref=source_ref,
        ),
        final=StatementReleaseVariable(variable=tmp_variable2, source_ref=source_ref),
        source_ref=source_ref,
    )

    return (
        preserve_to_tmp,
        # making sure the above temporary variable is deleted in any case.
        makeTryFinallyStatement(
            provider=provider,
            tried=(inplace_to_tmp, copy_back_from_tmp),
            final=StatementReleaseVariable(
                variable=tmp_variable1, source_ref=source_ref
            ),
            source_ref=source_ref,
        ),
    )