예제 #1
0
    def getStreamValueByte(self):
        """Return byte value, encoding the special built-in value."""

        # Currently the only one.
        if self.value == "Ellipsis":
            return to_byte(0)
        elif self.value == "NotImplemented":
            return to_byte(1)
        else:
            assert False, self.value
예제 #2
0
def _writeConstantValue(output, constant_value):
    # Massively many details per value, pylint: disable=too-many-branches,too-many-statements

    constant_type = type(constant_value)

    if constant_type is tuple:
        # TODO: Optimize for size of tuple to be < 256 with dedicated value
        output.write(b"T" + struct.pack("i", len(constant_value)))

        for element in constant_value:
            _writeConstantValue(output, element)
    elif constant_type is list:
        # TODO: Optimize for size of tuple to be < 256 with dedicated value
        output.write(b"L" + struct.pack("i", len(constant_value)))

        for element in constant_value:
            _writeConstantValue(output, element)
    elif constant_type is dict:
        # TODO: Optimize for size of tuple to be < 256 with dedicated value
        output.write(b"D" + struct.pack("i", len(constant_value)))

        for key, value in constant_value.items():
            _writeConstantValue(output, key)
            _writeConstantValue(output, value)
    elif constant_type is set:
        # TODO: Optimize for size of tuple to be < 256 with dedicated value
        output.write(b"S" + struct.pack("i", len(constant_value)))

        for element in constant_value:
            _writeConstantValue(output, element)
    elif constant_type is frozenset:
        # TODO: Optimize for size of tuple to be < 256 with dedicated value
        output.write(b"P" + struct.pack("i", len(constant_value)))

        for element in constant_value:
            _writeConstantValue(output, element)

    elif constant_type is long:
        if min_signed_long <= constant_value <= max_signed_long:
            output.write(b"l" + struct.pack("l", constant_value))
        elif min_signed_longlong <= constant_value <= max_signed_longlong:
            output.write(b"q" + struct.pack("q", constant_value))
        else:
            output.write(b"g")

            if constant_value < 0:
                constant_value = abs(constant_value)
                output.write(b"-")
            else:
                output.write(b"+")

            parts = []

            mod_value = 2**(sizeof_clonglong * 8)
            while constant_value > 0:
                parts.append(constant_value % mod_value)
                constant_value >>= sizeof_clonglong * 8

            output.write(struct.pack("i", len(parts)))
            for part in reversed(parts):
                output.write(struct.pack("Q", part))

    elif constant_type is int:
        # This is Python2 then. TODO: Special case smaller values.
        output.write(b"i" + struct.pack("l", constant_value))
    elif constant_type is float:
        if constant_value == 0.0:
            if math.copysign(1, constant_value) == 1:
                output.write(b"Z" + to_byte(0))
            else:
                output.write(b"Z" + to_byte(1))
        elif math.isnan(constant_value):
            if math.copysign(1, constant_value) == 1:
                output.write(b"Z" + to_byte(2))
            else:
                output.write(b"Z" + to_byte(3))
        elif math.isinf(constant_value):
            if math.copysign(1, constant_value) == 1:
                output.write(b"Z" + to_byte(4))
            else:
                output.write(b"Z" + to_byte(5))
        else:
            output.write(b"f" + struct.pack("d", constant_value))
    elif constant_type is unicode:

        if str is not bytes:
            encoded = constant_value.encode("utf8", "surrogatepass")
        else:
            encoded = constant_value.encode("utf8")

        if len(encoded) == 1:
            output.write(b"w" + encoded)
        # Zero termination if possible.
        elif b"\0" in encoded:
            output.write(b"v" + struct.pack("i", len(encoded)))
            output.write(encoded)
        else:
            if str is not bytes and _isAttributeName(constant_value):
                indicator = b"a"
            else:
                indicator = b"u"

            output.write(indicator + encoded + b"\0")

    elif constant_type is bytes:
        if len(constant_value) == 1:
            output.write(b"d" + constant_value)
        # Zero termination if possible.
        elif b"\0" in constant_value:
            output.write(b"b" + struct.pack("i", len(constant_value)))
            output.write(constant_value)
        else:
            if str is bytes and _isAttributeName(constant_value):
                indicator = b"a"
            else:
                indicator = b"c"

            output.write(indicator + constant_value + b"\0")
    elif constant_type is slice:
        output.write(b":")
        _writeConstantValue(output, constant_value.start)
        _writeConstantValue(output, constant_value.stop)
        _writeConstantValue(output, constant_value.step)
    elif constant_type is range:
        output.write(b";")
        _writeConstantValue(output, constant_value.start)
        _writeConstantValue(output, constant_value.stop)
        _writeConstantValue(output, constant_value.step)
    elif constant_type is xrange:
        output.write(b";")
        range_args = [
            int(v) for v in str(constant_value)
            [7 if str is bytes else 6:-1].split(",")
        ]

        # Default start.
        if len(range_args) == 1:
            range_args.insert(0, 0)

        # Default step
        if len(range_args) < 3:
            range_args.append(1)

        output.write(struct.pack("iii", *range_args))
    elif constant_value is None:
        output.write(b"n")
    elif constant_value is True:
        output.write(b"t")
    elif constant_value is False:
        output.write(b"F")
    elif constant_type is complex:
        # Some float values do not transport well, use float streaming then.
        if (constant_value.real == 0 or constant_value.imag == 0
                or math.isnan(constant_value.real)
                or math.isnan(constant_value.imag)
                or math.isinf(constant_value.real)
                or math.isinf(constant_value.imag)):
            output.write(b"J")

            _writeConstantValue(output, constant_value.real)
            _writeConstantValue(output, constant_value.imag)
        else:
            output.write(b"j")
            output.write(
                struct.pack("dd", constant_value.real, constant_value.imag))

    elif constant_type is bytearray:
        output.write(b"B" + struct.pack("i", len(constant_value)))

        if python_version < 0x270:
            constant_value = constant_value.decode("latin1")
        output.write(constant_value)
    elif constant_type is BuiltinAnonValue:
        output.write(b"M")
        output.write(constant_value.getStreamValueByte())
    elif constant_type is BuiltinSpecialValue:
        output.write(b"Q")
        output.write(constant_value.getStreamValueByte())
    elif constant_type is BlobData:
        constant_value = constant_value.getData()
        output.write(b"X")
        output.write(struct.pack("i", len(constant_value)))
        output.write(constant_value)
    elif constant_value in builtin_named_values:
        output.write(b"O")
        output.write(builtin_named_values[constant_value].encode("utf8"))
        output.write(b"\0")
    elif constant_value in builtin_exception_values_list:
        output.write(b"E")
        output.write(constant_value.__name__.encode("utf8"))
        output.write(b"\0")
    else:
        assert False, constant_value
예제 #3
0
    def getStreamValueByte(self):
        """Return byte value, encoding the anon built-in value."""

        return to_byte(self.anon_values.index(self.anon_name))