Index: Objects/methodobject.c =================================================================== --- Objects/methodobject.c (revision 61365) +++ Objects/methodobject.c (working copy) @@ -227,13 +227,9 @@ meth_hash(PyCFunctionObject *a) { long x,y; - if (a->m_self == NULL) - x = 0; - else { - x = PyObject_Hash(a->m_self); - if (x == -1) - return -1; - } + x = _Py_HashPointer(a->m_self); + if (x == -1) + return -1; y = _Py_HashPointer((void*)(a->m_ml->ml_meth)); if (y == -1) return -1; Index: Objects/descrobject.c =================================================================== --- Objects/descrobject.c (revision 61365) +++ Objects/descrobject.c (working copy) @@ -897,8 +897,10 @@ static int wrapper_compare(wrapperobject *a, wrapperobject *b) { + if (a->self != b->self) + return (a->self < b->self) ? -1 : 1; if (a->descr == b->descr) - return PyObject_Compare(a->self, b->self); + return 0; else return (a->descr < b->descr) ? -1 : 1; } @@ -907,10 +909,10 @@ wrapper_hash(wrapperobject *wp) { int x, y; - x = _Py_HashPointer(wp->descr); + x = _Py_HashPointer(wp->self); if (x == -1) return -1; - y = PyObject_Hash(wp->self); + y = _Py_HashPointer(wp->descr); if (y == -1) return -1; x = x ^ y; Index: Objects/classobject.c =================================================================== --- Objects/classobject.c (revision 61365) +++ Objects/classobject.c (working copy) @@ -2359,10 +2359,8 @@ if (a->im_self == b->im_self) return 0; - if (a->im_self == NULL || b->im_self == NULL) - return (a->im_self < b->im_self) ? -1 : 1; else - return PyObject_Compare(a->im_self, b->im_self); + return (a->im_self < b->im_self) ? -1 : 1; } static PyObject * @@ -2429,10 +2427,7 @@ instancemethod_hash(PyMethodObject *a) { long x, y; - if (a->im_self == NULL) - x = PyObject_Hash(Py_None); - else - x = PyObject_Hash(a->im_self); + x = _Py_HashPointer(a->im_self); if (x == -1) return -1; y = PyObject_Hash(a->im_func); Index: Lib/test/test_descr.py =================================================================== --- Lib/test/test_descr.py (revision 61365) +++ Lib/test/test_descr.py (working copy) @@ -4178,7 +4178,7 @@ l = [] self.assertEqual(l.__add__, l.__add__) - self.assertEqual(l.__add__, [].__add__) + self.assert_(l.__add__ != [].__add__) self.assert_(l.__add__ != [5].__add__) self.assert_(l.__add__ != l.__mul__) self.assert_(l.__add__.__name__ == '__add__') @@ -4188,15 +4188,39 @@ try: hash(l.__add__) except TypeError: - pass - else: - self.fail("no TypeError from hash([].__add__)") + self.fail("hash([].__add__) should not be based on hash([])") - 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 seems not + # to be tested elsewhere + l = [] + self.assertEqual(l.append, l.append) + self.assert_(l.append != [].append) + self.assert_(l.append != [5].append) + self.assert_(l.append != l.__mul__) + self.assert_(l.append.__name__ == 'append') + self.assert_(l.append.__self__ is l) + #self.assert_(l.append.__objclass__ is list) --- could be added? + self.assertEqual(l.append.__doc__, list.append.__doc__) + try: + hash(l.append) + except TypeError: + self.fail("hash([].append) should not be based on hash([])") + def test_special_unbound_method_types(self): + # Testing objects of ... + self.assertEqual(list.__add__, list.__add__) + self.assert_(list.__add__ != list.__mul__) + self.assert_(list.__add__.__name__ == '__add__') + self.assert_(list.__add__.__objclass__ is list) + + # Testing objects of ... + self.assertEqual(list.append, list.append) + self.assert_(list.append != list.pop) + self.assert_(list.append.__name__ == 'append') + self.assert_(list.append.__objclass__ is list) + def test_not_implemented(self): # Testing NotImplemented... # all binary methods should be able to return a NotImplemented Index: Lib/test/test_class.py =================================================================== --- Lib/test/test_class.py (revision 61365) +++ Lib/test/test_class.py (working copy) @@ -584,37 +584,29 @@ def testHashComparisonOfMethods(self): # Test comparison and hash of methods class A: - def __init__(self, x): - self.x = x def f(self): pass def g(self): pass def __eq__(self, other): - return self.x == other.x + return True def __hash__(self): - return self.x + raise TypeError class B(A): pass - a1 = A(1) - a2 = A(2) + a1 = A() + a2 = A() self.assertEquals(a1.f, a1.f) self.assertNotEquals(a1.f, a2.f) self.assertNotEquals(a1.f, a1.g) - self.assertEquals(a1.f, A(1).f) self.assertEquals(hash(a1.f), hash(a1.f)) - self.assertEquals(hash(a1.f), hash(A(1).f)) self.assertNotEquals(A.f, a1.f) self.assertNotEquals(A.f, A.g) self.assertEquals(B.f, A.f) self.assertEquals(hash(B.f), hash(A.f)) - # the following triggers a SystemError in 2.4 - a = A(hash(A.f.im_func)^(-1)) - hash(a.f) - def test_main(): test_support.run_unittest(ClassTests)