1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
"""
Interp-level implementation of the basic space operations.
"""
import math
from pypy.interpreter import gateway
from pypy.interpreter.error import OperationError, oefmt
from pypy.interpreter.gateway import unwrap_spec, WrappedDefault
from rpython.rlib.runicode import UNICHR
import __builtin__
def abs(space, w_val):
"abs(number) -> number\n\nReturn the absolute value of the argument."
return space.abs(w_val)
def ascii(space, w_obj):
""""ascii(object) -> string
As repr(), return a string containing a printable representation of an
object, but escape the non-ASCII characters in the string returned by
repr() using \\x, \\u or \\U escapes. This generates a string similar
to that returned by repr() in Python 2."""
from pypy.objspace.std.unicodeobject import ascii_from_object
return ascii_from_object(space, w_obj)
@unwrap_spec(code=int)
def chr(space, code):
"Return a Unicode string of one character with the given ordinal."
if code < 0 or code > 0x10FFFF:
raise oefmt(space.w_ValueError, "chr() arg out of range")
c = UNICHR(code)
return space.newunicode(c)
def len(space, w_obj):
"len(object) -> integer\n\nReturn the number of items of a sequence or mapping."
return space.len(w_obj)
def checkattrname(space, w_name):
# This is a check to ensure that getattr/setattr/delattr only pass a
# string to the rest of the code. XXX not entirely sure if these three
# functions are the only way for non-string objects to reach
# space.{get,set,del}attr()...
# Note that if w_name is already an exact string it must be returned
# unmodified (and not e.g. unwrapped-rewrapped).
if not space.is_w(space.type(w_name), space.w_text):
name = space.text_w(w_name) # typecheck
w_name = space.newtext(name) # rewrap as a real string
return w_name
def delattr(space, w_object, w_name):
"""Delete a named attribute on an object.
delattr(x, 'y') is equivalent to ``del x.y''."""
w_name = checkattrname(space, w_name)
space.delattr(w_object, w_name)
return space.w_None
def getattr(space, w_object, w_name, w_defvalue=None):
"""Get a named attribute from an object.
getattr(x, 'y') is equivalent to ``x.y''."""
w_name = checkattrname(space, w_name)
try:
return space.getattr(w_object, w_name)
except OperationError as e:
if w_defvalue is not None:
if e.match(space, space.w_AttributeError):
return w_defvalue
raise
def hasattr(space, w_object, w_name):
"""Return whether the object has an attribute with the given name.
(This is done by calling getattr(object, name) and catching exceptions.)"""
w_name = checkattrname(space, w_name)
try:
space.getattr(w_object, w_name)
except OperationError as e:
if e.match(space, space.w_AttributeError):
return space.w_False
raise
else:
return space.w_True
def hash(space, w_object):
"""Return a hash value for the object. Two objects which compare as
equal have the same hash value. It is possible, but unlikely, for
two un-equal objects to have the same hash value."""
return space.hash(w_object)
def id(space, w_object):
"Return the identity of an object: id(x) == id(y) if and only if x is y."
return space.id(w_object)
def divmod(space, w_x, w_y):
"""Return the tuple ((x-x%y)/y, x%y). Invariant: div*y + mod == x."""
return space.divmod(w_x, w_y)
# ____________________________________________________________
def round(space, w_number, w_ndigits=None):
"""round(number[, ndigits]) -> number
Round a number to a given precision in decimal digits (default 0 digits).
This returns an int when called with one argument or if ndigits=None,
otherwise the same type as the number. ndigits may be negative."""
round = space.lookup(w_number, '__round__')
if round is None:
raise oefmt(space.w_TypeError,
"type %T doesn't define __round__ method", w_number)
if space.is_none(w_ndigits):
return space.get_and_call_function(round, w_number)
else:
return space.get_and_call_function(round, w_number, w_ndigits)
# ____________________________________________________________
iter_sentinel = gateway.applevel('''
# NOT_RPYTHON -- uses yield
# App-level implementation of the iter(callable,sentinel) operation.
def iter_generator(callable_, sentinel):
while 1:
result = callable_()
if result == sentinel:
return
yield result
def iter_sentinel(callable_, sentinel):
if not callable(callable_):
raise TypeError('iter(v, w): v must be callable')
return iter_generator(callable_, sentinel)
''', filename=__file__).interphook("iter_sentinel")
def iter(space, w_collection_or_callable, w_sentinel=None):
"""iter(collection) -> iterator over the elements of the collection.
iter(callable, sentinel) -> iterator calling callable() until it returns
the sentinel.
"""
if w_sentinel is None:
return space.iter(w_collection_or_callable)
else:
return iter_sentinel(space, w_collection_or_callable, w_sentinel)
def next(space, w_iterator, w_default=None):
"""next(iterator[, default])
Return the next item from the iterator. If default is given and the iterator
is exhausted, it is returned instead of raising StopIteration."""
try:
return space.next(w_iterator)
except OperationError as e:
if w_default is not None and e.match(space, space.w_StopIteration):
return w_default
raise
def ord(space, w_val):
"""Return the integer ordinal of a character."""
return space.ord(w_val)
@unwrap_spec(w_modulus = WrappedDefault(None))
def pow(space, w_base, w_exponent, w_modulus):
"""With two arguments, equivalent to ``base**exponent''.
With three arguments, equivalent to ``(base**exponent) % modulus'',
but much more efficient for large exponents."""
return space.pow(w_base, w_exponent, w_modulus)
def repr(space, w_object):
"""Return a canonical string representation of the object.
For simple object types, eval(repr(object)) == object."""
return space.repr(w_object)
def setattr(space, w_object, w_name, w_val):
"""Store a named attribute into an object.
setattr(x, 'y', z) is equivalent to ``x.y = z''."""
w_name = checkattrname(space, w_name)
space.setattr(w_object, w_name, w_val)
return space.w_None
def callable(space, w_object):
"""Check whether the object appears to be callable (i.e., some kind of
function). Note that classes are callable."""
return space.callable(w_object)
@unwrap_spec(w_format_spec = WrappedDefault(u""))
def format(space, w_obj, w_format_spec):
"""Format a obj according to format_spec"""
return space.format(w_obj, w_format_spec)
|