SF 548651:  Fix the METH_CLASS implementation.
Most of these patches are from Thomas Heller, with long lines folded
by Tim.  The change to test_descr.py is from Guido.  See the bug report.

Not a bugfix candidate -- METH_CLASS is new in 2.3.
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index 63e94e8..761e1ab 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -79,6 +79,13 @@
 }
 
 static PyObject *
+classmethod_get(PyMethodDescrObject *descr, PyObject *obj,
+		PyTypeObject *type)
+{
+	return PyCFunction_New(descr->d_method, (PyObject *)type);
+}
+
+static PyObject *
 method_get(PyMethodDescrObject *descr, PyObject *obj, PyTypeObject *type)
 {
 	PyObject *res;
@@ -213,6 +220,21 @@
 }
 
 static PyObject *
+classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args,
+		      PyObject *kwds)
+{
+	PyObject *func, *result;
+
+	func = PyCFunction_New(descr->d_method, (PyObject *)descr->d_type);
+	if (func == NULL)
+		return NULL;
+
+	result = PyEval_CallObjectWithKeywords(func, args, kwds);
+	Py_DECREF(func);
+	return result;
+}
+
+static PyObject *
 wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
 {
 	int argc;
@@ -373,6 +395,44 @@
 	0,					/* tp_descr_set */
 };
 
+static PyTypeObject PyClassMethodDescr_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"special_method_descriptor",
+	sizeof(PyMethodDescrObject),
+	0,
+	(destructor)descr_dealloc,		/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	(reprfunc)method_repr,			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	(ternaryfunc)classmethoddescr_call,		/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+	0,					/* tp_doc */
+	descr_traverse,				/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	descr_members,				/* tp_members */
+	method_getset,				/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	(descrgetfunc)classmethod_get,		/* tp_descr_get */
+	0,					/* tp_descr_set */
+};
+
 static PyTypeObject PyMemberDescr_Type = {
 	PyObject_HEAD_INIT(&PyType_Type)
 	0,
@@ -518,6 +578,18 @@
 }
 
 PyObject *
+PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method)
+{
+	PyMethodDescrObject *descr;
+
+	descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type,
+						 type, method->ml_name);
+	if (descr != NULL)
+		descr->d_method = method;
+	return (PyObject *)descr;
+}
+
+PyObject *
 PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
 {
 	PyMemberDescrObject *descr;
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 69adc50..712ec2c 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -963,17 +963,16 @@
 }
 
 static PyObject *
-dict_fromkeys(PyObject *mp, PyObject *args)
+dict_fromkeys(PyObject *cls, PyObject *args)
 {
 	PyObject *seq;
 	PyObject *value = Py_None;
 	PyObject *it;	/* iter(seq) */
 	PyObject *key;
 	PyObject *d;
-	PyObject *cls;
 	int status;
 
-	if (!PyArg_ParseTuple(args, "OO|O:fromkeys", &cls, &seq, &value))
+	if (!PyArg_ParseTuple(args, "O|O:fromkeys", &seq, &value))
 		return NULL;
 
 	d = PyObject_CallObject(cls, NULL);
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 0b7f00d..193b0cc 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2435,7 +2435,7 @@
 				     "method cannot be both class and static");
 				return -1;
 			}
-			descr = create_specialmethod(meth, PyClassMethod_New);
+			descr = PyDescr_NewClassMethod(type, meth);
 		}
 		else if (meth->ml_flags & METH_STATIC) {
 			descr = create_specialmethod(meth, PyStaticMethod_New);