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
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
def getStreamValueByte(self): """Return byte value, encoding the anon built-in value.""" return to_byte(self.anon_values.index(self.anon_name))