mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	Make isinstance() more permissive in what types of arguments it
accepts. Clarify exception messages for isinstance() and issubclass(). Closes bug #124106.
This commit is contained in:
		
							parent
							
								
									24342d96c5
								
							
						
					
					
						commit
						cc343caf41
					
				
					 1 changed files with 9 additions and 17 deletions
				
			
		|  | @ -1995,7 +1995,7 @@ Without arguments, equivalent to locals().\n\ | ||||||
| With an argument, equivalent to object.__dict__."; | With an argument, equivalent to object.__dict__."; | ||||||
| 
 | 
 | ||||||
| static int | static int | ||||||
| abstract_issubclass(PyObject *derived, PyObject *cls, char *err, int first) | abstract_issubclass(PyObject *derived, PyObject *cls, int first) | ||||||
| { | { | ||||||
| 	static PyObject *__bases__ = NULL; | 	static PyObject *__bases__ = NULL; | ||||||
| 	PyObject *bases; | 	PyObject *bases; | ||||||
|  | @ -2012,7 +2012,8 @@ abstract_issubclass(PyObject *derived, PyObject *cls, char *err, int first) | ||||||
| 		bases = PyObject_GetAttr(cls, __bases__); | 		bases = PyObject_GetAttr(cls, __bases__); | ||||||
| 		if (bases == NULL || !PyTuple_Check(bases)) { | 		if (bases == NULL || !PyTuple_Check(bases)) { | ||||||
| 		        Py_XDECREF(bases); | 		        Py_XDECREF(bases); | ||||||
| 	        	PyErr_SetString(PyExc_TypeError, err); | 	        	PyErr_SetString(PyExc_TypeError, | ||||||
|  | 					"arg 2 must be a class or type"); | ||||||
| 			return -1; | 			return -1; | ||||||
| 		} | 		} | ||||||
| 		Py_DECREF(bases); | 		Py_DECREF(bases); | ||||||
|  | @ -2024,14 +2025,14 @@ abstract_issubclass(PyObject *derived, PyObject *cls, char *err, int first) | ||||||
| 	bases = PyObject_GetAttr(derived, __bases__); | 	bases = PyObject_GetAttr(derived, __bases__); | ||||||
| 	if (bases == NULL || !PyTuple_Check(bases)) { | 	if (bases == NULL || !PyTuple_Check(bases)) { | ||||||
| 	        Py_XDECREF(bases); | 	        Py_XDECREF(bases); | ||||||
| 	        PyErr_SetString(PyExc_TypeError, err); | 		PyErr_SetString(PyExc_TypeError, | ||||||
|  | 				"arg 2 must be a class or type"); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	n = PyTuple_GET_SIZE(bases); | 	n = PyTuple_GET_SIZE(bases); | ||||||
| 	for (i = 0; i < n; i++) { | 	for (i = 0; i < n; i++) { | ||||||
| 		r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), | 		r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls, 0); | ||||||
| 					cls, err, 0); |  | ||||||
| 		if (r != 0) | 		if (r != 0) | ||||||
| 			break; | 			break; | ||||||
| 	} | 	} | ||||||
|  | @ -2071,25 +2072,17 @@ builtin_isinstance(PyObject *self, PyObject *args) | ||||||
| 		} | 		} | ||||||
| 		icls = PyObject_GetAttr(inst, __class__); | 		icls = PyObject_GetAttr(inst, __class__); | ||||||
| 		if (icls != NULL) { | 		if (icls != NULL) { | ||||||
| 			retval = abstract_issubclass( | 			retval = abstract_issubclass( icls, cls, 1); | ||||||
| 				icls, cls, |  | ||||||
| 				"isinstance() arg 2 must be a class",  |  | ||||||
| 				1); |  | ||||||
| 			Py_DECREF(icls); | 			Py_DECREF(icls); | ||||||
| 			if (retval < 0) | 			if (retval < 0) | ||||||
| 				return NULL; | 				return NULL; | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			PyErr_SetString(PyExc_TypeError, | 			PyErr_SetString(PyExc_TypeError, | ||||||
| 					"isinstance() arg 2 must be a class"); | 					"arg 2 must be a class or type"); | ||||||
| 			return NULL; | 			return NULL; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|         else { |  | ||||||
| 		PyErr_SetString(PyExc_TypeError, |  | ||||||
| 				"isinstance() arg 2 must be a class"); |  | ||||||
| 		return NULL; |  | ||||||
| 	} |  | ||||||
| 	return PyInt_FromLong(retval); | 	return PyInt_FromLong(retval); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -2111,8 +2104,7 @@ builtin_issubclass(PyObject *self, PyObject *args) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 
 | 
 | ||||||
| 	if (!PyClass_Check(derived) || !PyClass_Check(cls)) { | 	if (!PyClass_Check(derived) || !PyClass_Check(cls)) { | ||||||
| 		retval = abstract_issubclass( | 		retval = abstract_issubclass(derived, cls, 1); | ||||||
| 				derived, cls, "arguments must be classes", 1); |  | ||||||
| 		if (retval < 0)  | 		if (retval < 0)  | ||||||
| 			return NULL; | 			return NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Neil Schemenauer
						Neil Schemenauer