Rich comparisons fallout: instance_hash() should check for both

__cmp__ and __eq__ absent before deciding to do a quickie
based on the object address.  (Tim Peters discovered this.)
This commit is contained in:
Guido van Rossum 2001-01-18 23:46:31 +00:00
parent 0c6614c789
commit 65e8bd7fd5
1 changed files with 14 additions and 7 deletions

View File

@ -762,21 +762,28 @@ instance_hash(PyInstanceObject *inst)
PyObject *func;
PyObject *res;
long outcome;
static PyObject *hashstr, *cmpstr;
static PyObject *hashstr, *eqstr, *cmpstr;
if (hashstr == NULL)
hashstr = PyString_InternFromString("__hash__");
func = instance_getattr(inst, hashstr);
if (func == NULL) {
/* If there is no __cmp__ method, we hash on the address.
If a __cmp__ method exists, there must be a __hash__. */
/* If there is no __eq__ and no __cmp__ method, we hash on the
address. If an __eq__ or __cmp__ method exists, there must
be a __hash__. */
PyErr_Clear();
if (cmpstr == NULL)
cmpstr = PyString_InternFromString("__cmp__");
func = instance_getattr(inst, cmpstr);
if (eqstr == NULL)
eqstr = PyString_InternFromString("__eq__");
func = instance_getattr(inst, eqstr);
if (func == NULL) {
PyErr_Clear();
return _Py_HashPointer(inst);
if (cmpstr == NULL)
cmpstr = PyString_InternFromString("__cmp__");
func = instance_getattr(inst, cmpstr);
if (func == NULL) {
PyErr_Clear();
return _Py_HashPointer(inst);
}
}
PyErr_SetString(PyExc_TypeError, "unhashable instance");
return -1;