Guido van Rossum added the comment:

I can reproduce the segfault in 2.2 through 2.4; in 2.5 and 2.6 the
output is this instead:

Test 1, using __eq__(a, b).__nonzero__()
this is never the right answer
Test 2, using tuple's tp_richcompare
New Watch 0xf7f8cbac
New Watch 0xf7f8cc0c
Deleting Watch 0xf7f8cbac
Deleting Watch 0xf7f8cbac
Deleting Watch 0xf7f8cc0c
Traceback (most recent call last):
  File "/tmp/", line 72, in <module>
    print(d[(Bar(), Watch())])
TypeError: __eq__() takes exactly 1 argument (2 given)

which suggests it's still there ("this is never the right answer").

In 3.0 the output from the 1st test is "this is an acceptable answer"
suggesting it's no longer there; but I suspect it's there in 3.0 as well
but due to the unicode transition the dict code there is different
enough that the example doesn't trigger it.

The key that needs to be INCREF'ed is actually startkey.  Patch attached.

nosy: +gvanrossum
versions: +Python 2.2, Python 2.2.1, Python 2.2.2, Python 2.2.3, Python 2.3, 
Python 2.4, Python 2.5, Python 2.6
Added file:

Index: Objects/dictobject.c
--- Objects/dictobject.c	(revision 59221)
+++ Objects/dictobject.c	(working copy)
@@ -272,7 +272,9 @@
 	else {
 		if (ep->me_hash == hash) {
 			startkey = ep->me_key;
+                        Py_INCREF(startkey);
 			cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
+                        Py_DECREF(startkey);
 			if (cmp < 0)
 				return NULL;
 			if (ep0 == mp->ma_table && ep->me_key == startkey) {
Python-bugs-list mailing list 

Reply via email to