From 7e5c6a02eba1a6f5e93bfa1241ceff39bec9f3c9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Walter=20D=C3=B6rwald?= Date: Thu, 12 Dec 2002 19:14:08 +0000 Subject: [PATCH] Change issubclass() so that recursive tuples (directly or indirectly 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 | 19 ++++++++++++++++++- Objects/abstract.c | 8 ++++---- Objects/classobject.c | 3 ++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index 1bb09a6edc..5a19387ab9 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -165,6 +165,13 @@ class Super: class Child(Super): pass +# new-style classes +class NewSuper(object): + pass + +class NewChild(NewSuper): + pass + 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)))) diff --git a/Objects/abstract.c b/Objects/abstract.c index 47d2f31dd7..8389774e2f 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -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, diff --git a/Objects/classobject.c b/Objects/classobject.c index f3b98733de..5234a658a2 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -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; -- 2.40.0