diff options
author | Guido van Rossum <guido@python.org> | 2006-08-24 17:29:38 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2006-08-24 17:29:38 (GMT) |
commit | 19960597adb65c9ecd33e4c3d320390eecd38625 (patch) | |
tree | c6c521459bb3649bfde7dd670a23f95eb5c07188 /Lib/test | |
parent | b6bb0c79d98a45bdc550ae0ab2e774e5c3cf607a (diff) | |
download | cpython-19960597adb65c9ecd33e4c3d320390eecd38625.zip cpython-19960597adb65c9ecd33e4c3d320390eecd38625.tar.gz cpython-19960597adb65c9ecd33e4c3d320390eecd38625.tar.bz2 |
Fix the datetime comparison conundrum.
The special-casing of other objects with a timetuple attribute is gone.
Let's hope Tim agrees.
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/test_datetime.py | 87 |
1 files changed, 53 insertions, 34 deletions
diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py index 4f765c1..765bdaf 100644 --- a/Lib/test/test_datetime.py +++ b/Lib/test/test_datetime.py @@ -954,41 +954,60 @@ class TestDate(HarmlessMixedComparison): def test_mixed_compare(self): our = self.theclass(2000, 4, 5) + + # Our class can be compared for equality to other classes + self.assertEqual(our == 1, False) + self.assertEqual(1 == our, False) + self.assertEqual(our != 1, True) + self.assertEqual(1 != our, True) + + # But the ordering is undefined + self.assertRaises(TypeError, lambda: our < 1) + self.assertRaises(TypeError, lambda: 1 < our) self.assertRaises(TypeError, cmp, our, 1) self.assertRaises(TypeError, cmp, 1, our) - class AnotherDateTimeClass(object): - def __cmp__(self, other): - # Return "equal" so calling this can't be confused with - # compare-by-address (which never says "equal" for distinct - # objects). - return 0 - - # This still errors, because date and datetime comparison raise - # TypeError instead of NotImplemented when they don't know what to - # do, in order to stop comparison from falling back to the default - # compare-by-address. - their = AnotherDateTimeClass() + # Repeat those tests with a different class + + class SomeClass: + pass + + their = SomeClass() + self.assertEqual(our == their, False) + self.assertEqual(their == our, False) + self.assertEqual(our != their, True) + self.assertEqual(their != our, True) + self.assertRaises(TypeError, lambda: our < their) + self.assertRaises(TypeError, lambda: their < our) self.assertRaises(TypeError, cmp, our, their) - # Oops: The next stab raises TypeError in the C implementation, - # but not in the Python implementation of datetime. The difference - # is due to that the Python implementation defines __cmp__ but - # the C implementation defines tp_richcompare. This is more pain - # to fix than it's worth, so commenting out the test. - # self.assertEqual(cmp(their, our), 0) - - # But date and datetime comparison return NotImplemented instead if the - # other object has a timetuple attr. This gives the other object a - # chance to do the comparison. - class Comparable(AnotherDateTimeClass): - def timetuple(self): - return () - - their = Comparable() - self.assertEqual(cmp(our, their), 0) - self.assertEqual(cmp(their, our), 0) - self.failUnless(our == their) - self.failUnless(their == our) + self.assertRaises(TypeError, cmp, their, our) + + # However, if the other class explicitly defines ordering + # relative to our class, it is allowed to do so + + class LargerThanAnything: + def __lt__(self, other): + return False + def __le__(self, other): + return isinstance(other, LargerThanAnything) + def __eq__(self, other): + return isinstance(other, LargerThanAnything) + def __ne__(self, other): + return not isinstance(other, LargerThanAnything) + def __gt__(self, other): + return not isinstance(other, LargerThanAnything) + def __ge__(self, other): + return True + + their = LargerThanAnything() + self.assertEqual(our == their, False) + self.assertEqual(their == our, False) + self.assertEqual(our != their, True) + self.assertEqual(their != our, True) + self.assertEqual(our < their, True) + self.assertEqual(their < our, False) + self.assertEqual(cmp(our, their), -1) + self.assertEqual(cmp(their, our), 1) def test_bool(self): # All dates are considered true. @@ -3217,10 +3236,10 @@ class Oddballs(unittest.TestCase): # Neverthelss, comparison should work with the base-class (date) # projection if use of a date method is forced. - self.assert_(as_date.__eq__(as_datetime)) + self.assertEqual(as_date.__eq__(as_datetime), True) different_day = (as_date.day + 1) % 20 + 1 - self.assert_(not as_date.__eq__(as_datetime.replace(day= - different_day))) + as_different = as_datetime.replace(day= different_day) + self.assertEqual(as_date.__eq__(as_different), False) # And date should compare with other subclasses of date. If a # subclass wants to stop this, it's up to the subclass to do so. |