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/Lib/test/test_descr.py b/Lib/test/test_descr.py
index f481205..75ad135 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -3735,7 +3735,8 @@
 
 def meth_class_get():
     # Full coverage of descrobject.c::classmethod_get()
-    if verbose: print "Testing __get__ method of METH_CLASS C methods..."
+    if verbose:
+        print "Testing __get__ method of METH_CLASS C methods..."
     # Baseline
     arg = [1, 2, 3]
     res = {1: None, 2: None, 3: None}
@@ -3772,6 +3773,32 @@
     else:
         raise TestFailed, "shouldn't have allowed descr.__get__(None, int)"
 
+def isinst_isclass():
+    if verbose:
+        print "Testing proxy isinstance() and isclass()..."
+    class Proxy(object):
+        def __init__(self, obj):
+            self.__obj = obj
+        def __getattribute__(self, name):
+            if name.startswith("_Proxy__"):
+                return object.__getattribute__(self, name)
+            else:
+                return getattr(self.__obj, name)
+    # Test with a classic class
+    class C:
+        pass
+    a = C()
+    pa = Proxy(a)
+    verify(isinstance(a, C))  # Baseline
+    verify(isinstance(pa, C)) # Test
+    # Test with a new-style class
+    class C(object):
+        pass
+    a = C()
+    pa = Proxy(a)
+    verify(isinstance(a, C))  # Baseline
+    verify(isinstance(pa, C)) # Test
+
 
 def test_main():
     do_this_first()
@@ -3859,6 +3886,7 @@
     subclass_right_op()
     dict_type_with_metaclass()
     meth_class_get()
+    isinst_isclass()
 
     if verbose: print "All OK"
 
diff --git a/Misc/NEWS b/Misc/NEWS
index ed4f7cf..d88f753 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,11 @@
 Core and builtins
 -----------------
 
+- isinstance(x, X): if X is a new-style class, this is now equivalent
+  to issubclass(type(x), X) or issubclass(x.__class__, X).  Previously
+  only type(x) was tested.  (For classic classes this was already the
+  case.)
+
 - compile(), eval() and the exec statement now fully support source code
   passed as unicode strings.
 
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();