/pypy/module/__builtin__/operation.py

https://bitbucket.org/pypy/pypy/ · Python · 238 lines · 206 code · 12 blank · 20 comment · 12 complexity · 7e725ca4443e71a42ce31f688c44941e MD5 · raw file

  1. """
  2. Interp-level implementation of the basic space operations.
  3. """
  4. from pypy.interpreter import gateway
  5. from pypy.interpreter.error import OperationError, oefmt
  6. from pypy.interpreter.gateway import unwrap_spec, WrappedDefault
  7. from rpython.rlib.runicode import UNICHR
  8. from rpython.rlib.rfloat import isnan, isinf, round_double
  9. from rpython.rlib import rfloat
  10. import __builtin__
  11. def abs(space, w_val):
  12. "abs(number) -> number\n\nReturn the absolute value of the argument."
  13. return space.abs(w_val)
  14. def chr(space, w_ascii):
  15. "Return a string of one character with the given ascii code."
  16. try:
  17. char = __builtin__.chr(space.int_w(w_ascii))
  18. except ValueError: # chr(out-of-range)
  19. raise oefmt(space.w_ValueError, "character code not in range(256)")
  20. return space.wrap(char)
  21. @unwrap_spec(code=int)
  22. def unichr(space, code):
  23. "Return a Unicode string of one character with the given ordinal."
  24. # XXX range checking!
  25. try:
  26. c = UNICHR(code)
  27. except ValueError:
  28. raise oefmt(space.w_ValueError, "unichr() arg out of range")
  29. return space.wrap(c)
  30. def len(space, w_obj):
  31. "len(object) -> integer\n\nReturn the number of items of a sequence or mapping."
  32. return space.len(w_obj)
  33. def checkattrname(space, w_name):
  34. # This is a check to ensure that getattr/setattr/delattr only pass a
  35. # string to the rest of the code. XXX not entirely sure if these three
  36. # functions are the only way for non-string objects to reach
  37. # space.{get,set,del}attr()...
  38. # Note that if w_name is already an exact string it must be returned
  39. # unmodified (and not e.g. unwrapped-rewrapped).
  40. if not space.is_w(space.type(w_name), space.w_str):
  41. name = space.str_w(w_name) # typecheck
  42. w_name = space.wrap(name) # rewrap as a real string
  43. return w_name
  44. def delattr(space, w_object, w_name):
  45. """Delete a named attribute on an object.
  46. delattr(x, 'y') is equivalent to ``del x.y''."""
  47. w_name = checkattrname(space, w_name)
  48. space.delattr(w_object, w_name)
  49. return space.w_None
  50. def getattr(space, w_object, w_name, w_defvalue=None):
  51. """Get a named attribute from an object.
  52. getattr(x, 'y') is equivalent to ``x.y''."""
  53. w_name = checkattrname(space, w_name)
  54. try:
  55. return space.getattr(w_object, w_name)
  56. except OperationError as e:
  57. if w_defvalue is not None:
  58. if e.match(space, space.w_AttributeError):
  59. return w_defvalue
  60. raise
  61. def hasattr(space, w_object, w_name):
  62. """Return whether the object has an attribute with the given name.
  63. (This is done by calling getattr(object, name) and catching exceptions.)"""
  64. w_name = checkattrname(space, w_name)
  65. if space.findattr(w_object, w_name) is not None:
  66. return space.w_True
  67. else:
  68. return space.w_False
  69. def hash(space, w_object):
  70. """Return a hash value for the object. Two objects which compare as
  71. equal have the same hash value. It is possible, but unlikely, for
  72. two un-equal objects to have the same hash value."""
  73. return space.hash(w_object)
  74. def oct(space, w_val):
  75. """Return the octal representation of an integer."""
  76. # XXX does this need to be a space operation?
  77. return space.oct(w_val)
  78. def hex(space, w_val):
  79. """Return the hexadecimal representation of an integer."""
  80. return space.hex(w_val)
  81. def id(space, w_object):
  82. "Return the identity of an object: id(x) == id(y) if and only if x is y."
  83. return space.id(w_object)
  84. def cmp(space, w_x, w_y):
  85. """return 0 when x == y, -1 when x < y and 1 when x > y """
  86. return space.cmp(w_x, w_y)
  87. def coerce(space, w_x, w_y):
  88. """coerce(x, y) -> (x1, y1)
  89. Return a tuple consisting of the two numeric arguments converted to
  90. a common type, using the same rules as used by arithmetic operations.
  91. If coercion is not possible, raise TypeError."""
  92. return space.coerce(w_x, w_y)
  93. def divmod(space, w_x, w_y):
  94. """Return the tuple ((x-x%y)/y, x%y). Invariant: div*y + mod == x."""
  95. return space.divmod(w_x, w_y)
  96. # semi-private: works only for new-style classes.
  97. def _issubtype(space, w_cls1, w_cls2):
  98. return space.issubtype(w_cls1, w_cls2)
  99. # ____________________________________________________________
  100. # Here 0.30103 is an upper bound for log10(2)
  101. NDIGITS_MAX = int((rfloat.DBL_MANT_DIG - rfloat.DBL_MIN_EXP) * 0.30103)
  102. NDIGITS_MIN = -int((rfloat.DBL_MAX_EXP + 1) * 0.30103)
  103. @unwrap_spec(number=float, w_ndigits = WrappedDefault(0))
  104. def round(space, number, w_ndigits):
  105. """round(number[, ndigits]) -> floating point number
  106. Round a number to a given precision in decimal digits (default 0 digits).
  107. This always returns a floating point number. Precision may be negative."""
  108. # Algorithm copied directly from CPython
  109. # interpret 2nd argument as a Py_ssize_t; clip on overflow
  110. ndigits = space.getindex_w(w_ndigits, None)
  111. # nans, infinities and zeros round to themselves
  112. if number == 0 or isinf(number) or isnan(number):
  113. return space.wrap(number)
  114. # Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x
  115. # always rounds to itself. For ndigits < NDIGITS_MIN, x always
  116. # rounds to +-0.0.
  117. if ndigits > NDIGITS_MAX:
  118. return space.wrap(number)
  119. elif ndigits < NDIGITS_MIN:
  120. # return 0.0, but with sign of x
  121. return space.wrap(0.0 * number)
  122. # finite x, and ndigits is not unreasonably large
  123. z = round_double(number, ndigits)
  124. if isinf(z):
  125. raise oefmt(space.w_OverflowError,
  126. "rounded value too large to represent")
  127. return space.wrap(z)
  128. # ____________________________________________________________
  129. iter_sentinel = gateway.applevel('''
  130. # NOT_RPYTHON -- uses yield
  131. # App-level implementation of the iter(callable,sentinel) operation.
  132. def iter_generator(callable_, sentinel):
  133. while 1:
  134. result = callable_()
  135. if result == sentinel:
  136. return
  137. yield result
  138. def iter_sentinel(callable_, sentinel):
  139. if not callable(callable_):
  140. raise TypeError, 'iter(v, w): v must be callable'
  141. return iter_generator(callable_, sentinel)
  142. ''', filename=__file__).interphook("iter_sentinel")
  143. def iter(space, w_collection_or_callable, w_sentinel=None):
  144. """iter(collection) -> iterator over the elements of the collection.
  145. iter(callable, sentinel) -> iterator calling callable() until it returns
  146. the sentinal.
  147. """
  148. if w_sentinel is None:
  149. return space.iter(w_collection_or_callable)
  150. else:
  151. return iter_sentinel(space, w_collection_or_callable, w_sentinel)
  152. def next(space, w_iterator, w_default=None):
  153. """next(iterator[, default])
  154. Return the next item from the iterator. If default is given and the iterator
  155. is exhausted, it is returned instead of raising StopIteration."""
  156. try:
  157. return space.next(w_iterator)
  158. except OperationError as e:
  159. if w_default is not None and e.match(space, space.w_StopIteration):
  160. return w_default
  161. raise
  162. def ord(space, w_val):
  163. """Return the integer ordinal of a character."""
  164. return space.ord(w_val)
  165. @unwrap_spec(w_modulus = WrappedDefault(None))
  166. def pow(space, w_base, w_exponent, w_modulus):
  167. """With two arguments, equivalent to ``base**exponent''.
  168. With three arguments, equivalent to ``(base**exponent) % modulus'',
  169. but much more efficient for large exponents."""
  170. return space.pow(w_base, w_exponent, w_modulus)
  171. def repr(space, w_object):
  172. """Return a canonical string representation of the object.
  173. For simple object types, eval(repr(object)) == object."""
  174. return space.repr(w_object)
  175. def setattr(space, w_object, w_name, w_val):
  176. """Store a named attribute into an object.
  177. setattr(x, 'y', z) is equivalent to ``x.y = z''."""
  178. w_name = checkattrname(space, w_name)
  179. space.setattr(w_object, w_name, w_val)
  180. return space.w_None
  181. def intern(space, w_str):
  182. """``Intern'' the given string. This enters the string in the (global)
  183. table of interned strings whose purpose is to speed up dictionary lookups.
  184. Return the string itself or the previously interned string object with the
  185. same value."""
  186. if space.is_w(space.type(w_str), space.w_str):
  187. return space.new_interned_w_str(w_str)
  188. raise oefmt(space.w_TypeError, "intern() argument must be string.")
  189. def callable(space, w_object):
  190. """Check whether the object appears to be callable (i.e., some kind of
  191. function). Note that classes are callable."""
  192. return space.callable(w_object)
  193. @unwrap_spec(w_format_spec = WrappedDefault(""))
  194. def format(space, w_obj, w_format_spec):
  195. """Format a obj according to format_spec"""
  196. return space.format(w_obj, w_format_spec)