]> granicus.if.org Git - python/commitdiff
Change issubclass() so that recursive tuples (directly or indirectly
authorWalter Dörwald <walter@livinglogic.de>
Thu, 12 Dec 2002 19:14:08 +0000 (19:14 +0000)
committerWalter Dörwald <walter@livinglogic.de>
Thu, 12 Dec 2002 19:14:08 +0000 (19:14 +0000)
containing class objects) are allowed as the second argument.
This makes issubclass() more similar to isinstance() where recursive
tuples are allowed too.

Lib/test/test_isinstance.py
Objects/abstract.c
Objects/classobject.c

index 1bb09a6edc353f695712a1fdb38bbd0db503f778..5a19387ab9c3926bf05f6791afc59c7ace353049 100644 (file)
@@ -165,6 +165,13 @@ class Super:
 class Child(Super):
     pass
 
+# new-style classes
+class NewSuper(object):
+    pass
+
+class NewChild(NewSuper):
+    pass
+
 
 \f
 class TestIsInstanceIsSubclass(unittest.TestCase):
@@ -225,7 +232,17 @@ class TestIsInstanceIsSubclass(unittest.TestCase):
         self.assertEqual(False, issubclass(Super, (Child,)))
         self.assertEqual(True, issubclass(Super, (Child, Super)))
         self.assertEqual(False, issubclass(Child, ()))
-        self.assertRaises(TypeError, issubclass, Child, ((Child,),))
+        self.assertEqual(True, issubclass(Super, (Child, (Super,))))
+
+        self.assertEqual(True, issubclass(NewChild, (NewChild,)))
+        self.assertEqual(True, issubclass(NewChild, (NewSuper,)))
+        self.assertEqual(False, issubclass(NewSuper, (NewChild,)))
+        self.assertEqual(True, issubclass(NewSuper, (NewChild, NewSuper)))
+        self.assertEqual(False, issubclass(NewChild, ()))
+        self.assertEqual(True, issubclass(NewSuper, (NewChild, (NewSuper,))))
+
+        self.assertEqual(True, issubclass(int, (long, (float, int))))
+        self.assertEqual(True, issubclass(str, (unicode, (Child, NewChild, basestring))))
 
 
 
index 47d2f31dd7f1da99131b219226f70888e34e1e54..8389774e2fa66242c2de1891cd3cf89227314e25 100644 (file)
@@ -2021,11 +2021,11 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
                        int i;
                        int n = PyTuple_GET_SIZE(cls);
                        for (i = 0; i < n; ++i) {
-                               if (!check_class(PyTuple_GET_ITEM(cls, i),
-                                               "issubclass() arg 2 must be a class"
-                                               " or tuple of classes"))
-                                       return -1;
+                               retval = PyObject_IsSubclass(derived, PyTuple_GET_ITEM(cls, i));
+                               if (retval != 0) /* either found it, or got an error */
+                                       return retval;
                        }
+                       return 0;
                }
                else {
                        if (!check_class(cls,
index f3b98733de02e00f975a67112b33215239504569..5234a658a248e78da1509aaa85c4965ccbb07577 100644 (file)
@@ -490,9 +490,10 @@ PyClass_IsSubclass(PyObject *class, PyObject *base)
        if (PyTuple_Check(base)) {
                n = PyTuple_GET_SIZE(base);
                for (i = 0; i < n; i++) {
-                       if (class == PyTuple_GET_ITEM(base, i))
+                       if (PyClass_IsSubclass(class, PyTuple_GET_ITEM(base, i)))
                                return 1;
                }
+               return 0;
        }
        if (class == NULL || !PyClass_Check(class))
                return 0;