changeset: 96946:5ec2bfbe8115 branch: 3.4 parent: 96940:24cf6b4d72c2 user: Serhiy Storchaka date: Sat Jul 18 23:19:05 2015 +0300 files: Lib/inspect.py Lib/test/test_inspect.py Misc/NEWS description: Issue #24206: Fixed __eq__ and __ne__ methods of inspect classes. diff -r 24cf6b4d72c2 -r 5ec2bfbe8115 Lib/inspect.py --- a/Lib/inspect.py Sat Jul 18 10:59:13 2015 -0700 +++ b/Lib/inspect.py Sat Jul 18 23:19:05 2015 +0300 @@ -2206,15 +2206,13 @@ id(self), self.name) def __eq__(self, other): - return (issubclass(other.__class__, Parameter) and - self._name == other._name and + if not isinstance(other, Parameter): + return NotImplemented + return (self._name == other._name and self._kind == other._kind and self._default == other._default and self._annotation == other._annotation) - def __ne__(self, other): - return not self.__eq__(other) - class BoundArguments: '''Result of `Signature.bind` call. Holds the mapping of arguments @@ -2295,13 +2293,11 @@ return kwargs def __eq__(self, other): - return (issubclass(other.__class__, BoundArguments) and - self.signature == other.signature and + if not isinstance(other, BoundArguments): + return NotImplemented + return (self.signature == other.signature and self.arguments == other.arguments) - def __ne__(self, other): - return not self.__eq__(other) - class Signature: '''A Signature object represents the overall signature of a function. @@ -2493,9 +2489,10 @@ return_annotation=return_annotation) def __eq__(self, other): - if (not issubclass(type(other), Signature) or - self.return_annotation != other.return_annotation or - len(self.parameters) != len(other.parameters)): + if not isinstance(other, Signature): + return NotImplemented + if (self.return_annotation != other.return_annotation or + len(self.parameters) != len(other.parameters)): return False other_positions = {param: idx @@ -2522,9 +2519,6 @@ return True - def __ne__(self, other): - return not self.__eq__(other) - def _bind(self, args, kwargs, *, partial=False): '''Private method. Don't use directly.''' diff -r 24cf6b4d72c2 -r 5ec2bfbe8115 Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py Sat Jul 18 10:59:13 2015 -0700 +++ b/Lib/test/test_inspect.py Sat Jul 18 23:19:05 2015 +0300 @@ -76,6 +76,10 @@ for i in range(2): yield i +class EqualsToAll: + def __eq__(self, other): + return True + class TestPredicates(IsTestBase): def test_sixteen(self): count = len([x for x in dir(inspect) if x.startswith('is')]) @@ -2459,47 +2463,62 @@ def test_signature_equality(self): def foo(a, *, b:int) -> float: pass - self.assertNotEqual(inspect.signature(foo), 42) + self.assertFalse(inspect.signature(foo) == 42) + self.assertTrue(inspect.signature(foo) != 42) + self.assertTrue(inspect.signature(foo) == EqualsToAll()) + self.assertFalse(inspect.signature(foo) != EqualsToAll()) def bar(a, *, b:int) -> float: pass - self.assertEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertTrue(inspect.signature(foo) == inspect.signature(bar)) + self.assertFalse(inspect.signature(foo) != inspect.signature(bar)) def bar(a, *, b:int) -> int: pass - self.assertNotEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertFalse(inspect.signature(foo) == inspect.signature(bar)) + self.assertTrue(inspect.signature(foo) != inspect.signature(bar)) def bar(a, *, b:int): pass - self.assertNotEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertFalse(inspect.signature(foo) == inspect.signature(bar)) + self.assertTrue(inspect.signature(foo) != inspect.signature(bar)) def bar(a, *, b:int=42) -> float: pass - self.assertNotEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertFalse(inspect.signature(foo) == inspect.signature(bar)) + self.assertTrue(inspect.signature(foo) != inspect.signature(bar)) def bar(a, *, c) -> float: pass - self.assertNotEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertFalse(inspect.signature(foo) == inspect.signature(bar)) + self.assertTrue(inspect.signature(foo) != inspect.signature(bar)) def bar(a, b:int) -> float: pass - self.assertNotEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertFalse(inspect.signature(foo) == inspect.signature(bar)) + self.assertTrue(inspect.signature(foo) != inspect.signature(bar)) def spam(b:int, a) -> float: pass - self.assertNotEqual(inspect.signature(spam), inspect.signature(bar)) + self.assertFalse(inspect.signature(spam) == inspect.signature(bar)) + self.assertTrue(inspect.signature(spam) != inspect.signature(bar)) def foo(*, a, b, c): pass def bar(*, c, b, a): pass - self.assertEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertTrue(inspect.signature(foo) == inspect.signature(bar)) + self.assertFalse(inspect.signature(foo) != inspect.signature(bar)) def foo(*, a=1, b, c): pass def bar(*, c, b, a=1): pass - self.assertEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertTrue(inspect.signature(foo) == inspect.signature(bar)) + self.assertFalse(inspect.signature(foo) != inspect.signature(bar)) def foo(pos, *, a=1, b, c): pass def bar(pos, *, c, b, a=1): pass - self.assertEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertTrue(inspect.signature(foo) == inspect.signature(bar)) + self.assertFalse(inspect.signature(foo) != inspect.signature(bar)) def foo(pos, *, a, b, c): pass def bar(pos, *, c, b, a=1): pass - self.assertNotEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertFalse(inspect.signature(foo) == inspect.signature(bar)) + self.assertTrue(inspect.signature(foo) != inspect.signature(bar)) def foo(pos, *args, a=42, b, c, **kwargs:int): pass def bar(pos, *args, c, b, a=42, **kwargs:int): pass - self.assertEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertTrue(inspect.signature(foo) == inspect.signature(bar)) + self.assertFalse(inspect.signature(foo) != inspect.signature(bar)) def test_signature_unhashable(self): def foo(a): pass @@ -2629,11 +2648,17 @@ P = inspect.Parameter p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY) - self.assertEqual(p, p) - self.assertNotEqual(p, 42) - - self.assertEqual(p, P('foo', default=42, - kind=inspect.Parameter.KEYWORD_ONLY)) + self.assertTrue(p == p) + self.assertFalse(p != p) + self.assertFalse(p == 42) + self.assertTrue(p != 42) + self.assertTrue(p == EqualsToAll()) + self.assertFalse(p != EqualsToAll()) + + self.assertTrue(p == P('foo', default=42, + kind=inspect.Parameter.KEYWORD_ONLY)) + self.assertFalse(p != P('foo', default=42, + kind=inspect.Parameter.KEYWORD_ONLY)) def test_signature_parameter_unhashable(self): p = inspect.Parameter('foo', default=42, @@ -2936,19 +2961,26 @@ def test_signature_bound_arguments_equality(self): def foo(a): pass ba = inspect.signature(foo).bind(1) - self.assertEqual(ba, ba) + self.assertTrue(ba == ba) + self.assertFalse(ba != ba) + self.assertTrue(ba == EqualsToAll()) + self.assertFalse(ba != EqualsToAll()) ba2 = inspect.signature(foo).bind(1) - self.assertEqual(ba, ba2) + self.assertTrue(ba == ba2) + self.assertFalse(ba != ba2) ba3 = inspect.signature(foo).bind(2) - self.assertNotEqual(ba, ba3) + self.assertFalse(ba == ba3) + self.assertTrue(ba != ba3) ba3.arguments['a'] = 1 - self.assertEqual(ba, ba3) + self.assertTrue(ba == ba3) + self.assertFalse(ba != ba3) def bar(b): pass ba4 = inspect.signature(bar).bind(1) - self.assertNotEqual(ba, ba4) + self.assertFalse(ba == ba4) + self.assertTrue(ba != ba4) class TestSignaturePrivateHelpers(unittest.TestCase): diff -r 24cf6b4d72c2 -r 5ec2bfbe8115 Misc/NEWS --- a/Misc/NEWS Sat Jul 18 10:59:13 2015 -0700 +++ b/Misc/NEWS Sat Jul 18 23:19:05 2015 +0300 @@ -66,6 +66,8 @@ Library ------- +- Issue #24206: Fixed __eq__ and __ne__ methods of inspect classes. + - Issue #21750: mock_open.read_data can now be read from each instance, as it could in Python 3.3.