Author: Amaury Forgeot d'Arc <[email protected]>
Branch: py3.3
Changeset: r71010:b33a765ba524
Date: 2014-04-26 21:45 +0200
http://bitbucket.org/pypy/pypy/changeset/b33a765ba524/
Log: Equality for range objects is now based on equality of the
underlying sequences (CPython Issue #13201)
diff --git a/pypy/module/__builtin__/functional.py
b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -447,6 +447,31 @@
w_index = space.sub(w_item, self.w_start)
return space.floordiv(w_index, self.w_step)
+ def descr_eq(self, space, w_other):
+ # Compare two range objects.
+ if space.is_w(self, w_other):
+ return space.w_True
+ if not isinstance(w_other, W_Range):
+ return space.w_NotImplemented
+ if not space.eq_w(self.w_length, w_other.w_length):
+ return space.w_False
+ if space.eq_w(self.w_length, space.wrap(0)):
+ return space.w_True
+ if not space.eq_w(self.w_start, w_other.w_start):
+ return space.w_False
+ if space.eq_w(self.w_length, space.wrap(1)):
+ return space.w_True
+ return space.eq(self.w_step, w_other.w_step)
+
+ def descr_hash(self, space):
+ if space.eq_w(self.w_length, space.wrap(0)):
+ w_tup = space.newtuple([self.w_length, space.w_None, space.w_None])
+ elif space.eq_w(self.w_length, space.wrap(0)):
+ w_tup = space.newtuple([self.w_length, self.w_start, space.w_None])
+ else:
+ w_tup = space.newtuple([self.w_length, self.w_start, self.w_step])
+ return space.hash(w_tup)
+
W_Range.typedef = TypeDef("range",
__new__ = interp2app(W_Range.descr_new.im_func),
@@ -457,6 +482,8 @@
__reversed__ = interp2app(W_Range.descr_reversed),
__reduce__ = interp2app(W_Range.descr_reduce),
__contains__ = interp2app(W_Range.descr_contains),
+ __eq__ = interp2app(W_Range.descr_eq),
+ __hash__ = interp2app(W_Range.descr_hash),
count = interp2app(W_Range.descr_count),
index = interp2app(W_Range.descr_index),
start = interp_attrproperty_w('w_start', cls=W_Range),
diff --git a/pypy/module/__builtin__/test/test_functional.py
b/pypy/module/__builtin__/test/test_functional.py
--- a/pypy/module/__builtin__/test/test_functional.py
+++ b/pypy/module/__builtin__/test/test_functional.py
@@ -462,6 +462,50 @@
raises(AttributeError, "del rangeobj.stop")
raises(AttributeError, "del rangeobj.step")
+ def test_comparison(self):
+ test_ranges = [range(0), range(0, -1), range(1, 1, 3),
+ range(1), range(5, 6), range(5, 6, 2),
+ range(5, 7, 2), range(2), range(0, 4, 2),
+ range(0, 5, 2), range(0, 6, 2)]
+ test_tuples = list(map(tuple, test_ranges))
+
+ # Check that equality of ranges matches equality of the corresponding
+ # tuples for each pair from the test lists above.
+ ranges_eq = [a == b for a in test_ranges for b in test_ranges]
+ tuples_eq = [a == b for a in test_tuples for b in test_tuples]
+ assert ranges_eq == tuples_eq
+
+ # Check that != correctly gives the logical negation of ==
+ ranges_ne = [a != b for a in test_ranges for b in test_ranges]
+ assert ranges_ne == [not x for x in ranges_eq]
+
+ # Equal ranges should have equal hashes.
+ for a in test_ranges:
+ for b in test_ranges:
+ if a == b:
+ assert (hash(a), hash(b))
+
+ # Ranges are unequal to other types (even sequence types)
+ assert (range(0) == ()) is False
+ assert (() == range(0)) is False
+ assert (range(2) == [0, 1]) is False
+
+ # Huge integers aren't a problem.
+ assert range(0, 2**100 - 1, 2) == range(0, 2**100, 2)
+ assert hash(range(0, 2**100 - 1, 2)) == hash(range(0, 2**100, 2))
+ assert range(0, 2**100, 2) != range(0, 2**100 + 1, 2)
+ assert (range(2**200, 2**201 - 2**99, 2**100) ==
+ range(2**200, 2**201, 2**100))
+ assert (hash(range(2**200, 2**201 - 2**99, 2**100)) ==
+ hash(range(2**200, 2**201, 2**100)))
+ assert (range(2**200, 2**201, 2**100) !=
+ range(2**200, 2**201 + 1, 2**100))
+
+ # Order comparisons are not implemented for ranges.
+ raises(TypeError, "range(0) < range(0)")
+ raises(TypeError, "range(0) > range(0)")
+ raises(TypeError, "range(0) <= range(0)")
+ raises(TypeError, "range(0) >= range(0)")
class AppTestReversed:
def test_reversed(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit