| Index: third_party/google-endpoints/future/types/newint.py
|
| diff --git a/third_party/google-endpoints/future/types/newint.py b/third_party/google-endpoints/future/types/newint.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..705b8fa95bfc622d40cb882fe33925628237d7aa
|
| --- /dev/null
|
| +++ b/third_party/google-endpoints/future/types/newint.py
|
| @@ -0,0 +1,379 @@
|
| +"""
|
| +Backport of Python 3's int, based on Py2's long.
|
| +
|
| +They are very similar. The most notable difference is:
|
| +
|
| +- representation: trailing L in Python 2 removed in Python 3
|
| +"""
|
| +from __future__ import division
|
| +
|
| +import struct
|
| +import collections
|
| +
|
| +from future.types.newbytes import newbytes
|
| +from future.types.newobject import newobject
|
| +from future.utils import PY3, isint, istext, isbytes, with_metaclass, native
|
| +
|
| +
|
| +if PY3:
|
| + long = int
|
| +
|
| +
|
| +class BaseNewInt(type):
|
| + def __instancecheck__(cls, instance):
|
| + if cls == newint:
|
| + # Special case for Py2 short or long int
|
| + return isinstance(instance, (int, long))
|
| + else:
|
| + return issubclass(instance.__class__, cls)
|
| +
|
| +
|
| +class newint(with_metaclass(BaseNewInt, long)):
|
| + """
|
| + A backport of the Python 3 int object to Py2
|
| + """
|
| + def __new__(cls, x=0, base=10):
|
| + """
|
| + From the Py3 int docstring:
|
| +
|
| + | int(x=0) -> integer
|
| + | int(x, base=10) -> integer
|
| + |
|
| + | Convert a number or string to an integer, or return 0 if no
|
| + | arguments are given. If x is a number, return x.__int__(). For
|
| + | floating point numbers, this truncates towards zero.
|
| + |
|
| + | If x is not a number or if base is given, then x must be a string,
|
| + | bytes, or bytearray instance representing an integer literal in the
|
| + | given base. The literal can be preceded by '+' or '-' and be
|
| + | surrounded by whitespace. The base defaults to 10. Valid bases are
|
| + | 0 and 2-36. Base 0 means to interpret the base from the string as an
|
| + | integer literal.
|
| + | >>> int('0b100', base=0)
|
| + | 4
|
| +
|
| + """
|
| + try:
|
| + val = x.__int__()
|
| + except AttributeError:
|
| + val = x
|
| + else:
|
| + if not isint(val):
|
| + raise TypeError('__int__ returned non-int ({0})'.format(
|
| + type(val)))
|
| +
|
| + if base != 10:
|
| + # Explicit base
|
| + if not (istext(val) or isbytes(val) or isinstance(val, bytearray)):
|
| + raise TypeError(
|
| + "int() can't convert non-string with explicit base")
|
| + try:
|
| + return super(newint, cls).__new__(cls, val, base)
|
| + except TypeError:
|
| + return super(newint, cls).__new__(cls, newbytes(val), base)
|
| + # After here, base is 10
|
| + try:
|
| + return super(newint, cls).__new__(cls, val)
|
| + except TypeError:
|
| + # Py2 long doesn't handle bytearray input with an explicit base, so
|
| + # handle this here.
|
| + # Py3: int(bytearray(b'10'), 2) == 2
|
| + # Py2: int(bytearray(b'10'), 2) == 2 raises TypeError
|
| + # Py2: long(bytearray(b'10'), 2) == 2 raises TypeError
|
| + try:
|
| + return super(newint, cls).__new__(cls, newbytes(val))
|
| + except:
|
| + raise TypeError("newint argument must be a string or a number,"
|
| + "not '{0}'".format(type(val)))
|
| +
|
| + def __repr__(self):
|
| + """
|
| + Without the L suffix
|
| + """
|
| + value = super(newint, self).__repr__()
|
| + assert value[-1] == 'L'
|
| + return value[:-1]
|
| +
|
| + def __add__(self, other):
|
| + value = super(newint, self).__add__(other)
|
| + if value is NotImplemented:
|
| + return long(self) + other
|
| + return newint(value)
|
| +
|
| + def __radd__(self, other):
|
| + value = super(newint, self).__radd__(other)
|
| + if value is NotImplemented:
|
| + return other + long(self)
|
| + return newint(value)
|
| +
|
| + def __sub__(self, other):
|
| + value = super(newint, self).__sub__(other)
|
| + if value is NotImplemented:
|
| + return long(self) - other
|
| + return newint(value)
|
| +
|
| + def __rsub__(self, other):
|
| + value = super(newint, self).__rsub__(other)
|
| + if value is NotImplemented:
|
| + return other - long(self)
|
| + return newint(value)
|
| +
|
| + def __mul__(self, other):
|
| + value = super(newint, self).__mul__(other)
|
| + if isint(value):
|
| + return newint(value)
|
| + elif value is NotImplemented:
|
| + return long(self) * other
|
| + return value
|
| +
|
| + def __rmul__(self, other):
|
| + value = super(newint, self).__rmul__(other)
|
| + if isint(value):
|
| + return newint(value)
|
| + elif value is NotImplemented:
|
| + return other * long(self)
|
| + return value
|
| +
|
| + def __div__(self, other):
|
| + # We override this rather than e.g. relying on object.__div__ or
|
| + # long.__div__ because we want to wrap the value in a newint()
|
| + # call if other is another int
|
| + value = long(self) / other
|
| + if isinstance(other, (int, long)):
|
| + return newint(value)
|
| + else:
|
| + return value
|
| +
|
| + def __rdiv__(self, other):
|
| + value = other / long(self)
|
| + if isinstance(other, (int, long)):
|
| + return newint(value)
|
| + else:
|
| + return value
|
| +
|
| + def __idiv__(self, other):
|
| + # long has no __idiv__ method. Use __itruediv__ and cast back to
|
| + # newint:
|
| + value = self.__itruediv__(other)
|
| + if isinstance(other, (int, long)):
|
| + return newint(value)
|
| + else:
|
| + return value
|
| +
|
| + def __truediv__(self, other):
|
| + value = super(newint, self).__truediv__(other)
|
| + if value is NotImplemented:
|
| + value = long(self) / other
|
| + return value
|
| +
|
| + def __rtruediv__(self, other):
|
| + return super(newint, self).__rtruediv__(other)
|
| +
|
| + def __itruediv__(self, other):
|
| + # long has no __itruediv__ method
|
| + mylong = long(self)
|
| + mylong /= other
|
| + return mylong
|
| +
|
| + def __floordiv__(self, other):
|
| + return newint(super(newint, self).__floordiv__(other))
|
| +
|
| + def __rfloordiv__(self, other):
|
| + return newint(super(newint, self).__rfloordiv__(other))
|
| +
|
| + def __ifloordiv__(self, other):
|
| + # long has no __ifloordiv__ method
|
| + mylong = long(self)
|
| + mylong //= other
|
| + return newint(mylong)
|
| +
|
| + def __mod__(self, other):
|
| + value = super(newint, self).__mod__(other)
|
| + if value is NotImplemented:
|
| + return long(self) % other
|
| + return newint(value)
|
| +
|
| + def __rmod__(self, other):
|
| + value = super(newint, self).__rmod__(other)
|
| + if value is NotImplemented:
|
| + return other % long(self)
|
| + return newint(value)
|
| +
|
| + def __divmod__(self, other):
|
| + value = super(newint, self).__divmod__(other)
|
| + if value is NotImplemented:
|
| + mylong = long(self)
|
| + return (mylong // other, mylong % other)
|
| + return (newint(value[0]), newint(value[1]))
|
| +
|
| + def __rdivmod__(self, other):
|
| + value = super(newint, self).__rdivmod__(other)
|
| + if value is NotImplemented:
|
| + mylong = long(self)
|
| + return (other // mylong, other % mylong)
|
| + return (newint(value[0]), newint(value[1]))
|
| +
|
| + def __pow__(self, other):
|
| + value = super(newint, self).__pow__(other)
|
| + if value is NotImplemented:
|
| + return long(self) ** other
|
| + return newint(value)
|
| +
|
| + def __rpow__(self, other):
|
| + value = super(newint, self).__rpow__(other)
|
| + if value is NotImplemented:
|
| + return other ** long(self)
|
| + return newint(value)
|
| +
|
| + def __lshift__(self, other):
|
| + if not isint(other):
|
| + raise TypeError(
|
| + "unsupported operand type(s) for <<: '%s' and '%s'" %
|
| + (type(self).__name__, type(other).__name__))
|
| + return newint(super(newint, self).__lshift__(other))
|
| +
|
| + def __rshift__(self, other):
|
| + if not isint(other):
|
| + raise TypeError(
|
| + "unsupported operand type(s) for >>: '%s' and '%s'" %
|
| + (type(self).__name__, type(other).__name__))
|
| + return newint(super(newint, self).__rshift__(other))
|
| +
|
| + def __and__(self, other):
|
| + if not isint(other):
|
| + raise TypeError(
|
| + "unsupported operand type(s) for &: '%s' and '%s'" %
|
| + (type(self).__name__, type(other).__name__))
|
| + return newint(super(newint, self).__and__(other))
|
| +
|
| + def __or__(self, other):
|
| + if not isint(other):
|
| + raise TypeError(
|
| + "unsupported operand type(s) for |: '%s' and '%s'" %
|
| + (type(self).__name__, type(other).__name__))
|
| + return newint(super(newint, self).__or__(other))
|
| +
|
| + def __xor__(self, other):
|
| + if not isint(other):
|
| + raise TypeError(
|
| + "unsupported operand type(s) for ^: '%s' and '%s'" %
|
| + (type(self).__name__, type(other).__name__))
|
| + return newint(super(newint, self).__xor__(other))
|
| +
|
| + def __neg__(self):
|
| + return newint(super(newint, self).__neg__())
|
| +
|
| + def __pos__(self):
|
| + return newint(super(newint, self).__pos__())
|
| +
|
| + def __abs__(self):
|
| + return newint(super(newint, self).__abs__())
|
| +
|
| + def __invert__(self):
|
| + return newint(super(newint, self).__invert__())
|
| +
|
| + def __int__(self):
|
| + return self
|
| +
|
| + def __nonzero__(self):
|
| + return self.__bool__()
|
| +
|
| + def __bool__(self):
|
| + """
|
| + So subclasses can override this, Py3-style
|
| + """
|
| + return super(newint, self).__nonzero__()
|
| +
|
| + def __native__(self):
|
| + return long(self)
|
| +
|
| + def to_bytes(self, length, byteorder='big', signed=False):
|
| + """
|
| + Return an array of bytes representing an integer.
|
| +
|
| + The integer is represented using length bytes. An OverflowError is
|
| + raised if the integer is not representable with the given number of
|
| + bytes.
|
| +
|
| + The byteorder argument determines the byte order used to represent the
|
| + integer. If byteorder is 'big', the most significant byte is at the
|
| + beginning of the byte array. If byteorder is 'little', the most
|
| + significant byte is at the end of the byte array. To request the native
|
| + byte order of the host system, use `sys.byteorder' as the byte order value.
|
| +
|
| + The signed keyword-only argument determines whether two's complement is
|
| + used to represent the integer. If signed is False and a negative integer
|
| + is given, an OverflowError is raised.
|
| + """
|
| + if length < 0:
|
| + raise ValueError("length argument must be non-negative")
|
| + if length == 0 and self == 0:
|
| + return newbytes()
|
| + if signed and self < 0:
|
| + bits = length * 8
|
| + num = (2**bits) + self
|
| + if num <= 0:
|
| + raise OverflowError("int too smal to convert")
|
| + else:
|
| + if self < 0:
|
| + raise OverflowError("can't convert negative int to unsigned")
|
| + num = self
|
| + if byteorder not in ('little', 'big'):
|
| + raise ValueError("byteorder must be either 'little' or 'big'")
|
| + h = b'%x' % num
|
| + s = newbytes((b'0'*(len(h) % 2) + h).zfill(length*2).decode('hex'))
|
| + if signed:
|
| + high_set = s[0] & 0x80
|
| + if self > 0 and high_set:
|
| + raise OverflowError("int too big to convert")
|
| + if self < 0 and not high_set:
|
| + raise OverflowError("int too small to convert")
|
| + if len(s) > length:
|
| + raise OverflowError("int too big to convert")
|
| + return s if byteorder == 'big' else s[::-1]
|
| +
|
| + @classmethod
|
| + def from_bytes(cls, mybytes, byteorder='big', signed=False):
|
| + """
|
| + Return the integer represented by the given array of bytes.
|
| +
|
| + The mybytes argument must either support the buffer protocol or be an
|
| + iterable object producing bytes. Bytes and bytearray are examples of
|
| + built-in objects that support the buffer protocol.
|
| +
|
| + The byteorder argument determines the byte order used to represent the
|
| + integer. If byteorder is 'big', the most significant byte is at the
|
| + beginning of the byte array. If byteorder is 'little', the most
|
| + significant byte is at the end of the byte array. To request the native
|
| + byte order of the host system, use `sys.byteorder' as the byte order value.
|
| +
|
| + The signed keyword-only argument indicates whether two's complement is
|
| + used to represent the integer.
|
| + """
|
| + if byteorder not in ('little', 'big'):
|
| + raise ValueError("byteorder must be either 'little' or 'big'")
|
| + if isinstance(mybytes, unicode):
|
| + raise TypeError("cannot convert unicode objects to bytes")
|
| + # mybytes can also be passed as a sequence of integers on Py3.
|
| + # Test for this:
|
| + elif isinstance(mybytes, collections.Iterable):
|
| + mybytes = newbytes(mybytes)
|
| + b = mybytes if byteorder == 'big' else mybytes[::-1]
|
| + if len(b) == 0:
|
| + b = b'\x00'
|
| + # The encode() method has been disabled by newbytes, but Py2's
|
| + # str has it:
|
| + num = int(native(b).encode('hex'), 16)
|
| + if signed and (b[0] & 0x80):
|
| + num = num - (2 ** (len(b)*8))
|
| + return cls(num)
|
| +
|
| +
|
| +# def _twos_comp(val, bits):
|
| +# """compute the 2's compliment of int value val"""
|
| +# if( (val&(1<<(bits-1))) != 0 ):
|
| +# val = val - (1<<bits)
|
| +# return val
|
| +
|
| +
|
| +__all__ = ['newint']
|
|
|