1""" 2Backport of Python 3's int, based on Py2's long. 3 4They are very similar. The most notable difference is: 5 6- representation: trailing L in Python 2 removed in Python 3 7""" 8from __future__ import division 9 10import struct 11 12from future.types.newbytes import newbytes 13from future.types.newobject import newobject 14from future.utils import PY3, isint, istext, isbytes, with_metaclass, native 15 16 17if PY3: 18 long = int 19 from collections.abc import Iterable 20else: 21 from collections import Iterable 22 23 24class BaseNewInt(type): 25 def __instancecheck__(cls, instance): 26 if cls == newint: 27 # Special case for Py2 short or long int 28 return isinstance(instance, (int, long)) 29 else: 30 return issubclass(instance.__class__, cls) 31 32 33class newint(with_metaclass(BaseNewInt, long)): 34 """ 35 A backport of the Python 3 int object to Py2 36 """ 37 def __new__(cls, x=0, base=10): 38 """ 39 From the Py3 int docstring: 40 41 | int(x=0) -> integer 42 | int(x, base=10) -> integer 43 | 44 | Convert a number or string to an integer, or return 0 if no 45 | arguments are given. If x is a number, return x.__int__(). For 46 | floating point numbers, this truncates towards zero. 47 | 48 | If x is not a number or if base is given, then x must be a string, 49 | bytes, or bytearray instance representing an integer literal in the 50 | given base. The literal can be preceded by '+' or '-' and be 51 | surrounded by whitespace. The base defaults to 10. Valid bases are 52 | 0 and 2-36. Base 0 means to interpret the base from the string as an 53 | integer literal. 54 | >>> int('0b100', base=0) 55 | 4 56 57 """ 58 try: 59 val = x.__int__() 60 except AttributeError: 61 val = x 62 else: 63 if not isint(val): 64 raise TypeError('__int__ returned non-int ({0})'.format( 65 type(val))) 66 67 if base != 10: 68 # Explicit base 69 if not (istext(val) or isbytes(val) or isinstance(val, bytearray)): 70 raise TypeError( 71 "int() can't convert non-string with explicit base") 72 try: 73 return super(newint, cls).__new__(cls, val, base) 74 except TypeError: 75 return super(newint, cls).__new__(cls, newbytes(val), base) 76 # After here, base is 10 77 try: 78 return super(newint, cls).__new__(cls, val) 79 except TypeError: 80 # Py2 long doesn't handle bytearray input with an explicit base, so 81 # handle this here. 82 # Py3: int(bytearray(b'10'), 2) == 2 83 # Py2: int(bytearray(b'10'), 2) == 2 raises TypeError 84 # Py2: long(bytearray(b'10'), 2) == 2 raises TypeError 85 try: 86 return super(newint, cls).__new__(cls, newbytes(val)) 87 except: 88 raise TypeError("newint argument must be a string or a number," 89 "not '{0}'".format(type(val))) 90 91 def __repr__(self): 92 """ 93 Without the L suffix 94 """ 95 value = super(newint, self).__repr__() 96 assert value[-1] == 'L' 97 return value[:-1] 98 99 def __add__(self, other): 100 value = super(newint, self).__add__(other) 101 if value is NotImplemented: 102 return long(self) + other 103 return newint(value) 104 105 def __radd__(self, other): 106 value = super(newint, self).__radd__(other) 107 if value is NotImplemented: 108 return other + long(self) 109 return newint(value) 110 111 def __sub__(self, other): 112 value = super(newint, self).__sub__(other) 113 if value is NotImplemented: 114 return long(self) - other 115 return newint(value) 116 117 def __rsub__(self, other): 118 value = super(newint, self).__rsub__(other) 119 if value is NotImplemented: 120 return other - long(self) 121 return newint(value) 122 123 def __mul__(self, other): 124 value = super(newint, self).__mul__(other) 125 if isint(value): 126 return newint(value) 127 elif value is NotImplemented: 128 return long(self) * other 129 return value 130 131 def __rmul__(self, other): 132 value = super(newint, self).__rmul__(other) 133 if isint(value): 134 return newint(value) 135 elif value is NotImplemented: 136 return other * long(self) 137 return value 138 139 def __div__(self, other): 140 # We override this rather than e.g. relying on object.__div__ or 141 # long.__div__ because we want to wrap the value in a newint() 142 # call if other is another int 143 value = long(self) / other 144 if isinstance(other, (int, long)): 145 return newint(value) 146 else: 147 return value 148 149 def __rdiv__(self, other): 150 value = other / long(self) 151 if isinstance(other, (int, long)): 152 return newint(value) 153 else: 154 return value 155 156 def __idiv__(self, other): 157 # long has no __idiv__ method. Use __itruediv__ and cast back to 158 # newint: 159 value = self.__itruediv__(other) 160 if isinstance(other, (int, long)): 161 return newint(value) 162 else: 163 return value 164 165 def __truediv__(self, other): 166 value = super(newint, self).__truediv__(other) 167 if value is NotImplemented: 168 value = long(self) / other 169 return value 170 171 def __rtruediv__(self, other): 172 return super(newint, self).__rtruediv__(other) 173 174 def __itruediv__(self, other): 175 # long has no __itruediv__ method 176 mylong = long(self) 177 mylong /= other 178 return mylong 179 180 def __floordiv__(self, other): 181 return newint(super(newint, self).__floordiv__(other)) 182 183 def __rfloordiv__(self, other): 184 return newint(super(newint, self).__rfloordiv__(other)) 185 186 def __ifloordiv__(self, other): 187 # long has no __ifloordiv__ method 188 mylong = long(self) 189 mylong //= other 190 return newint(mylong) 191 192 def __mod__(self, other): 193 value = super(newint, self).__mod__(other) 194 if value is NotImplemented: 195 return long(self) % other 196 return newint(value) 197 198 def __rmod__(self, other): 199 value = super(newint, self).__rmod__(other) 200 if value is NotImplemented: 201 return other % long(self) 202 return newint(value) 203 204 def __divmod__(self, other): 205 value = super(newint, self).__divmod__(other) 206 if value is NotImplemented: 207 mylong = long(self) 208 return (mylong // other, mylong % other) 209 return (newint(value[0]), newint(value[1])) 210 211 def __rdivmod__(self, other): 212 value = super(newint, self).__rdivmod__(other) 213 if value is NotImplemented: 214 mylong = long(self) 215 return (other // mylong, other % mylong) 216 return (newint(value[0]), newint(value[1])) 217 218 def __pow__(self, other): 219 value = super(newint, self).__pow__(other) 220 if value is NotImplemented: 221 return long(self) ** other 222 return newint(value) 223 224 def __rpow__(self, other): 225 value = super(newint, self).__rpow__(other) 226 if value is NotImplemented: 227 return other ** long(self) 228 return newint(value) 229 230 def __lshift__(self, other): 231 if not isint(other): 232 raise TypeError( 233 "unsupported operand type(s) for <<: '%s' and '%s'" % 234 (type(self).__name__, type(other).__name__)) 235 return newint(super(newint, self).__lshift__(other)) 236 237 def __rshift__(self, other): 238 if not isint(other): 239 raise TypeError( 240 "unsupported operand type(s) for >>: '%s' and '%s'" % 241 (type(self).__name__, type(other).__name__)) 242 return newint(super(newint, self).__rshift__(other)) 243 244 def __and__(self, other): 245 if not isint(other): 246 raise TypeError( 247 "unsupported operand type(s) for &: '%s' and '%s'" % 248 (type(self).__name__, type(other).__name__)) 249 return newint(super(newint, self).__and__(other)) 250 251 def __or__(self, other): 252 if not isint(other): 253 raise TypeError( 254 "unsupported operand type(s) for |: '%s' and '%s'" % 255 (type(self).__name__, type(other).__name__)) 256 return newint(super(newint, self).__or__(other)) 257 258 def __xor__(self, other): 259 if not isint(other): 260 raise TypeError( 261 "unsupported operand type(s) for ^: '%s' and '%s'" % 262 (type(self).__name__, type(other).__name__)) 263 return newint(super(newint, self).__xor__(other)) 264 265 def __neg__(self): 266 return newint(super(newint, self).__neg__()) 267 268 def __pos__(self): 269 return newint(super(newint, self).__pos__()) 270 271 def __abs__(self): 272 return newint(super(newint, self).__abs__()) 273 274 def __invert__(self): 275 return newint(super(newint, self).__invert__()) 276 277 def __int__(self): 278 return self 279 280 def __nonzero__(self): 281 return self.__bool__() 282 283 def __bool__(self): 284 """ 285 So subclasses can override this, Py3-style 286 """ 287 return super(newint, self).__nonzero__() 288 289 def __native__(self): 290 return long(self) 291 292 def to_bytes(self, length, byteorder='big', signed=False): 293 """ 294 Return an array of bytes representing an integer. 295 296 The integer is represented using length bytes. An OverflowError is 297 raised if the integer is not representable with the given number of 298 bytes. 299 300 The byteorder argument determines the byte order used to represent the 301 integer. If byteorder is 'big', the most significant byte is at the 302 beginning of the byte array. If byteorder is 'little', the most 303 significant byte is at the end of the byte array. To request the native 304 byte order of the host system, use `sys.byteorder' as the byte order value. 305 306 The signed keyword-only argument determines whether two's complement is 307 used to represent the integer. If signed is False and a negative integer 308 is given, an OverflowError is raised. 309 """ 310 if length < 0: 311 raise ValueError("length argument must be non-negative") 312 if length == 0 and self == 0: 313 return newbytes() 314 if signed and self < 0: 315 bits = length * 8 316 num = (2**bits) + self 317 if num <= 0: 318 raise OverflowError("int too smal to convert") 319 else: 320 if self < 0: 321 raise OverflowError("can't convert negative int to unsigned") 322 num = self 323 if byteorder not in ('little', 'big'): 324 raise ValueError("byteorder must be either 'little' or 'big'") 325 h = b'%x' % num 326 s = newbytes((b'0'*(len(h) % 2) + h).zfill(length*2).decode('hex')) 327 if signed: 328 high_set = s[0] & 0x80 329 if self > 0 and high_set: 330 raise OverflowError("int too big to convert") 331 if self < 0 and not high_set: 332 raise OverflowError("int too small to convert") 333 if len(s) > length: 334 raise OverflowError("int too big to convert") 335 return s if byteorder == 'big' else s[::-1] 336 337 @classmethod 338 def from_bytes(cls, mybytes, byteorder='big', signed=False): 339 """ 340 Return the integer represented by the given array of bytes. 341 342 The mybytes argument must either support the buffer protocol or be an 343 iterable object producing bytes. Bytes and bytearray are examples of 344 built-in objects that support the buffer protocol. 345 346 The byteorder argument determines the byte order used to represent the 347 integer. If byteorder is 'big', the most significant byte is at the 348 beginning of the byte array. If byteorder is 'little', the most 349 significant byte is at the end of the byte array. To request the native 350 byte order of the host system, use `sys.byteorder' as the byte order value. 351 352 The signed keyword-only argument indicates whether two's complement is 353 used to represent the integer. 354 """ 355 if byteorder not in ('little', 'big'): 356 raise ValueError("byteorder must be either 'little' or 'big'") 357 if isinstance(mybytes, unicode): 358 raise TypeError("cannot convert unicode objects to bytes") 359 # mybytes can also be passed as a sequence of integers on Py3. 360 # Test for this: 361 elif isinstance(mybytes, Iterable): 362 mybytes = newbytes(mybytes) 363 b = mybytes if byteorder == 'big' else mybytes[::-1] 364 if len(b) == 0: 365 b = b'\x00' 366 # The encode() method has been disabled by newbytes, but Py2's 367 # str has it: 368 num = int(native(b).encode('hex'), 16) 369 if signed and (b[0] & 0x80): 370 num = num - (2 ** (len(b)*8)) 371 return cls(num) 372 373 374# def _twos_comp(val, bits): 375# """compute the 2's compliment of int value val""" 376# if( (val&(1<<(bits-1))) != 0 ): 377# val = val - (1<<bits) 378# return val 379 380 381__all__ = ['newint'] 382