summaryrefslogtreecommitdiff
path: root/Objects
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2006-06-08 10:56:24 +0000
committerArmin Rigo <arigo@tunes.org>2006-06-08 10:56:24 +0000
commitfd01d7933bc3e9fd64d81961fbb7eabddcc82bc3 (patch)
tree04841c9342f5a07bd7436f8520aa2d54f0e54580 /Objects
parent996710fd44426f43d54034ebf3ee2355fca18f6a (diff)
downloadcpython-git-fd01d7933bc3e9fd64d81961fbb7eabddcc82bc3.tar.gz
(arre, arigo) SF bug #1350060
Give a consistent behavior for comparison and hashing of method objects (both user- and built-in methods). Now compares the 'self' recursively. The hash was already asking for the hash of 'self'.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/classobject.c17
-rw-r--r--Objects/descrobject.c26
2 files changed, 33 insertions, 10 deletions
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 6d2c648de5..9e57269d24 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -2221,9 +2221,17 @@ instancemethod_dealloc(register PyMethodObject *im)
static int
instancemethod_compare(PyMethodObject *a, PyMethodObject *b)
{
- if (a->im_self != b->im_self)
+ int cmp;
+ cmp = PyObject_Compare(a->im_func, b->im_func);
+ if (cmp)
+ return cmp;
+
+ 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;
- return PyObject_Compare(a->im_func, b->im_func);
+ else
+ return PyObject_Compare(a->im_self, b->im_self);
}
static PyObject *
@@ -2299,7 +2307,10 @@ instancemethod_hash(PyMethodObject *a)
y = PyObject_Hash(a->im_func);
if (y == -1)
return -1;
- return x ^ y;
+ x = x ^ y;
+ if (x == -1)
+ x = -2;
+ return x;
}
static int
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index 561ba4a5f0..606ef05304 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -901,16 +901,28 @@ wrapper_dealloc(wrapperobject *wp)
static int
wrapper_compare(wrapperobject *a, wrapperobject *b)
{
- if (a->descr == b->descr) {
- if (a->self == b->self)
- return 0;
- else
- return (a->self < b->self) ? -1 : 1;
- }
+ if (a->descr == b->descr)
+ return PyObject_Compare(a->self, b->self);
else
return (a->descr < b->descr) ? -1 : 1;
}
+static long
+wrapper_hash(wrapperobject *wp)
+{
+ int x, y;
+ x = _Py_HashPointer(wp->descr);
+ if (x == -1)
+ return -1;
+ y = PyObject_Hash(wp->self);
+ if (y == -1)
+ return -1;
+ x = x ^ y;
+ if (x == -1)
+ x = -2;
+ return x;
+}
+
static PyObject *
wrapper_repr(wrapperobject *wp)
{
@@ -1008,7 +1020,7 @@ static PyTypeObject wrappertype = {
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
- 0, /* tp_hash */
+ (hashfunc)wrapper_hash, /* tp_hash */
(ternaryfunc)wrapper_call, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */