summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2003-01-20 16:54:59 (GMT)
committerTim Peters <tim.peters@gmail.com>2003-01-20 16:54:59 (GMT)
commit4440f22e987f2ccfb798eb8df349884082cccb64 (patch)
treea2dece7290ef6d87562a80a8e5a6259757419b85
parent0780e470dcba9d9b7307cbce7dcddd6053efaf53 (diff)
downloadcpython-4440f22e987f2ccfb798eb8df349884082cccb64.zip
cpython-4440f22e987f2ccfb798eb8df349884082cccb64.tar.gz
cpython-4440f22e987f2ccfb798eb8df349884082cccb64.tar.bz2
Recursive compare machinery: The code that intended to exempt tuples
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.
-rw-r--r--Objects/object.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/Objects/object.c b/Objects/object.c
index e3234de..e44edca 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -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) {