Skip to content

Commit 32d34c8

Browse files
committed
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.
1 parent a56b42b commit 32d34c8

10 files changed

Lines changed: 43 additions & 26 deletions

File tree

Include/descrobject.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
/* XXX getter, setter, getsetlist and wrapperbase need 'Py'-prefixed names */
1+
/* Descriptors */
22

33
typedef PyObject *(*getter)(PyObject *, void *);
44
typedef int (*setter)(PyObject *, PyObject *, void *);
55

6-
struct getsetlist {
6+
typedef struct PyGetSetDef {
77
char *name;
88
getter get;
99
setter set;
10+
char *doc;
1011
void *closure;
11-
};
12+
} PyGetSetDef;
1213

1314
typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args,
1415
void *wrapped);
@@ -23,7 +24,7 @@ extern DL_IMPORT(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *);
2324
extern DL_IMPORT(PyObject *) PyDescr_NewMember(PyTypeObject *,
2425
struct PyMemberDef *);
2526
extern DL_IMPORT(PyObject *) PyDescr_NewGetSet(PyTypeObject *,
26-
struct getsetlist *);
27+
struct PyGetSetDef *);
2728
extern DL_IMPORT(PyObject *) PyDescr_NewWrapper(PyTypeObject *,
2829
struct wrapperbase *, void *);
2930
extern DL_IMPORT(int) PyDescr_IsData(PyObject *);

Include/object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ typedef struct _typeobject {
275275
/* Attribute descriptor and subclassing stuff */
276276
struct PyMethodDef *tp_methods;
277277
struct PyMemberDef *tp_members;
278-
struct getsetlist *tp_getset;
278+
struct PyGetSetDef *tp_getset;
279279
struct _typeobject *tp_base;
280280
PyObject *tp_dict;
281281
descrgetfunc tp_descr_get;

Modules/xxsubtype.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,9 @@ spamlist_state_get(spamlistobject *self)
5555
return PyInt_FromLong(self->state);
5656
}
5757

58-
static struct getsetlist spamlist_getsets[] = {
59-
{"state", (getter)spamlist_state_get, NULL, NULL},
58+
static PyGetSetDef spamlist_getsets[] = {
59+
{"state", (getter)spamlist_state_get, NULL,
60+
"an int variable for demonstration purposes"},
6061
{0}
6162
};
6263

Objects/classobject.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2036,10 +2036,10 @@ im_get_name(PyMethodObject *im)
20362036
return PyObject_GetAttrString(im->im_func, "__name__");
20372037
}
20382038

