]> granicus.if.org Git - python/commitdiff
Recursive compare machinery: The code that intended to exempt tuples
authorTim Peters <tim.peters@gmail.com>
Mon, 20 Jan 2003 16:54:59 +0000 (16:54 +0000)
committerTim Peters <tim.peters@gmail.com>
Mon, 20 Jan 2003 16:54:59 +0000 (16:54 +0000)
was broken because new-in-2.3 code added a tp_as_mapping slot to tuples.
Repaired that.

Added basic docs to check_recursion().

The code that intended to exempt tuples and strings was also broken here,
and in 2.2:  these should use PyXYZ_CheckExact(), not PyXYZ_Check() -- we
can't know whether subclass instances are immutable.  This part (and this
part alone) is a bugfix candidate.

Objects/object.c

index e3234deca72dd5fded659606fba9577a3bd9b5e3..e44edca96c725cd92814415019daca3e2622757a 100644 (file)
@@ -742,6 +742,14 @@ get_inprogress_dict(void)
        return inprogress;
 }
 
+/* If the comparison "v op w" is already in progress in this thread, returns
+ * a borrowed reference to Py_None (the caller must not decref).
+ * If it's not already in progress, returns "a token" which must eventually
+ * be passed to delete_token().  The caller must not decref this either
+ * (delete_token decrefs it).  The token must not survive beyond any point
+ * where v or w may die.
+ * If an error occurs (out-of-memory), returns NULL.
+ */
 static PyObject *
 check_recursion(PyObject *v, PyObject *w, int op)
 {
@@ -830,10 +838,9 @@ PyObject_Compare(PyObject *v, PyObject *w)
        vtp = v->ob_type;
        compare_nesting++;
        if (compare_nesting > NESTING_LIMIT &&
-               (vtp->tp_as_mapping
-                || (vtp->tp_as_sequence
-                    && !PyString_Check(v)
-                    && !PyTuple_Check(v)))) {
+           (vtp->tp_as_mapping || vtp->tp_as_sequence) &&
+           !PyString_CheckExact(v) &&
+           !PyTuple_CheckExact(v)) {
                /* try to detect circular data structures */
                PyObject *token = check_recursion(v, w, -1);
 
@@ -927,11 +934,9 @@ PyObject_RichCompare(PyObject *v, PyObject *w, int op)
 
        compare_nesting++;
        if (compare_nesting > NESTING_LIMIT &&
-               (v->ob_type->tp_as_mapping
-                || (v->ob_type->tp_as_sequence
-                    && !PyString_Check(v)
-                    && !PyTuple_Check(v)))) {
-
+           (v->ob_type->tp_as_mapping || v->ob_type->tp_as_sequence) &&
+           !PyString_CheckExact(v) &&
+           !PyTuple_CheckExact(v)) {
                /* try to detect circular data structures */
                PyObject *token = check_recursion(v, w, op);
                if (token == NULL) {