[Python-checkins] python/dist/src/Objects abstract.c,2.110,2.111 classobject.c,2.164,2.165

doerwalter@users.sourceforge.net doerwalter@users.sourceforge.net
2002年12月12日 08:41:46 -0800


Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1:/tmp/cvs-serv439/Objects
Modified Files:
	abstract.c classobject.c 
Log Message:
Enhance issubclass() and PyObject_IsSubclass() so that a tuple is
supported as the second argument. This has the same meaning as
for isinstance(), i.e. issubclass(X, (A, B)) is equivalent
to issubclass(X, A) or issubclass(X, B). Compared to isinstance(),
this patch does not search the tuple recursively for classes, i.e.
any entry in the tuple that is not a class, will result in a
TypeError.
This closes SF patch #649608.
Index: abstract.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v
retrieving revision 2.110
retrieving revision 2.111
diff -C2 -d -r2.110 -r2.111
*** abstract.c	7 Dec 2002 10:05:25 -0000	2.110
--- abstract.c	12 Dec 2002 16:41:41 -0000	2.111
***************
*** 1915,1918 ****
--- 1915,1927 ----
 		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) {
***************
*** 1933,1936 ****
--- 1942,1959 ----
 }
 
+ 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)
***************
*** 1963,1976 ****
 	}
 	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");
 			return -1;
- 		}
- 		Py_DECREF(cls_bases);
 		if (__class__ == NULL) {
 			__class__ = PyString_FromString("__class__");
--- 1986,1993 ----
 	}
 	else {
! 		if (!check_class(cls,
! 			"isinstance() arg 2 must be a class, type,"
! 			" or tuple of classes and types"))
 			return -1;
 		if (__class__ == NULL) {
 			__class__ = PyString_FromString("__class__");
***************
*** 1998,2023 ****
 
 	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");
 			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;
 		}
- 		Py_DECREF(cls_bases);
 
 		retval = abstract_issubclass(derived, cls);
--- 2015,2037 ----
 
 	if (!PyClass_Check(derived) || !PyClass_Check(cls)) {
! 		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;
! 			}
! 		}
! 		else {
! 			if (!check_class(cls,
! 					"issubclass() arg 2 must be a class"
! 					" or tuple of classes"))
! 				return -1;
 		}
 
 		retval = abstract_issubclass(derived, cls);
Index: classobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v
retrieving revision 2.164
retrieving revision 2.165
diff -C2 -d -r2.164 -r2.165
*** classobject.c	29 Oct 2002 18:36:40 -0000	2.164
--- classobject.c	12 Dec 2002 16:41:42 -0000	2.165
***************
*** 488,491 ****
--- 488,498 ----
 	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;

AltStyle によって変換されたページ (->オリジナル) /