SF #532767: isinstance(x, X) should work when x is a proxy for an X
instance, as long as x.__class__ is X or a subclass thereof.
Did a little cleanup of PyObject_IsInstance() too.
diff --git a/Objects/abstract.c b/Objects/abstract.c
index abc7e70..45d2206 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -2040,6 +2040,12 @@
 	static PyObject *__class__ = NULL;
 	int retval = 0;
 
+	if (__class__ == NULL) {
+		__class__ = PyString_FromString("__class__");
+		if (__class__ == NULL)
+			return -1;
+	}
+
 	if (PyClass_Check(cls) && PyInstance_Check(inst)) {
 		PyObject *inclass =
 			(PyObject*)((PyInstanceObject*)inst)->in_class;
@@ -2047,6 +2053,19 @@
 	}
 	else if (PyType_Check(cls)) {
 		retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
+		if (retval == 0) {
+			PyObject *c = PyObject_GetAttr(inst, __class__);
+			if (c == NULL) {
+				PyErr_Clear();
+			}
+			else {
+				if (c != inst->ob_type && PyType_Check(c))
+					retval = PyType_IsSubtype(
+						(PyTypeObject *)c,
+						(PyTypeObject *)cls);
+				Py_DECREF(c);
+			}
+		}
 	}
 	else if (PyTuple_Check(cls)) {
 		/* Not a general sequence -- that opens up the road to
@@ -2060,18 +2079,12 @@
 			if (retval != 0)
 				break;
 		}
-		return retval;
 	}
 	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__");
-			if (__class__ == NULL)
-				return -1;
-		}
 		icls = PyObject_GetAttr(inst, __class__);
 		if (icls == NULL) {
 			PyErr_Clear();