]> granicus.if.org Git - python/commitdiff
PySequence_Check(), PyMapping_Check(): only return true if the
authorGuido van Rossum <guido@python.org>
Fri, 7 Sep 2001 20:20:11 +0000 (20:20 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 7 Sep 2001 20:20:11 +0000 (20:20 +0000)
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.

Objects/abstract.c

index f7ade6de63d545c7acdd6a34f1f975351cafcdb4..c3a397c7c0d47d428b985e74cf45f21b6892f317 100644 (file)
@@ -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