Index: Objects/longobject.c =================================================================== --- Objects/longobject.c (revision 74315) +++ Objects/longobject.c (working copy) @@ -4070,6 +4070,200 @@ } #endif + +PyDoc_STRVAR(long_as_bytes_doc, +"int.as_bytes(fixed_length=None, little_endian=False, signed=True) -> bytes\n\ +\n\ +Return an array of bytes representing an integer.\n\ +\n\ +If the fixed_length argument is not None, the integer is represented using \n\ +fixed_length bytes. An OverflowError is raised if the integer is not \n\ +representable using the given fixed number of bytes. If fixed_length is \n\ +None, an heuristic is used to determine the minimum number of bytes needed \n\ +to represent the given integer. In that case, array of bytes returned will \n\ +be at least one byte long.\n\ +\n\ +The little_endian argument determines the byte-order used to represent the \n\ +integer. If little_endian is False, the most significant byte is at the \n\ +beginning of the byte array. Otherwise, the most significant byte is at \n\ +the end of the byte array.\n\ +\n\ +The signed argument determines whether two's complement is used to \n\ +represent the integer. If signed is False and a negative integer is \n\ +given, an OverflowError is raised."); + +static PyObject * +long_as_bytes(PyLongObject *v, PyObject *args, PyObject *kwds) +{ + PyObject *little_endian_obj = NULL; + PyObject *is_signed_obj = NULL; + PyObject *length_obj = Py_None; + size_t length = 0; + int little_endian = 0; + int is_signed = 1; + int sign; + PyObject *bytes; + char *kwlist[] = {"fixed_length", "little_endian", "signed", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOO:as_bytes", kwlist, + &length_obj, &little_endian_obj, + &is_signed_obj)) + return NULL; + + if (little_endian_obj && PyObject_IsTrue(little_endian_obj)) + little_endian = 1; + if (is_signed_obj && !PyObject_IsTrue(is_signed_obj)) + is_signed = 0; + + if (length_obj == Py_None) { + size_t nbits = _PyLong_NumBits((PyObject *)v); + if (nbits == (size_t)-1 && PyErr_Occurred()) + return NULL; + /* How many bytes do we need to represent a signed long? + * There are nbits >> 3 full bytes of data, and nbits & 7 + * leftover bits. If there are any leftover bits, then we + * clearly need another byte. What's not so obvious is that + * we *probably* need another byte even if there aren't any + * leftovers: the most-significant bit of the most-significant + * byte acts like a sign bit, and it's usually got a sense + * opposite of the one we need. The exception is longs of the + * form -(2**(8*j-1)) for j > 0. Such a long is its own + * 256's-complement, so has the right sign bit even without + * the extra byte. That's a pain to check for in advance, + * though, so we always grab an extra byte at the start, and + * cut it back later if possible. + */ + if (is_signed || nbits & 7) + length = (nbits >> 3) + 1; + else { + /* The use of the MAX() macro makes sure we represent + * unsigned zero as one null byte and not as an empty + * byte array. + */ + length = MAX((nbits >> 3), 1); + } + } + else if (length_obj && PyLong_Check(length_obj)) { + /* The size of the byte array is set by the user. */ + length = PyLong_AsSize_t(length_obj); + if (length == (size_t)-1 && PyErr_Occurred()) + return NULL; + } + else { + PyErr_SetString(PyExc_TypeError, "length must be an int"); + return NULL; + } + + bytes = PyBytes_FromStringAndSize(NULL, length); + if (!bytes) + return NULL; + + if (_PyLong_AsByteArray(v, (unsigned char *)PyBytes_AS_STRING(bytes), + length, little_endian, is_signed) < 0) { + Py_DECREF(bytes); + return NULL; + } + + /* If the long is negative, there may be an extra byte. This + * is the case when the MSB consists of redundant sign bits. + */ + sign = _PyLong_Sign((PyObject *)v); + if (length_obj == Py_None && sign < 0 && length > 1) { + unsigned char *data = (unsigned char *)PyBytes_AS_STRING(bytes); + if (!little_endian && + data[0] == 0xff && + (data[1] & 0x80) != 0) { + /* Strip the leading byte. */ + memmove(data, data+1, length - 1); + if (_PyBytes_Resize(&bytes, length - 1) < 0) + return NULL; + } + if (little_endian && + data[length - 1] == 0xff && + (data[length - 2] & 0x80) != 0) { + /* Strip the trailing byte. */ + if (_PyBytes_Resize(&bytes, length - 1) < 0) + return NULL; + } + } + + return bytes; +} + +PyDoc_STRVAR(long_frombytes_doc, +"int.frombytes(bytes, little_endian=False, signed=True) -> int\n\ +\n\ +Return the integer represented by the given array of bytes.\n\ +\n\ +The bytes argument must either support the buffer protocol or be an\n\ +iterable object producing bytes. Builtin objects that support the buffer\n\ +protocol include bytes and bytearray.\n\ +\n\ +The little_endian argument indicates the byte-order used to represent the \n\ +integer. If little_endian is False, the most significant byte is at the \n\ +beginning of the byte array. Otherwise, the most significant byte is at \n\ +the end of the byte array.\n\ +\n\ +The signed argument indicates whether two's complement is used to \n\ +represent the integer."); + +static PyObject * +long_frombytes(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *little_endian_obj = NULL; + PyObject *is_signed_obj = NULL; + int little_endian = 0; + int is_signed = 1; + PyObject *obj; + PyObject *bytes; + PyObject *long_obj; + char *kwlist[] = {"bytes", "little_endian", "signed", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO:frombytes", kwlist, + &obj, &little_endian_obj, + &is_signed_obj)) + return NULL; + + if (little_endian_obj && PyObject_IsTrue(little_endian_obj)) + little_endian = 1; + if (is_signed_obj && !PyObject_IsTrue(is_signed_obj)) + is_signed = 0; + + bytes = PyObject_Bytes(obj); + if (!bytes) + return NULL; + + long_obj = _PyLong_FromByteArray( + (unsigned char *)PyBytes_AS_STRING(bytes), Py_SIZE(bytes), + little_endian, is_signed); + Py_DECREF(bytes); + + /* If frombytes() was used on subclass, allocate new subclass + * instance, initialize it with decoded long value and return it. + */ + if (type != &PyLong_Type && PyType_IsSubtype(type, &PyLong_Type)) { + PyLongObject *newobj; + int i; + Py_ssize_t n = ABS(Py_SIZE(long_obj)); + + newobj = (PyLongObject *)type->tp_alloc(type, n); + if (newobj == NULL) { + Py_DECREF(long_obj); + return NULL; + } + assert(PyLong_Check(newobj)); + Py_SIZE(newobj) = Py_SIZE(long_obj); + for (i = 0; i < n; i++) { + newobj->ob_digit[i] = + ((PyLongObject *)long_obj)->ob_digit[i]; + } + Py_DECREF(long_obj); + return (PyObject *)newobj; + } + + return long_obj; +} + static PyMethodDef long_methods[] = { {"conjugate", (PyCFunction)long_long, METH_NOARGS, "Returns self, the complex conjugate of any int."}, @@ -4079,6 +4273,10 @@ {"is_finite", (PyCFunction)long_is_finite, METH_NOARGS, "Returns always True."}, #endif + {"as_bytes", (PyCFunction)long_as_bytes, + METH_VARARGS|METH_KEYWORDS, long_as_bytes_doc}, + {"frombytes", (PyCFunction)long_frombytes, + METH_VARARGS|METH_KEYWORDS|METH_CLASS, long_frombytes_doc}, {"__trunc__", (PyCFunction)long_long, METH_NOARGS, "Truncating an Integral returns itself."}, {"__floor__", (PyCFunction)long_long, METH_NOARGS, Index: Doc/library/stdtypes.rst =================================================================== --- Doc/library/stdtypes.rst (revision 74315) +++ Doc/library/stdtypes.rst (working copy) @@ -457,7 +457,72 @@ .. versionadded:: 3.1 + .. method:: int.as_bytes([fixed_length[, little_endian[, signed]]]) + Return an array of bytes representing an integer. + + >>> (1024).as_bytes() + b'\x04\x00' + >>> (1024).as_bytes(fixed_length=10) + b'\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00' + >>> (-1024).as_bytes(fixed_length=10) + b'\xff\xff\xff\xff\xff\xff\xff\xff\xfc\x00' + >>> (-1024).as_bytes(little_endian=True) + b'\x00\xfc' + >>> ((2**16)-1).as_bytes(fixed_length=2, signed=False) + b'\xff\xff' + + If the *fixed_length* argument is not specified or ``None``, the integer + is represented using *fixed_length* bytes. An :exc:`OverflowError` is + raised if the integer is not representable using the given fixed number of + bytes. If *fixed_length* is ``None``, an heuristic is used to determine + the minimum number of bytes needed to represent the given integer. In + that case, array of bytes returned will be at least one byte long. + + The *little_endian* argument determines the byte-order used to represent + the integer. If *little_endian* is ``False``, the most significant byte is + at the beginning of the byte array. Otherwise, the most significant byte + is at the end of the byte array. The default value for *little_endian* is + ``False``. + + The *signed* argument determines whether two's complement is used to + represent the integer. If *signed* is ``False`` and a negative integer is + given, an :exc:`OverflowError` is raised. The default value for *signed* + is ``True``. + + .. versionadded:: 3.2 + + .. classmethod:: int.frombytes(bytes[, little_endian[, signed]]) + + Return the integer represented by the given array of bytes. + + >>> int.frombytes(b'\x00\x10') + 16 + >>> int.frombytes(b'\x00\x10', little_endian=True) + 4096 + >>> int.frombytes(b'\xfc\x00') + -1024 + >>> int.frombytes(b'\xfc\x00', signed=False) + 64512 + >>> int.frombytes([255, 0, 0]) + -65536 + + The argument *bytes* must either support the buffer protocol or be an + iterable producing bytes. Builtin objects that support the buffer + protocol include :class:`bytes` and :class:`bytearray`. + + The *little_endian* argument indicates the byte-order used to represent + the integer. If *little_endian* is ``False``, the most significant byte + is at the beginning of the byte array. Otherwise, the most significant + byte is at the end of the byte array. The default value for + *little_endian* is ``False``. + + The *signed* argument indicates whether two's complement is used to + represent the integer. + + .. versionadded:: 3.2 + + Additional Methods on Float --------------------------- Index: Lib/test/test_long.py =================================================================== --- Lib/test/test_long.py (revision 74315) +++ Lib/test/test_long.py (working copy) @@ -4,6 +4,7 @@ import random import math +import array # Used for lazy formatting of failure messages class Frm(object): @@ -1058,8 +1059,210 @@ for e in bad_exponents: self.assertRaises(TypeError, round, 3, e) + def test_as_bytes(self): + # Convert integers to signed big-endian byte arrays. + self.assertEqual((0).as_bytes(), b'\x00') + self.assertEqual((1).as_bytes(), b'\x01') + self.assertEqual((-1).as_bytes(), b'\xff') + self.assertEqual((-127).as_bytes(), b'\x81') + self.assertEqual((-128).as_bytes(), b'\x80') + self.assertEqual((-129).as_bytes(), b'\xff\x7f') + self.assertEqual((127).as_bytes(), b'\x7f') + self.assertEqual((129).as_bytes(), b'\x00\x81') + self.assertEqual((-255).as_bytes(), b'\xff\x01') + self.assertEqual((-256).as_bytes(), b'\xff\x00') + self.assertEqual((255).as_bytes(), b'\x00\xff') + self.assertEqual((256).as_bytes(), b'\x01\x00') + self.assertEqual((32767).as_bytes(), b'\x7f\xff') + self.assertEqual((-32768).as_bytes(), b'\x80\x00') + self.assertEqual((65535).as_bytes(), b'\x00\xff\xff') + self.assertEqual((-65536).as_bytes(), b'\xff\x00\x00') + self.assertEqual((-8388608).as_bytes(), b'\x80\x00\x00') + # Convert integers to signed little-endian byte arrays. + self.assertEqual((0).as_bytes(little_endian=True), b'\x00') + self.assertEqual((1).as_bytes(little_endian=True), b'\x01') + self.assertEqual((-1).as_bytes(little_endian=True), b'\xff') + self.assertEqual((-127).as_bytes(little_endian=True), b'\x81') + self.assertEqual((-128).as_bytes(little_endian=True), b'\x80') + self.assertEqual((-129).as_bytes(little_endian=True), b'\x7f\xff') + self.assertEqual((127).as_bytes(little_endian=True), b'\x7f') + self.assertEqual((129).as_bytes(little_endian=True), b'\x81\x00') + self.assertEqual((-255).as_bytes(little_endian=True), b'\x01\xff') + self.assertEqual((-256).as_bytes(little_endian=True), b'\x00\xff') + self.assertEqual((255).as_bytes(little_endian=True), b'\xff\x00') + self.assertEqual((256).as_bytes(little_endian=True), b'\x00\x01') + self.assertEqual((32767).as_bytes(little_endian=True), b'\xff\x7f') + self.assertEqual((-32768).as_bytes(little_endian=True), b'\x00\x80') + self.assertEqual( + (65535).as_bytes(little_endian=True), b'\xff\xff\x00') + self.assertEqual( + (-65536).as_bytes(little_endian=True), b'\x00\x00\xff') + self.assertEqual( + (-8388608).as_bytes(little_endian=True), b'\x00\x00\x80') + # Convert integers to unsigned big-endian byte arrays. + self.assertEqual((0).as_bytes(signed=False), b'\x00') + self.assertEqual((1).as_bytes(signed=False), b'\x01') + self.assertEqual((127).as_bytes(signed=False), b'\x7f') + self.assertEqual((128).as_bytes(signed=False), b'\x80') + self.assertEqual((255).as_bytes(signed=False), b'\xff') + self.assertEqual((256).as_bytes(signed=False), b'\x01\x00') + self.assertEqual((32767).as_bytes(signed=False), b'\x7f\xff') + self.assertEqual((32768).as_bytes(signed=False), b'\x80\x00') + self.assertEqual((65535).as_bytes(signed=False), b'\xff\xff') + self.assertEqual((65536).as_bytes(signed=False), b'\x01\x00\x00') + self.assertRaises(OverflowError, (-1).as_bytes, signed=False) + + # Convert integers to unsigned little-endian byte arrays. + self.assertEqual( + (0).as_bytes(signed=False, little_endian=True), b'\x00') + self.assertEqual( + (1).as_bytes(signed=False, little_endian=True), b'\x01') + self.assertEqual( + (127).as_bytes(signed=False, little_endian=True), b'\x7f') + self.assertEqual( + (128).as_bytes(signed=False, little_endian=True), b'\x80') + self.assertEqual( + (255).as_bytes(signed=False, little_endian=True), b'\xff') + self.assertEqual( + (256).as_bytes(signed=False, little_endian=True), b'\x00\x01') + self.assertEqual( + (32767).as_bytes(signed=False, little_endian=True), b'\xff\x7f') + self.assertEqual( + (32768).as_bytes(signed=False, little_endian=True), b'\x00\x80') + self.assertEqual( + (65535).as_bytes(signed=False, little_endian=True), b'\xff\xff') + self.assertEqual( + (65536).as_bytes(signed=False, little_endian=True), b'\x00\x00\x01') + self.assertRaises(OverflowError, + (-1).as_bytes, signed=False, little_endian=True) + + # Convert integers to fixed-length byte arrays. + self.assertEqual((0).as_bytes(0), b'') + self.assertEqual((1).as_bytes(5), b'\x00\x00\x00\x00\x01') + self.assertEqual((0).as_bytes(5), b'\x00\x00\x00\x00\x00') + self.assertEqual((-1).as_bytes(5), b'\xff\xff\xff\xff\xff') + self.assertRaises(OverflowError, (1).as_bytes, 0) + + def test_from_bytes(self): + # Convert signed big-endian byte arrays to integers. + self.assertEqual(int.frombytes(b''), 0) + self.assertEqual(int.frombytes(b'\x00'), 0) + self.assertEqual(int.frombytes(b'\x00\x00'), 0) + self.assertEqual(int.frombytes(b'\x01'), 1) + self.assertEqual(int.frombytes(b'\x00\x01'), 1) + self.assertEqual(int.frombytes(b'\xff'), -1) + self.assertEqual(int.frombytes(b'\xff\xff'), -1) + self.assertEqual(int.frombytes(b'\x81'), -127) + self.assertEqual(int.frombytes(b'\x80'), -128) + self.assertEqual(int.frombytes(b'\xff\x7f'), -129) + self.assertEqual(int.frombytes(b'\x7f'), 127) + self.assertEqual(int.frombytes(b'\x00\x81'), 129) + self.assertEqual(int.frombytes(b'\xff\x01'), -255) + self.assertEqual(int.frombytes(b'\xff\x00'), -256) + self.assertEqual(int.frombytes(b'\x00\xff'), 255) + self.assertEqual(int.frombytes(b'\x01\x00'), 256) + self.assertEqual(int.frombytes(b'\x7f\xff'), 32767) + self.assertEqual(int.frombytes(b'\x80\x00'), -32768) + self.assertEqual(int.frombytes(b'\x00\xff\xff'), 65535) + self.assertEqual(int.frombytes(b'\xff\x00\x00'), -65536) + self.assertEqual(int.frombytes(b'\x80\x00\x00'), -8388608) + + # Convert signed little-endian byte arrays to integers. + self.assertEqual(int.frombytes(b''), 0) + self.assertEqual(int.frombytes(b'\x00', little_endian=True), 0) + self.assertEqual(int.frombytes(b'\x00\x00', little_endian=True), 0) + self.assertEqual(int.frombytes(b'\x01', little_endian=True), 1) + self.assertEqual(int.frombytes(b'\x00\x01', little_endian=True), 256) + self.assertEqual(int.frombytes(b'\xff', little_endian=True), -1) + self.assertEqual(int.frombytes(b'\xff\xff', little_endian=True), -1) + self.assertEqual(int.frombytes(b'\x81', little_endian=True), -127) + self.assertEqual(int.frombytes(b'\x80', little_endian=True), -128) + self.assertEqual(int.frombytes(b'\x7f\xff', little_endian=True), -129) + self.assertEqual(int.frombytes(b'\x7f', little_endian=True), 127) + self.assertEqual(int.frombytes(b'\x81\x00', little_endian=True), 129) + self.assertEqual(int.frombytes(b'\x01\xff', little_endian=True), -255) + self.assertEqual(int.frombytes(b'\x00\xff', little_endian=True), -256) + self.assertEqual(int.frombytes(b'\xff\x00', little_endian=True), 255) + self.assertEqual(int.frombytes(b'\x00\x01', little_endian=True), 256) + self.assertEqual(int.frombytes(b'\xff\x7f', little_endian=True), 32767) + self.assertEqual(int.frombytes(b'\x00\x80', little_endian=True), -32768) + self.assertEqual(int.frombytes( + b'\xff\xff\x00', little_endian=True), 65535) + self.assertEqual(int.frombytes( + b'\x00\x00\xff', little_endian=True), -65536) + self.assertEqual(int.frombytes( + b'\x00\x00\x80', little_endian=True), -8388608) + + # Convert unsigned big-endian byte arrays to integers. + self.assertEqual(int.frombytes(b'', signed=False), 0) + self.assertEqual(int.frombytes(b'\x00', signed=False), 0) + self.assertEqual(int.frombytes(b'\x01', signed=False), 1) + self.assertEqual(int.frombytes(b'\x7f', signed=False), 127) + self.assertEqual(int.frombytes(b'\x80', signed=False), 128) + self.assertEqual(int.frombytes(b'\xff', signed=False), 255) + self.assertEqual(int.frombytes(b'\x01\x00', signed=False), 256) + self.assertEqual(int.frombytes(b'\x7f\xff', signed=False), 32767) + self.assertEqual(int.frombytes(b'\x80\x00', signed=False), 32768) + self.assertEqual(int.frombytes(b'\xff\xff', signed=False), 65535) + self.assertEqual(int.frombytes(b'\x01\x00\x00', signed=False), 65536) + + # Convert integers to unsigned little-endian byte arrays. + self.assertEqual(int.frombytes( + b'', signed=False, little_endian=True), 0) + self.assertEqual(int.frombytes( + b'\x00', signed=False, little_endian=True), 0) + self.assertEqual(int.frombytes( + b'\x01', signed=False, little_endian=True), 1) + self.assertEqual(int.frombytes( + b'\x7f', signed=False, little_endian=True), 127) + self.assertEqual(int.frombytes( + b'\x80', signed=False, little_endian=True), 128) + self.assertEqual(int.frombytes( + b'\xff', signed=False, little_endian=True), 255) + self.assertEqual(int.frombytes( + b'\x00\x01', signed=False, little_endian=True), 256) + self.assertEqual(int.frombytes( + b'\xff\x7f', signed=False, little_endian=True), 32767) + self.assertEqual(int.frombytes( + b'\x00\x80', signed=False, little_endian=True), 32768) + self.assertEqual(int.frombytes( + b'\xff\xff', signed=False, little_endian=True), 65535) + self.assertEqual(int.frombytes( + b'\x00\x00\x01', signed=False, little_endian=True), 65536) + + class myint(int): + pass + + self.assertTrue(type(myint.frombytes(b'\x00')) is myint) + self.assertEqual(myint.frombytes(b'\x01'), 1) + self.assertTrue( + type(myint.frombytes(b'\x00', signed=False)) is myint) + self.assertEqual(myint.frombytes(b'\x01', signed=False), 1) + self.assertTrue( + type(myint.frombytes(b'\x00', little_endian=True)) is myint) + self.assertEqual(myint.frombytes(b'\x01', little_endian=True), 1) + self.assertTrue(type(myint.frombytes( + b'\x00', signed=False, little_endian=True)) is myint) + self.assertEqual(myint.frombytes( + b'\x01', signed=False, little_endian=True), 1) + + self.assertEqual(int.frombytes([255, 0, 0]), -65536) + self.assertEqual(int.frombytes((255, 0, 0)), -65536) + self.assertEqual(int.frombytes(bytearray(b'\xff\x00\x00')), -65536) + self.assertEqual(int.frombytes(bytearray(b'\xff\x00\x00')), -65536) + self.assertEqual(int.frombytes(array.array('B', b'\xff\x00\x00')), -65536) + self.assertEqual(int.frombytes(memoryview(b'\xff\x00\x00')), -65536) + self.aserrtRaises(ValueError, int.frombytes, [256]) + self.assertRaises(TypeError, int.frombytes, "") + self.assertRaises(TypeError, int.frombytes, "\x00") + self.assertRaises(TypeError, int.frombytes, 0) + self.assertRaises(TypeError, myint.frombytes, "") + self.assertRaises(TypeError, myint.frombytes, "\x00") + self.assertRaises(TypeError, myint.frombytes, 0) + + def test_main(): support.run_unittest(LongTest) Index: Lib/pickle.py =================================================================== --- Lib/pickle.py (revision 74315) +++ Lib/pickle.py (working copy) @@ -1272,48 +1272,8 @@ if x == 0: return b'' - if x > 0: - ashex = hex(x) - assert ashex.startswith("0x") - njunkchars = 2 + ashex.endswith('L') - nibbles = len(ashex) - njunkchars - if nibbles & 1: - # need an even # of nibbles for unhexlify - ashex = "0x0" + ashex[2:] - elif int(ashex[2], 16) >= 8: - # "looks negative", so need a byte of sign bits - ashex = "0x00" + ashex[2:] - else: - # Build the 256's-complement: (1L << nbytes) + x. The trick is - # to find the number of bytes in linear time (although that should - # really be a constant-time task). - ashex = hex(-x) - assert ashex.startswith("0x") - njunkchars = 2 + ashex.endswith('L') - nibbles = len(ashex) - njunkchars - if nibbles & 1: - # Extend to a full byte. - nibbles += 1 - nbits = nibbles * 4 - x += 1 << nbits - assert x > 0 - ashex = hex(x) - njunkchars = 2 + ashex.endswith('L') - newnibbles = len(ashex) - njunkchars - if newnibbles < nibbles: - ashex = "0x" + "0" * (nibbles - newnibbles) + ashex[2:] - if int(ashex[2], 16) < 8: - # "looks positive", so need a byte of sign bits - ashex = "0xff" + ashex[2:] + return x.as_bytes(little_endian=True) - if ashex.endswith('L'): - ashex = ashex[2:-1] - else: - ashex = ashex[2:] - assert len(ashex) & 1 == 0, (x, ashex) - binary = _binascii.unhexlify(ashex) - return bytes(binary[::-1]) - def decode_long(data): r"""Decode a long from a two's complement little-endian binary string. @@ -1332,16 +1292,8 @@ >>> decode_long(b"\x7f") 127 """ + return int.frombytes(data, little_endian=True) - nbytes = len(data) - if nbytes == 0: - return 0 - ashex = _binascii.hexlify(data[::-1]) - n = int(ashex, 16) # quadratic time before Python 2.3; linear now - if data[-1] >= 0x80: - n -= 1 << (nbytes * 8) - return n - # Use the faster _pickle if possible try: from _pickle import *