PageRenderTime 31ms CodeModel.GetById 9ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/module/__builtin__/operation.py

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