예제 #1
0
def buildDictionaryUnpackingArgs(provider, keys, values, source_ref):
    result = []

    for key, value in zip(keys, values):
        # TODO: We could be a lot cleverer about the dictionaries for non-starred
        # arguments, but lets get this to work first.
        if key is None:
            result.append(buildNode(provider, value, source_ref), )
        elif type(key) is str:
            result.append(
                ExpressionMakeDict(pairs=(ExpressionKeyValuePair(
                    key=ExpressionConstantRef(constant=key,
                                              source_ref=source_ref),
                    value=buildNode(provider, value, source_ref),
                    source_ref=source_ref), ),
                                   source_ref=source_ref))
        else:
            result.append(
                ExpressionMakeDict(pairs=(ExpressionKeyValuePair(
                    key=buildNode(provider, key, source_ref),
                    value=buildNode(provider, value, source_ref),
                    source_ref=source_ref), ),
                                   source_ref=source_ref))

    return result
예제 #2
0
def makeDictCreationOrConstant(keys, values, source_ref):
    # Create dictionary node. Tries to avoid it for constant values that are not
    # mutable.

    assert len(keys) == len(values)
    for key, value in zip(keys, values):
        if not key.isExpressionConstantRef() or not key.isKnownToBeHashable():
            constant = False
            break

        if not value.isExpressionConstantRef():
            constant = False
            break
    else:
        constant = True

    # Note: This would happen in optimization instead, but lets just do it
    # immediately to save some time.
    if constant:
        # Unless told otherwise, create the dictionary in its full size, so
        # that no growing occurs and the constant becomes as similar as possible
        # before being marshaled.
        result = makeConstantRefNode(
            constant      = Constants.createConstantDict(
                keys   = [
                    key.getConstant()
                    for key in
                    keys
                ],
                values = [
                    value.getConstant()
                    for value in
                    values
                ]
            ),
            user_provided = True,
            source_ref    = source_ref
        )
    else:
        result = ExpressionMakeDict(
            pairs      = [
                ExpressionKeyValuePair(
                    key        = key,
                    value      = value,
                    source_ref = key.getSourceReference()
                )
                for key, value in
                zip(keys, values)
            ],
            source_ref = source_ref
        )

    if values:
        result.setCompatibleSourceReference(
            source_ref = values[-1].getCompatibleSourceReference()
        )

    return result
예제 #3
0
def makeDictCreationOrConstant(keys, values, source_ref):
    # Create dictionary node. Tries to avoid it for constant values that are not
    # mutable.

    assert len(keys) == len(values)
    for key, value in zip(keys, values):
        if not key.isExpressionConstantRef() or not key.isKnownToBeHashable():
            constant = False
            break

        if not value.isExpressionConstantRef():
            constant = False
            break
    else:
        constant = True

    # Note: This would happen in optimization instead, but lets just do it
    # immediately to save some time.
    if constant:
        # Unless told otherwise, create the dictionary in its full size, so
        # that no growing occurs and the constant becomes as similar as possible
        # before being marshaled.
        result = makeConstantRefNode(
            constant      = Constants.createConstantDict(
                keys   = [
                    key.getConstant()
                    for key in
                    keys
                ],
                values = [
                    value.getConstant()
                    for value in
                    values
                ]
            ),
            user_provided = True,
            source_ref    = source_ref
        )
    else:
        result = ExpressionMakeDict(
            pairs      = [
                ExpressionKeyValuePair(
                    key        = key,
                    value      = value,
                    source_ref = key.getSourceReference()
                )
                for key, value in
                zip(keys, values)
            ],
            source_ref = source_ref
        )

    if values:
        result.setCompatibleSourceReference(
            source_ref = values[-1].getCompatibleSourceReference()
        )

    return result
