mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
bpo-1617161: Make the hash and equality of methods not depending on the value of self. (GH-7848)
* The hash of BuiltinMethodType instances no longer depends on the hash of __self__. It depends now on the hash of id(__self__). * The hash and equality of ModuleType and MethodWrapperType instances no longer depend on the hash and equality of __self__. They depend now on the hash and equality of id(__self__). * MethodWrapperType instances no longer support ordering.
This commit is contained in:
parent
c48e26dcad
commit
ac20e0f98d
6 changed files with 112 additions and 73 deletions
|
@ -4350,38 +4350,71 @@ order (MRO) for bases """
|
|||
else:
|
||||
self.fail("did not test __init__() for None return")
|
||||
|
||||
def assertNotOrderable(self, a, b):
|
||||
with self.assertRaises(TypeError):
|
||||
a < b
|
||||
with self.assertRaises(TypeError):
|
||||
a > b
|
||||
with self.assertRaises(TypeError):
|
||||
a <= b
|
||||
with self.assertRaises(TypeError):
|
||||
a >= b
|
||||
|
||||
def test_method_wrapper(self):
|
||||
# Testing method-wrapper objects...
|
||||
# <type 'method-wrapper'> did not support any reflection before 2.5
|
||||
|
||||
# XXX should methods really support __eq__?
|
||||
|
||||
l = []
|
||||
self.assertEqual(l.__add__, l.__add__)
|
||||
self.assertEqual(l.__add__, [].__add__)
|
||||
self.assertNotEqual(l.__add__, [5].__add__)
|
||||
self.assertNotEqual(l.__add__, l.__mul__)
|
||||
self.assertTrue(l.__add__ == l.__add__)
|
||||
self.assertFalse(l.__add__ != l.__add__)
|
||||
self.assertFalse(l.__add__ == [].__add__)
|
||||
self.assertTrue(l.__add__ != [].__add__)
|
||||
self.assertFalse(l.__add__ == l.__mul__)
|
||||
self.assertTrue(l.__add__ != l.__mul__)
|
||||
self.assertNotOrderable(l.__add__, l.__add__)
|
||||
self.assertEqual(l.__add__.__name__, '__add__')
|
||||
if hasattr(l.__add__, '__self__'):
|
||||
# CPython
|
||||
self.assertIs(l.__add__.__self__, l)
|
||||
self.assertIs(l.__add__.__objclass__, list)
|
||||
else:
|
||||
# Python implementations where [].__add__ is a normal bound method
|
||||
self.assertIs(l.__add__.im_self, l)
|
||||
self.assertIs(l.__add__.im_class, list)
|
||||
self.assertIs(l.__add__.__self__, l)
|
||||
self.assertIs(l.__add__.__objclass__, list)
|
||||
self.assertEqual(l.__add__.__doc__, list.__add__.__doc__)
|
||||
try:
|
||||
hash(l.__add__)
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
self.fail("no TypeError from hash([].__add__)")
|
||||
# hash([].__add__) should not be based on hash([])
|
||||
hash(l.__add__)
|
||||
|
||||
t = ()
|
||||
t += (7,)
|
||||
self.assertEqual(t.__add__, (7,).__add__)
|
||||
self.assertEqual(hash(t.__add__), hash((7,).__add__))
|
||||
def test_builtin_function_or_method(self):
|
||||
# Not really belonging to test_descr, but introspection and
|
||||
# comparison on <type 'builtin_function_or_method'> seems not
|
||||
# to be tested elsewhere
|
||||
l = []
|
||||
self.assertTrue(l.append == l.append)
|
||||
self.assertFalse(l.append != l.append)
|
||||
self.assertFalse(l.append == [].append)
|
||||
self.assertTrue(l.append != [].append)
|
||||
self.assertFalse(l.append == l.pop)
|
||||
self.assertTrue(l.append != l.pop)
|
||||
self.assertNotOrderable(l.append, l.append)
|
||||
self.assertEqual(l.append.__name__, 'append')
|
||||
self.assertIs(l.append.__self__, l)
|
||||
# self.assertIs(l.append.__objclass__, list) --- could be added?
|
||||
self.assertEqual(l.append.__doc__, list.append.__doc__)
|
||||
# hash([].append) should not be based on hash([])
|
||||
hash(l.append)
|
||||
|
||||
def test_special_unbound_method_types(self):
|
||||
# Testing objects of <type 'wrapper_descriptor'>...
|
||||
self.assertTrue(list.__add__ == list.__add__)
|
||||
self.assertFalse(list.__add__ != list.__add__)
|
||||
self.assertFalse(list.__add__ == list.__mul__)
|
||||
self.assertTrue(list.__add__ != list.__mul__)
|
||||
self.assertNotOrderable(list.__add__, list.__add__)
|
||||
self.assertEqual(list.__add__.__name__, '__add__')
|
||||
self.assertIs(list.__add__.__objclass__, list)
|
||||
|
||||
# Testing objects of <type 'method_descriptor'>...
|
||||
self.assertTrue(list.append == list.append)
|
||||
self.assertFalse(list.append != list.append)
|
||||
self.assertFalse(list.append == list.pop)
|
||||
self.assertTrue(list.append != list.pop)
|
||||
self.assertNotOrderable(list.append, list.append)
|
||||
self.assertEqual(list.append.__name__, 'append')
|
||||
self.assertIs(list.append.__objclass__, list)
|
||||
|
||||
def test_not_implemented(self):
|
||||
# Testing NotImplemented...
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue