-////////////////////////////////////////////////////////////////////////
-test_class
-////////////////////////////////////////////////////////////////////////
-
-test test_class failed -- hash(C1()) should raise <class 'exceptions.TypeError'>
-Also hash(C2())
-Also stack blowout, recursing between
-#5921 0x0003868c in slot_tp_call (self=0x5b0c90, args=0x338030, kwds=0x0) at ../Objects/typeobject.c:4583
-#5922 0x00021124 in PyObject_Call (func=0x5b0c90, arg=0x3384c0, kw=0x134e10) at ../Objects/abstract.c:1791
-
-////////////////////////////////////////////////////////////////////////
-test_descr
-////////////////////////////////////////////////////////////////////////
-
-Testing hash of mutable subclasses...
-Traceback (most recent call last):
- File "../Lib/test/test_descr.py", line 4096, in <module>
- test_main()
- File "../Lib/test/test_descr.py", line 4059, in test_main
- hashinherit()
- File "../Lib/test/test_descr.py", line 3108, in hashinherit
- raise TestFailed, "hash() of dict subclass should fail"
-test.test_support.TestFailed: hash() of dict subclass should fail
-
-
-////////////////////////////////////////////////////////////////////////
-test_set
-////////////////////////////////////////////////////////////////////////
-
-======================================================================
-FAIL: test_contains (__main__.TestSetSubclass)
-----------------------------------------------------------------------
-Traceback (most recent call last):
- File "../Lib/test/test_set.py", line 52, in test_contains
- self.assert_(self.thetype(self.letters) in s)
-AssertionError
-
-======================================================================
-FAIL: test_discard (__main__.TestSetSubclass)
-----------------------------------------------------------------------
-Traceback (most recent call last):
- File "../Lib/test/test_set.py", line 302, in test_discard
- self.assert_(self.thetype(self.word) in s)
-AssertionError
-
-======================================================================
-FAIL: test_hash (__main__.TestSetSubclass)
-----------------------------------------------------------------------
-Traceback (most recent call last):
- File "../Lib/test/test_set.py", line 265, in test_hash
- self.assertRaises(TypeError, hash, self.s)
-AssertionError: TypeError not raised
-
-======================================================================
-FAIL: test_remove (__main__.TestSetSubclass)
-----------------------------------------------------------------------
-Traceback (most recent call last):
- File "../Lib/test/test_set.py", line 291, in test_remove
- self.assert_(self.thetype(self.word) in s)
-AssertionError
+(Nothing is broken at the moment AFAIK.)
COPYVAL(tp_dictoffset);
}
+/* Map rich comparison operators to their __xx__ namesakes */
+static char *name_op[] = {
+ "__lt__",
+ "__le__",
+ "__eq__",
+ "__ne__",
+ "__gt__",
+ "__ge__",
+ /* These are only for overrides_cmp_or_hash(): */
+ "__cmp__",
+ "__hash__",
+};
+
+static int
+overrides_cmp_or_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)
{
COPYSLOT(tp_call);
COPYSLOT(tp_str);
{
+ /* Copy comparison-related slots only when
+ not overriding them anywhere */
if (type->tp_compare == NULL &&
type->tp_richcompare == NULL &&
- type->tp_hash == NULL)
+ type->tp_hash == NULL &&
+ !overrides_cmp_or_hash(type))
{
type->tp_compare = base->tp_compare;
type->tp_richcompare = base->tp_richcompare;
PyTypeObject *base;
Py_ssize_t i, n;
+ if (strcmp(type->tp_name, "C") == 0) {
+ _Py_Break();
+ }
+
if (type->tp_flags & Py_TPFLAGS_READY) {
assert(type->tp_dict != NULL);
return 0;
}
}
+ /* 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) {
+ if (PyDict_GetItemString(type->tp_dict, "__hash__") == NULL) {
+ if (PyDict_SetItemString(type->tp_dict, "__hash__", Py_None) < 0)
+ goto error;
+ }
+ }
+
/* Some more special stuff */
base = type->tp_base;
if (base != NULL) {
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)
{