Address SF patch #480716 as well as related issues.

SF patch #480716 by Greg Chapman fixes the problem that super's
__get__ method always returns an instance of super, even when the
instance whose __get__ method is called is an instance of a subclass
of super.

Other issues fixed:

- super(C, C()).__class__ would return the __class__ attribute of C()
  rather than the __class__ attribute of the super object.  This is
  confusing.  To fix this, I decided to change the semantics of super
  so that it only applies to code attributes, not to data attributes.
  After all, overriding data attributes is not supported anyway.

- While super(C, x) carefully checked that x is an instance of C,
  super(C).__get__(x) made no such check, allowing for a loophole.
  This is now fixed.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index c79636d..6fc5d02 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -3929,7 +3929,7 @@
 			else
 				continue;
 			res = PyDict_GetItem(dict, name);
-			if (res != NULL) {
+			if (res != NULL  && !PyDescr_IsData(res)) {
 				Py_INCREF(res);
 				f = res->ob_type->tp_descr_get;
 				if (f != NULL) {
@@ -3944,6 +3944,21 @@
 	return PyObject_GenericGetAttr(self, name);
 }
 
+static int
+supercheck(PyTypeObject *type, PyObject *obj)
+{
+	if (!PyType_IsSubtype(obj->ob_type, type) &&
+	    !(PyType_Check(obj) &&
+	      PyType_IsSubtype((PyTypeObject *)obj, type))) {
+		PyErr_SetString(PyExc_TypeError,
+			"super(type, obj): "
+			"obj must be an instance or subtype of type");
+		return -1;
+	}
+	else
+		return 0;
+}
+
 static PyObject *
 super_descr_get(PyObject *self, PyObject *obj, PyObject *type)
 {
@@ -3955,14 +3970,25 @@
 		Py_INCREF(self);
 		return self;
 	}
-	new = (superobject *)PySuper_Type.tp_new(&PySuper_Type, NULL, NULL);
-	if (new == NULL)
-		return NULL;
-	Py_INCREF(su->type);
-	Py_INCREF(obj);
-	new->type = su->type;
-	new->obj = obj;
-	return (PyObject *)new;
+	if (su->ob_type != &PySuper_Type)
+		/* If su is an instance of a subclass of super,
+		   call its type */
+		return PyObject_CallFunction((PyObject *)su->ob_type,
+					     "OO", su->type, obj);
+	else {
+		/* Inline the common case */
+		if (supercheck(su->type, obj) < 0)
+			return NULL;
+		new = (superobject *)PySuper_Type.tp_new(&PySuper_Type,
+							 NULL, NULL);
+		if (new == NULL)
+			return NULL;
+		Py_INCREF(su->type);
+		Py_INCREF(obj);
+		new->type = su->type;
+		new->obj = obj;
+		return (PyObject *)new;
+	}
 }
 
 static int
@@ -3976,15 +4002,8 @@
 		return -1;
 	if (obj == Py_None)
 		obj = NULL;
-	if (obj != NULL &&
-	    !PyType_IsSubtype(obj->ob_type, type) &&
-	    !(PyType_Check(obj) &&
-	      PyType_IsSubtype((PyTypeObject *)obj, type))) {
-		PyErr_SetString(PyExc_TypeError,
-			"super(type, obj): "
-			"obj must be an instance or subtype of type");
+	if (obj != NULL && supercheck(type, obj) < 0)
 		return -1;
-	}
 	Py_INCREF(type);
 	Py_XINCREF(obj);
 	su->type = type;