summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_descr.py35
-rw-r--r--Lib/test/test_doctest2.py6
-rw-r--r--Objects/typeobject.c25
3 files changed, 59 insertions, 7 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 4ed6853..cd65c2c 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -88,6 +88,38 @@ def testset3op(a, b, c, d, res, stmt="a[b:c]=d", meth="__setslice__"):
bm(b, c, d)
verify(dict['a'] == res)
+def class_docstrings():
+ class Classic:
+ "A classic docstring."
+ verify(Classic.__doc__ == "A classic docstring.")
+ verify(Classic.__dict__['__doc__'] == "A classic docstring.")
+
+ class Classic2:
+ pass
+ verify(Classic2.__doc__ is None)
+
+ class NewStatic:
+ "Another docstring."
+ __dynamic__ = 0
+ verify(NewStatic.__doc__ == "Another docstring.")
+ verify(NewStatic.__dict__['__doc__'] == "Another docstring.")
+
+ class NewStatic2:
+ __dynamic__ = 0
+ pass
+ verify(NewStatic2.__doc__ is None)
+
+ class NewDynamic:
+ "Another docstring."
+ __dynamic__ = 1
+ verify(NewDynamic.__doc__ == "Another docstring.")
+ verify(NewDynamic.__dict__['__doc__'] == "Another docstring.")
+
+ class NewDynamic2:
+ __dynamic__ = 1
+ pass
+ verify(NewDynamic2.__doc__ is None)
+
def lists():
if verbose: print "Testing list operations..."
testbinop([1], [2], [1,2], "a+b", "__add__")
@@ -2168,7 +2200,7 @@ def binopoverride():
return I(pow(int(other), int(self), mod))
else:
return I(pow(int(other), int(self), int(mod)))
-
+
vereq(`I(1) + I(2)`, "I(3)")
vereq(`I(1) + 2`, "I(3)")
vereq(`1 + I(2)`, "I(3)")
@@ -2182,6 +2214,7 @@ def binopoverride():
def test_main():
+ class_docstrings()
lists()
dicts()
dict_constructor()
diff --git a/Lib/test/test_doctest2.py b/Lib/test/test_doctest2.py
index 9a0e57c..00b6cc4 100644
--- a/Lib/test/test_doctest2.py
+++ b/Lib/test/test_doctest2.py
@@ -7,7 +7,6 @@ yup
import test_support
-# XXX The class docstring is skipped.
class C(object):
"""Class C.
@@ -29,7 +28,6 @@ class C(object):
"""
return "42"
- # XXX The class docstring is skipped.
class D(object):
"""A nested D class.
@@ -96,9 +94,7 @@ class C(object):
def test_main():
import test_doctest2
- # XXX 2 class docstrings are skipped.
- # EXPECTED = 19
- EXPECTED = 17
+ EXPECTED = 19
f, t = test_support.run_doctest(test_doctest2)
if t != EXPECTED:
raise test_support.TestFailed("expected %d tests to run, not %d" %
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index c50b446..e8f436c 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -900,6 +900,24 @@ 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 (tp_doc is a char* -- can't copy a general object
+ into it).
+ XXX What if it's a Unicode string? Don't know -- this ignores it.
+ */
+ {
+ PyObject *doc = PyDict_GetItemString(dict, "__doc__");
+ if (doc != NULL && PyString_Check(doc)) {
+ const size_t n = (size_t)PyString_GET_SIZE(doc);
+ type->tp_doc = PyObject_MALLOC(n+1);
+ if (type->tp_doc == NULL) {
+ Py_DECREF(type);
+ return NULL;
+ }
+ memcpy(type->tp_doc, PyString_AS_STRING(doc), n+1);
+ }
+ }
+
/* Special-case __new__: if it's a plain function,
make it a static function */
tmp = PyDict_GetItemString(dict, "__new__");
@@ -1162,6 +1180,11 @@ type_clear(PyTypeObject *type)
CLEAR(type->tp_base);
CLEAR(et->slots);
+ if (type->tp_doc != NULL) {
+ PyObject_FREE(type->tp_doc);
+ type->tp_doc = NULL;
+ }
+
#undef CLEAR
return 0;
@@ -1350,7 +1373,7 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
PyErr_Format(PyExc_TypeError,
"__class__ assignment: "
"'%s' object layout differs from '%s'",
- new->tp_name,
+ new->tp_name,
old->tp_name);
return -1;
}