From 01fc6cd056ba5b389af55c58d46fbe1a33767d0c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 17 Aug 2011 12:03:47 -0500 Subject: [PATCH] make __doc__ mutable on heaptypes (closes #12773) --- Lib/test/test_descr.py | 13 +++++++++++++ Misc/NEWS | 2 ++ Objects/typeobject.c | 11 ++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index aade9f5a451..2a9f88083b9 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -4261,6 +4261,19 @@ order (MRO) for bases """ m = str(cm.exception) self.assertEqual("'foo' in __slots__ conflicts with class variable", m) + def test_set_doc(self): + class X: + "elephant" + X.__doc__ = "banana" + self.assertEqual(X.__doc__, "banana") + with self.assertRaises(TypeError) as cm: + type(list).__dict__["__doc__"].__set__(list, "blah") + self.assertIn("can't set list.__doc__", str(cm.exception)) + with self.assertRaises(TypeError) as cm: + type(X).__dict__["__doc__"].__delete__(X) + self.assertIn("can't delete X.__doc__", str(cm.exception)) + self.assertEqual(X.__doc__, "banana") + class DictProxyTests(unittest.TestCase): def setUp(self): class C(object): diff --git a/Misc/NEWS b/Misc/NEWS index 4cf9dda5488..e30a3cb627b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,8 @@ What's New in Python 3.3 Alpha 1? Core and Builtins ----------------- +- Issue #12773: Make __doc__ mutable on user-defined classes. + - Issue #12766: Raise an ValueError when creating a class with a class variable that conflicts with a name in __slots__. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 33becb3e7e3..640d14f2f0c 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -588,6 +588,15 @@ type_get_doc(PyTypeObject *type, void *context) return result; } +static int +type_set_doc(PyTypeObject *type, PyObject *value, void *context) +{ + if (!check_set_special_type_attr(type, value, "__doc__")) + return -1; + PyType_Modified(type); + return PyDict_SetItemString(type->tp_dict, "__doc__", value); +} + static PyObject * type___instancecheck__(PyObject *type, PyObject *inst) { @@ -623,7 +632,7 @@ static PyGetSetDef type_getsets[] = { {"__abstractmethods__", (getter)type_abstractmethods, (setter)type_set_abstractmethods, NULL}, {"__dict__", (getter)type_dict, NULL, NULL}, - {"__doc__", (getter)type_get_doc, NULL, NULL}, + {"__doc__", (getter)type_get_doc, (setter)type_set_doc, NULL}, {0} };