]> granicus.if.org Git - python/commitdiff
Change fix for segfaulting property(), add a NEWS entry and a test.
authorGeorg Brandl <georg@python.org>
Fri, 4 Aug 2006 18:03:37 +0000 (18:03 +0000)
committerGeorg Brandl <georg@python.org>
Fri, 4 Aug 2006 18:03:37 +0000 (18:03 +0000)
Lib/test/test_descr.py
Misc/NEWS
Modules/_testcapimodule.c
Objects/descrobject.c

index 6484ef1a75812ba6a632aeaae5d3b762ad17bb55..e9286b0e6a202d740e809e748721e64227ff9369 100644 (file)
@@ -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..."
 
index 3c1ba7f1de1a6de427ead5e693a924e5cea554aa..5b7830968a6cd33dfa575cbc4186772799dd4aee 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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
 -------
index b90ca5763c9c8aac96db7d0d09fbea334e2dd9e5..f5f3ab23bdcb07e51dd5465e8b7c8b76559621a1 100644 (file)
@@ -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},
index 1fe62812a200630bb530af4de19c543c728bc411..914b6d35a1244cb792efd8019643350de3e9496f 100644 (file)
@@ -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;