PySequence_Check(), PyMapping_Check(): only return true if the
corresponding "getitem" operation (sq_item or mp_subscript) is implemented. I realize that "sequence-ness" and "mapping-ness" are poorly defined (and the tests may still be wrong for user-defined instances, which always have both slots filled), but I believe that a sequence that doesn't support its getitem operation should not be considered a sequence. All other operations are optional though. For example, the ZODB BTree tests crashed because PySequence_Check() returned true for a dictionary! (In 2.2, the dictionary type has a tp_as_sequence pointer, but the only field filled is sq_contains, so you can write "if key in dict".) With this fix, all standalone ZODB tests succeed.
This commit is contained in:
parent
9478d07ee7
commit
8700b4281a
|
@ -919,7 +919,8 @@ PyNumber_Float(PyObject *o)
|
|||
int
|
||||
PySequence_Check(PyObject *s)
|
||||
{
|
||||
return s != NULL && s->ob_type->tp_as_sequence;
|
||||
return s != NULL && s->ob_type->tp_as_sequence &&
|
||||
s->ob_type->tp_as_sequence->sq_item != NULL;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1509,7 +1510,8 @@ PySequence_Index(PyObject *s, PyObject *o)
|
|||
int
|
||||
PyMapping_Check(PyObject *o)
|
||||
{
|
||||
return o && o->ob_type->tp_as_mapping;
|
||||
return o && o->ob_type->tp_as_mapping &&
|
||||
o->ob_type->tp_as_mapping->mp_subscript;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
Loading…
Reference in New Issue