def buildParameterSpec(name, node, source_ref):
    kind = getKind(node)

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

    def extractArg(arg):
        if type(arg) is str or arg is None:
            return arg
        elif getKind(arg) == "Name":
            return arg.id
        elif getKind(arg) == "arg":
            return arg.arg
        elif getKind(arg) == "Tuple":
            return tuple(extractArg(arg) for arg in arg.elts)
        else:
            assert False, getKind(arg)

    result = ParameterSpec(
        name=name,
        normal_args=[extractArg(arg) for arg in node.args.args],
        kw_only_args=[extractArg(arg) for arg in node.args.kwonlyargs]
        if Utils.python_version >= 300 else [],
        list_star_arg=extractArg(node.args.vararg),
        dict_star_arg=extractArg(node.args.kwarg),
        default_count=len(node.args.defaults))

    message = result.checkValid()

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

    return result
def buildParameterSpec( name, node, source_ref ):
    kind = getKind( node )

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

    def extractArg( arg ):
        if getKind( arg ) == "Name":
            return arg.id
        elif getKind( arg ) == "arg":
            return arg.arg
        elif getKind( arg ) == "Tuple":
            return tuple( extractArg( arg ) for arg in arg.elts )
        else:
            assert False, getKind( arg )

    result = ParameterSpec(
        name           = name,
        normal_args    = [ extractArg( arg ) for arg in node.args.args ],
        kw_only_args   = [ extractArg( arg ) for arg in node.args.kwonlyargs ] if Utils.python_version >= 300 else [],
        list_star_arg  = node.args.vararg,
        dict_star_arg  = node.args.kwarg,
        default_count  = len( node.args.defaults )
    )

    message = result.checkValid()

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

    return result
Пример #3
0
    def __init__( self, name, arg_names, default_count, list_star_arg = None, dict_star_arg = None ):
        ParameterSpec.__init__(
            self,
            name           = name,
            normal_args    = arg_names,
            list_star_arg  = list_star_arg,
            dict_star_arg  = dict_star_arg,
            default_count  = default_count,
            kw_only_args   = ()
        )

        self.builtin = __builtins__[ name ]
Пример #4
0
    def __init__(self, name, arg_names, default_count, list_star_arg = None,
                  dict_star_arg = None):
        ParameterSpec.__init__(
            self,
            ps_name          = name,
            ps_normal_args   = arg_names,
            ps_list_star_arg = list_star_arg,
            ps_dict_star_arg = dict_star_arg,
            ps_default_count = default_count,
            ps_kw_only_args  = ()
        )

        self.builtin = __builtins__[name]
Пример #5
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
Пример #6
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
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)
Пример #8
0
def getDictUnpackingHelper():
    helper_name = "_unpack_dict"

    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, "dict")
    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),
        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=(ExpressionOperationBinary(
                        operator="Mod",
                        left=ExpressionConstantRef(
                            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),
    )

    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
Пример #9
0
    getKind,
    makeDictCreationOrConstant,
    makeSequenceCreationOrConstant,
    makeStatementsSequence,
    makeStatementsSequenceFromStatement,
    makeTryFinallyStatement,
    popIndicatorVariable,
    pushIndicatorVariable
)

# TODO: Once we start to modify these, we should make sure, the copy is not
# shared.
make_class_parameters = ParameterSpec(
    name          = "class",
    normal_args   = (),
    list_star_arg = None,
    dict_star_arg = None,
    default_count = 0,
    kw_only_args  = ()
)


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(
def getListUnpackingHelper():
    helper_name = "_unpack_list"

    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, "list")
    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=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=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
