Add optional docstrings to getset descriptors.  Fortunately, there's
no backwards compatibility to worry about, so I just pushed the
'closure' struct member to the back -- it's never used in the current
code base (I may eliminate it, but that's more work because the getter
and setter signatures would have to change.)

As examples, I added actual docstrings to the getset attributes of a
few types: file.closed, xxsubtype.spamdict.state.
diff --git a/Include/descrobject.h b/Include/descrobject.h
index 3d58181..1671ceb 100644
--- a/Include/descrobject.h
+++ b/Include/descrobject.h
@@ -1,14 +1,15 @@
-/* XXX getter, setter, getsetlist and wrapperbase need 'Py'-prefixed names */
+/* Descriptors */
 
 typedef PyObject *(*getter)(PyObject *, void *);
 typedef int (*setter)(PyObject *, PyObject *, void *);
 
-struct getsetlist {
+typedef struct PyGetSetDef {
 	char *name;
 	getter get;
 	setter set;
+	char *doc;
 	void *closure;
-};
+} PyGetSetDef;
 
 typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args,
 				 void *wrapped);
@@ -23,7 +24,7 @@
 extern DL_IMPORT(PyObject *) PyDescr_NewMember(PyTypeObject *,
 					       struct PyMemberDef *);
 extern DL_IMPORT(PyObject *) PyDescr_NewGetSet(PyTypeObject *,
-					       struct getsetlist *);
+					       struct PyGetSetDef *);
 extern DL_IMPORT(PyObject *) PyDescr_NewWrapper(PyTypeObject *,
 						struct wrapperbase *, void *);
 extern DL_IMPORT(int) PyDescr_IsData(PyObject *);
diff --git a/Include/object.h b/Include/object.h
index 1d0ae5f..4529b61 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -275,7 +275,7 @@
 	/* Attribute descriptor and subclassing stuff */
 	struct PyMethodDef *tp_methods;
 	struct PyMemberDef *tp_members;
-	struct getsetlist *tp_getset;
+	struct PyGetSetDef *tp_getset;
 	struct _typeobject *tp_base;
 	PyObject *tp_dict;
 	descrgetfunc tp_descr_get;
diff --git a/Modules/xxsubtype.c b/Modules/xxsubtype.c
index cdf6d07..ae2b619 100644
--- a/Modules/xxsubtype.c
+++ b/Modules/xxsubtype.c
@@ -55,8 +55,9 @@
 	return PyInt_FromLong(self->state);
 }
 
-static struct getsetlist spamlist_getsets[] = {
-	{"state", (getter)spamlist_state_get, NULL, NULL},
+static PyGetSetDef spamlist_getsets[] = {
+	{"state", (getter)spamlist_state_get, NULL,
+	 "an int variable for demonstration purposes"},
 	{0}
 };
 
diff --git a/Objects/classobject.c b/Objects/classobject.c
index f8ee6fd..df10aa2 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -2036,10 +2036,10 @@
 	return PyObject_GetAttrString(im->im_func, "__name__");
 }
 
