From 32d34c809f5971f79462dcb7d0f536d46e624acc Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Thu, 20 Sep 2001 21:45:26 +0000 Subject: [PATCH] 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. --- Include/descrobject.h | 9 +++++---- Include/object.h | 2 +- Modules/xxsubtype.c | 5 +++-- Objects/classobject.c | 8 ++++---- Objects/descrobject.c | 29 ++++++++++++++++++++++------- Objects/fileobject.c | 4 ++-- Objects/frameobject.c | 2 +- Objects/funcobject.c | 2 +- Objects/methodobject.c | 2 +- Objects/typeobject.c | 6 +++--- 10 files changed, 43 insertions(+), 26 deletions(-) diff --git a/Include/descrobject.h b/Include/descrobject.h index 3d581818f59..1671cebe1bf 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_NewMethod(PyTypeObject *, PyMethodDef *); 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 1d0ae5f0953..4529b614235 100644 --- a/Include/object.h +++ b/Include/object.h @@ -275,7 +275,7 @@ typedef struct _typeobject { /* 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 cdf6d07329c..ae2b619dd3f 100644 --- a/Modules/xxsubtype.c +++ b/Modules/xxsubtype.c @@ -55,8 +55,9 @@ spamlist_state_get(spamlistobject *self) 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 f8ee6fddad9..df10aa20ee5 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -2036,10 +2036,10 @@ im_get_name(PyMethodObject *im) 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 dfbb3b628f6..7be10747791 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -26,7 +26,7 @@ typedef struct { typedef struct { COMMON; - struct getsetlist *d_getset; + PyGetSetDef *d_getset; } PyGetSetDescrObject; typedef struct { @@ -302,7 +302,7 @@ static PyMemberDef descr_members[] = { {0} }; -static struct getsetlist method_getset[] = { +static PyGetSetDef method_getset[] = { {"__doc__", (getter)method_get_doc}, {0} }; @@ -317,11 +317,26 @@ member_get_doc(PyMemberDescrObject *descr, void *closure) 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) { @@ -332,7 +347,7 @@ wrapper_get_doc(PyWrapperDescrObject *descr, void *closure) 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 @@ static PyTypeObject PyGetSetDescr_Type = { 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 @@ PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member) } PyObject * -PyDescr_NewGetSet(PyTypeObject *type, struct getsetlist *getset) +PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset) { PyGetSetDescrObject *descr; @@ -778,7 +793,7 @@ wrapper_doc(wrapperobject *wp) } } -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 5c879ff1d4c..b6c039ccbcb 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -1400,8 +1400,8 @@ get_closed(PyFileObject *f, void *closure) 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 cb7e80a3fe2..e092ce62408 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -33,7 +33,7 @@ frame_getlocals(PyFrameObject *f, void *closure) 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 e1cf0808620..4e77d524342 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -257,7 +257,7 @@ func_set_defaults(PyFunctionObject *op, PyObject *value) 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 5fe91780557..e0968afc763 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -159,7 +159,7 @@ meth_get__self__(PyCFunctionObject *m, void *closure) 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 b53555d6678..9e6d3dfc06d 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -91,7 +91,7 @@ type_dynamic(PyTypeObject *type, void *context) 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 @@ subtype_dict(PyObject *obj, void *context) } } -struct getsetlist subtype_getsets[] = { +PyGetSetDef subtype_getsets[] = { {"__dict__", subtype_dict, NULL, NULL}, {0}, }; @@ -1282,7 +1282,7 @@ add_members(PyTypeObject *type, PyMemberDef *memb) } static int -add_getset(PyTypeObject *type, struct getsetlist *gsp) +add_getset(PyTypeObject *type, PyGetSetDef *gsp) { PyObject *dict = type->tp_defined;