Guido van Rossum added the comment:

propset2.diff is a new version that improves upon the heuristic for
making the deleter match the setter: when changing setters, if the old
deleter is the same as the old setter, it will replace both the deleter
and setter.

This diff is relative to the 2.6 trunk; it applies to 3.0 too.

Added file: http://bugs.python.org/file8726/propset2.diff

__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1416>
__________________________________
Index: Objects/descrobject.c
===================================================================
--- Objects/descrobject.c	(revision 58906)
+++ Objects/descrobject.c	(working copy)
@@ -1108,7 +1108,72 @@
 	{0}
 };
 
+PyDoc_STRVAR(getter_doc,
+	     "Descriptor to change the setter on a property.");
 
+PyObject *
+property_getter(PyObject *self, PyObject *getter)
+{
+	Py_XDECREF(((propertyobject *)self)->prop_get);
+	if (getter == Py_None)
+		getter = NULL;
+	Py_XINCREF(getter);
+	((propertyobject *)self)->prop_get = getter;
+	Py_INCREF(self);
+	return self;
+}
+
+PyDoc_STRVAR(setter_doc,
+	     "Descriptor to change the setter on a property.\n"
+	     "This also sets the deleter if it hasn't been set before.");
+
+PyObject *
+property_setter(PyObject *self, PyObject *setter)
+{
+	propertyobject *pself = (propertyobject *)self;
+
+	if (pself->prop_del != NULL && pself->prop_del == pself->prop_set) {
+		Py_DECREF(pself->prop_del);
+		pself->prop_del = NULL;
+	}
+	Py_XDECREF(pself->prop_set);
+	if (setter == Py_None)
+		setter = NULL;
+	Py_XINCREF(setter);
+	pself->prop_set = setter;
+	if (pself->prop_del == NULL && setter != NULL) {
+		Py_INCREF(setter);
+		pself->prop_del = setter;
+	}
+	Py_INCREF(self);
+	return self;
+}
+
+PyDoc_STRVAR(deleter_doc,
+	     "Descriptor to change the deleter on a property.");
+
+PyObject *
+property_deleter(PyObject *self, PyObject *deleter)
+{
+	Py_XDECREF(((propertyobject *)self)->prop_del);
+	if (deleter == Py_None)
+		deleter = NULL;
+	Py_XINCREF(deleter);
+	((propertyobject *)self)->prop_del = deleter;
+	Py_INCREF(self);
+	return self;
+}
+
+
+
+static PyMethodDef property_methods[] = {
+	{"getter", property_getter, METH_O, getter_doc},
+	{"setter", property_setter, METH_O, setter_doc},
+	{"deleter", property_deleter, METH_O, deleter_doc},
+	{0}
+};
+
+
 static void
 property_dealloc(PyObject *self)
 {
@@ -1260,7 +1325,7 @@
 	0,					/* tp_weaklistoffset */
 	0,					/* tp_iter */
 	0,					/* tp_iternext */
-	0,					/* tp_methods */
+	property_methods,			/* tp_methods */
 	property_members,			/* tp_members */
 	0,					/* tp_getset */
 	0,					/* tp_base */
Index: Lib/rfc822.py
===================================================================
--- Lib/rfc822.py	(revision 58906)
+++ Lib/rfc822.py	(working copy)
@@ -160,8 +160,7 @@
             if headerseen and line[0] in ' \t':
                 # It's a continuation line.
                 lst.append(line)
-                x = (self.dict[headerseen] + "\n " + line.strip())
-                self.dict[headerseen] = x.strip()
+                self.dict[headerseen] += line.rstrip()
                 continue
             elif self.iscomment(line):
                 # It's a comment.  Ignore it.
Index: Lib/test/test_descr.py
===================================================================
--- Lib/test/test_descr.py	(revision 58906)
+++ Lib/test/test_descr.py	(working copy)
@@ -2131,6 +2131,70 @@
             p = property(_testcapi.test_with_docstring)
 
 
+def properties_more():
+    class C:
+        foo = property(doc="hello")
+        @foo.getter
+        def foo(self):
+            return self._foo
+        @foo.setter
+        def foo(self, value=None):
+            if value is None:
+                del self._foo
+            else:
+                self._foo = abs(value)
+    c = C()
+    assert C.foo.__doc__ == "hello"
+    assert not hasattr(c, "foo")
+    c.foo = -42
+    assert c.foo == 42
+    del c.foo
+    assert not hasattr(c, "foo")
+
+    class D(C):
+        @C.foo.deleter
+        def foo(self):
+            try:
+                del self._foo
+            except AttributeError:
+                pass
+    d = D()
+    d.foo = 24
+    assert d.foo == 24
+    del d.foo
+    del d.foo
+
+    class E:
+        @property
+        def foo(self):
+            return self._foo
+        @foo.setter
+        def foo (self, value=None):
+            raise RuntimeError
+        @foo.setter
+        def foo(self, value=None):
+            if value is None:
+                del self._foo
+            else:
+                self._foo = abs(value)
+    e = E()
+    e.foo = -42
+    assert e.foo == 42
+    del e.foo
+
+    class F(E):
+        @E.foo.deleter
+        def foo(self):
+            del self._foo
+        @foo.setter
+        def foo(self, value):
+            self._foo = max(0, value)
+    f = F()
+    f.foo = -10
+    assert f.foo == 0
+    del f.foo
+
+
 def supers():
     if verbose: print "Testing super..."
 
_______________________________________________
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to