PageRenderTime 82ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/objspace/std/longobject.py

https://bitbucket.org/pypy/pypy/
Python | 726 lines | 704 code | 16 blank | 6 comment | 7 complexity | fa4bfdfa57daac3ed6fe4ee3ee444acb MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. """The builtin long implementation"""
  2. import functools
  3. from rpython.rlib.objectmodel import specialize
  4. from rpython.rlib.rbigint import rbigint
  5. from rpython.rlib.rstring import ParseStringError
  6. from rpython.tool.sourcetools import func_renamer, func_with_new_name
  7. from pypy.interpreter import typedef
  8. from pypy.interpreter.baseobjspace import W_Root
  9. from pypy.interpreter.error import OperationError, oefmt
  10. from pypy.interpreter.gateway import (
  11. WrappedDefault, interp2app, interpindirect2app, unwrap_spec)
  12. from pypy.interpreter.typedef import TypeDef
  13. from pypy.objspace.std import newformat
  14. from pypy.objspace.std.intobject import W_AbstractIntObject
  15. from pypy.objspace.std.util import (
  16. BINARY_OPS, CMP_OPS, COMMUTATIVE_OPS, IDTAG_LONG, IDTAG_SHIFT, wrap_parsestringerror)
  17. def delegate_other(func):
  18. @functools.wraps(func)
  19. def delegated(self, space, w_other):
  20. if isinstance(w_other, W_AbstractIntObject):
  21. w_other = w_other.descr_long(space)
  22. elif not isinstance(w_other, W_AbstractLongObject):
  23. return space.w_NotImplemented
  24. return func(self, space, w_other)
  25. return delegated
  26. class W_AbstractLongObject(W_Root):
  27. __slots__ = ()
  28. def is_w(self, space, w_other):
  29. if not isinstance(w_other, W_AbstractLongObject):
  30. return False
  31. if self.user_overridden_class or w_other.user_overridden_class:
  32. return self is w_other
  33. return space.bigint_w(self).eq(space.bigint_w(w_other))
  34. def immutable_unique_id(self, space):
  35. if self.user_overridden_class:
  36. return None
  37. b = space.bigint_w(self)
  38. b = b.lshift(IDTAG_SHIFT).int_or_(IDTAG_LONG)
  39. return space.newlong_from_rbigint(b)
  40. def unwrap(self, space):
  41. return self.longval()
  42. def int(self, space):
  43. raise NotImplementedError
  44. def asbigint(self):
  45. raise NotImplementedError
  46. def descr_getnewargs(self, space):
  47. return space.newtuple([newlong(space, self.asbigint())])
  48. def descr_conjugate(self, space):
  49. """Returns self, the complex conjugate of any long."""
  50. return space.long(self)
  51. def descr_bit_length(self, space):
  52. """long.bit_length() -> int or long
  53. Number of bits necessary to represent self in binary.
  54. >>> bin(37L)
  55. '0b100101'
  56. >>> (37L).bit_length()
  57. 6
  58. """
  59. bigint = space.bigint_w(self)
  60. try:
  61. return space.wrap(bigint.bit_length())
  62. except OverflowError:
  63. raise oefmt(space.w_OverflowError, "too many digits in integer")
  64. def _truediv(self, space, w_other):
  65. try:
  66. f = self.asbigint().truediv(w_other.asbigint())
  67. except ZeroDivisionError:
  68. raise oefmt(space.w_ZeroDivisionError,
  69. "long division or modulo by zero")
  70. except OverflowError:
  71. raise oefmt(space.w_OverflowError,
  72. "long/long too large for a float")
  73. return space.newfloat(f)
  74. @delegate_other
  75. def descr_truediv(self, space, w_other):
  76. """x.__truediv__(y) <==> x/y"""
  77. return W_AbstractLongObject._truediv(self, space, w_other)
  78. @delegate_other
  79. def descr_rtruediv(self, space, w_other):
  80. """x.__rtruediv__(y) <==> y/x"""
  81. return W_AbstractLongObject._truediv(w_other, space, self)
  82. @delegate_other
  83. def descr_coerce(self, space, w_other):
  84. """x.__coerce__(y) <==> coerce(x, y)"""
  85. return space.newtuple([self, w_other])
  86. def descr_get_numerator(self, space):
  87. return space.long(self)
  88. descr_get_real = func_with_new_name(descr_get_numerator, 'descr_get_real')
  89. def descr_format(self, space, w_format_spec):
  90. return newformat.run_formatter(space, w_format_spec,
  91. "format_int_or_long", self,
  92. newformat.LONG_KIND)
  93. def descr_get_denominator(self, space):
  94. return space.newlong(1)
  95. def descr_get_imag(self, space):
  96. return space.newlong(0)
  97. def _make_descr_unaryop(opname):
  98. op = getattr(rbigint, opname)
  99. @func_renamer('descr_' + opname)
  100. def descr_unaryop(self, space):
  101. return space.wrap(op(self.asbigint()))
  102. descr_unaryop.__doc__ = 'x.__%s__(y) <==> %s(x, y)' % (opname, opname)
  103. return descr_unaryop
  104. descr_repr = _make_descr_unaryop('repr')
  105. descr_str = _make_descr_unaryop('str')
  106. descr_hash = _make_descr_unaryop('hash')
  107. descr_oct = _make_descr_unaryop('oct')
  108. descr_hex = _make_descr_unaryop('hex')
  109. def descr_pow(self, space, w_exponent, w_modulus=None):
  110. """x.__pow__(y[, z]) <==> pow(x, y[, z])"""
  111. raise NotImplementedError
  112. descr_rpow = func_with_new_name(descr_pow, 'descr_rpow')
  113. descr_rpow.__doc__ = "y.__rpow__(x[, z]) <==> pow(x, y[, z])"
  114. def _abstract_unaryop(opname, doc=None):
  115. @func_renamer('descr_' + opname)
  116. def descr_unaryop(self, space):
  117. raise NotImplementedError
  118. descr_unaryop.__doc__ = doc
  119. return descr_unaryop
  120. descr_long = _abstract_unaryop('long', "x.__long__() <==> long(x)")
  121. descr_float = _abstract_unaryop('float', "x.__float__() <==> float(x)")
  122. descr_index = _abstract_unaryop(
  123. 'index', "x[y:z] <==> x[y.__index__():z.__index__()]")
  124. descr_trunc = _abstract_unaryop('trunc',
  125. "Truncating an Integral returns itself.")
  126. descr_pos = _abstract_unaryop('pos', "x.__pos__() <==> +x")
  127. descr_neg = _abstract_unaryop('neg', "x.__neg__() <==> -x")
  128. descr_abs = _abstract_unaryop('abs', "x.__abs__() <==> abs(x)")
  129. descr_nonzero = _abstract_unaryop('nonzero', "x.__nonzero__() <==> x != 0")
  130. descr_invert = _abstract_unaryop('invert', "x.__invert__() <==> ~x")
  131. def _abstract_cmpop(opname):
  132. @func_renamer('descr_' + opname)
  133. def descr_cmp(self, space, w_other):
  134. raise NotImplementedError
  135. descr_cmp.__doc__ = 'x.__%s__(y) <==> x%sy' % (opname, CMP_OPS[opname])
  136. return descr_cmp
  137. descr_lt = _abstract_cmpop('lt')
  138. descr_le = _abstract_cmpop('le')
  139. descr_eq = _abstract_cmpop('eq')
  140. descr_ne = _abstract_cmpop('ne')
  141. descr_gt = _abstract_cmpop('gt')
  142. descr_ge = _abstract_cmpop('ge')
  143. def _abstract_binop(opname):
  144. oper = BINARY_OPS.get(opname)
  145. if oper == '%':
  146. oper = '%%'
  147. oper = '%s(%%s, %%s)' % opname if not oper else '%%s%s%%s' % oper
  148. @func_renamer('descr_' + opname)
  149. def descr_binop(self, space, w_other):
  150. raise NotImplementedError
  151. descr_binop.__doc__ = "x.__%s__(y) <==> %s" % (opname,
  152. oper % ('x', 'y'))
  153. descr_rbinop = func_with_new_name(descr_binop, 'descr_r' + opname)
  154. descr_rbinop.__doc__ = "x.__r%s__(y) <==> %s" % (opname,
  155. oper % ('y', 'x'))
  156. return descr_binop, descr_rbinop
  157. descr_add, descr_radd = _abstract_binop('add')
  158. descr_sub, descr_rsub = _abstract_binop('sub')
  159. descr_mul, descr_rmul = _abstract_binop('mul')
  160. descr_and, descr_rand = _abstract_binop('and')
  161. descr_or, descr_ror = _abstract_binop('or')
  162. descr_xor, descr_rxor = _abstract_binop('xor')
  163. descr_lshift, descr_rlshift = _abstract_binop('lshift')
  164. descr_rshift, descr_rrshift = _abstract_binop('rshift')
  165. descr_floordiv, descr_rfloordiv = _abstract_binop('floordiv')
  166. descr_div, descr_rdiv = _abstract_binop('div')
  167. descr_mod, descr_rmod = _abstract_binop('mod')
  168. descr_divmod, descr_rdivmod = _abstract_binop('divmod')
  169. class W_LongObject(W_AbstractLongObject):
  170. """This is a wrapper of rbigint."""
  171. _immutable_fields_ = ['num']
  172. def __init__(self, num):
  173. self.num = num # instance of rbigint
  174. @staticmethod
  175. def fromint(space, intval):
  176. return W_LongObject(rbigint.fromint(intval))
  177. def longval(self):
  178. return self.num.tolong()
  179. def tofloat(self, space):
  180. try:
  181. return self.num.tofloat()
  182. except OverflowError:
  183. raise oefmt(space.w_OverflowError,
  184. "long int too large to convert to float")
  185. def toint(self):
  186. return self.num.toint()
  187. @staticmethod
  188. def fromfloat(space, f):
  189. return newlong(space, rbigint.fromfloat(f))
  190. @staticmethod
  191. def fromlong(l):
  192. return W_LongObject(rbigint.fromlong(l))
  193. @staticmethod
  194. @specialize.argtype(0)
  195. def fromrarith_int(i):
  196. return W_LongObject(rbigint.fromrarith_int(i))
  197. def _int_w(self, space):
  198. try:
  199. return self.num.toint()
  200. except OverflowError:
  201. raise oefmt(space.w_OverflowError,
  202. "long int too large to convert to int")
  203. def uint_w(self, space):
  204. try:
  205. return self.num.touint()
  206. except ValueError:
  207. raise oefmt(space.w_ValueError,
  208. "cannot convert negative integer to unsigned int")
  209. except OverflowError:
  210. raise oefmt(space.w_OverflowError,
  211. "long int too large to convert to unsigned int")
  212. def bigint_w(self, space, allow_conversion=True):
  213. return self.num
  214. def _bigint_w(self, space):
  215. return self.num
  216. def float_w(self, space, allow_conversion=True):
  217. return self.tofloat(space)
  218. def _float_w(self, space):
  219. return self.tofloat(space)
  220. def int(self, space):
  221. if (type(self) is not W_LongObject and
  222. space.is_overloaded(self, space.w_long, '__int__')):
  223. return W_Root.int(self, space)
  224. try:
  225. return space.newint(self.num.toint())
  226. except OverflowError:
  227. return self.descr_long(space)
  228. def asbigint(self):
  229. return self.num
  230. def __repr__(self):
  231. return '<W_LongObject(%d)>' % self.num.tolong()
  232. def descr_long(self, space):
  233. # __long__ is supposed to do nothing, unless it has a derived
  234. # long object, where it should return an exact one.
  235. if space.is_w(space.type(self), space.w_long):
  236. return self
  237. return W_LongObject(self.num)
  238. descr_index = descr_trunc = descr_pos = descr_long
  239. def descr_float(self, space):
  240. return space.newfloat(self.tofloat(space))
  241. def descr_nonzero(self, space):
  242. return space.newbool(self.num.tobool())
  243. @unwrap_spec(w_modulus=WrappedDefault(None))
  244. def descr_pow(self, space, w_exponent, w_modulus=None):
  245. if isinstance(w_exponent, W_AbstractIntObject):
  246. w_exponent = w_exponent.descr_long(space)
  247. elif not isinstance(w_exponent, W_AbstractLongObject):
  248. return space.w_NotImplemented
  249. if space.is_none(w_modulus):
  250. if w_exponent.asbigint().sign < 0:
  251. self = self.descr_float(space)
  252. w_exponent = w_exponent.descr_float(space)
  253. return space.pow(self, w_exponent, space.w_None)
  254. return W_LongObject(self.num.pow(w_exponent.asbigint()))
  255. elif isinstance(w_modulus, W_AbstractIntObject):
  256. w_modulus = w_modulus.descr_long(space)
  257. elif not isinstance(w_modulus, W_AbstractLongObject):
  258. return space.w_NotImplemented
  259. if w_exponent.asbigint().sign < 0:
  260. raise oefmt(space.w_TypeError,
  261. "pow() 2nd argument cannot be negative when 3rd "
  262. "argument specified")
  263. try:
  264. result = self.num.pow(w_exponent.asbigint(), w_modulus.asbigint())
  265. except ValueError:
  266. raise oefmt(space.w_ValueError, "pow 3rd argument cannot be 0")
  267. return W_LongObject(result)
  268. @unwrap_spec(w_modulus=WrappedDefault(None))
  269. def descr_rpow(self, space, w_base, w_modulus=None):
  270. if isinstance(w_base, W_AbstractIntObject):
  271. w_base = w_base.descr_long(space)
  272. elif not isinstance(w_base, W_AbstractLongObject):
  273. return space.w_NotImplemented
  274. return w_base.descr_pow(space, self, w_modulus)
  275. def _make_descr_unaryop(opname):
  276. op = getattr(rbigint, opname)
  277. @func_renamer('descr_' + opname)
  278. def descr_unaryop(self, space):
  279. return W_LongObject(op(self.num))
  280. return descr_unaryop
  281. descr_neg = _make_descr_unaryop('neg')
  282. descr_abs = _make_descr_unaryop('abs')
  283. descr_invert = _make_descr_unaryop('invert')
  284. def _make_descr_cmp(opname):
  285. op = getattr(rbigint, opname)
  286. intop = getattr(rbigint, "int_" + opname)
  287. def descr_impl(self, space, w_other):
  288. if isinstance(w_other, W_AbstractIntObject):
  289. return space.newbool(intop(self.num, w_other.int_w(space)))
  290. elif not isinstance(w_other, W_AbstractLongObject):
  291. return space.w_NotImplemented
  292. return space.newbool(op(self.num, w_other.asbigint()))
  293. return func_with_new_name(descr_impl, "descr_" + opname)
  294. descr_lt = _make_descr_cmp('lt')
  295. descr_le = _make_descr_cmp('le')
  296. descr_eq = _make_descr_cmp('eq')
  297. descr_ne = _make_descr_cmp('ne')
  298. descr_gt = _make_descr_cmp('gt')
  299. descr_ge = _make_descr_cmp('ge')
  300. def _make_generic_descr_binop_noncommutative(opname):
  301. methname = opname + '_' if opname in ('and', 'or') else opname
  302. descr_rname = 'descr_r' + opname
  303. op = getattr(rbigint, methname)
  304. @func_renamer('descr_' + opname)
  305. @delegate_other
  306. def descr_binop(self, space, w_other):
  307. return W_LongObject(op(self.num, w_other.asbigint()))
  308. @func_renamer(descr_rname)
  309. @delegate_other
  310. def descr_rbinop(self, space, w_other):
  311. return W_LongObject(op(w_other.asbigint(), self.num))
  312. return descr_binop, descr_rbinop
  313. def _make_generic_descr_binop(opname):
  314. if opname not in COMMUTATIVE_OPS:
  315. raise Exception("Not supported")
  316. methname = opname + '_' if opname in ('and', 'or') else opname
  317. descr_rname = 'descr_r' + opname
  318. op = getattr(rbigint, methname)
  319. intop = getattr(rbigint, "int_" + methname)
  320. @func_renamer('descr_' + opname)
  321. def descr_binop(self, space, w_other):
  322. if isinstance(w_other, W_AbstractIntObject):
  323. return W_LongObject(intop(self.num, w_other.int_w(space)))
  324. elif not isinstance(w_other, W_AbstractLongObject):
  325. return space.w_NotImplemented
  326. return W_LongObject(op(self.num, w_other.asbigint()))
  327. @func_renamer(descr_rname)
  328. def descr_rbinop(self, space, w_other):
  329. if isinstance(w_other, W_AbstractIntObject):
  330. return W_LongObject(intop(self.num, w_other.int_w(space)))
  331. elif not isinstance(w_other, W_AbstractLongObject):
  332. return space.w_NotImplemented
  333. return W_LongObject(op(w_other.asbigint(), self.num))
  334. return descr_binop, descr_rbinop
  335. descr_add, descr_radd = _make_generic_descr_binop('add')
  336. descr_sub, descr_rsub = _make_generic_descr_binop_noncommutative('sub')
  337. descr_mul, descr_rmul = _make_generic_descr_binop('mul')
  338. descr_and, descr_rand = _make_generic_descr_binop('and')
  339. descr_or, descr_ror = _make_generic_descr_binop('or')
  340. descr_xor, descr_rxor = _make_generic_descr_binop('xor')
  341. def _make_descr_binop(func, int_func=None):
  342. opname = func.__name__[1:]
  343. if int_func:
  344. @func_renamer('descr_' + opname)
  345. def descr_binop(self, space, w_other):
  346. if isinstance(w_other, W_AbstractIntObject):
  347. return int_func(self, space, w_other.int_w(space))
  348. elif not isinstance(w_other, W_AbstractLongObject):
  349. return space.w_NotImplemented
  350. return func(self, space, w_other)
  351. else:
  352. @delegate_other
  353. @func_renamer('descr_' + opname)
  354. def descr_binop(self, space, w_other):
  355. return func(self, space, w_other)
  356. @delegate_other
  357. @func_renamer('descr_r' + opname)
  358. def descr_rbinop(self, space, w_other):
  359. if not isinstance(w_other, W_LongObject):
  360. # coerce other W_AbstractLongObjects
  361. w_other = W_LongObject(w_other.asbigint())
  362. return func(w_other, space, self)
  363. return descr_binop, descr_rbinop
  364. def _lshift(self, space, w_other):
  365. if w_other.asbigint().sign < 0:
  366. raise oefmt(space.w_ValueError, "negative shift count")
  367. try:
  368. shift = w_other.asbigint().toint()
  369. except OverflowError: # b too big
  370. raise oefmt(space.w_OverflowError, "shift count too large")
  371. return W_LongObject(self.num.lshift(shift))
  372. def _int_lshift(self, space, w_other):
  373. if w_other < 0:
  374. raise oefmt(space.w_ValueError, "negative shift count")
  375. return W_LongObject(self.num.lshift(w_other))
  376. descr_lshift, descr_rlshift = _make_descr_binop(_lshift, _int_lshift)
  377. def _rshift(self, space, w_other):
  378. if w_other.asbigint().sign < 0:
  379. raise oefmt(space.w_ValueError, "negative shift count")
  380. try:
  381. shift = w_other.asbigint().toint()
  382. except OverflowError: # b too big # XXX maybe just return 0L instead?
  383. raise oefmt(space.w_OverflowError, "shift count too large")
  384. return newlong(space, self.num.rshift(shift))
  385. def _int_rshift(self, space, w_other):
  386. if w_other < 0:
  387. raise oefmt(space.w_ValueError, "negative shift count")
  388. return newlong(space, self.num.rshift(w_other))
  389. descr_rshift, descr_rrshift = _make_descr_binop(_rshift, _int_rshift)
  390. def _floordiv(self, space, w_other):
  391. try:
  392. z = self.num.floordiv(w_other.asbigint())
  393. except ZeroDivisionError:
  394. raise oefmt(space.w_ZeroDivisionError,
  395. "long division or modulo by zero")
  396. return newlong(space, z)
  397. def _floordiv(self, space, w_other):
  398. try:
  399. z = self.num.floordiv(w_other.asbigint())
  400. except ZeroDivisionError:
  401. raise oefmt(space.w_ZeroDivisionError,
  402. "long division or modulo by zero")
  403. return newlong(space, z)
  404. descr_floordiv, descr_rfloordiv = _make_descr_binop(_floordiv)
  405. _div = func_with_new_name(_floordiv, '_div')
  406. descr_div, descr_rdiv = _make_descr_binop(_div)
  407. def _mod(self, space, w_other):
  408. try:
  409. z = self.num.mod(w_other.asbigint())
  410. except ZeroDivisionError:
  411. raise oefmt(space.w_ZeroDivisionError,
  412. "long division or modulo by zero")
  413. return newlong(space, z)
  414. def _int_mod(self, space, w_other):
  415. try:
  416. z = self.num.int_mod(w_other)
  417. except ZeroDivisionError:
  418. raise oefmt(space.w_ZeroDivisionError,
  419. "long division or modulo by zero")
  420. return newlong(space, z)
  421. descr_mod, descr_rmod = _make_descr_binop(_mod, _int_mod)
  422. def _divmod(self, space, w_other):
  423. try:
  424. div, mod = self.num.divmod(w_other.asbigint())
  425. except ZeroDivisionError:
  426. raise oefmt(space.w_ZeroDivisionError,
  427. "long division or modulo by zero")
  428. return space.newtuple([newlong(space, div), newlong(space, mod)])
  429. descr_divmod, descr_rdivmod = _make_descr_binop(_divmod)
  430. def newlong(space, bigint):
  431. """Turn the bigint into a W_LongObject. If withsmalllong is
  432. enabled, check if the bigint would fit in a smalllong, and return a
  433. W_SmallLongObject instead if it does.
  434. """
  435. if space.config.objspace.std.withsmalllong:
  436. try:
  437. z = bigint.tolonglong()
  438. except OverflowError:
  439. pass
  440. else:
  441. from pypy.objspace.std.smalllongobject import W_SmallLongObject
  442. return W_SmallLongObject(z)
  443. return W_LongObject(bigint)
  444. @unwrap_spec(w_x=WrappedDefault(0))
  445. def descr__new__(space, w_longtype, w_x, w_base=None):
  446. if space.config.objspace.std.withsmalllong:
  447. from pypy.objspace.std.smalllongobject import W_SmallLongObject
  448. else:
  449. W_SmallLongObject = None
  450. w_value = w_x # 'x' is the keyword argument name in CPython
  451. if w_base is None:
  452. # check for easy cases
  453. if (W_SmallLongObject and type(w_value) is W_SmallLongObject
  454. and space.is_w(w_longtype, space.w_long)):
  455. return w_value
  456. elif type(w_value) is W_LongObject:
  457. return newbigint(space, w_longtype, w_value.num)
  458. elif (space.lookup(w_value, '__long__') is not None or
  459. space.lookup(w_value, '__int__') is not None):
  460. w_obj = space.long(w_value)
  461. return newbigint(space, w_longtype, space.bigint_w(w_obj))
  462. elif space.lookup(w_value, '__trunc__') is not None:
  463. w_obj = space.trunc(w_value)
  464. # :-( blame CPython 2.7
  465. if space.lookup(w_obj, '__long__') is not None:
  466. w_obj = space.long(w_obj)
  467. else:
  468. w_obj = space.int(w_obj)
  469. return newbigint(space, w_longtype, space.bigint_w(w_obj))
  470. elif space.isinstance_w(w_value, space.w_str):
  471. return _string_to_w_long(space, w_longtype, w_value,
  472. space.str_w(w_value))
  473. elif space.isinstance_w(w_value, space.w_unicode):
  474. from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
  475. return _string_to_w_long(space, w_longtype, w_value,
  476. unicode_to_decimal_w(space, w_value))
  477. else:
  478. try:
  479. buf = space.charbuf_w(w_value)
  480. except OperationError as e:
  481. if not e.match(space, space.w_TypeError):
  482. raise
  483. raise oefmt(space.w_TypeError,
  484. "long() argument must be a string or a number, "
  485. "not '%T'", w_value)
  486. else:
  487. return _string_to_w_long(space, w_longtype, w_value, buf)
  488. else:
  489. base = space.int_w(w_base)
  490. if space.isinstance_w(w_value, space.w_unicode):
  491. from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
  492. s = unicode_to_decimal_w(space, w_value)
  493. else:
  494. try:
  495. s = space.str_w(w_value)
  496. except OperationError:
  497. raise oefmt(space.w_TypeError,
  498. "long() can't convert non-string with explicit "
  499. "base")
  500. return _string_to_w_long(space, w_longtype, w_value, s, base)
  501. def _string_to_w_long(space, w_longtype, w_source, string, base=10):
  502. try:
  503. bigint = rbigint.fromstr(string, base)
  504. except ParseStringError as e:
  505. raise wrap_parsestringerror(space, e, w_source)
  506. return newbigint(space, w_longtype, bigint)
  507. _string_to_w_long._dont_inline_ = True
  508. def newbigint(space, w_longtype, bigint):
  509. """Turn the bigint into a W_LongObject. If withsmalllong is enabled,
  510. check if the bigint would fit in a smalllong, and return a
  511. W_SmallLongObject instead if it does. Similar to newlong() in
  512. longobject.py, but takes an explicit w_longtype argument.
  513. """
  514. if (space.config.objspace.std.withsmalllong
  515. and space.is_w(w_longtype, space.w_long)):
  516. try:
  517. z = bigint.tolonglong()
  518. except OverflowError:
  519. pass
  520. else:
  521. from pypy.objspace.std.smalllongobject import W_SmallLongObject
  522. return W_SmallLongObject(z)
  523. w_obj = space.allocate_instance(W_LongObject, w_longtype)
  524. W_LongObject.__init__(w_obj, bigint)
  525. return w_obj
  526. W_AbstractLongObject.typedef = TypeDef("long",
  527. __doc__ = """long(x=0) -> long
  528. long(x, base=10) -> long
  529. Convert a number or string to a long integer, or return 0L if no arguments
  530. are given. If x is floating point, the conversion truncates towards zero.
  531. If x is not a number or if base is given, then x must be a string or
  532. Unicode object representing an integer literal in the given base. The
  533. literal can be preceded by '+' or '-' and be surrounded by whitespace.
  534. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to
  535. interpret the base from the string as an integer literal.
  536. >>> int('0b100', base=0)
  537. 4L""",
  538. __new__ = interp2app(descr__new__),
  539. numerator = typedef.GetSetProperty(
  540. W_AbstractLongObject.descr_get_numerator,
  541. doc="the numerator of a rational number in lowest terms"),
  542. denominator = typedef.GetSetProperty(
  543. W_AbstractLongObject.descr_get_denominator,
  544. doc="the denominator of a rational number in lowest terms"),
  545. real = typedef.GetSetProperty(
  546. W_AbstractLongObject.descr_get_real,
  547. doc="the real part of a complex number"),
  548. imag = typedef.GetSetProperty(
  549. W_AbstractLongObject.descr_get_imag,
  550. doc="the imaginary part of a complex number"),
  551. __repr__ = interp2app(W_AbstractLongObject.descr_repr),
  552. __str__ = interp2app(W_AbstractLongObject.descr_str),
  553. conjugate = interpindirect2app(W_AbstractLongObject.descr_conjugate),
  554. bit_length = interpindirect2app(W_AbstractLongObject.descr_bit_length),
  555. __format__ = interpindirect2app(W_AbstractLongObject.descr_format),
  556. __hash__ = interpindirect2app(W_AbstractLongObject.descr_hash),
  557. __coerce__ = interpindirect2app(W_AbstractLongObject.descr_coerce),
  558. __oct__ = interpindirect2app(W_AbstractLongObject.descr_oct),
  559. __hex__ = interpindirect2app(W_AbstractLongObject.descr_hex),
  560. __getnewargs__ = interpindirect2app(W_AbstractLongObject.descr_getnewargs),
  561. __int__ = interpindirect2app(W_AbstractLongObject.int),
  562. __long__ = interpindirect2app(W_AbstractLongObject.descr_long),
  563. __index__ = interpindirect2app(W_AbstractLongObject.descr_index),
  564. __trunc__ = interpindirect2app(W_AbstractLongObject.descr_trunc),
  565. __float__ = interpindirect2app(W_AbstractLongObject.descr_float),
  566. __pos__ = interpindirect2app(W_AbstractLongObject.descr_pos),
  567. __neg__ = interpindirect2app(W_AbstractLongObject.descr_neg),
  568. __abs__ = interpindirect2app(W_AbstractLongObject.descr_abs),
  569. __nonzero__ = interpindirect2app(W_AbstractLongObject.descr_nonzero),
  570. __invert__ = interpindirect2app(W_AbstractLongObject.descr_invert),
  571. __lt__ = interpindirect2app(W_AbstractLongObject.descr_lt),
  572. __le__ = interpindirect2app(W_AbstractLongObject.descr_le),
  573. __eq__ = interpindirect2app(W_AbstractLongObject.descr_eq),
  574. __ne__ = interpindirect2app(W_AbstractLongObject.descr_ne),
  575. __gt__ = interpindirect2app(W_AbstractLongObject.descr_gt),
  576. __ge__ = interpindirect2app(W_AbstractLongObject.descr_ge),
  577. __add__ = interpindirect2app(W_AbstractLongObject.descr_add),
  578. __radd__ = interpindirect2app(W_AbstractLongObject.descr_radd),
  579. __sub__ = interpindirect2app(W_AbstractLongObject.descr_sub),
  580. __rsub__ = interpindirect2app(W_AbstractLongObject.descr_rsub),
  581. __mul__ = interpindirect2app(W_AbstractLongObject.descr_mul),
  582. __rmul__ = interpindirect2app(W_AbstractLongObject.descr_rmul),
  583. __and__ = interpindirect2app(W_AbstractLongObject.descr_and),
  584. __rand__ = interpindirect2app(W_AbstractLongObject.descr_rand),
  585. __or__ = interpindirect2app(W_AbstractLongObject.descr_or),
  586. __ror__ = interpindirect2app(W_AbstractLongObject.descr_ror),
  587. __xor__ = interpindirect2app(W_AbstractLongObject.descr_xor),
  588. __rxor__ = interpindirect2app(W_AbstractLongObject.descr_rxor),
  589. __lshift__ = interpindirect2app(W_AbstractLongObject.descr_lshift),
  590. __rlshift__ = interpindirect2app(W_AbstractLongObject.descr_rlshift),
  591. __rshift__ = interpindirect2app(W_AbstractLongObject.descr_rshift),
  592. __rrshift__ = interpindirect2app(W_AbstractLongObject.descr_rrshift),
  593. __floordiv__ = interpindirect2app(W_AbstractLongObject.descr_floordiv),
  594. __rfloordiv__ = interpindirect2app(W_AbstractLongObject.descr_rfloordiv),
  595. __div__ = interpindirect2app(W_AbstractLongObject.descr_div),
  596. __rdiv__ = interpindirect2app(W_AbstractLongObject.descr_rdiv),
  597. __truediv__ = interpindirect2app(W_AbstractLongObject.descr_truediv),
  598. __rtruediv__ = interpindirect2app(W_AbstractLongObject.descr_rtruediv),
  599. __mod__ = interpindirect2app(W_AbstractLongObject.descr_mod),
  600. __rmod__ = interpindirect2app(W_AbstractLongObject.descr_rmod),
  601. __divmod__ = interpindirect2app(W_AbstractLongObject.descr_divmod),
  602. __rdivmod__ = interpindirect2app(W_AbstractLongObject.descr_rdivmod),
  603. __pow__ = interpindirect2app(W_AbstractLongObject.descr_pow),
  604. __rpow__ = interpindirect2app(W_AbstractLongObject.descr_rpow),
  605. )