summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'Objects')
-rw-r--r--Objects/abstract.c70
-rw-r--r--Objects/classobject.c7
2 files changed, 49 insertions, 28 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index e77cde3..47d2f31 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -1914,6 +1914,15 @@ abstract_issubclass(PyObject *derived, PyObject *cls)
if (derived == cls)
return 1;
+ if (PyTuple_Check(cls)) {
+ /* Not a general sequence -- that opens up the road to
+ recursion and stack overflow. */
+ n = PyTuple_GET_SIZE(cls);
+ for (i = 0; i < n; i++) {
+ if (derived == PyTuple_GET_ITEM(cls, i))
+ return 1;
+ }
+ }
bases = abstract_get_bases(derived);
if (bases == NULL) {
if (PyErr_Occurred())
@@ -1932,6 +1941,20 @@ abstract_issubclass(PyObject *derived, PyObject *cls)
return r;
}
+static int
+check_class(PyObject *cls, const char *error)
+{
+ PyObject *bases = abstract_get_bases(cls);
+ if (bases == NULL) {
+ /* Do not mask errors. */
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError, error);
+ return 0;
+ }
+ Py_DECREF(bases);
+ return -1;
+}
+
int
PyObject_IsInstance(PyObject *inst, PyObject *cls)
{
@@ -1962,16 +1985,10 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
return retval;
}
else {
- PyObject *cls_bases = abstract_get_bases(cls);
- if (cls_bases == NULL) {
- /* Do not mask errors. */
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_TypeError,
- "isinstance() arg 2 must be a class, type,"
- " or tuple of classes and types");
+ if (!check_class(cls,
+ "isinstance() arg 2 must be a class, type,"
+ " or tuple of classes and types"))
return -1;
- }
- Py_DECREF(cls_bases);
if (__class__ == NULL) {
__class__ = PyString_FromString("__class__");
if (__class__ == NULL)
@@ -1997,28 +2014,25 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
int retval;
if (!PyClass_Check(derived) || !PyClass_Check(cls)) {
- PyObject *derived_bases;
- PyObject *cls_bases;
-
- derived_bases = abstract_get_bases(derived);
- if (derived_bases == NULL) {
- /* Do not mask errors */
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_TypeError,
- "issubclass() arg 1 must be a class");
+ if (!check_class(derived, "issubclass() arg 1 must be a class"))
return -1;
+
+ if (PyTuple_Check(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;
+ }
}
- Py_DECREF(derived_bases);
-
- cls_bases = abstract_get_bases(cls);
- if (cls_bases == NULL) {
- /* Do not mask errors */
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_TypeError,
- "issubclass() arg 2 must be a class");
- return -1;
+ else {
+ if (!check_class(cls,
+ "issubclass() arg 2 must be a class"
+ " or tuple of classes"))
+ return -1;
}
- Py_DECREF(cls_bases);
retval = abstract_issubclass(derived, cls);
}
diff --git a/Objects/classobject.c b/Objects/classobject.c
index f7b442a..f3b9873 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -487,6 +487,13 @@ PyClass_IsSubclass(PyObject *class, PyObject *base)
PyClassObject *cp;
if (class == base)
return 1;
+ if (PyTuple_Check(base)) {
+ n = PyTuple_GET_SIZE(base);
+ for (i = 0; i < n; i++) {
+ if (class == PyTuple_GET_ITEM(base, i))
+ return 1;
+ }
+ }
if (class == NULL || !PyClass_Check(class))
return 0;
cp = (PyClassObject *)class;