예제 #4
0
    def computeExpression(self, constraint_collection):
        pos_arg = self.getPositionalArgument()
        pairs = self.getNamedArgumentPairs()

        if pos_arg is None:
            new_node = ExpressionMakeDict(pairs=self.getNamedArgumentPairs(),
                                          source_ref=self.source_ref)

            # This cannot raise anymore than its arguments, as the keys will
            # be known as hashable, due to being Python parameters before.

            return (
                new_node, "new_expression",
                "Replace 'dict' built-in call dictionary creation from arguments."
            )

        pos_iteration_length = pos_arg.getIterationLength()

        if pos_iteration_length == 0:
            new_node = ExpressionMakeDict(pairs=self.getNamedArgumentPairs(),
                                          source_ref=self.source_ref)

            # Maintain potential side effects from the positional arguments.
            new_node = wrapExpressionWithNodeSideEffects(
                old_node=ExpressionBuiltinIter1(value=pos_arg,
                                                source_ref=self.source_ref),
                new_node=new_node)

            # Just in case, the iteration may do that.
            if pos_arg.mayRaiseExceptionIter(BaseException):
                constraint_collection.onExceptionRaiseExit(BaseException)

            return (
                new_node, "new_expression",
                "Replace 'dict' built-in call dictionary creation from arguments."
            )

        if pos_iteration_length is not None and \
           pos_iteration_length + len(pairs) < 256 and \
           self.hasOnlyConstantArguments():
            if pos_arg is not None:
                pos_args = (pos_arg, )
            else:
                pos_args = None

            return constraint_collection.getCompileTimeComputationResult(
                node=self,
                computation=lambda: builtin_dict_spec.simulateCall(
                    (pos_args, self.getNamedArgumentPairs())),
                description="Replace 'dict' call with constant arguments.")
        else:
            constraint_collection.onExceptionRaiseExit(BaseException)

            return self, None, None
예제 #5
0
def buildDictionaryUnpacking(provider, node, source_ref):
    helper_args = []

    for key, value in zip(node.keys, node.values):

        # TODO: We could be a lot cleverer about the dictionaries for non-starred
        # arguments, but lets get this to work first.
        if key is None:
            helper_args.append(buildNode(provider, value, source_ref), )
        else:
            helper_args.append(
                ExpressionMakeDict(
                    pairs=(ExpressionKeyValuePair(
                        key=buildNode(provider, key, source_ref),
                        value=buildNode(provider, value, source_ref),
                        source_ref=source_ref), ),
                    source_ref=source_ref,
                    lazy_order=False,
                ))

    result = ExpressionFunctionCall(
        function=ExpressionFunctionCreation(function_ref=ExpressionFunctionRef(
            function_body=getDictUnpackingHelper(), source_ref=source_ref),
                                            defaults=(),
                                            kw_defaults=None,
                                            annotations=None,
                                            source_ref=source_ref),
        values=(ExpressionMakeTuple(helper_args, source_ref), ),
        source_ref=source_ref,
    )

    result.setCompatibleSourceReference(
        helper_args[-1].getCompatibleSourceReference())

    return result
예제 #6
0
    def computeExpression(self, constraint_collection):
        pos_arg = self.getPositionalArgument()

        if self.hasOnlyConstantArguments():
            if pos_arg is not None:
                pos_args = (pos_arg, )
            elif python_version >= 340:
                # Doing this here, because calling dict built-in apparently
                # mutates existing dictionaries in Python 3.4
                result = {}

                for pair in reversed(self.getNamedArgumentPairs()):
                    arg_name = pair.getKey().getCompileTimeConstant()
                    arg_value = pair.getValue().getCompileTimeConstant()

                    result[arg_name] = arg_value

                new_node = makeConstantReplacementNode(constant=result,
                                                       node=self)

                return new_node, "new_expression", "Replace 'dict' built-in call with constant arguments."
            else:
                pos_args = None

            return constraint_collection.getCompileTimeComputationResult(
                node=self,
                computation=lambda: builtin_dict_spec.simulateCall(
                    (pos_args, self.getNamedArgumentPairs())),
                description="Replace 'dict' call with constant arguments.")
        elif pos_arg is None:
            new_node = ExpressionMakeDict(pairs=self.getNamedArgumentPairs(),
                                          lazy_order=False,
                                          source_ref=self.source_ref)

            # This cannot raise anymore than its arguments, as the keys will
            # be known as hashable, due to being Python parameters before.

            return (
                new_node, "new_expression",
                "Replace 'dict' built-in call dictionary creation from arguments."
            )
        elif pos_arg.getIterationLength() == 0:
            new_node = ExpressionMakeDict(pairs=self.getNamedArgumentPairs(),
                                          lazy_order=False,
                                          source_ref=self.source_ref)

            # Maintain potential side effects from the positional arguments.
            new_node = wrapExpressionWithNodeSideEffects(
                old_node=ExpressionBuiltinIter1(value=pos_arg,
                                                source_ref=self.source_ref),
                new_node=new_node)

            # Just in case, the iteration may do that.
            if pos_arg.mayRaiseExceptionIter(BaseException):
                constraint_collection.onExceptionRaiseExit(BaseException)

            return (
                new_node, "new_expression",
                "Replace 'dict' built-in call dictionary creation from arguments."
            )
        else:
            constraint_collection.onExceptionRaiseExit(BaseException)

            return self, None, None