-static struct getsetlist instancemethod_getsetlist[] = {
-	{"__dict__", (getter)im_get_dict},
-	{"__doc__", (getter)im_get_doc},
-	{"__name__", (getter)im_get_name},
+static PyGetSetDef instancemethod_getsetlist[] = {
+	{"__dict__", (getter)im_get_dict, NULL, "same as im_func.__dict__"},
+	{"__doc__", (getter)im_get_doc, NULL, "same as im_func.__doc__"},
+	{"__name__", (getter)im_get_name, NULL, "same as im_func.__name__"},
 	{NULL}  /* Sentinel */
 };
 
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index dfbb3b6..7be1074 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -26,7 +26,7 @@
 
 typedef struct {
 	COMMON;
-	struct getsetlist *d_getset;
+	PyGetSetDef *d_getset;
 } PyGetSetDescrObject;
 
 typedef struct {
@@ -302,7 +302,7 @@
 	{0}
 };
 
-static struct getsetlist method_getset[] = {
+static PyGetSetDef method_getset[] = {
 	{"__doc__", (getter)method_get_doc},
 	{0}
 };
@@ -317,12 +317,27 @@
 	return PyString_FromString(descr->d_member->doc);
 }
 
-static struct getsetlist member_getset[] = {
+static PyGetSetDef member_getset[] = {
 	{"__doc__", (getter)member_get_doc},
 	{0}
 };
 
 static PyObject *
+getset_get_doc(PyGetSetDescrObject *descr, void *closure)
+{
+	if (descr->d_getset->doc == NULL) {
+		Py_INCREF(Py_None);
+		return Py_None;
+	}
+	return PyString_FromString(descr->d_getset->doc);
+}
+
+static PyGetSetDef getset_getset[] = {
+	{"__doc__", (getter)getset_get_doc},
+	{0}
+};
+
+static PyObject *
 wrapper_get_doc(PyWrapperDescrObject *descr, void *closure)
 {
 	if (descr->d_base->doc == NULL) {
@@ -332,7 +347,7 @@
 	return PyString_FromString(descr->d_base->doc);
 }
 
-static struct getsetlist wrapper_getset[] = {
+static PyGetSetDef wrapper_getset[] = {
 	{"__doc__", (getter)wrapper_get_doc},
 	{0}
 };
@@ -444,7 +459,7 @@
 	0,					/* tp_iternext */
 	0,					/* tp_methods */
 	descr_members,				/* tp_members */
-	0,					/* tp_getset */
+	getset_getset,				/* tp_getset */
 	0,					/* tp_base */
 	0,					/* tp_dict */
 	(descrgetfunc)getset_get,		/* tp_descr_get */
@@ -532,7 +547,7 @@
 }
 
 PyObject *
-PyDescr_NewGetSet(PyTypeObject *type, struct getsetlist *getset)
+PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
 {
 	PyGetSetDescrObject *descr;
 
@@ -778,7 +793,7 @@
 	}
 }
 
-static struct getsetlist wrapper_getsets[] = {
+static PyGetSetDef wrapper_getsets[] = {
 	{"__name__", (getter)wrapper_name},
 	{"__doc__", (getter)wrapper_doc},
 	{0}
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index 5c879ff..b6c039c 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -1400,8 +1400,8 @@
 	return PyInt_FromLong((long)(f->f_fp == 0));
 }
 
-static struct getsetlist file_getsetlist[] = {
-	{"closed", (getter)get_closed, NULL, NULL},
+static PyGetSetDef file_getsetlist[] = {
+	{"closed", (getter)get_closed, NULL, "flag set if the file is closed"},
 	{0},
 };
 
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index cb7e80a..e092ce6 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -33,7 +33,7 @@
 	return f->f_locals;
 }
 
-static struct getsetlist frame_getsetlist[] = {
+static PyGetSetDef frame_getsetlist[] = {
 	{"f_locals",	(getter)frame_getlocals, NULL, NULL},
 	{0}
 };
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index e1cf080..4e77d52 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -257,7 +257,7 @@
 	return 0;
 }
 
-static struct getsetlist func_getsetlist[] = {
+static PyGetSetDef func_getsetlist[] = {
         {"func_code", (getter)func_get_code, (setter)func_set_code},
         {"func_defaults", (getter)func_get_defaults,
 	 (setter)func_set_defaults},
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index 5fe9178..e0968af 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -159,7 +159,7 @@
 	return self;
 }
 
-static struct getsetlist meth_getsets [] = {
+static PyGetSetDef meth_getsets [] = {
 	{"__doc__",  (getter)meth_get__doc__,  NULL, NULL},
 	{"__name__", (getter)meth_get__name__, NULL, NULL},
 	{"__self__", (getter)meth_get__self__, NULL, NULL},
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index b53555d..9e6d3df 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -91,7 +91,7 @@
 	return res;
 }
 
-struct getsetlist type_getsets[] = {
+PyGetSetDef type_getsets[] = {
 	{"__name__", (getter)type_name, NULL, NULL},
 	{"__module__", (getter)type_module, NULL, NULL},
 	{"__dict__",  (getter)type_dict,  NULL, NULL},
@@ -659,7 +659,7 @@
 	}
 }
 
-struct getsetlist subtype_getsets[] = {
+PyGetSetDef subtype_getsets[] = {
 	{"__dict__", subtype_dict, NULL, NULL},
 	{0},
 };
@@ -1282,7 +1282,7 @@
 }
 
 static int
-add_getset(PyTypeObject *type, struct getsetlist *gsp)
+add_getset(PyTypeObject *type, PyGetSetDef *gsp)
 {
 	PyObject *dict = type->tp_defined;