]> granicus.if.org Git - python/commitdiff
SF patch 530070: pydoc regression, from Martin and Guido.
authorTim Peters <tim.peters@gmail.com>
Sun, 17 Mar 2002 18:56:20 +0000 (18:56 +0000)
committerTim Peters <tim.peters@gmail.com>
Sun, 17 Mar 2002 18:56:20 +0000 (18:56 +0000)
Change the way __doc__ is handled, to avoid blowing up on non-string
__doc__ values.

Lib/inspect.py
Objects/typeobject.c

index 806f52669079427552480353b694284e5e477802..9e2d23d58baa16270d184afd76a986ef5f3c2cab 100644 (file)
@@ -263,8 +263,17 @@ def getdoc(object):
     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
     uniformly removed from the second line onwards is removed."""
-    if hasattr(object, '__doc__') and object.__doc__:
-        lines = string.split(string.expandtabs(object.__doc__), '\n')
+    try:
+        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
         for line in lines[1:]:
             content = len(string.lstrip(line))
index ca7e64d8cfb1c809ae7813d72b6d6adea78f6a4c..c938f524536d527b63e17739ab62a0aa3f4dd95e 100644 (file)
@@ -79,10 +79,27 @@ type_dict(PyTypeObject *type, void *context)
        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[] = {
        {"__name__", (getter)type_name, NULL, NULL},
        {"__module__", (getter)type_module, (setter)type_set_module, NULL},
        {"__dict__",  (getter)type_dict,  NULL, NULL},
+       {"__doc__", (getter)type_get_doc, NULL, NULL},
        {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
-          and is a string.  Note that the tp_doc slot will only be used
-          by C code -- python code will use the version in tp_dict, so
-          it isn't that important that non string __doc__'s are ignored.
+          and is a string.  The __doc__ accessor will first look for tp_doc;
+          if that fails, it will still look into __dict__.
        */
        {
                PyObject *doc = PyDict_GetItemString(dict, "__doc__");