class W_TupleObject(W_AbstractTupleObject): _immutable_fields_ = ['wrappeditems[*]'] def __init__(self, wrappeditems): make_sure_not_resized(wrappeditems) self.wrappeditems = wrappeditems def tolist(self): return self.wrappeditems def getitems_copy(self): return self.wrappeditems[:] # returns a resizable list def length(self): return len(self.wrappeditems) @jit.look_inside_iff(lambda self, _1: _unroll_condition(self)) def descr_hash(self, space): mult = 1000003 x = 0x345678 z = len(self.wrappeditems) for w_item in self.wrappeditems: y = space.hash_w(w_item) x = (x ^ y) * mult z -= 1 mult += 82520 + z + z x += 97531 return space.wrap(intmask(x)) def descr_eq(self, space, w_other): if not isinstance(w_other, W_AbstractTupleObject): return space.w_NotImplemented return self._descr_eq(space, w_other) @jit.look_inside_iff(_unroll_condition_cmp) def _descr_eq(self, space, w_other): items1 = self.wrappeditems items2 = w_other.tolist() lgt1 = len(items1) lgt2 = len(items2) if lgt1 != lgt2: return space.w_False for i in range(lgt1): item1 = items1[i] item2 = items2[i] if not space.eq_w(item1, item2): return space.w_False return space.w_True descr_ne = negate(descr_eq) def getitem(self, space, index): try: return self.wrappeditems[index] except IndexError: raise OperationError(space.w_IndexError, space.wrap("tuple index out of range"))
class cls(W_AbstractTupleObject): _immutable_fields_ = ['value%s' % i for i in iter_n] def __init__(self, space, *values): self.space = space assert len(values) == typelen for i in iter_n: obj = values[i] val_type = typetuple[i] if val_type == int: assert isinstance(obj, int) elif val_type == float: assert isinstance(obj, float) elif val_type == str: assert isinstance(obj, str) elif val_type == object: pass else: raise AssertionError setattr(self, 'value%s' % i, obj) def length(self): return typelen def tolist(self): list_w = [None] * typelen for i in iter_n: value = getattr(self, 'value%s' % i) value = wraps[i](self.space, value) list_w[i] = value return list_w # same source code, but builds and returns a resizable list getitems_copy = func_with_new_name(tolist, 'getitems_copy') def descr_hash(self, space): mult = 1000003 x = 0x345678 z = typelen for i in iter_n: value = getattr(self, 'value%s' % i) if typetuple[i] == object: y = space.int_w(space.hash(value)) elif typetuple[i] == float: # get the correct hash for float which is an # integer & other less frequent cases from pypy.objspace.std.floatobject import _hash_float y = _hash_float(space, value) elif typetuple[i] == int: # hash for int which is different from the hash # given by rpython from pypy.objspace.std.intobject import _hash_int y = _hash_int(value) else: raise NotImplementedError x = (x ^ y) * mult z -= 1 mult += 82520 + z + z x += 97531 return space.newint(intmask(x)) def descr_eq(self, space, w_other): if not isinstance(w_other, W_AbstractTupleObject): return space.w_NotImplemented if not isinstance(w_other, cls): if typelen != w_other.length(): return space.w_False for i in iter_n: myval = getattr(self, 'value%s' % i) otherval = w_other.getitem(space, i) myval = wraps[i](self.space, myval) if not space.eq_w(myval, otherval): return space.w_False return space.w_True for i in iter_n: myval = getattr(self, 'value%s' % i) otherval = getattr(w_other, 'value%s' % i) if typetuple[i] == object: if not self.space.eq_w(myval, otherval): return space.w_False else: if myval != otherval: if typetuple[i] == float: # issue with NaNs, which should be equal here if (float2longlong(myval) == float2longlong( otherval)): continue return space.w_False return space.w_True descr_ne = negate(descr_eq) def getitem(self, space, index): if index < 0: index += typelen for i in iter_n: if index == i: value = getattr(self, 'value%s' % i) value = wraps[i](self.space, value) return value raise oefmt(space.w_IndexError, "tuple index out of range")
class cls(W_AbstractTupleObject): _immutable_fields_ = ['value%s' % i for i in iter_n] def __init__(self, space, *values_w): self.space = space assert len(values_w) == typelen for i in iter_n: w_obj = values_w[i] val_type = typetuple[i] if val_type == int: unwrapped = w_obj.int_w(space) elif val_type == float: unwrapped = w_obj.float_w(space) elif val_type == str: unwrapped = w_obj.str_w(space) elif val_type == object: unwrapped = w_obj else: raise AssertionError setattr(self, 'value%s' % i, unwrapped) def length(self): return typelen def tolist(self): list_w = [None] * typelen for i in iter_n: value = getattr(self, 'value%s' % i) if typetuple[i] != object: value = self.space.wrap(value) list_w[i] = value return list_w # same source code, but builds and returns a resizable list getitems_copy = func_with_new_name(tolist, 'getitems_copy') def descr_hash(self, space): mult = 1000003 x = 0x345678 z = typelen for i in iter_n: value = getattr(self, 'value%s' % i) if typetuple[i] == object: y = space.int_w(space.hash(value)) elif typetuple[i] == float: # get the correct hash for float which is an # integer & other less frequent cases from pypy.objspace.std.floatobject import _hash_float y = _hash_float(space, value) else: y = compute_hash(value) x = (x ^ y) * mult z -= 1 mult += 82520 + z + z x += 97531 return space.wrap(intmask(x)) def descr_eq(self, space, w_other): if not isinstance(w_other, W_AbstractTupleObject): return space.w_NotImplemented if not isinstance(w_other, cls): if typelen != w_other.length(): return space.w_False for i in iter_n: myval = getattr(self, 'value%s' % i) otherval = w_other.getitem(space, i) if typetuple[i] != object: myval = space.wrap(myval) if not space.eq_w(myval, otherval): return space.w_False return space.w_True for i in iter_n: myval = getattr(self, 'value%s' % i) otherval = getattr(w_other, 'value%s' % i) if typetuple[i] == object: if not self.space.eq_w(myval, otherval): return space.w_False else: if myval != otherval: return space.w_False return space.w_True descr_ne = negate(descr_eq) def getitem(self, space, index): if index < 0: index += typelen for i in iter_n: if index == i: value = getattr(self, 'value%s' % i) if typetuple[i] != object: value = space.wrap(value) return value raise OperationError(space.w_IndexError, space.wrap("tuple index out of range"))
class W_TupleObject(W_AbstractTupleObject): _immutable_fields_ = ['wrappeditems[*]'] def __init__(self, wrappeditems): make_sure_not_resized(wrappeditems) self.wrappeditems = wrappeditems def tolist(self): return self.wrappeditems def getitems_copy(self): return self.wrappeditems[:] # returns a resizable list def length(self): return len(self.wrappeditems) def descr_hash(self, space): if _unroll_condition(self): res = self._descr_hash_unroll(space) else: res = self._descr_hash_jitdriver(space) return space.newint(res) @jit.unroll_safe def _descr_hash_unroll(self, space): mult = 1000003 x = 0x345678 z = len(self.wrappeditems) for w_item in self.wrappeditems: y = space.hash_w(w_item) x = (x ^ y) * mult z -= 1 mult += 82520 + z + z x += 97531 return intmask(x) def _descr_hash_jitdriver(self, space): mult = 1000003 x = 0x345678 z = len(self.wrappeditems) w_type = space.type(self.wrappeditems[0]) wrappeditems = self.wrappeditems i = 0 while i < len(wrappeditems): hash_driver.jit_merge_point(w_type=w_type) w_item = wrappeditems[i] y = space.hash_w(w_item) x = (x ^ y) * mult z -= 1 mult += 82520 + z + z i += 1 x += 97531 return intmask(x) def descr_eq(self, space, w_other): if not isinstance(w_other, W_AbstractTupleObject): return space.w_NotImplemented return self._descr_eq(space, w_other) @jit.look_inside_iff(_unroll_condition_cmp) def _descr_eq(self, space, w_other): items1 = self.wrappeditems items2 = w_other.tolist() lgt1 = len(items1) lgt2 = len(items2) if lgt1 != lgt2: return space.w_False for i in range(lgt1): item1 = items1[i] item2 = items2[i] if not space.eq_w(item1, item2): return space.w_False return space.w_True descr_ne = negate(descr_eq) def getitem(self, space, index): try: return self.wrappeditems[index] except IndexError: raise oefmt(space.w_IndexError, "tuple index out of range")