Example #1
0
def makeDictCreationOrConstant(keys, values, lazy_order, 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():
            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 = ExpressionConstantRef(
            constant      = Constants.createConstantDict(
                lazy_order = not lazy_order,
                keys       = [
                    key.getConstant()
                    for key in
                    keys
                ],
                values     = [
                    value.getConstant()
                    for value in
                    values
                ]
            ),
            source_ref    = source_ref,
            user_provided = True
        )
    else:
        result = ExpressionMakeDict(
            pairs      = [
                ExpressionKeyValuePair(
                    key        = key,
                    value      = value,
                    source_ref = key.getSourceReference()
                )
                for key, value in
                zip(keys, values)
            ],
            lazy_order = lazy_order,
            source_ref = source_ref
        )

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

    return result
Example #2
0
    def computeExpression(self, constraint_collection):
        pairs = self.getPairs()

        for pair in pairs:
            key = pair.getKey()

            # TODO: Mutable key should cause an exception raise to be produced.
            if not key.isExpressionConstantRef() or not key.isKnownToBeHashable():
                return self, None, None

            value = pair.getValue()

            if not value.isExpressionConstantRef():
                return self, None, None

        constant_value = Constants.createConstantDict(
            keys   = [
                pair.getKey().getConstant()
                for pair in
                pairs
            ],
            values = [
                pair.getValue().getConstant()
                for pair in
                pairs
            ]
        )

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

        return new_node, "new_constant", """\
    def computeExpression(self, constraint_collection):
        # Children can tell all we need to know, pylint: disable=W0613
        pairs = self.getPairs()

        for count, pair in enumerate(pairs):
            if pair.willRaiseException(BaseException):
                from .NodeMakingHelpers import wrapExpressionWithSideEffects

                # Later elements have no side effects after the element that
                # raised the exception.
                result = wrapExpressionWithSideEffects(
                    side_effects = pairs[:count],
                    new_node     = pair,
                    old_node     = self
                )

                return result, "new_raise", "Dict creation raises exception"

        for pair in pairs:
            key = pair.getKey()

            # TODO: Mutable key should cause something problematic.
            if not key.isExpressionConstantRef() or key.isMutable():
                return self, None, None

            value = pair.getValue()

            if not value.isExpressionConstantRef():
                return self, None, None

        constant_value = Constants.createConstantDict(
            keys       = [
                pair.getKey().getConstant()
                for pair in
                pairs
            ],
            values     = [
                pair.getValue().getConstant()
                for pair in
                pairs
            ],
            lazy_order = self.lazy_order
        )

        from .NodeMakingHelpers import makeConstantReplacementNode

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

        return new_node, "new_constant", """\
Example #4
0
    def computeExpression(self, constraint_collection):
        pairs = self.getPairs()

        for count, pair in enumerate(pairs):
            if pair.willRaiseException(BaseException):
                # Later elements have no side effects after the element that
                # raised the exception.
                result = wrapExpressionWithSideEffects(
                    side_effects = pairs[:count],
                    new_node     = pair,
                    old_node     = self
                )

                return result, "new_raise", "Dict creation raises exception"

        for pair in pairs:
            key = pair.getKey()

            # TODO: Mutable key should cause an exception raise to be produced.
            if not key.isExpressionConstantRef() or not key.isKnownToBeHashable():
                return self, None, None

            value = pair.getValue()

            if not value.isExpressionConstantRef():
                return self, None, None

        constant_value = Constants.createConstantDict(
            keys       = [
                pair.getKey().getConstant()
                for pair in
                pairs
            ],
            values     = [
                pair.getValue().getConstant()
                for pair in
                pairs
            ],
            lazy_order = self.lazy_order
        )

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

        return new_node, "new_constant", """\
Example #5
0
    def computeExpression(self, constraint_collection):
        # Children can tell all we need to know, pylint: disable=W0613
        pairs = self.getPairs()

        for count, pair in enumerate(pairs):
            if pair.willRaiseException(BaseException):
                from .NodeMakingHelpers import wrapExpressionWithSideEffects

                result = wrapExpressionWithSideEffects(
                    side_effects=pairs[:count], new_node=pair, old_node=self)

                return result, "new_raise", "Dict creation raises exception"

        for pair in pairs:
            key = pair.getKey()

            # TODO: Mutable key should cause something problematic.
            if not key.isExpressionConstantRef() or key.isMutable():
                return self, None, None

            value = pair.getValue()

            if not value.isExpressionConstantRef():
                return self, None, None

        constant_value = Constants.createConstantDict(
            keys=[pair.getKey().getConstant() for pair in pairs],
            values=[pair.getValue().getConstant() for pair in pairs],
            lazy_order=self.lazy_order)

        from .NodeMakingHelpers import makeConstantReplacementNode

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

        return new_node, "new_constant", """\
Example #6
0
    def computeExpression(self, trace_collection):
        pairs = self.subnode_pairs

        is_constant = True

        for pair in pairs:
            key = pair.subnode_key

            if key.isKnownToBeHashable() is False:
                side_effects = []

                for pair2 in pairs:
                    side_effects.extend(pair2.extractSideEffects())

                    if pair2 is pair:
                        break

                result = makeRaiseExceptionExpressionFromTemplate(
                    exception_type="TypeError",
                    template="unhashable type: '%s'",
                    template_args=makeExpressionAttributeLookup(
                        expression=key.extractUnhashableNodeType(),
                        attribute_name="__name__",
                        source_ref=key.source_ref,
                    ),
                    source_ref=key.source_ref,
                )
                result = wrapExpressionWithSideEffects(
                    side_effects=side_effects, old_node=key, new_node=result
                )

                return (
                    result,
                    "new_raise",
                    "Dictionary key is known to not be hashable.",
                )

            if is_constant:
                if not key.isExpressionConstantRef():
                    is_constant = False
                else:
                    value = pair.subnode_value

                    if not value.isExpressionConstantRef():
                        is_constant = False

        if not is_constant:
            return self, None, None

        constant_value = Constants.createConstantDict(
            keys=[pair.subnode_key.getCompileTimeConstant() for pair in pairs],
            values=[pair.subnode_value.getCompileTimeConstant() for pair in pairs],
        )

        new_node = makeConstantReplacementNode(
            constant=constant_value, node=self, user_provided=True
        )

        return (
            new_node,
            "new_constant",
            """\
Created dictionary found to be constant.""",
        )
Example #7
0
    def computeExpression(self, trace_collection):
        pairs = self.getPairs()

        is_constant = True

        for pair in pairs:
            key = pair.getKey()

            if key.isKnownToBeHashable() is False:
                side_effects = []

                for pair2 in pairs:
                    side_effects.extend(pair2.extractSideEffects())

                    if pair2 is pair:
                        break

                result = makeRaiseExceptionExpressionFromTemplate(
                    exception_type="TypeError",
                    template="unhashable type: '%s'",
                    template_args=ExpressionAttributeLookup(
                        source=ExpressionBuiltinType1(
                            value=key.extractUnhashableNode(), source_ref=key.source_ref
                        ),
                        attribute_name="__name__",
                        source_ref=key.source_ref,
                    ),
                    source_ref=key.source_ref,
                )
                result = wrapExpressionWithSideEffects(
                    side_effects=side_effects, old_node=key, new_node=result
                )

                return (
                    result,
                    "new_raise",
                    "Dictionary key is known to not be hashable.",
                )

            if is_constant:
                if not key.isExpressionConstantRef():
                    is_constant = False
                else:
                    value = pair.getValue()

                    if not value.isExpressionConstantRef():
                        is_constant = False

        if not is_constant:
            return self, None, None

        constant_value = Constants.createConstantDict(
            keys=[pair.getKey().getConstant() for pair in pairs],
            values=[pair.getValue().getConstant() for pair in pairs],
        )

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

        return (
            new_node,
            "new_constant",
            """\
Created dictionary found to be constant.""",
        )