def pow_ovr(space, w_int1, w_int2): try: return _impl_pow(space, r_longlong(w_int1.intval), w_int2) except FailedToImplementArgs: from pypy.objspace.std import longobject w_a = W_LongObject.fromint(space, w_int1.intval) w_b = W_LongObject.fromint(space, w_int2.intval) return longobject.pow__Long_Long_None(space, w_a, w_b, space.w_None)
def lshift_ovr(space, w_int1, w_int2): a = r_longlong(w_int1.intval) try: return lshift__SmallLong_Int(space, W_SmallLongObject(a), w_int2) except FailedToImplementArgs: from pypy.objspace.std import longobject w_a = W_LongObject.fromint(space, w_int1.intval) w_b = W_LongObject.fromint(space, w_int2.intval) return longobject.lshift__Long_Long(space, w_a, w_b)
def _pow_ovf2long(space, iv, iw, w_modulus): if space.is_none(w_modulus) and _recover_with_smalllong(space): from pypy.objspace.std.smalllongobject import _pow as _pow_small try: # XXX: shouldn't have to pass r_longlong(0) here (see # 4fa4c6b93a84) return _pow_small(space, r_longlong(iv), iw, r_longlong(0)) except (OverflowError, ValueError): pass from pypy.objspace.std.longobject import W_LongObject w_iv = W_LongObject.fromint(space, iv) w_iw = W_LongObject.fromint(space, iw) return w_iv.descr_pow(space, w_iw, w_modulus)
def ovf2long(space, x, y): """Handle overflowing to smalllong or long""" if _recover_with_smalllong(space): if ovf2small: return ovf2small(space, x, y) # Assume a generic operation without an explicit ovf2small # handler from pypy.objspace.std.smalllongobject import W_SmallLongObject a = r_longlong(x) b = r_longlong(y) return W_SmallLongObject(op(a, b)) from pypy.objspace.std.longobject import W_LongObject w_x = W_LongObject.fromint(space, x) w_y = W_LongObject.fromint(space, y) return getattr(w_x, 'descr_' + opname)(space, w_y)
def unmarshal_Long(space, u, tc): # XXX access internals from pypy.rlib.rbigint import rbigint lng = u.get_int() if lng < 0: sign = -1 lng = -lng elif lng > 0: sign = 1 else: sign = 0 if long_bits != 15: SHIFT = 15 result = rbigint([0], 0) for i in range(lng): shift = i * SHIFT result = result.add(rbigint.fromint(u.get_short()).lshift(shift)) if lng and not result.tobool(): raise_exception(space, 'bad marshal data') if sign == -1: result = result.neg() else: digits = [0] * lng for i in range(lng): digit = u.get_int() if digit < 0: raise_exception(space, 'bad marshal data') digits[i] = digit if digits[-1] == 0: raise_exception(space, 'bad marshal data') result = rbigint(digits, sign) w_long = W_LongObject(result) return w_long
def long__Float(space, w_floatobj): try: return W_LongObject.fromfloat(w_floatobj.floatval) except OverflowError: raise OperationError( space.w_OverflowError, space.wrap("cannot convert float infinity to long"))
def descr_long(self, space): try: return W_LongObject.fromfloat(space, self.floatval) except OverflowError: raise oefmt(space.w_OverflowError, "cannot convert float infinity to integer") except ValueError: raise oefmt(space.w_ValueError, "cannot convert float NaN to integer")
def wrap(self, x): "Wraps the Python value 'x' into one of the wrapper classes." # You might notice that this function is rather conspicuously # not RPython. We can get away with this because the function # is specialized (see after the function body). Also worth # noting is that the isinstance's involving integer types # behave rather differently to how you might expect during # annotation (see pypy/annotation/builtin.py) if x is None: return self.w_None if isinstance(x, OperationError): raise TypeError, ("attempt to wrap already wrapped exception: %s"% (x,)) if isinstance(x, int): if isinstance(x, bool): return self.newbool(x) else: return self.newint(x) if isinstance(x, str): # this hack is temporary: look at the comment in # test_stdstdobjspace.test_wrap_string try: unicode_x = x.decode('ascii') except UnicodeDecodeError: # poor man's x.decode('ascii', 'replace'), since it's not # supported by RPython if not we_are_translated(): print 'WARNING: space.wrap() called on a non-ascii byte string: %r' % x lst = [] for ch in x: ch = ord(ch) if ch > 127: lst.append(u'\ufffd') else: lst.append(unichr(ch)) unicode_x = u''.join(lst) return wrapunicode(self, unicode_x) if isinstance(x, unicode): return wrapunicode(self, x) if isinstance(x, float): return W_FloatObject(x) if isinstance(x, W_Root): w_result = x.__spacebind__(self) #print 'wrapping', x, '->', w_result return w_result if isinstance(x, base_int): if self.config.objspace.std.withsmalllong: from pypy.objspace.std.smalllongobject import W_SmallLongObject from rpython.rlib.rarithmetic import r_longlong, r_ulonglong from rpython.rlib.rarithmetic import longlongmax if (not isinstance(x, r_ulonglong) or x <= r_ulonglong(longlongmax)): return W_SmallLongObject(r_longlong(x)) x = widen(x) if isinstance(x, int): return self.newint(x) else: return W_LongObject.fromrarith_int(x) return self._wrap_not_rpython(x)
def descr_long(self, space): try: return W_LongObject.fromfloat(space, self.floatval) except OverflowError: raise oefmt(space.w_OverflowError, "no puede convertir flot infinito a entero") except ValueError: raise oefmt(space.w_ValueError, "no puede convertir flot NuN a entero")
def newbigint(space, w_longtype, bigint): """Turn the bigint into a W_LongObject. If withsmalllong is enabled, check if the bigint would fit in a smalllong, and return a W_SmallLongObject instead if it does. Similar to newlong() in longobject.py, but takes an explicit w_longtype argument. """ if (space.config.objspace.std.withsmalllong and space.is_w(w_longtype, space.w_long)): try: z = bigint.tolonglong() except OverflowError: pass else: from pypy.objspace.std.smalllongobject import W_SmallLongObject return W_SmallLongObject(z) from pypy.objspace.std.longobject import W_LongObject w_obj = space.allocate_instance(W_LongObject, w_longtype) W_LongObject.__init__(w_obj, bigint) return w_obj
def eq__Float_Long(space, w_float1, w_long2): # XXX naive implementation x = w_float1.floatval if isinf(x) or math.floor(x) != x: return space.w_False try: w_long1 = W_LongObject.fromfloat(x) except OverflowError: return space.w_False return space.eq(w_long1, w_long2)
def long__Float(space, w_floatobj): try: return W_LongObject.fromfloat(space, w_floatobj.floatval) except OverflowError: if isnan(w_floatobj.floatval): raise OperationError( space.w_ValueError, space.wrap("cannot convert float NaN to integer")) raise OperationError(space.w_OverflowError, space.wrap("cannot convert float infinity to long"))
def test_integer_strategy_with_w_long(self): # tests all calls to is_plain_int1() so far space = self.space w = W_LongObject(rbigint.fromlong(42)) s1 = W_SetObject(space, self.wrapped([])) s1.add(w) assert s1.strategy is space.fromcache(IntegerSetStrategy) # s1 = W_SetObject(space, space.newlist([w])) assert s1.strategy is space.fromcache(IntegerSetStrategy)
def _ovf2long_lshift(space, x, w_x, y, w_y): if _recover_with_smalllong(space): return _lshift_ovf2small(space, x, y) from pypy.objspace.std.longobject import W_LongObject, W_AbstractLongObject if w_x is None or not isinstance(w_x, W_AbstractLongObject): w_x = W_LongObject.fromint(space, x) # crucially, *don't* convert w_y to W_LongObject, it will just be # converted back (huge lshifts always overflow) return w_x._int_lshift(space, y)
def long__Float(space, w_floatobj): try: return W_LongObject.fromfloat(space, w_floatobj.floatval) except OverflowError: if isnan(w_floatobj.floatval): raise OperationError( space.w_ValueError, space.wrap("cannot convert float NaN to integer")) raise OperationError( space.w_OverflowError, space.wrap("cannot convert float infinity to long"))
def lt__Float_Long(space, w_float1, w_long2): # XXX naive implementation x = w_float1.floatval if isinf(x): return space.newbool(x < 0.0) x_floor = math.floor(x) try: w_long1 = W_LongObject.fromfloat(x_floor) except OverflowError: return space.newbool(x < 0.0) return space.lt(w_long1, w_long2)
def wraplong(self, x): if self.config.objspace.std.withsmalllong: from rpython.rlib.rarithmetic import r_longlong try: rx = r_longlong(x) except OverflowError: pass else: from pypy.objspace.std.smalllongobject import \ W_SmallLongObject return W_SmallLongObject(rx) return W_LongObject.fromlong(x)
def newint(self, intval): if self.config.objspace.std.withsmalllong and isinstance(intval, base_int): from pypy.objspace.std.smalllongobject import W_SmallLongObject from rpython.rlib.rarithmetic import r_longlong, r_ulonglong from rpython.rlib.rarithmetic import longlongmax if (not isinstance(intval, r_ulonglong) or intval <= r_ulonglong(longlongmax)): return W_SmallLongObject(r_longlong(intval)) intval = widen(intval) if not isinstance(intval, int): return W_LongObject.fromrarith_int(intval) return wrapint(self, intval)
def wraplong(self, x): "NOT_RPYTHON" if self.config.objspace.std.withsmalllong: from rpython.rlib.rarithmetic import r_longlong try: rx = r_longlong(x) except OverflowError: pass else: from pypy.objspace.std.smalllongobject import \ W_SmallLongObject return W_SmallLongObject(rx) return W_LongObject.fromlong(x)
def test_integer_strategy_with_w_long(self): space = self.space w_x = space.wrap("x") w_A, w_B, w_C = self.get_three_classes() atag = w_A.version_tag() w = W_LongObject(rbigint.fromlong(42)) space.setattr(w_A, w_x, w) assert w_A.version_tag() is not atag assert space.int_w(space.getattr(w_A, w_x)) == 42 atag = w_A.version_tag() w = W_LongObject(rbigint.fromlong(43)) space.setattr(w_A, w_x, w) assert w_A.version_tag() is not atag assert space.int_w(space.getattr(w_A, w_x)) == 43 cell = w_A._getdictvalue_no_unwrapping(space, "x") assert cell.intvalue == 43 atag = w_A.version_tag() w = W_LongObject(rbigint.fromlong(44)) space.setattr(w_A, w_x, w) assert w_A.version_tag() is atag assert space.int_w(space.getattr(w_A, w_x)) == 44 assert cell.intvalue == 44
def _hash_float(space, v): if math.isnan(v): return 0 # This is designed so that Python numbers of different types # that compare equal hash to the same value; otherwise comparisons # of mapping keys will turn out weird. fractpart, intpart = math.modf(v) if fractpart == 0.0: # This must return the same hash as an equal int or long. try: x = ovfcheck_float_to_int(intpart) except OverflowError: # Convert to long and use its hash. try: w_lval = W_LongObject.fromfloat(space, v) except (OverflowError, ValueError): # can't convert to long int -- arbitrary if v < 0: return -271828 else: return 314159 return space.int_w(space.hash(w_lval)) else: # Fits in a C long == a Python int. from pypy.objspace.std.intobject import _hash_int return _hash_int(x) # The fractional part is non-zero, so we don't have to worry about # making this match the hash of some other type. # Use frexp to get at the bits in the double. # Since the VAX D double format has 56 mantissa bits, which is the # most of any double format in use, each of these parts may have as # many as (but no more than) 56 significant bits. # So, assuming sizeof(long) >= 4, each part can be broken into two # longs; frexp and multiplication are used to do that. # Also, since the Cray double format has 15 exponent bits, which is # the most of any double format in use, shifting the exponent field # left by 15 won't overflow a long (again assuming sizeof(long) >= 4). v, expo = math.frexp(v) v *= 2147483648.0 # 2**31 hipart = int(v) # take the top 32 bits v = (v - hipart) * 2147483648.0 # get the next 32 bits x = intmask(hipart + int(v) + (expo << 15)) x -= (x == -1) return x
def _hash_float(space, v): from pypy.objspace.std.longobject import hash__Long if isnan(v): return 0 # This is designed so that Python numbers of different types # that compare equal hash to the same value; otherwise comparisons # of mapping keys will turn out weird. fractpart, intpart = math.modf(v) if fractpart == 0.0: # This must return the same hash as an equal int or long. try: x = ovfcheck_float_to_int(intpart) # Fits in a C long == a Python int, so is its own hash. return x except OverflowError: # Convert to long and use its hash. try: w_lval = W_LongObject.fromfloat(space, v) except OverflowError: # can't convert to long int -- arbitrary if v < 0: return -271828 else: return 314159 return space.int_w(space.hash(w_lval)) # The fractional part is non-zero, so we don't have to worry about # making this match the hash of some other type. # Use frexp to get at the bits in the double. # Since the VAX D double format has 56 mantissa bits, which is the # most of any double format in use, each of these parts may have as # many as (but no more than) 56 significant bits. # So, assuming sizeof(long) >= 4, each part can be broken into two # longs; frexp and multiplication are used to do that. # Also, since the Cray double format has 15 exponent bits, which is # the most of any double format in use, shifting the exponent field # left by 15 won't overflow a long (again assuming sizeof(long) >= 4). v, expo = math.frexp(v) v *= 2147483648.0 # 2**31 hipart = int(v) # take the top 32 bits v = (v - hipart) * 2147483648.0 # get the next 32 bits x = intmask(hipart + int(v) + (expo << 15)) return x
def wrap(self, x): "Wraps the Python value 'x' into one of the wrapper classes." # You might notice that this function is rather conspicuously # not RPython. We can get away with this because the function # is specialized (see after the function body). Also worth # noting is that the isinstance's involving integer types # behave rather differently to how you might expect during # annotation (see pypy/annotation/builtin.py) if x is None: return self.w_None if isinstance(x, model.W_Object): raise TypeError, "attempt to wrap already wrapped object: %s" % ( x, ) if isinstance(x, OperationError): raise TypeError, ("attempt to wrap already wrapped exception: %s" % (x, )) if isinstance(x, int): if isinstance(x, bool): return self.newbool(x) else: return self.newint(x) if isinstance(x, str): return wrapstr(self, x) if isinstance(x, unicode): return wrapunicode(self, x) if isinstance(x, float): return W_FloatObject(x) if isinstance(x, Wrappable): w_result = x.__spacebind__(self) #print 'wrapping', x, '->', w_result return w_result if isinstance(x, base_int): if self.config.objspace.std.withsmalllong: from pypy.objspace.std.smalllongobject import W_SmallLongObject from pypy.rlib.rarithmetic import r_longlong, r_ulonglong from pypy.rlib.rarithmetic import longlongmax if (not isinstance(x, r_ulonglong) or x <= r_ulonglong(longlongmax)): return W_SmallLongObject(r_longlong(x)) x = widen(x) if isinstance(x, int): return self.newint(x) else: return W_LongObject.fromrarith_int(x) return self._wrap_not_rpython(x)
def wrap(self, x): "Wraps the Python value 'x' into one of the wrapper classes." # You might notice that this function is rather conspicuously # not RPython. We can get away with this because the function # is specialized (see after the function body). Also worth # noting is that the isinstance's involving integer types # behave rather differently to how you might expect during # annotation (see pypy/annotation/builtin.py) if x is None: return self.w_None if isinstance(x, model.W_Object): raise TypeError, "attempt to wrap already wrapped object: %s"%(x,) if isinstance(x, OperationError): raise TypeError, ("attempt to wrap already wrapped exception: %s"% (x,)) if isinstance(x, int): if isinstance(x, bool): return self.newbool(x) else: return self.newint(x) if isinstance(x, str): return wrapstr(self, x) if isinstance(x, unicode): return wrapunicode(self, x) if isinstance(x, float): return W_FloatObject(x) if isinstance(x, Wrappable): w_result = x.__spacebind__(self) #print 'wrapping', x, '->', w_result return w_result if isinstance(x, base_int): if self.config.objspace.std.withsmalllong: from pypy.objspace.std.smalllongobject import W_SmallLongObject from pypy.rlib.rarithmetic import r_longlong, r_ulonglong from pypy.rlib.rarithmetic import longlongmax if (not isinstance(x, r_ulonglong) or x <= r_ulonglong(longlongmax)): return W_SmallLongObject(r_longlong(x)) x = widen(x) if isinstance(x, int): return self.newint(x) else: return W_LongObject.fromrarith_int(x) return self._wrap_not_rpython(x)
def unmarshal_Long(space, u, tc): from pypy.rlib import rbigint lng = u.get_int() if lng < 0: sign = -1 lng = -lng elif lng > 0: sign = 1 else: sign = 0 digits = [0] * lng i = 0 while i < lng: digit = u.get_short() if digit < 0: raise_exception(space, 'bad marshal data') digits[i] = digit i += 1 # XXX poking at internals w_long = W_LongObject(rbigint.rbigint(digits, sign)) w_long.num._normalize() return w_long
def float_as_integer_ratio__Float(space, w_float): value = w_float.floatval if isinf(value): w_msg = space.wrap("cannot pass infinity to as_integer_ratio()") raise OperationError(space.w_OverflowError, w_msg) elif isnan(value): w_msg = space.wrap("cannot pass nan to as_integer_ratio()") raise OperationError(space.w_ValueError, w_msg) float_part, exp = math.frexp(value) for i in range(300): if float_part == math.floor(float_part): break float_part *= 2.0 exp -= 1 w_num = W_LongObject.fromfloat(space, float_part) w_den = space.newlong(1) w_exp = space.newlong(abs(exp)) w_exp = space.lshift(w_den, w_exp) if exp > 0: w_num = space.mul(w_num, w_exp) else: w_den = w_exp # Try to return int. return space.newtuple([space.int(w_num), space.int(w_den)])
def newlong_from_rarith_int(self, val): # val is an rarithmetic type return W_LongObject.fromrarith_int(val)
def newlong(self, val): # val is an int if self.config.objspace.std.withsmalllong: from pypy.objspace.std.smalllongobject import W_SmallLongObject return W_SmallLongObject.fromint(val) return W_LongObject.fromint(self, val)
def as_w_long(self, space): # XXX: should try smalllong from pypy.objspace.std.longobject import W_LongObject return W_LongObject.fromint(space, self.intval)
def _wrap_not_rpython(self, x): "NOT_RPYTHON" # _____ this code is here to support testing only _____ # wrap() of a container works on CPython, but the code is # not RPython. Don't use -- it is kept around mostly for tests. # Use instead newdict(), newlist(), newtuple(). if isinstance(x, dict): items_w = [(self.wrap(k), self.wrap(v)) for (k, v) in x.iteritems()] r = self.newdict() r.initialize_content(items_w) return r if isinstance(x, tuple): wrappeditems = [self.wrap(item) for item in list(x)] return self.newtuple(wrappeditems) if isinstance(x, list): wrappeditems = [self.wrap(item) for item in x] return self.newlist(wrappeditems) # The following cases are even stranger. # Really really only for tests. if type(x) is long: if self.config.objspace.std.withsmalllong: from pypy.rlib.rarithmetic import r_longlong try: rx = r_longlong(x) except OverflowError: pass else: from pypy.objspace.std.smalllongobject import \ W_SmallLongObject return W_SmallLongObject(rx) return W_LongObject.fromlong(x) if isinstance(x, slice): return W_SliceObject(self.wrap(x.start), self.wrap(x.stop), self.wrap(x.step)) if isinstance(x, complex): return W_ComplexObject(x.real, x.imag) if isinstance(x, set): rdict_w = r_dict(self.eq_w, self.hash_w) for item in x: rdict_w[self.wrap(item)] = None res = W_SetObject(self, rdict_w) return res if isinstance(x, frozenset): wrappeditems = [self.wrap(item) for item in x] return W_FrozensetObject(self, wrappeditems) if x is __builtin__.Ellipsis: # '__builtin__.Ellipsis' avoids confusion with special.Ellipsis return self.w_Ellipsis if self.config.objspace.nofaking: raise OperationError(self.w_RuntimeError, self.wrap("nofaking enabled: refusing " "to wrap cpython value %r" %(x,))) if isinstance(x, type(Exception)) and issubclass(x, Exception): w_result = self.wrap_exception_cls(x) if w_result is not None: return w_result from pypy.objspace.std.fake import fake_object return fake_object(self, x)
def delegate_SmallLong2Long(space, w_small): return W_LongObject(w_small.asbigint())
def long__Float(space, w_floatobj): try: return W_LongObject.fromfloat(w_floatobj.floatval) except OverflowError: raise OperationError(space.w_OverflowError, space.wrap("cannot convert float infinity to long"))
def descr_long(self, space): # XXX: should try smalllong from pypy.objspace.std.longobject import W_LongObject return W_LongObject.fromint(space, self.intval)
def _small2long(space, w_small): return W_LongObject(w_small.asbigint())
def int(self, space): if type(self) is W_SmallLongObject: return self if not space.is_overloaded(self, space.w_int, '__int__'): return W_LongObject(self.num) return W_Root.int(self, space)
except ParseStringError, e: raise OperationError(space.w_ValueError, space.wrap(e.msg)) else: # otherwise, use the __long__() method w_obj = space.long(w_value) # 'long(x)' should return whatever x.__long__() returned if space.is_w(w_longtype, space.w_long): return w_obj if space.is_true(space.isinstance(w_obj, space.w_long)): assert isinstance(w_obj, W_LongObject) # XXX this could fail! # XXX find a way to do that even if w_obj is not a W_LongObject w_value = w_obj elif space.is_true(space.isinstance(w_obj, space.w_int)): intval = space.int_w(w_obj) w_value = W_LongObject.fromint(space, intval) else: raise OperationError(space.w_ValueError, space.wrap("value can't be converted to long")) else: base = space.int_w(w_base) if space.is_true(space.isinstance(w_value, space.w_unicode)): from pypy.objspace.std.unicodeobject import unicode_to_decimal_w s = unicode_to_decimal_w(space, w_value) else: try: s = space.str_w(w_value) except OperationError, e: raise OperationError(space.w_TypeError, space.wrap("long() can't convert non-string "