SF patch 530070: pydoc regression, from Martin and Guido.

Change the way __doc__ is handled, to avoid blowing up on non-string
__doc__ values.
This commit is contained in:
Tim Peters 2002-03-17 18:56:20 +00:00
parent 587c98c863
commit 2400831773
2 changed files with 30 additions and 5 deletions

View File

@ -263,8 +263,17 @@ def getdoc(object):
All tabs are expanded to spaces. To clean up docstrings that are All tabs are expanded to spaces. To clean up docstrings that are
indented to line up with blocks of code, any whitespace than can be indented to line up with blocks of code, any whitespace than can be
uniformly removed from the second line onwards is removed.""" uniformly removed from the second line onwards is removed."""
if hasattr(object, '__doc__') and object.__doc__: try:
lines = string.split(string.expandtabs(object.__doc__), '\n') doc = object.__doc__
except AttributeError:
return None
if not isinstance(doc, (str, unicode)):
return None
try:
lines = string.split(string.expandtabs(doc), '\n')
except UnicodeError:
return None
else:
margin = None margin = None
for line in lines[1:]: for line in lines[1:]:
content = len(string.lstrip(line)) content = len(string.lstrip(line))

View File

@ -79,10 +79,27 @@ type_dict(PyTypeObject *type, void *context)
return PyDictProxy_New(type->tp_dict); return PyDictProxy_New(type->tp_dict);
} }
static PyObject *
type_get_doc(PyTypeObject *type, void *context)
{
PyObject *result;
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
if (type->tp_doc == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
return PyString_FromString(type->tp_doc);
}
result = PyDict_GetItemString(type->tp_dict, "__doc__");
Py_INCREF(result);
return result;
}
static PyGetSetDef type_getsets[] = { static PyGetSetDef type_getsets[] = {
{"__name__", (getter)type_name, NULL, NULL}, {"__name__", (getter)type_name, NULL, NULL},
{"__module__", (getter)type_module, (setter)type_set_module, NULL}, {"__module__", (getter)type_module, (setter)type_set_module, NULL},
{"__dict__", (getter)type_dict, NULL, NULL}, {"__dict__", (getter)type_dict, NULL, NULL},
{"__doc__", (getter)type_get_doc, NULL, NULL},
{0} {0}
}; };
@ -1079,9 +1096,8 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
} }
/* Set tp_doc to a copy of dict['__doc__'], if the latter is there /* Set tp_doc to a copy of dict['__doc__'], if the latter is there
and is a string. Note that the tp_doc slot will only be used and is a string. The __doc__ accessor will first look for tp_doc;
by C code -- python code will use the version in tp_dict, so if that fails, it will still look into __dict__.
it isn't that important that non string __doc__'s are ignored.
*/ */
{ {
PyObject *doc = PyDict_GetItemString(dict, "__doc__"); PyObject *doc = PyDict_GetItemString(dict, "__doc__");