2039-
static struct getsetlist instancemethod_getsetlist[] = {
2040-
{"__dict__", (getter)im_get_dict},
2041-
{"__doc__", (getter)im_get_doc},
2042-
{"__name__", (getter)im_get_name},
2039+
static PyGetSetDef instancemethod_getsetlist[] = {
2040+
{"__dict__", (getter)im_get_dict, NULL, "same as im_func.__dict__"},
2041+
{"__doc__", (getter)im_get_doc, NULL, "same as im_func.__doc__"},
2042+
{"__name__", (getter)im_get_name, NULL, "same as im_func.__name__"},
20432043
{NULL} /* Sentinel */
20442044
};
20452045

Objects/descrobject.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ typedef struct {
2626

2727
typedef struct {
2828
COMMON;
29-
struct getsetlist *d_getset;
29+
PyGetSetDef *d_getset;
3030
} PyGetSetDescrObject;
3131

3232
typedef struct {
@@ -302,7 +302,7 @@ static PyMemberDef descr_members[] = {
302302
{0}
303303
};
304304

305-
static struct getsetlist method_getset[] = {
305+
static PyGetSetDef method_getset[] = {
306306
{"__doc__", (getter)method_get_doc},
307307
{0}
308308
};
@@ -317,11 +317,26 @@ member_get_doc(PyMemberDescrObject *descr, void *closure)
317317
return PyString_FromString(descr->d_member->doc);
318318
}
319319

320-
static struct getsetlist member_getset[] = {
320+
static PyGetSetDef member_getset[] = {
321321
{"__doc__", (getter)member_get_doc},
322322
{0}
323323
};
324324

325+
static PyObject *
326+
getset_get_doc(PyGetSetDescrObject *descr, void *closure)
327+
{
328+
if (descr->d_getset->doc == NULL) {
329+
Py_INCREF(Py_None);
330+
return Py_None;
331+
}
332+
return PyString_FromString(descr->d_getset->doc);
333+
}
334+
335+
static PyGetSetDef getset_getset[] = {
336+
{"__doc__", (getter)getset_get_doc},
337+
{0}
338+
};
339+
325340
static PyObject *
326341
wrapper_get_doc(PyWrapperDescrObject *descr, void *closure)
327342
{
@@ -332,7 +347,7 @@ wrapper_get_doc(PyWrapperDescrObject *descr, void *closure)
332347
return PyString_FromString(descr->d_base->doc);
333348
}
334349

335-
static struct getsetlist wrapper_getset[] = {
350+
static PyGetSetDef wrapper_getset[] = {
336351
{"__doc__", (getter)wrapper_get_doc},
337352
{0}
338353
};
@@ -444,7 +459,7 @@ static PyTypeObject PyGetSetDescr_Type = {
444459
0, /* tp_iternext */
445460
0, /* tp_methods */
446461
descr_members, /* tp_members */
447-
0, /* tp_getset */
462+
getset_getset, /* tp_getset */
448463
0, /* tp_base */
449464
0, /* tp_dict */
450465
(descrgetfunc)getset_get, /* tp_descr_get */
@@ -532,7 +547,7 @@ PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member)
532547
}
533548

534549
PyObject *
535-
PyDescr_NewGetSet(PyTypeObject *type, struct getsetlist *getset)
550+
PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
536551
{
537552
PyGetSetDescrObject *descr;
538553

@@ -778,7 +793,7 @@ wrapper_doc(wrapperobject *wp)
778793
}
779794
}
780795

781-
static struct getsetlist wrapper_getsets[] = {
796+
static PyGetSetDef wrapper_getsets[] = {
782797
{"__name__", (getter)wrapper_name},
783798
{"__doc__", (getter)wrapper_doc},
784799
{0}

Objects/fileobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,8 +1400,8 @@ get_closed(PyFileObject *f, void *closure)
14001400
return PyInt_FromLong((long)(f->f_fp == 0));
14011401
}
14021402

1403-
static struct getsetlist file_getsetlist[] = {
1404-
{"closed", (getter)get_closed, NULL, NULL},
1403+
static PyGetSetDef file_getsetlist[] = {
1404+
{"closed", (getter)get_closed, NULL, "flag set if the file is closed"},
14051405
{0},
14061406
};
14071407

Objects/frameobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ frame_getlocals(PyFrameObject *f, void *closure)
3333
return f->f_locals;
3434
}
3535

36-
static struct getsetlist frame_getsetlist[] = {
36+
static PyGetSetDef frame_getsetlist[] = {
3737
{"f_locals", (getter)frame_getlocals, NULL, NULL},
3838
{0}
3939
};

Objects/funcobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ func_set_defaults(PyFunctionObject *op, PyObject *value)
257257
return 0;
258258
}
259259

260-
static struct getsetlist func_getsetlist[] = {
260+
static PyGetSetDef func_getsetlist[] = {
261261
{"func_code", (getter)func_get_code, (setter)func_set_code},
262262
{"func_defaults", (getter)func_get_defaults,
263263
(setter)func_set_defaults},

Objects/methodobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ meth_get__self__(PyCFunctionObject *m, void *closure)
159159
return self;
160160
}
161161

162-
static struct getsetlist meth_getsets [] = {
162+
static PyGetSetDef meth_getsets [] = {
163163
{"__doc__", (getter)meth_get__doc__, NULL, NULL},
164164
{"__name__", (getter)meth_get__name__, NULL, NULL},
165165
{"__self__", (getter)meth_get__self__, NULL, NULL},

Objects/typeobject.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ type_dynamic(PyTypeObject *type, void *context)
9191
return res;
9292
}
9393

94-
struct getsetlist type_getsets[] = {
94+
PyGetSetDef type_getsets[] = {
9595
{"__name__", (getter)type_name, NULL, NULL},
9696
{"__module__", (getter)type_module, NULL, NULL},
9797
{"__dict__", (getter)type_dict, NULL, NULL},
@@ -659,7 +659,7 @@ subtype_dict(PyObject *obj, void *context)
659659
}
660660
}
661661

662-
struct getsetlist subtype_getsets[] = {
662+
PyGetSetDef subtype_getsets[] = {
663663
{"__dict__", subtype_dict, NULL, NULL},
664664
{0},
665665
};
@@ -1282,7 +1282,7 @@ add_members(PyTypeObject *type, PyMemberDef *memb)
12821282
}
12831283

12841284
static int
1285-
add_getset(PyTypeObject *type, struct getsetlist *gsp)
1285+
add_getset(PyTypeObject *type, PyGetSetDef *gsp)
12861286
{
12871287
PyObject *dict = type->tp_defined;
12881288

0 commit comments

Comments
 (0)