diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2015-01-26 10:04:15 +0200 |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2015-01-26 10:04:15 +0200 |
commit | 34af5023fc1e74c2d6a7537a11148885c84d9cb4 (patch) | |
tree | 7d0798f2543f647ac94acef12bd9ebc71fe6dd29 /Lib | |
parent | 4e1942bcd8a3904047bf96a16305f0e1e4736b5c (diff) | |
parent | f4b7a02e932671c6e54e6b48340173cc859ab4c0 (diff) | |
download | cpython-git-34af5023fc1e74c2d6a7537a11148885c84d9cb4.tar.gz |
Issue #21408: The default __ne__() now returns NotImplemented if __eq__()
returned NotImplemented. Removed incorrect implementations of __ne__().
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/_collections_abc.py | 6 | ||||
-rw-r--r-- | Lib/doctest.py | 9 | ||||
-rw-r--r-- | Lib/lib2to3/pytree.py | 10 | ||||
-rw-r--r-- | Lib/numbers.py | 5 | ||||
-rw-r--r-- | Lib/pathlib.py | 3 | ||||
-rw-r--r-- | Lib/test/test_binop.py | 4 | ||||
-rw-r--r-- | Lib/test/test_compare.py | 65 | ||||
-rw-r--r-- | Lib/unittest/case.py | 3 | ||||
-rw-r--r-- | Lib/unittest/suite.py | 3 |
9 files changed, 63 insertions, 45 deletions
diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py index 9a84f4aa8d..3d3f07b92e 100644 --- a/Lib/_collections_abc.py +++ b/Lib/_collections_abc.py @@ -224,9 +224,6 @@ class Set(Sized, Iterable, Container): return NotImplemented return len(self) == len(other) and self.__le__(other) - def __ne__(self, other): - return not (self == other) - @classmethod def _from_iterable(cls, it): '''Construct an instance of the class from any iterable input. @@ -451,9 +448,6 @@ class Mapping(Sized, Iterable, Container): return NotImplemented return dict(self.items()) == dict(other.items()) - def __ne__(self, other): - return not (self == other) - Mapping.register(mappingproxy) diff --git a/Lib/doctest.py b/Lib/doctest.py index bb9f43229d..7d5bcf48f5 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -481,9 +481,6 @@ class Example: self.options == other.options and \ self.exc_msg == other.exc_msg - def __ne__(self, other): - return not self == other - def __hash__(self): return hash((self.source, self.want, self.lineno, self.indent, self.exc_msg)) @@ -548,9 +545,6 @@ class DocTest: self.filename == other.filename and \ self.lineno == other.lineno - def __ne__(self, other): - return not self == other - def __hash__(self): return hash((self.docstring, self.name, self.filename, self.lineno)) @@ -2291,9 +2285,6 @@ class DocTestCase(unittest.TestCase): self._dt_tearDown == other._dt_tearDown and \ self._dt_checker == other._dt_checker - def __ne__(self, other): - return not self == other - def __hash__(self): return hash((self._dt_optionflags, self._dt_setUp, self._dt_tearDown, self._dt_checker)) diff --git a/Lib/lib2to3/pytree.py b/Lib/lib2to3/pytree.py index c4a1be3500..ad3592c05f 100644 --- a/Lib/lib2to3/pytree.py +++ b/Lib/lib2to3/pytree.py @@ -64,16 +64,6 @@ class Base(object): __hash__ = None # For Py3 compatibility. - def __ne__(self, other): - """ - Compare two nodes for inequality. - - This calls the method _eq(). - """ - if self.__class__ is not other.__class__: - return NotImplemented - return not self._eq(other) - def _eq(self, other): """ Compare two nodes for equality. diff --git a/Lib/numbers.py b/Lib/numbers.py index b206457dfc..7eedc63ec0 100644 --- a/Lib/numbers.py +++ b/Lib/numbers.py @@ -141,11 +141,6 @@ class Complex(Number): """self == other""" raise NotImplementedError - def __ne__(self, other): - """self != other""" - # The default __ne__ doesn't negate __eq__ until 3.0. - return not (self == other) - Complex.register(complex) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index dd2ccba1a6..e1b07ca955 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -710,9 +710,6 @@ class PurePath(object): return NotImplemented return self._cparts == other._cparts and self._flavour is other._flavour - def __ne__(self, other): - return not self == other - def __hash__(self): try: return self._hash diff --git a/Lib/test/test_binop.py b/Lib/test/test_binop.py index 84179167e2..9c4c18e636 100644 --- a/Lib/test/test_binop.py +++ b/Lib/test/test_binop.py @@ -194,10 +194,6 @@ class Rat(object): return float(self) == other return NotImplemented - def __ne__(self, other): - """Compare two Rats for inequality.""" - return not self == other - class RatTestCase(unittest.TestCase): """Unit tests for Rat class and its support utilities.""" diff --git a/Lib/test/test_compare.py b/Lib/test/test_compare.py index ee3794ae9a..a663832b3d 100644 --- a/Lib/test/test_compare.py +++ b/Lib/test/test_compare.py @@ -48,8 +48,69 @@ class ComparisonTest(unittest.TestCase): def test_ne_defaults_to_not_eq(self): a = Cmp(1) b = Cmp(1) - self.assertTrue(a == b) - self.assertFalse(a != b) + c = Cmp(2) + self.assertIs(a == b, True) + self.assertIs(a != b, False) + self.assertIs(a != c, True) + + def test_ne_high_priority(self): + """object.__ne__() should allow reflected __ne__() to be tried""" + calls = [] + class Left: + # Inherits object.__ne__() + def __eq__(*args): + calls.append('Left.__eq__') + return NotImplemented + class Right: + def __eq__(*args): + calls.append('Right.__eq__') + return NotImplemented + def __ne__(*args): + calls.append('Right.__ne__') + return NotImplemented + Left() != Right() + self.assertSequenceEqual(calls, ['Left.__eq__', 'Right.__ne__']) + + def test_ne_low_priority(self): + """object.__ne__() should not invoke reflected __eq__()""" + calls = [] + class Base: + # Inherits object.__ne__() + def __eq__(*args): + calls.append('Base.__eq__') + return NotImplemented + class Derived(Base): # Subclassing forces higher priority + def __eq__(*args): + calls.append('Derived.__eq__') + return NotImplemented + def __ne__(*args): + calls.append('Derived.__ne__') + return NotImplemented + Base() != Derived() + self.assertSequenceEqual(calls, ['Derived.__ne__', 'Base.__eq__']) + + def test_other_delegation(self): + """No default delegation between operations except __ne__()""" + ops = ( + ('__eq__', lambda a, b: a == b), + ('__lt__', lambda a, b: a < b), + ('__le__', lambda a, b: a <= b), + ('__gt__', lambda a, b: a > b), + ('__ge__', lambda a, b: a >= b), + ) + for name, func in ops: + with self.subTest(name): + def unexpected(*args): + self.fail('Unexpected operator method called') + class C: + __ne__ = unexpected + for other, _ in ops: + if other != name: + setattr(C, other, unexpected) + if name == '__eq__': + self.assertIs(func(C(), object()), False) + else: + self.assertRaises(TypeError, func, C(), object()) def test_issue_1393(self): x = lambda: None diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index aa00b7accf..69888a5a68 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -1342,9 +1342,6 @@ class FunctionTestCase(TestCase): self._testFunc == other._testFunc and \ self._description == other._description - def __ne__(self, other): - return not self == other - def __hash__(self): return hash((type(self), self._setUpFunc, self._tearDownFunc, self._testFunc, self._description)) diff --git a/Lib/unittest/suite.py b/Lib/unittest/suite.py index 4997d81b8f..76c472514e 100644 --- a/Lib/unittest/suite.py +++ b/Lib/unittest/suite.py @@ -31,9 +31,6 @@ class BaseTestSuite(object): return NotImplemented return list(self) == list(other) - def __ne__(self, other): - return not self == other - def __iter__(self): return iter(self._tests) |