diff options
author | Guido van Rossum <guido@python.org> | 2007-11-22 00:55:51 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2007-11-22 00:55:51 (GMT) |
commit | 64c06e327d48150fc548cf18a4a7ae0b890e69fa (patch) | |
tree | daf53ab57c369a3d92c5a9deafc41df2ccd96127 /Objects | |
parent | cc7f26bf207ee17e2c1b3e6545e145942aff612d (diff) | |
download | cpython-64c06e327d48150fc548cf18a4a7ae0b890e69fa.zip cpython-64c06e327d48150fc548cf18a4a7ae0b890e69fa.tar.gz cpython-64c06e327d48150fc548cf18a4a7ae0b890e69fa.tar.bz2 |
Backport of _abccoll.py by Benjamin Arangueren, issue 1383.
With some changes of my own thrown in (e.g. backport of r58107).
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/dictobject.c | 9 | ||||
-rw-r--r-- | Objects/listobject.c | 10 | ||||
-rw-r--r-- | Objects/object.c | 2 | ||||
-rw-r--r-- | Objects/setobject.c | 9 | ||||
-rw-r--r-- | Objects/typeobject.c | 60 |
5 files changed, 46 insertions, 44 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 978071b..bfb891c 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2127,13 +2127,6 @@ dict_init(PyObject *self, PyObject *args, PyObject *kwds) return dict_update_common(self, args, kwds, "dict"); } -static long -dict_nohash(PyObject *self) -{ - PyErr_SetString(PyExc_TypeError, "dict objects are unhashable"); - return -1; -} - static PyObject * dict_iter(PyDictObject *dict) { @@ -2165,7 +2158,7 @@ PyTypeObject PyDict_Type = { 0, /* tp_as_number */ &dict_as_sequence, /* tp_as_sequence */ &dict_as_mapping, /* tp_as_mapping */ - dict_nohash, /* tp_hash */ + 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ diff --git a/Objects/listobject.c b/Objects/listobject.c index fb5ce82..deb3ca5 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2393,13 +2393,6 @@ list_init(PyListObject *self, PyObject *args, PyObject *kw) return 0; } -static long -list_nohash(PyObject *self) -{ - PyErr_SetString(PyExc_TypeError, "list objects are unhashable"); - return -1; -} - static PyObject *list_iter(PyObject *seq); static PyObject *list_reversed(PyListObject* seq, PyObject* unused); @@ -2694,7 +2687,7 @@ PyTypeObject PyList_Type = { 0, /* tp_as_number */ &list_as_sequence, /* tp_as_sequence */ &list_as_mapping, /* tp_as_mapping */ - list_nohash, /* tp_hash */ + 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ @@ -2959,4 +2952,3 @@ listreviter_len(listreviterobject *it) return 0; return len; } - diff --git a/Objects/object.c b/Objects/object.c index e75a03d..de385ea 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1902,7 +1902,7 @@ static PyTypeObject PyNone_Type = { 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ - 0, /*tp_hash */ + (hashfunc)_Py_HashPointer, /*tp_hash */ }; PyObject _Py_NoneStruct = { diff --git a/Objects/setobject.c b/Objects/setobject.c index 3cbcd9e..b049d09 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -789,13 +789,6 @@ frozenset_hash(PyObject *self) return hash; } -static long -set_nohash(PyObject *self) -{ - PyErr_SetString(PyExc_TypeError, "set objects are unhashable"); - return -1; -} - /***** Set iterator type ***********************************************/ typedef struct { @@ -2012,7 +2005,7 @@ PyTypeObject PySet_Type = { &set_as_number, /* tp_as_number */ &set_as_sequence, /* tp_as_sequence */ 0, /* tp_as_mapping */ - set_nohash, /* tp_hash */ + 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 59dec4a..1a221c8 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2590,12 +2590,6 @@ object_str(PyObject *self) return f(self); } -static long -object_hash(PyObject *self) -{ - return _Py_HashPointer(self); -} - static PyObject * object_get_class(PyObject *self, void *closure) { @@ -3030,7 +3024,7 @@ PyTypeObject PyBaseObject_Type = { 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ - object_hash, /* tp_hash */ + (hashfunc)_Py_HashPointer, /* tp_hash */ 0, /* tp_call */ object_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ @@ -3236,6 +3230,33 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) type->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS; } +/* Map rich comparison operators to their __xx__ namesakes */ +static char *name_op[] = { + "__lt__", + "__le__", + "__eq__", + "__ne__", + "__gt__", + "__ge__", + "__cmp__", + /* These are only for overrides_hash(): */ + "__hash__", +}; + +static int +overrides_hash(PyTypeObject *type) +{ + int i; + PyObject *dict = type->tp_dict; + + assert(dict != NULL); + for (i = 0; i < 8; i++) { + if (PyDict_GetItemString(dict, name_op[i]) != NULL) + return 1; + } + return 0; +} + static void inherit_slots(PyTypeObject *type, PyTypeObject *base) { @@ -3367,7 +3388,8 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_RICHCOMPARE) { if (type->tp_compare == NULL && type->tp_richcompare == NULL && - type->tp_hash == NULL) + type->tp_hash == NULL && + !overrides_hash(type)) { type->tp_compare = base->tp_compare; type->tp_richcompare = base->tp_richcompare; @@ -3548,6 +3570,18 @@ PyType_Ready(PyTypeObject *type) } } + /* Hack for tp_hash and __hash__. + If after all that, tp_hash is still NULL, and __hash__ is not in + tp_dict, set tp_dict['__hash__'] equal to None. + This signals that __hash__ is not inherited. + */ + if (type->tp_hash == NULL && + PyDict_GetItemString(type->tp_dict, "__hash__") == NULL && + PyDict_SetItemString(type->tp_dict, "__hash__", Py_None) < 0) + { + goto error; + } + /* Some more special stuff */ base = type->tp_base; if (base != NULL) { @@ -4937,16 +4971,6 @@ slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value) return 0; } -/* Map rich comparison operators to their __xx__ namesakes */ -static char *name_op[] = { - "__lt__", - "__le__", - "__eq__", - "__ne__", - "__gt__", - "__ge__", -}; - static PyObject * half_richcompare(PyObject *self, PyObject *other, int op) { |