mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
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.
This commit is contained in:
parent
0780e470dc
commit
4440f22e98
1 changed files with 14 additions and 9 deletions
|
@ -742,6 +742,14 @@ get_inprogress_dict(void)
|
||||||
return inprogress;
|
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 *
|
static PyObject *
|
||||||
check_recursion(PyObject *v, PyObject *w, int op)
|
check_recursion(PyObject *v, PyObject *w, int op)
|
||||||
{
|
{
|
||||||
|
@ -830,10 +838,9 @@ PyObject_Compare(PyObject *v, PyObject *w)
|
||||||
vtp = v->ob_type;
|
vtp = v->ob_type;
|
||||||
compare_nesting++;
|
compare_nesting++;
|
||||||
if (compare_nesting > NESTING_LIMIT &&
|
if (compare_nesting > NESTING_LIMIT &&
|
||||||
(vtp->tp_as_mapping
|
(vtp->tp_as_mapping || vtp->tp_as_sequence) &&
|
||||||
|| (vtp->tp_as_sequence
|
!PyString_CheckExact(v) &&
|
||||||
&& !PyString_Check(v)
|
!PyTuple_CheckExact(v)) {
|
||||||
&& !PyTuple_Check(v)))) {
|
|
||||||
/* try to detect circular data structures */
|
/* try to detect circular data structures */
|
||||||
PyObject *token = check_recursion(v, w, -1);
|
PyObject *token = check_recursion(v, w, -1);
|
||||||
|
|
||||||
|
@ -927,11 +934,9 @@ PyObject_RichCompare(PyObject *v, PyObject *w, int op)
|
||||||
|
|
||||||
compare_nesting++;
|
compare_nesting++;
|
||||||
if (compare_nesting > NESTING_LIMIT &&
|
if (compare_nesting > NESTING_LIMIT &&
|
||||||
(v->ob_type->tp_as_mapping
|
(v->ob_type->tp_as_mapping || v->ob_type->tp_as_sequence) &&
|
||||||
|| (v->ob_type->tp_as_sequence
|
!PyString_CheckExact(v) &&
|
||||||
&& !PyString_Check(v)
|
!PyTuple_CheckExact(v)) {
|
||||||
&& !PyTuple_Check(v)))) {
|
|
||||||
|
|
||||||
/* try to detect circular data structures */
|
/* try to detect circular data structures */
|
||||||
PyObject *token = check_recursion(v, w, op);
|
PyObject *token = check_recursion(v, w, op);
|
||||||
if (token == NULL) {
|
if (token == NULL) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue