diff options
-rw-r--r-- | Lib/test/test_descr.py | 10 | ||||
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Modules/_testcapimodule.c | 9 | ||||
-rw-r--r-- | Objects/descrobject.c | 22 |
4 files changed, 33 insertions, 10 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 6484ef1..e9286b0 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -2024,6 +2024,16 @@ def properties(): prop2 = property(fset=setter) vereq(prop2.__doc__, None) + # this segfaulted in 2.5b2 + try: + import _testcapi + except ImportError: + pass + else: + class X(object): + p = property(_testcapi.test_with_docstring) + + def supers(): if verbose: print "Testing super..." @@ -21,6 +21,8 @@ Core and builtins in the byte code and co_consts even if they were not used, ie immediately popped off the stack. +- Fixed a reference-counting problem in property(). + Library ------- diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index b90ca57..f5f3ab2 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -706,6 +706,13 @@ test_string_from_format(PyObject *self, PyObject *args) #undef CHECK_1_FORMAT } +/* This is here to provide a docstring for test_descr. */ +static PyObject * +test_with_docstring(PyObject *self) +{ + Py_RETURN_NONE; +} + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"test_config", (PyCFunction)test_config, METH_NOARGS}, @@ -716,6 +723,8 @@ static PyMethodDef TestMethods[] = { {"test_k_code", (PyCFunction)test_k_code, METH_NOARGS}, {"test_null_strings", (PyCFunction)test_null_strings, METH_NOARGS}, {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS}, + {"test_with_docstring", (PyCFunction)test_with_docstring, METH_NOARGS, + PyDoc_STR("This is a pretty normal docstring.")}, {"getargs_tuple", getargs_tuple, METH_VARARGS}, {"getargs_b", getargs_b, METH_VARARGS}, diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 1fe6281..914b6d3 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1190,19 +1190,21 @@ property_init(PyObject *self, PyObject *args, PyObject *kwds) if (del == Py_None) del = NULL; - /* if no docstring given and the getter has one, use that one */ - if ((doc == NULL || doc == Py_None) && get != NULL && - PyObject_HasAttrString(get, "__doc__")) { - doc = PyObject_GetAttrString(get, "__doc__"); - if (doc == NULL) - return -1; - } else { - Py_XINCREF(doc); - } - Py_XINCREF(get); Py_XINCREF(set); Py_XINCREF(del); + Py_XINCREF(doc); + + /* if no docstring given and the getter has one, use that one */ + if ((doc == NULL || doc == Py_None) && get != NULL) { + PyObject *get_doc = PyObject_GetAttrString(get, "__doc__"); + if (get_doc != NULL) { + Py_XDECREF(doc); + doc = get_doc; /* get_doc already INCREF'd by GetAttr */ + } else { + PyErr_Clear(); + } + } gs->prop_get = get; gs->prop_set = set; |