Пример #11
0
def _buildContractionNode(provider, node, name, emit_class, start_value,
                          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.

    # TODO: No function ought to be necessary.
    function_body = ExpressionFunctionBody(provider=provider,
                                           name=name,
                                           doc=None,
                                           parameters=ParameterSpec(
                                               ps_name=name,
                                               ps_normal_args=(".0", ),
                                               ps_list_star_arg=None,
                                               ps_dict_star_arg=None,
                                               ps_default_count=0,
                                               ps_kw_only_args=()),
                                           flags=set(),
                                           source_ref=source_ref)

    iter_tmp = function_body.getVariableForAssignment(variable_name=".0")
    assert iter_tmp.isParameterVariable()

    code_object = CodeObjectSpec(
        co_name=name,
        co_kind="Generator" if emit_class is ExpressionYield else "Function",
        co_varnames=function_body.getParameters().getParameterNames(),
        co_argcount=len(function_body.getParameters().getParameterNames()),
        co_kwonlyargcount=0,
        co_has_starlist=False,
        co_has_stardict=False,
    )

    if emit_class is ExpressionYield:
        code_body = ExpressionGeneratorObjectBody(provider=function_body,
                                                  name="<genexpr>",
                                                  flags=set(),
                                                  source_ref=source_ref)

        iter_tmp = code_body.getVariableForReference(variable_name=".0")
        assert iter_tmp.isLocalVariable()

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

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

    statements, release_statements = _buildContractionBodyNode(
        function_body=code_body,
        provider=provider,
        node=node,
        emit_class=emit_class,
        iter_tmp=iter_tmp,
        temp_scope=None,
        start_value=start_value,
        container_tmp=container_tmp,
        assign_provider=False,
        source_ref=source_ref,
    )

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

    statements = (makeTryFinallyStatement(
        provider=function_body,
        tried=statements,
        final=release_statements,
        source_ref=source_ref.atInternal()), )

    if emit_class is ExpressionYield:
        guard_mode = "generator"
    else:
        guard_mode = "full"

    code_body.setBody(
        makeStatementsSequenceFromStatement(statement=StatementsFrame(
            statements=mergeStatements(statements, False),
            guard_mode=guard_mode,
            code_object=code_object,
            source_ref=source_ref)))

    return 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=(ExpressionBuiltinIter1(
                                      value=buildNode(
                                          provider=provider,
                                          node=node.generators[0].iter,
                                          source_ref=source_ref),
                                      source_ref=source_ref), ),
                                  source_ref=source_ref)
                                        ExpressionFunctionBody,
                                        ExpressionFunctionCall,
                                        ExpressionFunctionRef)
from nuitka.nodes.LoopNodes import (StatementBreakLoop, StatementLoop)
from nuitka.nodes.ConditionalNodes import StatementConditional
from nuitka.nodes.BuiltinIteratorNodes import (ExpressionBuiltinNext1,
                                               ExpressionBuiltinIter1)
from nuitka.nodes.ContainerOperationNodes import (
    ExpressionListOperationAppend, ExpressionDictOperationSet,
    ExpressionSetOperationAdd)
from nuitka.nodes.ReturnNodes import StatementReturn
from nuitka.nodes.YieldNodes import ExpressionYield

make_contraction_parameters = ParameterSpec(name="contraction",
                                            normal_args=("__iterator", ),
                                            list_star_arg=None,
                                            dict_star_arg=None,
                                            default_count=0,
                                            kw_only_args=())

from .ReformulationTryExceptStatements import makeTryExceptSingleHandlerNode
from .ReformulationAssignmentStatements import buildAssignmentStatements
from .ReformulationBooleanExpressions import buildAndNode

from .Helpers import (makeStatementsSequenceFromStatement, mergeStatements,
                      buildNodeList, buildNode, getKind)


def buildListContractionNode(provider, node, source_ref):
    # List contractions are dealt with by general code.

    return _buildContractionNode(
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.

    # Note: The assign_provider is only to cover Python2 list contractions,
    # assigning one of the loop variables to the outside scope.
    if assign_provider:
        function_body = ExpressionOutlineBody(
            provider=provider,
            name=name,
            body=None,  # later
            source_ref=source_ref)

        iter_tmp = function_body.allocateTempVariable(temp_scope=None,
                                                      name=".0")
    else:
        function_body = ExpressionFunctionBody(provider=provider,
                                               name=name,
                                               doc=None,
                                               parameters=ParameterSpec(
                                                   name="contraction",
                                                   normal_args=(".0", ),
                                                   list_star_arg=None,
                                                   dict_star_arg=None,
                                                   default_count=0,
                                                   kw_only_args=()),
                                               is_class=False,
                                               source_ref=source_ref)

        iter_tmp = function_body.getVariableForAssignment(variable_name=".0")
        assert iter_tmp.isParameterVariable()

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

    statements, release_statements = _buildContractionBodyNode(
        function_body=function_body,
        assign_provider=assign_provider,
        provider=provider,
        node=node,
        emit_class=emit_class,
        iter_tmp=iter_tmp,
        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, source_ref=source_ref),
                            source_ref=source_ref))

    statements = (makeTryFinallyStatement(
        provider=function_body,
        tried=statements,
        final=release_statements,
        source_ref=source_ref.atInternal()), )

    function_body.setBody(
        makeStatementsSequenceFromStatement(statement=StatementsFrame(
            statements=mergeStatements(statements, False),
            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)))

    if not assign_provider:
        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)
    else:
        return function_body