Commit 3fea4a38 authored by Walter Dörwald's avatar Walter Dörwald

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.
parent 9130a9e2
...@@ -165,6 +165,13 @@ class Super: ...@@ -165,6 +165,13 @@ class Super:
class Child(Super): class Child(Super):
pass pass
# new-style classes
class NewSuper(object):
pass
class NewChild(NewSuper):
pass
class TestIsInstanceIsSubclass(unittest.TestCase): class TestIsInstanceIsSubclass(unittest.TestCase):
...@@ -225,7 +232,17 @@ class TestIsInstanceIsSubclass(unittest.TestCase): ...@@ -225,7 +232,17 @@ class TestIsInstanceIsSubclass(unittest.TestCase):
self.assertEqual(False, issubclass(Super, (Child,))) self.assertEqual(False, issubclass(Super, (Child,)))
self.assertEqual(True, issubclass(Super, (Child, Super))) self.assertEqual(True, issubclass(Super, (Child, Super)))
self.assertEqual(False, issubclass(Child, ())) 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))))
......
...@@ -2021,11 +2021,11 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls) ...@@ -2021,11 +2021,11 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
int i; int i;
int n = PyTuple_GET_SIZE(cls); int n = PyTuple_GET_SIZE(cls);
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
if (!check_class(PyTuple_GET_ITEM(cls, i), retval = PyObject_IsSubclass(derived, PyTuple_GET_ITEM(cls, i));
"issubclass() arg 2 must be a class" if (retval != 0) /* either found it, or got an error */
" or tuple of classes")) return retval;
return -1;
} }
return 0;
} }
else { else {
if (!check_class(cls, if (!check_class(cls,
......
...@@ -490,9 +490,10 @@ PyClass_IsSubclass(PyObject *class, PyObject *base) ...@@ -490,9 +490,10 @@ PyClass_IsSubclass(PyObject *class, PyObject *base)
if (PyTuple_Check(base)) { if (PyTuple_Check(base)) {
n = PyTuple_GET_SIZE(base); n = PyTuple_GET_SIZE(base);
for (i = 0; i < n; i++) { 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 1;
} }
return 0;
} }
if (class == NULL || !PyClass_Check(class)) if (class == NULL || !PyClass_Check(class))
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment